43 lines
1.1 KiB
C++
43 lines
1.1 KiB
C++
# pragma once
|
|
|
|
# include <utility>
|
|
|
|
# define AX_CONCATENATE_IMPL(s1, s2) s1##s2
|
|
# define AX_CONCATENATE(s1, s2) AX_CONCATENATE_IMPL(s1, s2)
|
|
# ifdef __COUNTER__
|
|
# define AX_ANONYMOUS_VARIABLE(str) AX_CONCATENATE(str, __COUNTER__)
|
|
# else
|
|
# define AX_ANONYMOUS_VARIABLE(str) AX_CONCATENATE(str, __LINE__)
|
|
# endif
|
|
|
|
namespace ax {
|
|
namespace scopeguard_detail {
|
|
|
|
enum class ScopeGuardOnExit {};
|
|
template <typename F>
|
|
class ScopeGuard
|
|
{
|
|
F f_;
|
|
bool active_;
|
|
public:
|
|
ScopeGuard() = delete;
|
|
ScopeGuard(const ScopeGuard&) = delete;
|
|
ScopeGuard& operator=(const ScopeGuard&) = delete;
|
|
ScopeGuard(ScopeGuard&& rhs): f_(std::move(rhs.f_)), active_(rhs.active_) { rhs.dismiss(); }
|
|
ScopeGuard(F f): f_(std::move(f)), active_(true) {}
|
|
~ScopeGuard() { if (active_) f_(); }
|
|
void dismiss() { active_ = false; }
|
|
};
|
|
template <typename F>
|
|
inline ScopeGuard<F> operator+(ScopeGuardOnExit, F&& f)
|
|
{
|
|
return ScopeGuard<F>(std::forward<F>(f));
|
|
}
|
|
|
|
} // namespace scopeguard_detail
|
|
} // namespace ax
|
|
|
|
# define AX_SCOPE_EXIT \
|
|
auto AX_ANONYMOUS_VARIABLE(AX_SCOPE_EXIT_STATE) \
|
|
= ::ax::scopeguard_detail::ScopeGuardOnExit() + [&]()
|