NetBurner 3.5.8
PDF Version
Toggle main menu visibility
defer.h
1
#ifndef __DEFER_H
2
#define __DEFER_H
3
/* As posted by Oded Lazar, modified from StackOverflow user R. Martinho Fernandes, */
4
/* and originally published by Andrei Alexandrescu and Petru Marginean in Dr. Dobbs
5
* December 2000 */
6
/* https://oded.blog/2017/10/05/go-defer-in-cpp/ */
7
/* https://stackoverflow.com/questions/10270328/the-simplest-and-neatest-c11-scopeguard/ */
8
/* http://www.drdobbs.com/cpp/generic-change-the-way-you-write-excepti/184403758 */
9
/*NB_REVISION*/
10
11
/*NB_COPYRIGHT*/
12
13
#include <functional>
14
#include <utility>
15
16
#define DEFER_CONCAT_(a, b) a##b
17
#define DEFER_CONCAT(a, b) DEFER_CONCAT_(a, b)
18
19
#define DEFER_CALL(fn) _ScopeGuard DEFER_CONCAT(__defer__, __LINE__) = [&]() { fn; };
20
21
class
_ScopeGuard
22
{
23
public
:
24
template
<
class
Callable>
25
_ScopeGuard(Callable &&fn) : fn_(std::forward<Callable>(fn))
26
{
27
}
28
29
_ScopeGuard(_ScopeGuard &&other) : fn_(std::move(other.fn_)) { other.fn_ =
nullptr
; }
30
31
~_ScopeGuard()
32
{
33
// must not throw
34
if
(fn_) fn_();
35
}
36
37
_ScopeGuard(
const
_ScopeGuard &) =
delete
;
38
void
operator=(
const
_ScopeGuard &) =
delete
;
39
40
private
:
41
std::function<void()> fn_;
42
};
43
44
#define IF_REENTERED(fn) \
45
static int DEFER_CONCAT(__reenter_guard_depth__, __LINE__) = 0; \
46
_ReentrancyGuard DEFER_CONCAT(__reenter_guard__, __LINE__)(DEFER_CONCAT(__reenter_guard_depth__, __LINE__), [&]() { fn; });
47
48
class
_ReentrancyGuard
49
{
50
public
:
51
template
<
class
Callable>
52
_ReentrancyGuard(
int
&entered, Callable &&fn) : depth(entered)
53
{
54
if
(depth) { fn(); }
55
depth++;
56
}
57
58
_ReentrancyGuard(_ReentrancyGuard &&other) : depth(other.depth) {}
59
60
~_ReentrancyGuard() { depth--; }
61
62
_ReentrancyGuard(
const
_ReentrancyGuard &) =
delete
;
63
void
operator=(
const
_ReentrancyGuard &) =
delete
;
64
65
private
:
66
int
&depth;
67
};
68
69
#endif
/* ----- #ifndef __DEFER_H ----- */
nbrtos
include
defer.h
Generated by
1.18.0