27 typename ReadLock = std::conditional_t<std::is_same_v<std::shared_mutex, Mutex>, std::shared_lock<Mutex>,
36 template <
typename... Args>
37 requires std::constructible_from<Value, Args...> &&
38 (
sizeof...( Args ) != 1 || !( std::same_as<SynchronizedValue, std::remove_cvref_t<Args>> || ... ) )
42 requires std::constructible_from<Value, Value const&>
44 auto _ = ReadLock{ rhs.m_mtx };
45 return Value( rhs.m_obj );
49 requires std::assignable_from<Value&, Value const&>
52 auto _ = std::scoped_lock{ rhs.m_mtx,
m_mtx };
59 requires std::constructible_from<Value, Value&&>
61 auto _ = WriteLock{ rhs.m_mtx };
62 return Value( std::move( rhs.m_obj ) );
66 requires std::assignable_from<Value&, Value&&>
69 auto _ = 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 ) {
78 auto _ = WriteLock{
m_mtx };
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 {
84 auto _ = ReadLock{
m_mtx };
85 return std::invoke( std::forward<F>( f ),
m_obj, std::forward<Args>( args )... );