15 #include <shared_mutex>
17 #include <type_traits>
24 template <
typename Value,
typename... Args>
37 static_assert( !std::is_reference_v<Value>,
"Value must not be a reference" );
46 static_assert( std::is_default_constructible_v<Value> );
49 static_assert( std::is_copy_assignable_v<Value> );
50 auto lock = std::scoped_lock{ rhs.
m_mtx,
m_mtx };
55 static_assert( std::is_copy_assignable_v<Value> );
57 auto lock = std::scoped_lock{ rhs.
m_mtx,
m_mtx };
64 static_assert( std::is_default_constructible_v<Value> );
67 static_assert( std::is_move_assignable_v<Value> );
68 auto lock = std::scoped_lock{ rhs.m_mtx,
m_mtx };
73 static_assert( std::is_move_assignable_v<Value> );
75 auto lock = std::scoped_lock{ rhs.m_mtx,
m_mtx };
81 template <
typename F,
typename... Args,
82 typename = std::enable_if_t<std::is_invocable_v<F,
Value&, Args...> &&
83 !std::is_invocable_v<F,
const Value&, Args...>>>
86 return std::invoke( std::forward<F>( f ),
m_obj, std::forward<Args>(
args )... );
89 template <
typename F,
typename... Args,
typename = std::enable_if_t<std::is_invocable_v<F,
const Value&, Args...>>>
92 return std::invoke( std::forward<F>( f ),
m_obj, std::forward<Args>(
args )... );
97 template <
typename Fun>
99 return [f = std::forward<Fun>( f )](
auto& p,
auto&&...
args ) -> decltype(
auto ) {
104 template <
typename ContainerOfSynced,
typename Fun>