14 #include <shared_mutex>
16 #include <type_traits>
23 template <
typename Value,
typename... Args>
36 static_assert( !std::is_reference_v<Value>,
"Value must not be a reference" );
45 static_assert( std::is_default_constructible_v<Value> );
48 static_assert( std::is_copy_assignable_v<Value> );
49 auto lock = std::scoped_lock{ rhs.
m_mtx,
m_mtx };
54 static_assert( std::is_copy_assignable_v<Value> );
56 auto lock = std::scoped_lock{ rhs.
m_mtx,
m_mtx };
63 static_assert( std::is_default_constructible_v<Value> );
66 static_assert( std::is_move_assignable_v<Value> );
67 auto lock = std::scoped_lock{ rhs.m_mtx,
m_mtx };
72 static_assert( std::is_move_assignable_v<Value> );
74 auto lock = std::scoped_lock{ rhs.m_mtx,
m_mtx };
80 template <
typename F,
typename... Args,
81 typename = std::enable_if_t<std::is_invocable_v<F,
Value&, Args...> &&
82 !std::is_invocable_v<F,
const Value&, Args...>>>
85 return std::invoke( std::forward<F>( f ),
m_obj, std::forward<Args>(
args )... );
88 template <
typename F,
typename... Args,
typename = std::enable_if_t<std::is_invocable_v<F,
const Value&, Args...>>>
91 return std::invoke( std::forward<F>( f ),
m_obj, std::forward<Args>(
args )... );
96 template <
typename Fun>
98 return [f = std::forward<Fun>( f )](
auto& p,
auto&&...
args ) -> decltype(
auto ) {
103 template <
typename ContainerOfSynced,
typename Fun>