| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- //
- // scope_guard.hpp
- // memory
- //
- // Created by Sam Jaffe on 9/24/15.
- //
- //
- #pragma once
- #include <functional>
- class scope_exit {
- public:
- template <typename F> scope_exit(F f) : on_exit_(f) {}
-
- scope_exit(scope_exit const &) = delete;
- scope_exit &operator=(scope_exit const &) = delete;
- scope_exit(scope_exit &&) = default;
- scope_exit &operator=(scope_exit &&) = default;
-
- ~scope_exit() noexcept { if (on_exit_) { on_exit_(); } }
-
- void release() { on_exit_ = {}; }
- private:
- std::function<void()> on_exit_;
- };
- #if __cplusplus > 201402L
- template <bool RunOnFailure>
- class scope_exception {
- public:
- template <typename F>
- scope_exception(F f) : on_exit_(f), depth_(std::uncaught_exceptions()) {}
-
- scope_exception(scope_exception const &) = delete;
- scope_exception &operator=(scope_exception const &) = delete;
- scope_exception(scope_exception &&) = default;
- scope_exception &operator=(scope_exception &&) = default;
- ~scope_exception() noexcept(RunOnFailure) {
- if (on_exit_ && RunOnFailure == is_failure()) { on_exit_(); }
- }
-
- void release() { on_exit_ = {}; }
-
- private:
- bool is_failure() const {
- return std::uncaught_exceptions() > depth_;
- }
-
- private:
- std::function<void()> on_exit_;
- int depth_;
- };
- using scope_failure = scope_exception<true>;
- using scope_success = scope_exception<false>;
- #endif
- #if !defined(CONCAT)
- #define CONCAT2(A, B) A##B
- #define CONCAT(A, B) CONCAT2(A, B)
- #endif
- #define SCOPE_TYPE(t) CONCAT(scope_,t)
- #define SCOPE_GUARD_NAME(t) CONCAT(CONCAT(scope_guard_,t),__LINE__)
- #define scope(t) SCOPE_TYPE(t) SCOPE_GUARD_NAME(t) = [&]()
- #define scope_guard(t, f) SCOPE_TYPE(t) SCOPE_GUARD_NAME(t){f};
|