33 #ifndef REALTIME_TOOLS__REALTIME_BOX_HPP_
34 #define REALTIME_TOOLS__REALTIME_BOX_HPP_
37 #include <initializer_list>
42 #include <rcpputils/pointer_traits.hpp>
48 constexpr
auto is_ptr_or_smart_ptr = rcpputils::is_pointer<T>::value;
58 template <
class T,
typename mutex_type = std::mutex>
61 static_assert(std::is_copy_constructible_v<T>,
"Passed type must be copy constructible");
64 using mutex_t = mutex_type;
67 constexpr
explicit RealtimeBoxBase(
const T & init = T{}) : value_(init) {}
68 constexpr
explicit RealtimeBoxBase(
const T && init) : value_(std::move(init)) {}
74 std::unique_lock<mutex_t> lock(o.lock_);
85 std::unique_lock<mutex_t> lock_other(o.lock_);
86 std::unique_lock<mutex_t> lock_self(lock_);
96 std::unique_lock<mutex_t> lock(o.lock_);
98 value_ = std::move(o.value_);
102 template <
typename U = T>
104 const std::initializer_list<U> & init,
105 std::enable_if_t<std::is_constructible_v<U, std::initializer_list<U>>>)
115 std::unique_lock<mutex_t> lock_other(o.lock_);
116 std::unique_lock<mutex_t> lock_self(lock_);
118 value_ = std::move(o.value_);
128 template <
typename U = T>
129 typename std::enable_if_t<!is_ptr_or_smart_ptr<U>,
bool>
try_set(
const T & value)
131 std::unique_lock<mutex_t> guard(lock_, std::defer_lock);
132 if (!guard.try_lock()) {
144 bool try_set(
const std::function<
void(T &)> & func)
146 std::unique_lock<mutex_t> guard(lock_, std::defer_lock);
147 if (!guard.try_lock()) {
161 template <
typename U = T>
162 [[deprecated(
"Use try_set(const T & value) instead!")]]
163 typename std::enable_if_t<!is_ptr_or_smart_ptr<U>,
bool>
trySet(
const T & value)
165 std::unique_lock<mutex_t> guard(lock_, std::defer_lock);
166 if (!guard.try_lock()) {
179 template <
typename U = T>
180 [[deprecated(
"Use try_set(const std::function<void(T &)> & func) instead!")]]
181 bool trySet(
const std::function<
void(T &)> & func)
190 template <
typename U = T>
191 [[nodiscard]]
typename std::enable_if_t<!is_ptr_or_smart_ptr<U>, std::optional<U>>
try_get()
const
193 std::unique_lock<mutex_t> guard(lock_, std::defer_lock);
194 if (!guard.try_lock()) {
205 bool try_get(
const std::function<
void(
const T &)> & func)
207 std::unique_lock<mutex_t> guard(lock_, std::defer_lock);
208 if (!guard.try_lock()) {
221 template <
typename U = T>
222 [[deprecated(
"Use try_get() instead!")]] [[nodiscard]]
223 typename std::enable_if_t<!is_ptr_or_smart_ptr<U>, std::optional<U>>
tryGet()
const
234 template <
typename U = T>
235 [[deprecated(
"Use try_get(const std::function<void(const T &)> & func) instead!")]]
236 bool tryGet(
const std::function<
void(
const T &)> & func)
246 template <
typename U = T>
247 typename std::enable_if_t<!is_ptr_or_smart_ptr<U>,
void>
set(
const T & value)
249 std::lock_guard<mutex_t> guard(lock_);
260 template <
typename U = T>
261 [[deprecated(
"Use set(const std::function<void(T &)> & func) instead!")]]
262 typename std::enable_if_t<is_ptr_or_smart_ptr<U>,
void>
set(
const T & value)
264 std::lock_guard<mutex_t> guard(lock_);
272 void set(
const std::function<
void(T &)> & func)
274 std::lock_guard<mutex_t> guard(lock_);
276 if constexpr (is_ptr_or_smart_ptr<T>) {
288 template <
typename U = T>
289 [[nodiscard]]
typename std::enable_if_t<!is_ptr_or_smart_ptr<U>, U>
get()
const
291 std::lock_guard<mutex_t> guard(lock_);
299 template <
typename U = T>
300 typename std::enable_if_t<!is_ptr_or_smart_ptr<U>,
void>
get(T & in)
const
302 std::lock_guard<mutex_t> guard(lock_);
313 template <
typename U = T>
314 [[deprecated(
"Use get(const std::function<void(const T &)> & func) instead!")]]
315 typename std::enable_if_t<is_ptr_or_smart_ptr<U>,
void>
get(T & in)
const
317 std::lock_guard<mutex_t> guard(lock_);
327 void get(
const std::function<
void(
const T &)> & func)
329 std::lock_guard<mutex_t> guard(lock_);
337 template <
typename U = T>
338 typename std::enable_if_t<!is_ptr_or_smart_ptr<U>,
void>
operator=(
const T & value)
347 template <
typename U = T,
typename =
typename std::enable_if_t<!is_ptr_or_smart_ptr<U>>>
348 [[nodiscard]]
operator T()
const
358 template <
typename U = T,
typename =
typename std::enable_if_t<!is_ptr_or_smart_ptr<U>>>
359 [[nodiscard]]
operator std::optional<T>()
const
368 [[nodiscard]]
const mutex_t & get_mutex()
const {
return lock_; }
369 [[nodiscard]] mutex_t & get_mutex() {
return lock_; }
371 [[nodiscard]] [[deprecated(
"Use get_mutex() instead!")]] mutex_t & getMutex() {
return lock_; }
372 [[nodiscard]] [[deprecated(
"Use get_mutex() instead!")]]
const mutex_t & getMutex()
const
385 mutable mutex_t lock_;
391 template <
typename T,
typename mutex_type = std::mutex>
392 using RealtimeBoxBestEffort [[deprecated(
"Use RealtimeBox instead")]] =
393 RealtimeBoxBase<T, mutex_type>;
396 template <
typename T>
397 using RealtimeBoxStandard = RealtimeBoxBase<T, std::mutex>;
399 template <
typename T>
400 using RealtimeBoxRecursive = RealtimeBoxBase<T, std::recursive_mutex>;
403 template <
typename T>
404 using RealtimeBox = RealtimeBoxStandard<T>;