-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscope_guard.h
More file actions
69 lines (53 loc) · 1.77 KB
/
Copy pathscope_guard.h
File metadata and controls
69 lines (53 loc) · 1.77 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
// SPDX-License-Identifier: MIT
#ifndef STDCORELIB_SCOPE_GUARD_H
#define STDCORELIB_SCOPE_GUARD_H
#include <functional>
#include <type_traits>
#include <utility>
#include <stdcorelib/stdc_global.h>
namespace stdc {
/// \addtogroup utility
/// @{
template <class F>
class scope_guard {
public:
explicit scope_guard(F &&f) noexcept(std::is_nothrow_move_constructible_v<F>)
: m_func(std::move(f)) {
}
explicit scope_guard(const F &f) noexcept(std::is_nothrow_copy_constructible_v<F>)
: m_func(f) {
}
scope_guard(scope_guard &&RHS) noexcept(std::is_nothrow_move_constructible_v<F>)
: m_func(std::move(RHS.m_func)), m_active(std::exchange(RHS.m_active, false)) {
}
~scope_guard() noexcept {
if (m_active)
m_func();
}
void dismiss() noexcept {
m_active = false;
}
protected:
F m_func;
bool m_active = true;
STDC_DISABLE_COPY(scope_guard)
};
template <class F>
scope_guard(F (&)()) -> scope_guard<F (*)()>;
/// A scope_guard over \a f, deducing what to hold it as.
///
/// \code
/// auto guard = stdc::make_scope_guard([&] { std::fclose(file); });
/// ...
/// guard.dismiss(); // where the close is no longer wanted
/// \endcode
///
/// \note Nodiscard, since a guard nobody keeps is destroyed at the end of the full
/// expression and runs \a f there rather than at the end of the scope.
template <typename F>
[[nodiscard]] scope_guard<typename std::decay<F>::type> make_scope_guard(F &&f) {
return scope_guard<typename std::decay<F>::type>(std::forward<F>(f));
}
/// @}
}
#endif // STDCORELIB_SCOPE_GUARD_H