aboutsummaryrefslogtreecommitdiff
path: root/build/diagnostics
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-12-11 09:45:26 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2014-12-11 09:45:26 +0200
commitfdc21950905d64b2ca1df5a0b2622022beffe922 (patch)
tree767f87d249a116f896c1de728e8dc32f899f0f4d /build/diagnostics
parentf4ed3e569cb5ebae855ea5309bfc17aa6b35874a (diff)
Improve diagnostics and error handling
g++-4.9 -std=c++14 -g -I.. -o bd bd.cxx target.cxx native.cxx rule.cxx cxx/rule.cxx cxx/target.cxx process.cxx timestamp.cxx path.cxx
Diffstat (limited to 'build/diagnostics')
-rw-r--r--build/diagnostics54
1 files changed, 54 insertions, 0 deletions
diff --git a/build/diagnostics b/build/diagnostics
new file mode 100644
index 0000000..c8fb169
--- /dev/null
+++ b/build/diagnostics
@@ -0,0 +1,54 @@
+// file : build/diagnostics -*- C++ -*-
+// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef BUILD_DIAGNOSTICS
+#define BUILD_DIAGNOSTICS
+
+#include <tuple>
+#include <utility>
+#include <exception>
+
+namespace build
+{
+ // Throw this exception to terminate the build. The handler should
+ // assume that the diagnostics has already been issued.
+ //
+ class error: public std::exception {};
+
+ // Call a function if there is an exception.
+ //
+ template <typename F, typename T>
+ struct exception_guard;
+
+ template <typename F, typename... A>
+ inline exception_guard<F, std::tuple<A&&...>>
+ make_exception_guard (F f, A&&... a)
+ {
+ return exception_guard<F, std::tuple<A&&...>> (
+ std::move (f), std::forward_as_tuple (a...));
+ }
+
+ template <typename F, typename... A>
+ struct exception_guard<F, std::tuple<A...>>
+ {
+ typedef std::tuple<A...> T;
+
+ exception_guard (F f, T a): f_ (std::move (f)), a_ (std::move (a)) {}
+ ~exception_guard ()
+ {
+ if (std::uncaught_exception ())
+ call (std::index_sequence_for<A...> ());
+ }
+
+ private:
+ template <std::size_t... I>
+ void
+ call (std::index_sequence<I...>) {f_ (std::get<I> (a_)...);}
+
+ F f_;
+ T a_;
+ };
+}
+
+#endif // BUILD_DIAGNOSTICS