From fbe0716682ad4fd64df670978785db372cbe2ed2 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Wed, 16 Sep 2015 07:14:53 +0200 Subject: Add exception_guard --- bpkg/utility | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'bpkg/utility') 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 // move() +#include // uncaught_exception () + #include 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 + struct exception_guard; + + template + inline exception_guard + make_exception_guard (F f) + { + return exception_guard (std::move (f)); + } + + template + 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 -- cgit v1.1