Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
woops, align the 'noexcept' declaration between .hpp and .cpp
[simgrid.git] / include / xbt / exception.hpp
1 /* Copyright (c) 2005-2016. The SimGrid Team.All rights reserved. */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #ifndef SIMGRID_XBT_EXCEPTION_HPP
7 #define SIMGRID_XBT_EXCEPTION_HPP
8
9 #include <string>
10 #include <type_traits>
11 #include <vector>
12
13 #include <xbt/base.h>
14 #include <xbt/backtrace.h>
15 #include <xbt/backtrace.hpp>
16 #include <xbt/log.h>
17 #include <xbt/misc.h>  // xbt_procname
18 #include <xbt/virtu.h> // xbt_getpid
19
20 namespace simgrid {
21 namespace xbt {
22
23 typedef std::vector<xbt_backtrace_location_t> Backtrace;
24
25 /** A polymorphic mixin class for adding context to an exception */
26 XBT_PUBLIC_CLASS WithContextException {
27 public:
28   WithContextException() :
29     backtrace_(simgrid::xbt::backtrace()),
30     procname_(xbt_procname()),
31     pid_(xbt_getpid())
32   {}
33   WithContextException(Backtrace bt) :
34     backtrace_(std::move(bt)),
35     procname_(xbt_procname()),
36     pid_(xbt_getpid())
37   {}
38   virtual ~WithContextException();
39   Backtrace const& backtrace() const
40   {
41     return backtrace_;
42   }
43   int pid() const { return pid_; }
44   std::string const& processName() const { return procname_; }
45 private:
46   Backtrace backtrace_;
47   std::string procname_; /**< Name of the process who thrown this */
48   int pid_;              /**< PID of the process who thrown this */
49 };
50
51 /** Internal class used to mixin the two classes */
52 template<class E>
53 class WithContext : public E, public WithContextException
54 {
55 public:
56   WithContext(E exception)
57     : E(std::move(exception)) {}
58   WithContext(E exception, Backtrace backtrace)
59     : E(std::move(exception)), WithContextException(std::move(backtrace)) {}
60   WithContext(E exception, WithContextException context)
61     : E(std::move(exception)), WithContextException(std::move(context)) {}
62   ~WithContext() override {}
63 };
64
65 /** Throw a given exception a context
66  *
67  *  @param exception exception to throw
68  *  @param backtrace backtrace to attach
69  */
70 template<class E>
71 [[noreturn]] inline
72 typename std::enable_if< !std::is_base_of<WithContextException,E>::value >::type
73 throwWithContext(
74   E exception,
75   // Thanks to the default argument, we are taking the backtrace in the caller:
76   Backtrace backtrace = simgrid::xbt::backtrace())
77 {
78  throw WithContext<E>(std::move(exception), std::move(backtrace));
79 }
80
81 }
82 }
83
84 #endif