7#include "min-cpp-version/cpp20.h"
23 { t.try_lock() } -> std::convertible_to<bool>;
31 { t.try_lock_for(std::chrono::seconds(1)) } -> std::convertible_to<bool>;
32 { t.try_lock_until(std::chrono::high_resolution_clock::now()) } -> std::convertible_to<bool>;
40 { t.try_lock_shared() } -> std::convertible_to<bool>;
41 { t.unlock_shared() };
45 template <
mutexlike MUTEX_TYPE,
typename FUNC,
typename... ARGS>
48 std::unique_lock<MUTEX_TYPE> guard{ m };
49 if constexpr (std::is_invocable_v<FUNC, MUTEX_TYPE&, ARGS...>)
50 return func(m, std::forward<ARGS>(args)...);
52 return func(std::forward<ARGS>(args)...);
56 template <shared_mutexlike MUTEX_TYPE,
typename FUNC,
typename... ARGS>
59 std::shared_lock<MUTEX_TYPE> guard{ m };
60 if constexpr (std::is_invocable_v<FUNC, MUTEX_TYPE&, ARGS...>)
61 return func(m, std::forward<ARGS>(args)...);
63 return func(std::forward<ARGS>(args)...);
67 template <mutexlike MUTEX_TYPE,
typename T>
70 using lock_type = std::conditional_t<shared_mutexlike<MUTEX_TYPE>, std::shared_lock<MUTEX_TYPE>, std::unique_lock<MUTEX_TYPE>>;
76 template <mutexlike MUTEX_TYPE,
typename T>
79 std::unique_lock guard{ m };
84 template <mutexlike MUTEX_TYPE,
typename T,
typename U>
87 std::unique_lock guard{ m };
88 return std::exchange<T>(t, std::forward<U>(u));
92 template <
typename T, mutexlike MUTEX_TYPE = std::mutex>
98 using object_type = T;
99 using reference = object_type&;
100 using const_reference = object_type
const&;
101 using mutex_type = MUTEX_TYPE;
118 template <
typename U>
125 template <
typename FUNC>
129 static_assert(std::is_invocable_v<FUNC, const_reference>,
"Function must be invocable with a const reference to the object");
134 template <
typename U = T>
141 template <
typename FUNC>
144 static_assert(std::is_invocable_v<FUNC, reference>,
"Function must be invocable with a reference to the object");
150 template <
typename FUNC>
153 static_assert(std::is_invocable_v<FUNC, reference>,
"Function must be invocable with a reference to the object");
154 auto copy = this->
get();
156 this->
set(std::move(copy));
159 mutex_type
const& mutex()
const {
return m_mutex; }
164 mutable mutex_type m_mutex;
168 template <
typename T, shared_mutexlike MUTEX_TYPE = std::shared_mutex>
Anything that's lockable.
RW mutex (read access can be shared, write access is exclusive).
Any mutexlike that can also be attempted to be locked for some time.
protected_object< T, MUTEX_TYPE > shared_protected_object
Same as protected_object but uses std::shared_mutex by default.
auto protected_move(MUTEX_TYPE &m, T &&t)
Moves t under the protection of mutexlike m.
auto protected_copy(MUTEX_TYPE &m, T &&t)
Creates a copy of t under the protection of mutexlike m.
auto under_read_protection(MUTEX_TYPE &m, FUNC &&func, ARGS &&... args)
Runs func under the read (shared) protection of mutexlike m.
auto protected_exchange(MUTEX_TYPE &m, T &t, U &&u) -> T
Exchanges t with u and returns the value of t, all under the protection of mutexlike m.
auto under_protection(MUTEX_TYPE &m, FUNC &&func, ARGS &&... args)
Runs func under the protection of mutexlike m.
Primary namespace for everything in this library.
A class that stores an object to which access is protected via a mutexlike; all operations are thread...
void set(U &&value)
Sets a new value for the object.
T exchange(U &&u)
Exchanges the value of the object with u and returns the old value.
auto read_only_access(FUNC &&func) const
Calls func with a const reference to the object which can be safely accessed; only available if the m...
T take()
Takes the value of the object via move.
T get() const
Returns a copy of the object.
void mutate_by_copy(FUNC &&func)
Calls func with a reference to a copy of the object, but not under the protection of the mutex.
auto mutate_in_place(FUNC &&func)
Calls func with a reference to the object which can be safely mutated.