From 8dd4a066ca0312ff03595b96a75abc8c6123f576 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Sat, 29 Oct 2016 11:35:33 +0200 Subject: 8.5 --- zen/scope_guard.h | 64 ++++++++++++++++++++++--------------------------------- 1 file changed, 25 insertions(+), 39 deletions(-) (limited to 'zen/scope_guard.h') 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 #include -#include //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 -struct ScopeGuardDestructor; - -//specialize scope guard destructor code and get rid of those pesky MSVC "4127 conditional expression is constant" -template -struct ScopeGuardDestructor +//partially specialize scope guard destructor code and get rid of those pesky MSVC "4127 conditional expression is constant" +template inline +void runScopeGuardDestructor(F& fun, int /*exeptionCountOld*/, StaticEnum) { - 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 -struct ScopeGuardDestructor +template inline +void runScopeGuardDestructor(F& fun, int exeptionCountOld, StaticEnum) { - 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 -struct ScopeGuardDestructor +template inline +void runScopeGuardDestructor(F& fun, int exeptionCountOld, StaticEnum) { - 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 @@ -115,7 +101,7 @@ public: ~ScopeGuard() noexcept(runMode != ScopeGuardRunMode::ON_SUCCESS) { if (!dismissed) - ScopeGuardDestructor::run(fun_, exeptionCount); + runScopeGuardDestructor(fun_, exeptionCount, StaticEnum()); } void dismiss() { dismissed = true; } -- cgit