summaryrefslogtreecommitdiff
path: root/zen/scope_guard.h
diff options
context:
space:
mode:
Diffstat (limited to 'zen/scope_guard.h')
-rw-r--r--zen/scope_guard.h64
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; }
bgstack15