Last active
December 10, 2015 20:58
-
-
Save PkmX/4491652 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef SCOPEGUARD_HPP | |
#define SCOPEGUARD_HPP | |
#include <functional> | |
#ifndef __has_feature | |
#define __has_feature(x) 0 | |
#endif | |
namespace detail | |
{ | |
template<typename F> | |
class scopeguard_impl | |
{ | |
public: | |
explicit scopeguard_impl(F&& f_) | |
: f(std::forward<F>(f_)), dismissed(false) | |
{ | |
} | |
// Note: defining a move constructor inhibits auto-generation of copy constructor and copy assignment operator. | |
scopeguard_impl(scopeguard_impl&& rhs) | |
: f(std::move(rhs.f)), dismissed(std::move(rhs.dismissed)) | |
{ | |
rhs.dismiss(); | |
} | |
#if __has_feature(cxx_reference_qualified_functions) | |
scopeguard_impl& operator=(scopeguard_impl&& rhs) & | |
#else | |
scopeguard_impl& operator=(scopeguard_impl&& rhs) | |
#endif | |
{ | |
this->f = std::move(rhs.f); | |
this->dismissed = std::move(rhs.dismissed); | |
rhs.dismiss(); | |
return *this; | |
} | |
~scopeguard_impl() | |
{ | |
if (!this->dismissed) | |
{ | |
this->f(); | |
} | |
} | |
void dismiss() | |
{ | |
this->dismissed = true; | |
} | |
private: | |
F f; | |
bool dismissed; | |
// Prevent scopeguard from being new'ed. | |
void* operator new(std::size_t) = delete; | |
void* operator new[](std::size_t) = delete; | |
void operator delete(void*) = delete; | |
void operator delete[](void*) = delete; | |
}; | |
} | |
template<typename F> | |
detail::scopeguard_impl<F> scopeguard(F&& f) | |
{ | |
return detail::scopeguard_impl<F>(std::forward<F>(f)); | |
} | |
#define SCOPEGUARD_PP_CAT_IMPL(x, y) x##y | |
#define SCOPEGUARD_PP_CAT(x, y) SCOPEGUARD_PP_CAT_IMPL(x, y) | |
#define at_scope_exit(f) \ | |
__attribute__((unused)) const auto SCOPEGUARD_PP_CAT(scopeguard, __COUNTER__) = scopeguard((f)); | |
#endif // SCOPEGUARD_HPP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment