+
+#if defined(FOLLY_EXCEPTION_COUNT_USE_CXA_GET_GLOBALS) || \
+ defined(FOLLY_EXCEPTION_COUNT_USE_GETPTD)
+
+/**
+ * ScopeGuard used for executing a function when leaving the current scope
+ * depending on the presence of a new uncaught exception.
+ *
+ * If the executeOnException template parameter is true, the function is
+ * executed if a new uncaught exception is present at the end of the scope.
+ * If the parameter is false, then the function is executed if no new uncaught
+ * exceptions are present at the end of the scope.
+ *
+ * Used to implement SCOPE_FAIL and SCOPE_SUCCES below.
+ */
+template <typename FunctionType, bool executeOnException>
+class ScopeGuardForNewException {
+ public:
+ explicit ScopeGuardForNewException(const FunctionType& fn)
+ : function_(fn) {
+ }
+
+ explicit ScopeGuardForNewException(FunctionType&& fn)
+ : function_(std::move(fn)) {
+ }
+
+ ScopeGuardForNewException(ScopeGuardForNewException&& other)
+ : function_(std::move(other.function_))
+ , exceptionCounter_(std::move(other.exceptionCounter_)) {
+ }
+
+ ~ScopeGuardForNewException() noexcept(executeOnException) {
+ if (executeOnException == exceptionCounter_.isNewUncaughtException()) {
+ function_();
+ }
+ }
+
+ private:
+ ScopeGuardForNewException(const ScopeGuardForNewException& other) = delete;
+
+ void* operator new(size_t) = delete;
+
+ FunctionType function_;
+ UncaughtExceptionCounter exceptionCounter_;
+};
+
+/**
+ * Internal use for the macro SCOPE_FAIL below
+ */
+enum class ScopeGuardOnFail {};
+
+template <typename FunctionType>
+ScopeGuardForNewException<typename std::decay<FunctionType>::type, true>
+operator+(detail::ScopeGuardOnFail, FunctionType&& fn) {
+ return
+ ScopeGuardForNewException<typename std::decay<FunctionType>::type, true>(
+ std::forward<FunctionType>(fn));
+}
+
+/**
+ * Internal use for the macro SCOPE_SUCCESS below
+ */
+enum class ScopeGuardOnSuccess {};
+
+template <typename FunctionType>
+ScopeGuardForNewException<typename std::decay<FunctionType>::type, false>
+operator+(ScopeGuardOnSuccess, FunctionType&& fn) {
+ return
+ ScopeGuardForNewException<typename std::decay<FunctionType>::type, false>(
+ std::forward<FunctionType>(fn));
+}
+
+#endif // native uncaught_exception() supported
+