18 #ifndef CSLIBGUARDED_ORDERED_GUARDED_H
19 #define CSLIBGUARDED_ORDERED_GUARDED_H
23 #include <type_traits>
24 #include <shared_mutex>
43 template <
typename T,
typename M = std::shared_timed_mutex>
50 using shared_handle = std::unique_ptr<
const T, shared_deleter>;
56 template <
typename... Us>
57 ordered_guarded(Us &&... data);
59 template <
typename Func>
60 decltype(
auto) modify(Func &&func);
62 template <
typename Func>
63 [[nodiscard]]
decltype(
auto) read(Func &&func)
const;
65 [[nodiscard]] shared_handle lock_shared()
const;
66 [[nodiscard]] shared_handle try_lock_shared()
const;
68 template <
class Duration>
69 [[nodiscard]] shared_handle try_lock_shared_for(
const Duration &duration)
const;
71 template <
class TimePoint>
72 [[nodiscard]] shared_handle try_lock_shared_until(
const TimePoint &timepoint)
const;
78 using pointer =
const T *;
80 shared_deleter() : m_deleter_mutex(
nullptr) {}
82 shared_deleter(M &mutex)
83 : m_deleter_mutex(&mutex)
87 void operator()(
const T *ptr) {
88 if (ptr && m_deleter_mutex) {
89 m_deleter_mutex->unlock_shared();
101 template <
typename T,
typename M>
102 template <
typename... Us>
103 ordered_guarded<T, M>::ordered_guarded(Us &&... data)
104 : m_obj(std::forward<Us>(data)...)
108 template <
typename T,
typename M>
109 template <
typename Func>
110 decltype(
auto) ordered_guarded<T, M>::modify(Func &&func)
112 std::lock_guard<M> lock(m_mutex);
117 template <
typename T,
typename M>
118 template <
typename Func>
119 decltype(
auto) ordered_guarded<T, M>::read(Func &&func)
const
121 std::shared_lock<M> lock(m_mutex);
126 template <
typename T,
typename M>
127 auto ordered_guarded<T, M>::lock_shared()
const -> shared_handle
129 m_mutex.lock_shared();
130 return std::unique_ptr<
const T, shared_deleter>(&m_obj, shared_deleter(m_mutex));
133 template <
typename T,
typename M>
134 auto ordered_guarded<T, M>::try_lock_shared()
const -> shared_handle
136 if (m_mutex.try_lock_shared()) {
137 return std::unique_ptr<
const T, shared_deleter>(&m_obj, shared_deleter(m_mutex));
139 return std::unique_ptr<
const T, shared_deleter>(
nullptr, shared_deleter(m_mutex));
143 template <
typename T,
typename M>
144 template <
typename Duration>
145 auto ordered_guarded<T, M>::try_lock_shared_for(
const Duration &duration)
const -> shared_handle
147 if (m_mutex.try_lock_shared_for(duration)) {
148 return std::unique_ptr<
const T, shared_deleter>(&m_obj, shared_deleter(m_mutex));
150 return std::unique_ptr<
const T, shared_deleter>(
nullptr, shared_deleter(m_mutex));
154 template <
typename T,
typename M>
155 template <
typename TimePoint>
156 auto ordered_guarded<T, M>::try_lock_shared_until(
const TimePoint &timepoint)
const -> shared_handle
158 if (m_mutex.try_lock_shared_until(timepoint)) {
159 return std::unique_ptr<
const T, shared_deleter>(&m_obj, shared_deleter(m_mutex));
161 return std::unique_ptr<
const T, shared_deleter>(
nullptr, shared_deleter(m_mutex));