mrs_lib
Various reusable classes, functions and utilities for use in MRS projects
Loading...
Searching...
No Matches
owning_mutex.hpp
Go to the documentation of this file.
1
2
3#ifndef MRS_LIB_UTILITY_OWNING_MUTEX_HPP_
4#define MRS_LIB_UTILITY_OWNING_MUTEX_HPP_
5
6
7#include <concepts>
8#include <memory>
9#include <mutex>
10#include <type_traits>
11#include <utility>
12
13
14namespace mrs_lib
15{
16
23 template <typename T, typename Mutex = std::mutex>
24 requires(std::same_as<T, std::remove_cvref_t<T>> && std::default_initializable<Mutex>)
26 {
27 private:
28 template <bool Mutable>
29 class [[nodiscard]] OwningMutexGuard;
30
31 public:
40 requires(std::default_initializable<T>)
41 = default;
42
48 OwningMutex(const T& val) : data_(val)
49 {
50 }
51
57 OwningMutex(T&& val) : data_(std::move(val))
58 {
59 }
60
62 ~OwningMutex() = default;
63
65 OwningMutex(const OwningMutex&) = delete;
72
78 OwningMutexGuard<true> acquire()
79 {
80 return OwningMutexGuard<true>(*this);
81 }
82
88 OwningMutexGuard<false> acquire() const
89 {
90 return OwningMutexGuard<false>(*this);
91 }
92
98 [[nodiscard]] T load() const
99 {
100 std::lock_guard lock(mutex_);
101 return data_;
102 }
103
113 void store(T val)
114 requires(std::is_nothrow_move_assignable_v<T>)
115 {
116 std::lock_guard lock(mutex_);
117 data_ = std::move(val);
118 }
119
120 private:
121 mutable Mutex mutex_;
122 T data_;
123 };
124
139 template <typename T, typename Mutex>
140 requires(std::same_as<T, std::remove_cvref_t<T>> && std::default_initializable<Mutex>)
141 template <bool Mutable>
142 class OwningMutex<T, Mutex>::OwningMutexGuard
143 {
144 public:
146 ~OwningMutexGuard() = default;
147
149 OwningMutexGuard(const OwningMutexGuard&) = delete;
151 OwningMutexGuard& operator=(const OwningMutexGuard&) = delete;
153 OwningMutexGuard(OwningMutexGuard&&) = delete;
155 OwningMutexGuard& operator=(OwningMutexGuard&&) = delete;
156
165 T& operator*() &
166 requires(Mutable)
167 {
168 return parent_.data_;
169 }
170
176 const T& operator*() const&
177 {
178 return parent_.data_;
179 }
180
182 T& operator*() && = delete;
184 const T& operator*() const&& = delete;
185
194 T* operator->() &
195 requires(Mutable)
196 {
197 return std::addressof(parent_.data_);
198 }
199
205 const T* operator->() const&
206 {
207 return std::addressof(parent_.data_);
208 }
209
211 T* operator->() && = delete;
213 const T* operator->() const&& = delete;
214
215 private:
216 using RefType = std::conditional_t<Mutable, OwningMutex&, const OwningMutex&>;
217
223 explicit OwningMutexGuard(RefType parent) : lock_(parent.mutex_), parent_(parent)
224 {
225 }
226
227 std::lock_guard<Mutex> lock_;
228 RefType parent_;
229
230 friend class OwningMutex;
231 };
232
233} // namespace mrs_lib
234
235
236#endif // MRS_LIB_UTILITY_OWNING_MUTEX_HPP_
A thread-safe wrapper for shared data with mutex protection.
Definition owning_mutex.hpp:26
T load() const
Loads the current value of the data.
Definition owning_mutex.hpp:98
OwningMutex()=default
Construct with default-initialized data.
OwningMutex(OwningMutex &&)=delete
OwningMutex is immovable.
OwningMutex(const T &val)
Construct by copying the data.
Definition owning_mutex.hpp:48
OwningMutex(const OwningMutex &)=delete
OwningMutex is immovable.
void store(T val)
Stores a new value into the data.
Definition owning_mutex.hpp:113
OwningMutex(T &&val)
Construct by moving the data.
Definition owning_mutex.hpp:57
OwningMutex & operator=(const OwningMutex &)=delete
OwningMutex is immovable.
OwningMutex & operator=(OwningMutex &&)=delete
OwningMutex is immovable.
OwningMutexGuard< false > acquire() const
Acquires a const guard for the OwningMutex.
Definition owning_mutex.hpp:88
OwningMutexGuard< true > acquire()
Acquires a mutable guard for the OwningMutex.
Definition owning_mutex.hpp:78
~OwningMutex()=default
Default destructor.
All mrs_lib functions, classes, variables and definitions are contained in this namespace.
Definition attitude_converter.h:24