emilib
scope_exit.hpp
1 // By Emil Ernerfeldt 2015-2017
2 // LICENSE:
3 // This software is dual-licensed to the public domain and under the following
4 // license: you are granted a perpetual, irrevocable license to copy, modify,
5 // publish, and distribute this file as you see fit.
6 
7 #pragma once
8 
9 namespace emilib {
10 
13 template<class Fun>
15 {
16 public:
17  explicit ScopeGuard(Fun f) : _fun(std::move(f)), _active(true) {}
18 
19  ~ScopeGuard() noexcept(false)
20  {
21  if (_active) {
22  _fun();
23  }
24  }
25 
26  void dismiss() { _active = false; }
27  ScopeGuard() = delete;
28  ScopeGuard(const ScopeGuard&) = delete;
29  ScopeGuard& operator=(const ScopeGuard&) = delete;
30 
31  ScopeGuard(ScopeGuard && rhs) : _fun(std::move(rhs._fun)), _active(rhs._active)
32  {
33  rhs.dismiss();
34  }
35 
36 private:
37  Fun _fun;
38  bool _active;
39 };
40 
41 template<class Fun>
42 ScopeGuard<Fun> make_scope_guard(Fun f)
43 {
44  return ScopeGuard<Fun>(std::move(f));
45 }
46 
47 namespace detail {
48  enum class ScopeGuardOnExit { };
49 
50  template<typename Fun>
51  ScopeGuard<Fun> operator+(ScopeGuardOnExit, Fun&& fn)
52  {
53  return ScopeGuard<Fun>(std::forward<Fun>(fn));
54  }
55 } // namespace detail
56 
76 #define SCOPE_EXIT \
77  auto LOGURU_ANONYMOUS_VARIABLE(scope_guard_) = ::emilib::detail::ScopeGuardOnExit() + [&]()
78 
79 } // namespace emilib
Definition: scope_exit.hpp:14
Definition: coroutine.hpp:18