22 explicit scope_guard(EFP&& f)
noexcept(
noexcept(EFP(std::forward<EFP>(f))))
23 : exit_function(std::forward<EFP>(f))
27 scope_guard(scope_guard&& rhs)
noexcept(
noexcept(EF(std::move(rhs.exit_function))))
28 : exit_function(std::move(rhs.exit_function))
33 scope_guard(
const scope_guard&) =
delete;
34 scope_guard& operator=(
const scope_guard&) =
delete;
35 scope_guard& operator=(scope_guard&&) =
delete;
37 ~scope_guard()
noexcept(
noexcept(this->exit_function()))
39 if (this->execute_on_destruction)
40 this->exit_function();
43 void release()
noexcept
45 this->execute_on_destruction =
false;
48 bool will_execute_on_destruction()
const noexcept
50 return this->execute_on_destruction;
56 bool execute_on_destruction{
true };
61 struct counted_scope_guard
64 explicit counted_scope_guard(EFP&& f,
int initial_count = 0)
noexcept(
noexcept(EFP(std::forward<EFP>(f))))
65 : m_exit_function(std::forward<EFP>(f))
66 , m_count(initial_count)
70 counted_scope_guard(counted_scope_guard&& rhs)
noexcept(
noexcept(EF(std::move(rhs.m_exit_function))))
71 : m_exit_function(std::move(rhs.m_exit_function))
72 , m_count(std::exchange(rhs.m_count, 0))
76 counted_scope_guard(
const counted_scope_guard&) =
delete;
77 counted_scope_guard& operator=(
const counted_scope_guard&) =
delete;
78 counted_scope_guard& operator=(counted_scope_guard&&) =
delete;
106 bool will_execute_on_destruction() const noexcept
123 struct unique_resource
125 unique_resource() =
default;
127 template <
class RR,
class DD>
128 unique_resource(RR&& r, DD&& d)
noexcept(std::is_nothrow_constructible_v<R1, RR> && std::is_nothrow_constructible_v<D, DD>)
129 : resource(std::forward<RR>(r))
130 , deleter(std::forward<DD>(d))
131 , execute_on_reset(
true)
135 template <
class RR,
class DD,
class I = std::decay_t<RR>>
136 unique_resource(RR&& r,
const I& invalid, DD&& d)
noexcept(std::is_nothrow_constructible_v<R1, RR> && std::is_nothrow_constructible_v<D, DD>)
137 : resource(std::forward<RR>(r))
138 , deleter(std::forward<DD>(d))
139 , execute_on_reset(!
bool(resource == invalid))
143 unique_resource(unique_resource&& rhs)
noexcept(std::is_nothrow_move_constructible_v<R1> && std::is_nothrow_move_constructible_v<D>)
144 : resource(std::move(rhs.resource))
145 , deleter(std::move(rhs.deleter))
146 , execute_on_reset(std::exchange(rhs.execute_on_reset,
false))
150 ~unique_resource()
noexcept(
noexcept(deleter(resource)))
152 if (execute_on_reset)
156 unique_resource& operator=(unique_resource&& rhs)
noexcept(std::is_nothrow_move_assignable_v<R1> && std::is_nothrow_move_assignable_v<D> &&
noexcept(deleter(resource)))
158 if (std::addressof(rhs) ==
this)
162 if constexpr (std::is_nothrow_move_assignable_v<R1>)
164 if constexpr (std::is_nothrow_move_assignable_v<D>)
166 resource = std::move(rhs.resource);
167 deleter = std::move(rhs.deleter);
171 deleter = rhs.deleter;
172 resource = std::move(rhs.resource);
177 if constexpr (std::is_nothrow_move_assignable_v<D>)
179 resource = rhs.resource;
180 deleter = std::move(rhs.deleter);
184 resource = rhs.resource;
185 deleter = rhs.deleter;
188 execute_on_reset = std::exchange(rhs.execute_on_reset,
false);
192 void reset()
noexcept(
noexcept(deleter(resource)))
194 if (execute_on_reset)
196 execute_on_reset =
false;
202 void reset(RR&& r)
noexcept(
noexcept(deleter(resource)) && std::is_nothrow_assignable_v<R1&, RR>)
204 if (std::addressof(r) == std::addressof(resource))
210 if constexpr (std::is_nothrow_assignable_v<R1&, RR>)
211 resource = std::forward<RR>(r);
213 resource = std::as_const(r);
220 execute_on_reset =
true;
223 void release()
noexcept
225 execute_on_reset =
false;
228 const R& get()
const noexcept
232 explicit operator R&()
noexcept {
return resource; }
234 auto operator*()
const noexcept
235 GHPL_REQUIRES(std::is_pointer_v<R> && (!std::is_void_v<std::remove_pointer_t<R>>))
240 R operator->()
const noexcept
246 const D& get_deleter()
const noexcept {
return deleter; }
250 using R1 = std::conditional_t<std::is_reference_v<R>, std::reference_wrapper<std::remove_reference_t<R>>, R>;
253 bool execute_on_reset{};
264 struct scoped_value_change
266 template <
typename U,
bool OPT = IS_OPTIONAL>
267 scoped_value_change(T& ref, U new_val,
typename std::enable_if_t<!OPT>* = 0)
noexcept(std::is_nothrow_move_constructible_v<T>)
268 : m_ref(std::addressof(ref))
269 , m_original_value(std::exchange(ref, new_val))
273 template <
typename U,
bool OPT = IS_OPTIONAL>
274 scoped_value_change(T& ref, U new_val,
typename std::enable_if_t<OPT>* = 0)
noexcept(std::is_nothrow_move_constructible_v<T> && std::is_nothrow_copy_constructible_v<T>)
275 : m_ref(std::addressof(ref))
276 , m_original_value(*m_ref != new_val ? std::exchange(ref, new_val) : ref)
280 ~scoped_value_change()
noexcept(std::is_nothrow_move_assignable_v<T>)
285 scoped_value_change(
const scoped_value_change&) =
delete;
286 scoped_value_change(scoped_value_change&& other)
noexcept(std::is_nothrow_move_constructible_v<T>)
288 , m_original_value(std::move(other.m_original_value))
290 other.m_ref =
nullptr;
293 scoped_value_change& operator=(
const scoped_value_change&) =
delete;
297 scoped_value_change&
operator=(scoped_value_change&& other) =
delete;
311 bool valid() const noexcept {
return m_ref !=
nullptr; }
317 return m_original_value;
324 return std::move(m_original_value);
336 void revert() noexcept(std::is_nothrow_move_assignable_v<T>)
343 if constexpr (IS_OPTIONAL)
345 if (ref == m_original_value)
349 ref = std::move(m_original_value);
357 T
revert_and_return() noexcept(std::is_nothrow_move_assignable_v<T> && std::is_nothrow_move_constructible_v<T>)
362 if constexpr (IS_OPTIONAL)
364 if (ref != m_original_value)
365 return std::move(m_original_value);
368 return std::exchange(ref, std::move(m_original_value));
384 return std::move(m_original_value);
405 scope_counter(T& ref)
noexcept(
noexcept(++ref))
406 : m_ref(std::addressof(ref))
411 scope_counter(
const scope_counter&) =
delete;
412 scope_counter(scope_counter&& other)
noexcept
414 m_ref = std::exchange(other.m_ref,
nullptr);
416 scope_counter& operator=(
const scope_counter&) =
delete;
417 scope_counter& operator=(scope_counter&&) =
delete;
419 bool valid()
const noexcept {
return m_ref !=
nullptr; }
421 ~scope_counter()
noexcept(
noexcept(--m_ref))
427 void release()
const noexcept