diff options
author | Daniel Wilhelm <daniel@wili.li> | 2016-05-24 22:10:57 +0200 |
---|---|---|
committer | Daniel Wilhelm <daniel@wili.li> | 2016-05-24 22:10:57 +0200 |
commit | 9043b32bb1835628c5a1d8be4a271c848443c629 (patch) | |
tree | 98ccb4936562731d9cae02a486441dfd446e8a4e /zen/scope_guard.h | |
parent | 8.0 (diff) | |
download | FreeFileSync-9043b32bb1835628c5a1d8be4a271c848443c629.tar.gz FreeFileSync-9043b32bb1835628c5a1d8be4a271c848443c629.tar.bz2 FreeFileSync-9043b32bb1835628c5a1d8be4a271c848443c629.zip |
8.1
Diffstat (limited to 'zen/scope_guard.h')
-rw-r--r-- | zen/scope_guard.h | 64 |
1 files changed, 43 insertions, 21 deletions
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 @@ -61,6 +61,47 @@ 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> +{ + 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 <typename F> +struct ScopeGuardDestructor<ScopeGuardRunMode::ON_SUCCESS, F> +{ + static void run(F& fun, int exeptionCountOld) + { + const bool failed = getUncaughtExceptionCount() > exeptionCountOld; + if (!failed) + fun(); //throw X + } +}; + + +template <typename F> +struct ScopeGuardDestructor<ScopeGuardRunMode::ON_FAIL, F> +{ + static void run(F& fun, int exeptionCountOld) + { + const bool failed = getUncaughtExceptionCount() > exeptionCountOld; + if (failed) + try { fun(); } + catch (...) { assert(false); } + } +}; + + +template <ScopeGuardRunMode runMode, typename F> class ScopeGuard { public: @@ -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<runMode, F>::run(fun_, exeptionCount); } void dismiss() { dismissed = true; } |