From b0524a0b18eec9d5e5c3f6ce30b6cecdd02a6306 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 20 Jan 2015 17:18:09 +0200 Subject: Diagnostic infrastructure revamp --- build/utility | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'build/utility') diff --git a/build/utility b/build/utility index bcbf834..5523e8b 100644 --- a/build/utility +++ b/build/utility @@ -5,9 +5,12 @@ #ifndef BUILD_UTILITY #define BUILD_UTILITY +#include #include -#include +#include #include // strcmp +#include +#include namespace build @@ -26,6 +29,54 @@ namespace build bool operator() (const P& x, const P& y) const {return *x < *y;} }; + // Call a function if there is an exception. + // + + // 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, A&&... a) + { + return exception_guard> ( + std::move (f), std::forward_as_tuple (a...)); + } + + template + struct exception_guard> + { + typedef std::tuple T; + + exception_guard (F f, T a): f_ (std::move (f)), a_ (std::move (a)) {} + ~exception_guard () + { + if (std::uncaught_exception ()) + { + exception_unwinding_dtor = true; + call (std::index_sequence_for ()); + exception_unwinding_dtor = false; + } + } + + private: + template + void + call (std::index_sequence) {f_ (std::get (a_)...);} + + F f_; + T a_; + }; + // Pools (@@ perhaps move into a separate header). // struct string_pool: std::unordered_set -- cgit v1.1