diff options
Diffstat (limited to 'zen/scope_guard.h')
-rw-r--r-- | zen/scope_guard.h | 64 |
1 files changed, 25 insertions, 39 deletions
diff --git a/zen/scope_guard.h b/zen/scope_guard.h index 69d4b060..8ab58901 100644 --- a/zen/scope_guard.h +++ b/zen/scope_guard.h @@ -9,9 +9,7 @@ #include <cassert> #include <exception> -#include <type_traits> //std::decay - -//best of Zen, Loki and C++17 +#include "type_tools.h" #ifdef ZEN_WIN @@ -20,9 +18,9 @@ inline int getUncaughtExceptionCount() { return std::uncaught_exceptions(); } #elif defined ZEN_LINUX || defined ZEN_MAC //std::uncaught_exceptions() currently unsupported on GCC and Clang => clean up ASAP #ifdef ZEN_LINUX - static_assert(__GNUC__ < 6 || (__GNUC__ == 6 && (__GNUC_MINOR__ < 1 || (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ <= 1))), "check std::uncaught_exceptions support"); -#else - static_assert(__clang_major__ < 7 || (__clang_major__ == 7 && __clang_minor__ <= 3), "check std::uncaught_exceptions support"); + static_assert(__GNUC__ < 6 || (__GNUC__ == 6 && (__GNUC_MINOR__ < 2 || (__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ <= 1))), "check std::uncaught_exceptions support"); +#else //std::uncaught_exceptions() requires "mmacosx-version-min=10.12" + static_assert(__clang_major__ < 8 || (__clang_major__ == 8 && __clang_minor__ <= 0), "check std::uncaught_exceptions support"); #endif namespace __cxxabiv1 @@ -37,6 +35,7 @@ inline int getUncaughtExceptionCount() } #endif +//best of Zen, Loki and C++17 namespace zen { @@ -60,45 +59,32 @@ enum class ScopeGuardRunMode }; -template <ScopeGuardRunMode runMode, typename F> -struct ScopeGuardDestructor; - -//specialize scope guard destructor code and get rid of those pesky MSVC "4127 conditional expression is constant" -template <typename F> -struct ScopeGuardDestructor<ScopeGuardRunMode::ON_EXIT, F> +//partially specialize scope guard destructor code and get rid of those pesky MSVC "4127 conditional expression is constant" +template <typename F> inline +void runScopeGuardDestructor(F& fun, int /*exeptionCountOld*/, StaticEnum<ScopeGuardRunMode, ScopeGuardRunMode::ON_EXIT>) { - static void run(F& fun, int exeptionCountOld) - { - (void)exeptionCountOld; //silence unused parameter warning - try { fun(); } - catch (...) { assert(false); } //consistency: don't expect exceptions for ON_EXIT even if "!failed"! - } -}; + try { fun(); } + catch (...) { assert(false); } //consistency: don't expect exceptions for ON_EXIT even if "!failed"! +} -template <typename F> -struct ScopeGuardDestructor<ScopeGuardRunMode::ON_SUCCESS, F> +template <typename F> inline +void runScopeGuardDestructor(F& fun, int exeptionCountOld, StaticEnum<ScopeGuardRunMode, ScopeGuardRunMode::ON_SUCCESS>) { - static void run(F& fun, int exeptionCountOld) - { - const bool failed = getUncaughtExceptionCount() > exeptionCountOld; - if (!failed) - fun(); //throw X - } -}; + const bool failed = getUncaughtExceptionCount() > exeptionCountOld; + if (!failed) + fun(); //throw X +} -template <typename F> -struct ScopeGuardDestructor<ScopeGuardRunMode::ON_FAIL, F> +template <typename F> inline +void runScopeGuardDestructor(F& fun, int exeptionCountOld, StaticEnum<ScopeGuardRunMode, ScopeGuardRunMode::ON_FAIL>) { - static void run(F& fun, int exeptionCountOld) - { - const bool failed = getUncaughtExceptionCount() > exeptionCountOld; - if (failed) - try { fun(); } - catch (...) { assert(false); } - } -}; + const bool failed = getUncaughtExceptionCount() > exeptionCountOld; + if (failed) + try { fun(); } + catch (...) { assert(false); } +} template <ScopeGuardRunMode runMode, typename F> @@ -115,7 +101,7 @@ public: ~ScopeGuard() noexcept(runMode != ScopeGuardRunMode::ON_SUCCESS) { if (!dismissed) - ScopeGuardDestructor<runMode, F>::run(fun_, exeptionCount); + runScopeGuardDestructor(fun_, exeptionCount, StaticEnum<ScopeGuardRunMode, runMode>()); } void dismiss() { dismissed = true; } |