18 : exit_function(std::forward<EFP>(
f))
23 : exit_function(std::move(
rhs.exit_function))
34 if (this->execute_on_destruction)
35 this->exit_function();
38 void release()
noexcept
40 this->execute_on_destruction =
false;
43 bool will_execute_on_destruction()
const noexcept
45 return this->execute_on_destruction;
51 bool execute_on_destruction{
true };
60 : m_exit_function(std::forward<EFP>(
f))
66 : m_exit_function(std::move(
rhs.m_exit_function))
67 , m_count(std::exchange(
rhs.m_count, 0))
117 template <
class R,
class D>
122 template <
class RR,
class DD>
123 unique_resource(
RR&&
r,
DD&&
d)
noexcept(std::is_nothrow_constructible_v<R1, RR> && std::is_nothrow_constructible_v<D, DD>)
124 : resource(std::forward<RR>(
r))
125 , deleter(std::forward<DD>(
d))
126 , execute_on_reset(
true)
130 template <
class RR,
class DD,
class I = std::decay_t<RR>>
131 unique_resource(
RR&&
r,
const I& invalid,
DD&&
d)
noexcept(std::is_nothrow_constructible_v<R1, RR> && std::is_nothrow_constructible_v<D, DD>)
132 : resource(std::forward<RR>(
r))
133 , deleter(std::forward<DD>(
d))
134 , execute_on_reset(!
bool(resource == invalid))
139 : resource(std::move(
rhs.resource))
140 , deleter(std::move(
rhs.deleter))
141 , execute_on_reset(std::exchange(
rhs.execute_on_reset,
false))
147 if (execute_on_reset)
151 unique_resource& operator=(
unique_resource&&
rhs)
noexcept(std::is_nothrow_move_assignable_v<R1> && std::is_nothrow_move_assignable_v<D> &&
noexcept(deleter(resource)))
153 if (std::addressof(
rhs) ==
this)
157 if constexpr (std::is_nothrow_move_assignable_v<R1>)
159 if constexpr (std::is_nothrow_move_assignable_v<D>)
161 resource = std::move(
rhs.resource);
162 deleter = std::move(
rhs.deleter);
166 deleter =
rhs.deleter;
167 resource = std::move(
rhs.resource);
172 if constexpr (std::is_nothrow_move_assignable_v<D>)
174 resource =
rhs.resource;
175 deleter = std::move(
rhs.deleter);
179 resource =
rhs.resource;
180 deleter =
rhs.deleter;
183 execute_on_reset = std::exchange(
rhs.execute_on_reset,
false);
187 void reset()
noexcept(
noexcept(deleter(resource)))
189 if (execute_on_reset)
191 execute_on_reset =
false;
197 void reset(
RR&&
r)
noexcept(
noexcept(deleter(resource)) && std::is_nothrow_assignable_v<R1&, RR>)
199 if (std::addressof(
r) == std::addressof(resource))
205 if constexpr (std::is_nothrow_assignable_v<R1&, RR>)
206 resource = std::forward<RR>(
r);
208 resource = std::as_const(
r);
215 execute_on_reset =
true;
218 void release()
noexcept
220 execute_on_reset =
false;
223 const R& get()
const noexcept
228 auto operator*()
const noexcept
229 requires std::is_pointer_v<R> && (!std::is_void_v<std::remove_pointer_t<R>>)
234 R operator->()
const noexcept
235 requires std::is_pointer_v<R>
240 const D& get_deleter()
const noexcept {
return deleter; }
244 using R1 = std::conditional_t<std::is_reference_v<R>, std::reference_wrapper<std::remove_reference_t<R>>, R>;
247 bool execute_on_reset{};
250 template<
class R,
class D>
252 template <
class R,
class D,
class I = std::decay_t<R>>
257 template <
typename T,
bool OPTIONAL = false>
260 template <
typename U>
263 : m_ref(std::addressof(ref))
264 , m_original_value(std::exchange(ref,
new_val))
268 template <
typename U>
269 scoped_value_change(T& ref,
U new_val)
noexcept(std::is_nothrow_move_constructible_v<T> && std::is_nothrow_copy_constructible_v<T>)
271 : m_ref(std::addressof(ref))
272 , m_original_value(*m_ref !=
new_val ? std::exchange(ref,
new_val) : ref)
284 , m_original_value(std::move(
other.m_original_value))
286 other.m_ref =
nullptr;
313 return m_original_value;
320 return std::move(m_original_value);
341 if (ref == m_original_value)
345 ref = std::move(m_original_value);
360 if (ref != m_original_value)
361 return std::move(m_original_value);
364 return std::exchange(ref, std::move(m_original_value));
380 return std::move(m_original_value);
389 template <
typename T>
392 template <
typename T,
typename U>
398 template <
typename T>
402 : m_ref(std::addressof(ref))
410 m_ref = std::exchange(
other.m_ref,
nullptr);
415 bool valid()
const noexcept {
return m_ref !=
nullptr; }
423 void release()
const noexcept
constexpr auto bit_count
Equal to the number of bits in the type.
Primary namespace for everything in this library.
A RAII class that executes a function on destruction, if its request counter is greater than zero.
void unrequest() noexcept
Decrements the request counter.
~counted_scope_guard() noexcept(noexcept(m_exit_function()))
Executes the function on destruction if the request counter is greater than zero.
void request() noexcept
Increments the request counter.
void release() noexcept
Releases the guard, so that it will not execute the function on destruction.
TODO: atomic_scoped_value_change.
A RAII class that executes a function on destruction.
A RAII class that changes the value of a variable and reverts it to the original value on destruction...
void revert() noexcept(std::is_nothrow_move_assignable_v< T >)
Reverts the value to the original one.
T original_value() &&noexcept(std::is_nothrow_move_constructible_v< T >)
Returns the original value.
T release_and_return() noexcept(std::is_nothrow_move_constructible_v< T >)
Causes the value to not be reverted on destruction.
void release() noexcept
Causes the value to not be reverted on destruction.
T const & current_value()
Returns the current value.
T const & original_value() const &noexcept
Returns the original value.
T revert_and_return() noexcept(std::is_nothrow_move_assignable_v< T > &&std::is_nothrow_move_constructible_v< T >)
Reverts the value to the original one.
scoped_value_change & operator=(scoped_value_change &&other)=delete
Move assignment is not implemented because it's not clear and obvious what the order of reversions wo...
An equivalent to unique_ptr for values that are not heap pointers.