From 9043b32bb1835628c5a1d8be4a271c848443c629 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Tue, 24 May 2016 22:10:57 +0200 Subject: 8.1 --- zen/scope_guard.h | 64 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'zen/scope_guard.h') diff --git a/zen/scope_guard.h b/zen/scope_guard.h index 67eb3053..f8c32127 100644 --- a/zen/scope_guard.h +++ b/zen/scope_guard.h @@ -22,7 +22,7 @@ inline int getUncaughtExceptionCount() { return std::uncaught_exceptions(); } #ifdef ZEN_LINUX static_assert(__GNUC__ < 5 || (__GNUC__ == 5 && (__GNUC_MINOR__ < 3 || (__GNUC_MINOR__ == 3 && __GNUC_PATCHLEVEL__ <= 1))), "check std::uncaught_exceptions support"); #else - static_assert(__clang_major__ < 7 || (__clang_major__ == 7 && __clang_minor__ <= 0), "check std::uncaught_exceptions support"); + static_assert(__clang_major__ < 7 || (__clang_major__ == 7 && __clang_minor__ <= 3), "check std::uncaught_exceptions support"); #endif namespace __cxxabiv1 @@ -60,6 +60,47 @@ 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 +{ + 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"! + } +}; + + +template +struct ScopeGuardDestructor +{ + static void run(F& fun, int exeptionCountOld) + { + const bool failed = getUncaughtExceptionCount() > exeptionCountOld; + if (!failed) + fun(); //throw X + } +}; + + +template +struct ScopeGuardDestructor +{ + static void run(F& fun, int exeptionCountOld) + { + const bool failed = getUncaughtExceptionCount() > exeptionCountOld; + if (failed) + try { fun(); } + catch (...) { assert(false); } + } +}; + + template class ScopeGuard { @@ -74,26 +115,7 @@ public: ~ScopeGuard() noexcept(runMode != ScopeGuardRunMode::ON_SUCCESS) { if (!dismissed) - { -#ifdef _MSC_VER -#pragma warning(suppress: 4127) //"conditional expression is constant" -#endif - if (runMode != ScopeGuardRunMode::ON_EXIT) - { - const bool failed = getUncaughtExceptionCount() > exeptionCount; - if ((runMode == ScopeGuardRunMode::ON_FAIL) != failed) - return; - } - -#ifdef _MSC_VER -#pragma warning(suppress: 4127) //"conditional expression is constant" -#endif - if (runMode == ScopeGuardRunMode::ON_SUCCESS) - fun_(); //throw X - else - try { fun_(); } - catch (...) { assert(false); } //consistency: don't expect exceptions for ON_EXIT even if "!failed"! - } + ScopeGuardDestructor::run(fun_, exeptionCount); } void dismiss() { dismissed = true; } -- cgit