Elements  5.8
A C++ base framework for the Euclid Software.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Exception.h
Go to the documentation of this file.
1 
26 #ifndef ELEMENTSKERNEL_ELEMENTSKERNEL_EXCEPTION_H_
27 #define ELEMENTSKERNEL_ELEMENTSKERNEL_EXCEPTION_H_
28 
29 #include <string>
30 #include <sstream>
31 #include <cstdio>
32 #include <utility>
33 #include <exception>
34 #include <type_traits>
35 
36 #include "ElementsKernel/Exit.h"
37 #include "ElementsKernel/Export.h" // for ELEMENTS_API
38 
39 namespace Elements {
40 
42 public:
49  m_exit_code{e} {
50  }
51 
60  explicit Exception(const char* message, ExitCode e = ExitCode::NOT_OK) :
61  m_error_msg(message), m_exit_code{e} {
62  }
63 
69  explicit Exception(const std::string& message, ExitCode e = ExitCode::NOT_OK) :
70  m_error_msg(message), m_exit_code{e} {
71  }
72 
79  template <typename ...Args>
80  explicit Exception(const char* stringFormat, Args &&...args)
81  : m_exit_code{ExitCodeHelper<Args...>{args...}.code} {
82  size_t len = snprintf(NULL, 0, stringFormat, std::forward<Args>(args)...)+1;
83  char* message = new char[len];
84  snprintf(message, len, stringFormat, std::forward<Args>(args)...);
85  m_error_msg = std::string {message};
86  delete [] message;
87  }
88 
91  virtual ~Exception() noexcept = default;
92 
98  const char * what() const noexcept override {
99  return m_error_msg.c_str();
100  }
101 
106  ExitCode exitCode() const noexcept {
107  return m_exit_code;
108  }
109 
117  template <typename T>
118  void appendMessage(const T& message) {
119  std::stringstream new_message;
120  new_message << m_error_msg << message;
121  m_error_msg = new_message.str();
122  }
123 
124 protected:
127  std::string m_error_msg {};
128  const ExitCode m_exit_code {ExitCode::NOT_OK};
129 
130 private:
131 
135  template<typename... Args>
136  struct ExitCodeHelper{};
137 
138  // Specialisation which handles the last argument
139  template<typename Last>
140  struct ExitCodeHelper<Last> {
141  explicit ExitCodeHelper(const Last& last) : code{getCode(last)} {}
143  private:
144  // This method is used if the T is an ExitCode object
145  template<typename T, typename std::enable_if<std::is_same<T, ExitCode>::value>::type* = nullptr>
146  ExitCode getCode(const T& t) {
147  return t;
148  }
149  // This method is used when the T is not an ExitCode object
150  template<typename T, typename std::enable_if<not std::is_same<T, ExitCode>::value>::type* = nullptr>
151  ExitCode getCode(const T&) {
152  return ExitCode::NOT_OK;
153  }
154  };
155 
156  // Specialization which handles two or more arguments
157  template<typename First, typename... Rest>
158  struct ExitCodeHelper<First, Rest...> : ExitCodeHelper<Rest...> {
159  ExitCodeHelper(const First&, const Rest&... rest) : ExitCodeHelper<Rest...>(rest...) {}
160  };
161 
162 };
163 
164 template <typename Ex, typename T,
165  typename = typename std::enable_if<std::is_base_of<Exception,
166  typename std::remove_reference<Ex>::type>::value>::type>
167 auto operator<<(Ex&& ex, const T& message) -> decltype(std::forward<Ex>(ex)) {
168  ex.appendMessage(message);
169  return std::forward<Ex>(ex);
170 }
171 
172 } // namespace Elements
173 
174 #endif // ELEMENTSKERNEL_ELEMENTSKERNEL_EXCEPTION_H_
175 
ExitCodeHelper(const First &, const Rest &...rest)
Definition: Exception.h:159
Exception(const char *stringFormat, Args &&...args)
Constructs a new Exception with a message using format specifiers.
Definition: Exception.h:80
Generic unknown failure.
constexpr double e
The base of the natural logarithm .
Definition: MathConstants.h:50
delete[] message
Definition: Exception.h:86
void appendMessage(const T &message)
Appends in the end of the exception message the parameter.
Definition: Exception.h:118
STL class.
defines the macros to be used for explicit export of the symbols
T str(T...args)
#define ELEMENTS_API
Dummy definitions for the backward compatibility mode.
Definition: Export.h:74
Exception(const char *message, ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:60
Exception(ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:48
STL class.
Exception(const std::string &message, ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:69
ExitCode
Strongly typed exit numbers.
Definition: Exit.h:97
ExitCode exitCode() const noexcept
Definition: Exception.h:106
define a list of standard exit codes for executables
ELEMENTS_API std::ostream & operator<<(std::ostream &, const Environment::Variable &)