Skip to content

Instantly share code, notes, and snippets.

@KindDragon
Last active July 30, 2019 18:06

Revisions

  1. KindDragon renamed this gist Jan 27, 2013. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. KindDragon created this gist Jan 27, 2013.
    42 changes: 42 additions & 0 deletions ScopeGuard11.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,42 @@
    template <class Fun>
    class ScopeGuard {
    Fun f_;
    bool active_;
    public:
    ScopeGuard(Fun f)
    : f_(std::move(f))
    , active_(true) {
    }
    ~ScopeGuard() { if (active_) f_(); }
    void dismiss() { active_ = false; }
    ScopeGuard() = delete;
    ScopeGuard(const ScopeGuard&) = delete;
    ScopeGuard& operator=(const ScopeGuard&) = delete;
    ScopeGuard(ScopeGuard&& rhs)
    : f_(std::move(rhs.f_))
    , active_(rhs.active_) {
    rhs.dismiss();
    }
    };

    namespace detail {
    enum class ScopeGuardOnExit {};
    template <typename Fun>
    ScopeGuard<Fun> operator+(ScopeGuardOnExit, Fun&& fn) {
    return ScopeGuard<Fun>(std::forward<Fun>(fn));
    }
    }

    #define SCOPE_EXIT \
    auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) \
    = ::detail::ScopeGuardOnExit() + [&]()

    #define CONCATENATE_IMPL(s1, s2) s1##s2
    #define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)
    #ifdef __COUNTER__
    #define ANONYMOUS_VARIABLE(str) \
    CONCATENATE(str, __COUNTER__)
    #else
    #define ANONYMOUS_VARIABLE(str) \
    CONCATENATE(str, __LINE__)
    #endif