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... Args, std::invocable<
Value&, Args...> F>
82 requires( !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... Args, std::invocable<
const Value&, Args...> F>
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>