diff options
Diffstat (limited to 'bpkg/utility')
-rw-r--r-- | bpkg/utility | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/bpkg/utility b/bpkg/utility index a5bafec..ea7dfa6 100644 --- a/bpkg/utility +++ b/bpkg/utility @@ -5,6 +5,9 @@ #ifndef BPKG_UTILITY #define BPKG_UTILITY +#include <utility> // move() +#include <exception> // uncaught_exception () + #include <bpkg/types> namespace bpkg @@ -39,6 +42,46 @@ namespace bpkg inline void run (const cstrings& args) {run (args.data ());} + + // Call a function if there is an exception. + // + + // True means we are in the body of a destructor that is being + // called as part of the exception stack unwindining. Used to + // compensate for the deficiencies of uncaught_exception() until + // C++17 uncaught_exceptions() becomes available. + // + // @@ MT: will have to be TLS. + // + extern bool exception_unwinding_dtor; + + template <typename F> + struct exception_guard; + + template <typename F> + inline exception_guard<F> + make_exception_guard (F f) + { + return exception_guard<F> (std::move (f)); + } + + template <typename F> + struct exception_guard + { + exception_guard (F f): f_ (std::move (f)) {} + ~exception_guard () + { + if (std::uncaught_exception ()) + { + exception_unwinding_dtor = true; + f_ (); + exception_unwinding_dtor = false; + } + } + + private: + F f_; + }; } #endif // BPKG_UTILITY |