xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
include
xrpl
basics
scope.h
1
#pragma once
2
3
#include <xrpl/beast/utility/instrumentation.h>
4
5
#include <
exception
>
6
#include <
mutex
>
7
#include <
type_traits
>
8
#include <
utility
>
9
10
namespace
xrpl
{
11
12
// RAII scope helpers. As specified in Library Fundamental, Version 3
13
// Basic design of idea: https://www.youtube.com/watch?v=WjTrfoiB0MQ
14
// Specification:
15
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/n4873.html#scopeguard
16
17
// This implementation deviates from the spec slightly:
18
// The scope_exit and scope_fail constructors taking a functor are not
19
// permitted to throw an exception. This was done because some compilers
20
// did not like the superfluous try/catch in the common instantiations
21
// where the construction was noexcept. Instead a static_assert is used
22
// to enforce this restriction.
23
24
template
<
class
EF>
25
class
ScopeExit
26
{
27
EF
exitFunction_
;
28
bool
executeOnDestruction_
{
true
};
29
30
public
:
31
~ScopeExit
()
32
{
33
if
(
executeOnDestruction_
)
34
exitFunction_
();
35
}
36
37
ScopeExit
(
ScopeExit
&& rhs)
noexcept
(
38
std::is_nothrow_move_constructible_v<EF>
||
std::is_nothrow_copy_constructible_v<EF>
)
39
:
exitFunction_
{
std
::forward<EF>(rhs.
exitFunction_
)}
40
,
executeOnDestruction_
{rhs.
executeOnDestruction_
}
41
{
42
rhs.release();
43
}
44
45
ScopeExit
&
46
operator=
(
ScopeExit
&&) =
delete
;
47
48
template
<
class
EFP>
49
explicit
ScopeExit
(EFP&& f)
noexcept
50
requires
(
51
!
std::is_same_v<std::remove_cv_t<EFP>
,
ScopeExit
> &&
std::is_constructible_v<EF, EFP>
)
52
:
exitFunction_
{
std
::forward<EFP>(f)}
53
{
54
static_assert
(
std::is_nothrow_constructible_v<EF, decltype(std::forward<EFP>
(f))>);
55
}
56
57
void
58
release
() noexcept
59
{
60
executeOnDestruction_
=
false
;
61
}
62
};
63
64
template
<
class
EF>
65
ScopeExit
(EF) ->
ScopeExit<EF>
;
66
67
template
<
class
EF>
68
class
ScopeFail
69
{
70
EF
exitFunction_
;
71
bool
executeOnDestruction_
{
true
};
72
int
uncaughtOnCreation_
{
std::uncaught_exceptions
()};
73
74
public
:
75
~ScopeFail
()
76
{
77
if
(
executeOnDestruction_
&&
std::uncaught_exceptions
() >
uncaughtOnCreation_
)
78
exitFunction_
();
79
}
80
81
ScopeFail
(
ScopeFail
&& rhs)
noexcept
(
82
std::is_nothrow_move_constructible_v<EF>
||
std::is_nothrow_copy_constructible_v<EF>
)
83
:
exitFunction_
{
std
::forward<EF>(rhs.
exitFunction_
)}
84
,
executeOnDestruction_
{rhs.
executeOnDestruction_
}
85
,
uncaughtOnCreation_
{rhs.
uncaughtOnCreation_
}
86
{
87
rhs.release();
88
}
89
90
ScopeFail
&
91
operator=
(
ScopeFail
&&) =
delete
;
92
93
template
<
class
EFP>
94
explicit
ScopeFail
(EFP&& f)
noexcept
95
requires
(
96
!
std::is_same_v<std::remove_cv_t<EFP>
,
ScopeFail
> &&
std::is_constructible_v<EF, EFP>
)
97
:
exitFunction_
{
std
::forward<EFP>(f)}
98
{
99
static_assert
(
std::is_nothrow_constructible_v<EF, decltype(std::forward<EFP>
(f))>);
100
}
101
102
void
103
release
() noexcept
104
{
105
executeOnDestruction_
=
false
;
106
}
107
};
108
109
template
<
class
EF>
110
ScopeFail
(EF) ->
ScopeFail<EF>
;
111
112
template
<
class
EF>
113
class
ScopeSuccess
114
{
115
EF
exitFunction_
;
116
bool
executeOnDestruction_
{
true
};
117
int
uncaughtOnCreation_
{
std::uncaught_exceptions
()};
118
119
public
:
120
~ScopeSuccess
() noexcept(noexcept(
exitFunction_
()))
121
{
122
if
(
executeOnDestruction_
&&
std::uncaught_exceptions
() <=
uncaughtOnCreation_
)
123
exitFunction_
();
124
}
125
126
ScopeSuccess
(
ScopeSuccess
&& rhs)
noexcept
(
127
std::is_nothrow_move_constructible_v<EF>
||
std::is_nothrow_copy_constructible_v<EF>
)
128
:
exitFunction_
{
std
::forward<EF>(rhs.
exitFunction_
)}
129
,
executeOnDestruction_
{rhs.
executeOnDestruction_
}
130
,
uncaughtOnCreation_
{rhs.
uncaughtOnCreation_
}
131
{
132
rhs.release();
133
}
134
135
ScopeSuccess
&
136
operator=
(
ScopeSuccess
&&) =
delete
;
137
138
template
<
class
EFP>
139
explicit
ScopeSuccess
(EFP&& f)
noexcept
(
140
std::is_nothrow_constructible_v<EF, EFP>
||
std::is_nothrow_constructible_v<EF, EFP&>
)
141
requires
(
142
!
std::is_same_v
<
std::remove_cv_t<EFP>
,
ScopeSuccess
> &&
143
std::is_constructible_v<EF, EFP>
)
144
:
exitFunction_
{
std::forward<EFP>
(f)}
145
{
146
}
147
148
void
149
release
() noexcept
150
{
151
executeOnDestruction_
=
false
;
152
}
153
};
154
155
template
<
class
EF>
156
ScopeSuccess
(EF) ->
ScopeSuccess<EF>
;
157
194
195
template
<
class
Mutex>
196
class
ScopeUnlock
197
{
198
std::unique_lock<Mutex>
*
plock_
;
199
200
public
:
201
explicit
ScopeUnlock
(
std::unique_lock<Mutex>
& lock)
noexcept
(
true
) :
plock_
(&lock)
202
{
203
XRPL_ASSERT(
plock_
->owns_lock(),
"xrpl::ScopeUnlock::ScopeUnlock : mutex must be locked"
);
204
plock_
->unlock();
205
}
206
207
// Immovable type
208
ScopeUnlock
(
ScopeUnlock
const
&) =
delete
;
209
ScopeUnlock
&
210
operator=
(
ScopeUnlock
const
&) =
delete
;
211
212
~ScopeUnlock
() noexcept(true)
213
{
214
plock_
->lock();
215
}
216
};
217
218
template
<
class
Mutex>
219
ScopeUnlock
(
std::unique_lock<Mutex>
&) ->
ScopeUnlock<Mutex>
;
220
221
}
// namespace xrpl
xrpl::ScopeExit
Definition
scope.h:26
xrpl::ScopeExit::~ScopeExit
~ScopeExit()
Definition
scope.h:31
xrpl::ScopeExit::executeOnDestruction_
bool executeOnDestruction_
Definition
scope.h:28
xrpl::ScopeExit::exitFunction_
EF exitFunction_
Definition
scope.h:27
xrpl::ScopeExit::release
void release() noexcept
Definition
scope.h:58
xrpl::ScopeExit::ScopeExit
ScopeExit(ScopeExit &&rhs) noexcept(std::is_nothrow_move_constructible_v< EF >||std::is_nothrow_copy_constructible_v< EF >)
Definition
scope.h:37
xrpl::ScopeExit::ScopeExit
ScopeExit(EFP &&f) noexcept
Definition
scope.h:49
xrpl::ScopeExit::operator=
ScopeExit & operator=(ScopeExit &&)=delete
xrpl::ScopeFail
Definition
scope.h:69
xrpl::ScopeFail::operator=
ScopeFail & operator=(ScopeFail &&)=delete
xrpl::ScopeFail::uncaughtOnCreation_
int uncaughtOnCreation_
Definition
scope.h:72
xrpl::ScopeFail::ScopeFail
ScopeFail(EFP &&f) noexcept
Definition
scope.h:94
xrpl::ScopeFail::~ScopeFail
~ScopeFail()
Definition
scope.h:75
xrpl::ScopeFail::ScopeFail
ScopeFail(ScopeFail &&rhs) noexcept(std::is_nothrow_move_constructible_v< EF >||std::is_nothrow_copy_constructible_v< EF >)
Definition
scope.h:81
xrpl::ScopeFail::executeOnDestruction_
bool executeOnDestruction_
Definition
scope.h:71
xrpl::ScopeFail::exitFunction_
EF exitFunction_
Definition
scope.h:70
xrpl::ScopeFail::release
void release() noexcept
Definition
scope.h:103
xrpl::ScopeSuccess
Definition
scope.h:114
xrpl::ScopeSuccess::operator=
ScopeSuccess & operator=(ScopeSuccess &&)=delete
xrpl::ScopeSuccess::ScopeSuccess
ScopeSuccess(EFP &&f) noexcept(std::is_nothrow_constructible_v< EF, EFP >||std::is_nothrow_constructible_v< EF, EFP & >)
Definition
scope.h:139
xrpl::ScopeSuccess::exitFunction_
EF exitFunction_
Definition
scope.h:115
xrpl::ScopeSuccess::release
void release() noexcept
Definition
scope.h:149
xrpl::ScopeSuccess::executeOnDestruction_
bool executeOnDestruction_
Definition
scope.h:116
xrpl::ScopeSuccess::~ScopeSuccess
~ScopeSuccess() noexcept(noexcept(exitFunction_()))
Definition
scope.h:120
xrpl::ScopeSuccess::uncaughtOnCreation_
int uncaughtOnCreation_
Definition
scope.h:117
xrpl::ScopeSuccess::ScopeSuccess
ScopeSuccess(ScopeSuccess &&rhs) noexcept(std::is_nothrow_move_constructible_v< EF >||std::is_nothrow_copy_constructible_v< EF >)
Definition
scope.h:126
xrpl::ScopeUnlock
Automatically unlocks and re-locks a unique_lock object.
Definition
scope.h:197
xrpl::ScopeUnlock::~ScopeUnlock
~ScopeUnlock() noexcept(true)
Definition
scope.h:212
xrpl::ScopeUnlock::operator=
ScopeUnlock & operator=(ScopeUnlock const &)=delete
xrpl::ScopeUnlock::plock_
std::unique_lock< Mutex > * plock_
Definition
scope.h:198
xrpl::ScopeUnlock::ScopeUnlock
ScopeUnlock(ScopeUnlock const &)=delete
xrpl::ScopeUnlock::ScopeUnlock
ScopeUnlock(std::unique_lock< Mutex > &lock) noexcept(true)
Definition
scope.h:201
exception
std::forward
T forward(T... args)
std::is_constructible_v
T is_constructible_v
std::is_nothrow_copy_constructible_v
T is_nothrow_copy_constructible_v
std::is_nothrow_move_constructible_v
T is_nothrow_move_constructible_v
std::is_same_v
T is_same_v
mutex
std
STL namespace.
xrpl
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition
algorithm.h:5
xrpl::ScopeExit
ScopeExit(EF) -> ScopeExit< EF >
xrpl::ScopeUnlock
ScopeUnlock(std::unique_lock< Mutex > &) -> ScopeUnlock< Mutex >
xrpl::ScopeSuccess
ScopeSuccess(EF) -> ScopeSuccess< EF >
xrpl::ScopeFail
ScopeFail(EF) -> ScopeFail< EF >
std::remove_cv_t
type_traits
std::uncaught_exceptions
T uncaught_exceptions(T... args)
std::unique_lock
utility
Generated by
1.17.0