Elements  5.12.0
A C++ base framework for the Euclid Software.
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 
47 public:
54  m_exit_code{e} {
55  }
56 
65  explicit Exception(const char* message, ExitCode e = ExitCode::NOT_OK) :
66  m_error_msg(message), m_exit_code{e} {
67  }
68 
74  explicit Exception(const std::string& message, ExitCode e = ExitCode::NOT_OK) :
75  m_error_msg(message), m_exit_code{e} {
76  }
77 
84  template <typename ...Args>
85  explicit Exception(const char* stringFormat, Args &&...args)
86  : m_exit_code{ExitCodeHelper<Args...>{args...}.code} {
87  size_t len = snprintf(NULL, 0, stringFormat, std::forward<Args>(args)...)+1;
88  char* message = new char[len];
89  snprintf(message, len, stringFormat, std::forward<Args>(args)...);
90  m_error_msg = std::string(message);
91  delete [] message;
92  }
93 
96  virtual ~Exception() noexcept = default;
97 
103  const char * what() const noexcept override {
104  return m_error_msg.c_str();
105  }
106 
111  ExitCode exitCode() const noexcept {
112  return m_exit_code;
113  }
114 
122  template <typename T>
123  void appendMessage(const T& message) {
124  std::stringstream new_message;
125  new_message << m_error_msg << message;
126  m_error_msg = new_message.str();
127  }
128 
129 protected:
132  std::string m_error_msg {};
133  const ExitCode m_exit_code {ExitCode::NOT_OK};
134 
135 private:
136 
140  template<typename... Args>
141  struct ExitCodeHelper{};
142 
143  // Specialisation which handles the last argument
144  template<typename Last>
145  struct ExitCodeHelper<Last> {
146  explicit ExitCodeHelper(const Last& last) : code{getCode(last)} {}
148  private:
149  // This method is used if the T is an ExitCode object
150  template<typename T, typename std::enable_if<std::is_same<T, ExitCode>::value>::type* = nullptr>
151  ExitCode getCode(const T& t) {
152  return t;
153  }
154  // This method is used when the T is not an ExitCode object
155  template<typename T, typename std::enable_if<not std::is_same<T, ExitCode>::value>::type* = nullptr>
156  ExitCode getCode(const T&) {
157  return ExitCode::NOT_OK;
158  }
159  };
160 
161  // Specialization which handles two or more arguments
162  template<typename First, typename... Rest>
163  struct ExitCodeHelper<First, Rest...> : ExitCodeHelper<Rest...> {
164  ExitCodeHelper(const First&, const Rest&... rest) : ExitCodeHelper<Rest...>(rest...) {}
165  };
166 
167 };
168 
169 template <typename Ex, typename T,
170  typename = typename std::enable_if<std::is_base_of<Exception,
171  typename std::remove_reference<Ex>::type>::value>::type>
172 auto operator<<(Ex&& ex, const T& message) -> decltype(std::forward<Ex>(ex)) {
173  ex.appendMessage(message);
174  return std::forward<Ex>(ex);
175 }
176 
177 } // namespace Elements
178 
179 #endif // ELEMENTSKERNEL_ELEMENTSKERNEL_EXCEPTION_H_
180 
define a list of standard exit codes for executables
defines the macros to be used for explicit export of the symbols
Elements base exception class.
Definition: Exception.h:46
ExitCode exitCode() const noexcept
Definition: Exception.h:111
Exception(const char *stringFormat, Args &&...args)
Constructs a new Exception with a message using format specifiers.
Definition: Exception.h:85
void appendMessage(const T &message)
Appends in the end of the exception message the parameter.
Definition: Exception.h:123
Exception(const std::string &message, ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:74
Exception(ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:53
virtual ~Exception() noexcept=default
Exception(const char *message, ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:65
ExitCode
Strongly typed exit numbers.
Definition: Exit.h:98
#define ELEMENTS_API
Dummy definitions for the backward compatibility mode.
Definition: Export.h:74
constexpr double e
The base of the natural logarithm .
Definition: MathConstants.h:50
auto operator<<(Ex &&ex, const T &message) -> decltype(std::forward< Ex >(ex))
Definition: Exception.h:172
@ NOT_OK
Generic unknown failure.
T str(T... args)
ExitCodeHelper(const First &, const Rest &... rest)
Definition: Exception.h:164