wwa-scope-action 1.0.0
Scope guard utilities for managing exit actions in C++
wwa::utils::success_action< ExitFunc > Class Template Reference

A scope guard that calls its exit function when a scope is exited normally. More...

#include <scope_action.h>

+ Collaboration diagram for wwa::utils::success_action< ExitFunc >:

Public Member Functions

template<typename Func >
requires detail::can_move_construct_from_noexcept<success_action, ExitFunc, Func>
 success_action (Func &&fn) noexcept
 Constructs a new success_action from an exit function of type Func.
 
template<typename Func >
requires (detail::can_construct_from<success_action, ExitFunc, Func>)
 success_action (Func &&fn) noexcept(std::is_nothrow_constructible_v< ExitFunc, Func >||std::is_nothrow_constructible_v< ExitFunc, Func & >)
 Constructs a new success_action from an exit function of type Func.
 
 success_action (success_action &&other) noexcept(std::is_nothrow_move_constructible_v< ExitFunc >||std::is_nothrow_copy_constructible_v< ExitFunc >)
 Move constructor.
 
 ~success_action () noexcept(noexcept(this->m_exit_function()))
 Calls the exit function when the scope is exited normally if the success_action is active, then destroys the object.
 
void release () noexcept
 Makes the success_action object inactive.
 

Detailed Description

template<typename ExitFunc>
class wwa::utils::success_action< ExitFunc >

A scope guard that calls its exit function when a scope is exited normally.

Like exit_action, a success_action may be active or inactive. A success_action is active after construction from an exit function.

An success_action becomes inactive by calling release() or a move constructor. An inactive success_action may also be obtained by initializing with another inactive success_action. Once an success_action is inactive, it cannot become active again.

Usage example:

try {
auto guard = wwa::utils::success_action{[&exit_status] { exit_status = true; }};
maybe_throw();
}
catch (...) {
did_throw = true;
}
print_exit_status("success_action", exit_status, did_throw);
Template Parameters
ExitFuncExit function type. Func is either a Destructible FunctionObject type, or an lvalue reference to a FunctionObject or function.
See also
https://en.cppreference.com/w/cpp/experimental/scope_success
Note
Constructing a success_action of dynamic storage duration might lead to unexpected behavior.
Constructing a success_action from another success_action created in a different thread might also lead to unexpected behavior since the count of uncaught exceptions obtained in different threads may be compared during the destruction.
If the exit function stored in an success_action object refers to a local variable of the function where it is defined (e.g., as a lambda capturing the variable by reference), and that variable is used as a return operand in that function, that variable might have already been returned when the success_action's destructor executes, calling the exit function. This can lead to surprising behavior.
Examples
scope_action.cpp.

Definition at line 417 of file scope_action.h.

Constructor & Destructor Documentation

◆ success_action() [1/3]

template<typename ExitFunc >
template<typename Func >
requires (detail::can_construct_from<success_action, ExitFunc, Func>)
wwa::utils::success_action< ExitFunc >::success_action ( Func && fn)
inlineexplicitnoexcept

Constructs a new success_action from an exit function of type Func.

Initializes the exit function with a function or function object, and initializes the counter of uncaught exceptions as if with std::uncaught_exceptions(). The constructed success_action is active.

If Func is not an lvalue reference type, and std::is_nothrow_constructible_v<ExitFunc, Func> is true, the stored exit function is initialized with std::forward<Func>(fn); otherwise it is initialized with fn. If initialization of the stored exit function throws an exception, calls fn().

This overload participates in overload resolution only if:

  • std::is_same_v<std::remove_cvref_t<Func>, success_action> is false, and
  • std::is_constructible_v<ExitFunc, Func> is true.
Template Parameters
FuncExit function type. Must be constructible from ExitFunc.
Parameters
fnExit function.
Exceptions
anythingAny exception thrown during the initialization of the stored exit function.
See also
https://en.cppreference.com/w/cpp/experimental/scope_success/scope_success

Definition at line 443 of file scope_action.h.

◆ success_action() [2/3]

template<typename ExitFunc >
template<typename Func >
requires detail::can_move_construct_from_noexcept<success_action, ExitFunc, Func>
wwa::utils::success_action< ExitFunc >::success_action ( Func && fn)
inlineexplicitnoexcept

Constructs a new success_action from an exit function of type Func.

Initializes the exit function with a function or function object fn. The constructed success_action is active. The stored exit function is initialized with std::forward<Func>(fn).

This overload participates in overload resolution only if:

  • std::is_same_v<std::remove_cvref_t<Func>, success_action> is false, and
  • std::is_lvalue_reference_v<Func> is false, and
  • std::is_nothrow_constructible_v<ExitFunc, Func> is true.
Template Parameters
FuncExit function type. Must be constructible from ExitFunc.
Parameters
fnExit function.
See also
https://en.cppreference.com/w/cpp/experimental/scope_success/scope_success

Definition at line 472 of file scope_action.h.

◆ success_action() [3/3]

template<typename ExitFunc >
wwa::utils::success_action< ExitFunc >::success_action ( success_action< ExitFunc > && other)
inlinenoexcept

Move constructor.

Initializes the stored exit function with the one in other, and initializes the counter of uncaught exceptions with the one in other. The constructed success_action is active if and only if other is active before the construction.

If std::is_nothrow_move_constructible_v<ExitFunc> is true, initializes stored exit function (denoted by exitfun) with std::forward<ExitFunc>(other.exitfun), otherwise initializes it with other.exitfun.

After successful move construction, other.release() is called and other becomes inactive.

This overload participates in overload resolution only if:

  • std::is_nothrow_move_constructible_v<ExitFunc> is true, or
  • std::is_copy_constructible_v<ExitFunc> is true.
Parameters
othersuccess_action to move from.
Exceptions
anythingAny exception thrown during the initialization of the stored exit function.
See also
https://en.cppreference.com/w/cpp/experimental/scope_success/scope_success

Definition at line 495 of file scope_action.h.

◆ ~success_action()

template<typename ExitFunc >
wwa::utils::success_action< ExitFunc >::~success_action ( )
inlinenoexcept

Calls the exit function when the scope is exited normally if the success_action is active, then destroys the object.

Calls the exit function if the result of std::uncaught_exceptions() is less than or equal to the counter of uncaught exceptions (typically on normal exit) and the success_action is active, then destroys the object.

Exceptions
anythingThrows any exception thrown by calling the exit function.
See also
https://en.cppreference.com/w/cpp/experimental/scope_success/%7Escope_success

Definition at line 530 of file scope_action.h.

Member Function Documentation

◆ release()

template<typename ExitFunc >
void wwa::utils::success_action< ExitFunc >::release ( )
inlinenoexcept

Makes the success_action object inactive.

Once an success_action is inactive, it cannot become active again, and it will not call its exit function upon destruction.

See also
https://en.cppreference.com/w/cpp/experimental/scope_exit/release

Definition at line 545 of file scope_action.h.


The documentation for this class was generated from the following file: