-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdefer.hpp
56 lines (42 loc) · 1.67 KB
/
defer.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#ifndef DEFER_HPP
#define DEFER_HPP
#include <utility>
#ifdef __cpp_exceptions
#include <exception>
#endif
#define DEFER_DEFCLASS(name, ...) \
template <class F> \
class name { \
const F _func; \
\
public: \
constexpr name(F &&f) noexcept : _func(std::forward<F>(f)) {} \
__VA_ARGS__ \
name(name &&) = delete; \
name &operator=(name &&) = delete; \
}
namespace Defer {
#if __cplusplus >= 202002L
DEFER_DEFCLASS(Exit, constexpr ~Exit() { _func(); });
#else
DEFER_DEFCLASS(Exit, ~Exit() { _func(); });
#endif
#ifdef __cpp_exceptions
DEFER_DEFCLASS(Success, ~Success() {
if (std::uncaught_exceptions() == 0) _func();
});
DEFER_DEFCLASS(Failure, ~Failure() {
if (std::uncaught_exceptions() > 0) _func();
});
#endif
}
#define DEFER_ANONNAME2(x, y) x ## _ ## y
#define DEFER_ANONNAME1(x, y) DEFER_ANONNAME2(x, y)
#define DEFER_ANONNAME DEFER_ANONNAME1(defer, __LINE__)
#define DEFER_(policy) const Defer::policy DEFER_ANONNAME = [&]
#define DEFER DEFER_(Exit)
#ifdef __cpp_exceptions
#define DEFER_SUCCESS DEFER_(Success)
#define DEFER_FAILURE DEFER_(Failure)
#endif
#endif