Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
scope_guard.hpp
Go to the documentation of this file.
1
// Copyright 2024, Toyota Motor Corporation
2
//
3
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5
#
ifndef
INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SCOPE_GUARD_SCOPE_GUARD_HPP_
6
#
define
INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SCOPE_GUARD_SCOPE_GUARD_HPP_
7
8
// IWYU pragma: private, include "arene/base/scope_guard.hpp"
9
// IWYU pragma: friend "(arene/base(?!/tests)|stdlib/include/stdlib_detail)/.*"
10
11
// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
12
#
include
"arene/base/compiler_support/attributes.hpp"
13
#
include
"arene/base/constraints/constraints.hpp"
14
#
include
"arene/base/stdlib_choice/enable_if.hpp"
15
#
include
"arene/base/stdlib_choice/exchange.hpp"
16
#
include
"arene/base/stdlib_choice/forward.hpp"
17
#
include
"arene/base/stdlib_choice/is_constructible.hpp"
18
#
include
"arene/base/stdlib_choice/is_move_constructible.hpp"
19
#
include
"arene/base/stdlib_choice/is_same.hpp"
20
#
include
"arene/base/stdlib_choice/move.hpp"
21
#
include
"arene/base/stdlib_choice/remove_cv.hpp"
22
#
include
"arene/base/stdlib_choice/remove_reference.hpp"
23
#
include
"arene/base/type_traits/is_invocable.hpp"
24
#
include
"arene/base/type_traits/remove_cvref.hpp"
25
// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
26
27
// parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
28
29
namespace
arene
{
30
namespace
base
{
31
32
/// @brief RAII utility for executing logic on scope exit
33
///
34
/// The @c scope_guard type is a utility that helps writing exception-safe code by ensuring that some code gets run on
35
/// scope-exit, regardless of how the scope is exited (return, exception, flowing off end, etc). The destructor of the
36
/// @c scope_guard class invokes the function passed to the constructor.
37
///
38
/// @see arene::base::on_scope_exit for a helper function for creating @c scope_guard instances.
39
///
40
/// @tparam Func The functor to be called on scope exit. Must have signature <c> void(void) noexcept </c>. It also must
41
/// be nothrow move constructable for scope_guard to be move-constructable.
42
template
<
typename
Func
>
43
class
ARENE_NODISCARD
scope_guard
{
44
static_assert
(
is_nothrow_invocable_r_v
<
void
,
Func
>,
"Func must have signature void(void) noexcept"
);
45
46
public
:
47
/// @brief Construct a new scope_guard that decay-copies the
48
/// function and ensure that it is called upon destruction of the
49
/// scope_guard object.
50
/// @tparam Func2 The type of the supplied callable
51
/// @param supplied_callable The supplied callable
52
template
<
53
typename
Func2
,
54
constraints
<
55
std
::
enable_if_t
<
std
::
is_constructible
<
Func
,
Func2
>::
value
>,
56
std
::
enable_if_t
<!
std
::
is_same
<
remove_cvref_t
<
Func2
>,
scope_guard
>::
value
>> =
nullptr
>
57
// This has been guarded against by the !is_same<...> constraint above.
58
// NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
59
explicit
scope_guard
(
Func2
&&
supplied_callable
)
noexcept
(
std
::
is_nothrow_constructible
<
Func
,
Func2
>::
value
)
60
:
func_
(
std
::
forward
<
Func2
>(
supplied_callable
)),
61
cancelled_
(
false
) {}
62
63
/// @brief Move constructor.
64
///
65
/// Moves ownership of the function and responsibility for calling the function on destruction to the newly
66
/// constructed scope_guard object.
67
///
68
/// @param other The scope_guard to move from.
69
/// @post The held function will be the one from @c other
70
/// @post The cancel state will be the one from @c other
71
/// @post The moved-from @c scope_guard can be safely destructed.
72
scope_guard
(
scope_guard
&&
other
)
noexcept
73
:
func_
(
std
::
move
(
other
.
func_
)),
74
cancelled_
(
std
::
exchange
(
other
.
cancelled_
,
true
)) {
75
static_assert
(
std
::
is_nothrow_move_constructible
<
Func
>::
value
,
"Func must be nothrow move constructible"
);
76
}
77
78
/// @brief Move assignment is deleted as allowing it would overwrite the existing guard function without executing it.
79
auto
operator
=(
scope_guard
&&
other
) ->
scope_guard
& =
delete
;
80
81
/// @brief copy-construction is deleted as two guards cannot own the same function.
82
scope_guard
(
scope_guard
const
&) =
delete
;
83
/// @brief copy-assignment is deleted as two guards cannot own the same function.
84
auto
operator
=(
scope_guard
const
&) ->
scope_guard
& =
delete
;
85
86
/// @brief Destroy the scope guard and invoke the function if it should be executed
87
/// @post The held function is executed as if via @c invoke_now() .
88
~
scope_guard
() {
invoke_now
(); }
89
90
/// @brief Declares the held function should not be invoked.
91
/// @post Calls to @c invoke_now() will be noops.
92
void
cancel
()
noexcept
{
cancelled_
=
true
; }
93
94
/// @brief Invokes the held function if it has not be otherwise canceled.
95
/// @post If @c cancel() has not been called, invokes the held functor.
96
/// @post Subsequent calls to @c invoke_now() are noops as if @c cancel() had been called.
97
void
invoke_now
()
noexcept
{
98
if
(!
cancelled_
) {
99
cancelled_
=
true
;
100
func_
();
101
}
102
}
103
104
private
:
105
/// @brief The function to invoke
106
Func
func_
;
107
108
/// @brief Flag to signal if the functor should be invoked.
109
bool
cancelled_
;
// NOLINT(modernize-use-default-member-init)
110
};
111
112
/// @brief Declarative helper for constructing @c scope_guard instances.
113
///
114
/// A simple factory function for @c scope_guard with a declarative name that makes its purpose clear. Example usage:
115
/// \snippet docs/examples/scope_guard_examples.cpp basic_usage
116
///
117
/// @tparam CallableType a callable with signature <c> void(void) noexcept </c>. Must be move-copyable and decay
118
/// constructible.
119
/// @param func The callable to invoke upon destruction of the returned scope_guard object.
120
/// @return scope_guard A scope_guard instance initialized from @c func through forwarding.
121
template
<
typename
CallableType
,
constraints
<
std
::
enable_if_t
<
is_nothrow_invocable_r_v
<
void
,
CallableType
>>> =
nullptr
>
122
ARENE_NODISCARD
auto
on_scope_exit
(
CallableType
&&
func
123
)
noexcept
(
std
::
is_nothrow_constructible
<
remove_cvref_t
<
CallableType
>,
CallableType
>::
value
)
124
->
scope_guard
<
remove_cvref_t
<
CallableType
>> {
125
return
scope_guard
<
remove_cvref_t
<
CallableType
>>{
std
::
forward
<
CallableType
>(
func
)};
126
}
127
128
}
// namespace base
129
}
// namespace arene
130
#
endif
// INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_SCOPE_GUARD_SCOPE_GUARD_HPP_
arene::base::scope_guard
RAII utility for executing logic on scope exit.
Definition
scope_guard.hpp:43
arene::base
Definition
array_exceptions_disabled.cpp:11
arene
Copyright 2026, Toyota Motor Corporation.
Definition
array_exceptions_disabled.cpp:10
arene
base
scope_guard
scope_guard.hpp
Generated by
1.13.2