26 typename ReadLock = std::conditional_t<std::is_same_v<std::shared_mutex, Mutex>, std::shared_lock<Mutex>,
30 static_assert( !std::is_reference_v<Value>,
"Value must not be a reference" );
35 template <
typename... Args>
36 requires( std::is_constructible_v<Value, Args...> )
40 static_assert( std::is_default_constructible_v<Value> );
43 static_assert( std::is_copy_assignable_v<Value> );
44 auto lock = std::scoped_lock{ rhs.
m_mtx,
m_mtx };
49 static_assert( std::is_copy_assignable_v<Value> );
51 auto lock = std::scoped_lock{ rhs.
m_mtx,
m_mtx };
58 static_assert( std::is_default_constructible_v<Value> );
61 static_assert( std::is_move_assignable_v<Value> );
62 auto lock = std::scoped_lock{ rhs.m_mtx,
m_mtx };
63 m_obj = std::move( rhs.m_obj );
67 static_assert( std::is_move_assignable_v<Value> );
69 auto lock = std::scoped_lock{ rhs.m_mtx,
m_mtx };
70 m_obj = std::move( rhs.m_obj );
75 template <
typename... Args, std::invocable<Value&, Args...> F>
76 requires( !std::is_invocable_v<F,
const Value&, Args...> )
77 decltype(
auto )
with_lock( F&& f, Args&&... args ) {
79 return std::invoke( std::forward<F>( f ),
m_obj, std::forward<Args>( args )... );
82 template <
typename... Args, std::invocable<
const Value&, Args...> F>
83 decltype( auto )
with_lock( F&& f, Args&&... args )
const {
85 return std::invoke( std::forward<F>( f ),
m_obj, std::forward<Args>( args )... );