Skip to content

Instantly share code, notes, and snippets.

@KindDragon
Last active July 30, 2019 18:06
Show Gist options
  • Save KindDragon/4650442 to your computer and use it in GitHub Desktop.
Save KindDragon/4650442 to your computer and use it in GitHub Desktop.
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment