Elements  5.12
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:
53  explicit Exception(ExitCode e = ExitCode::NOT_OK) :
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 
Elements::Exception::ExitCodeHelper< Last >::getCode
ExitCode getCode(const T &)
Definition: Exception.h:156
Export.h
defines the macros to be used for explicit export of the symbols
Elements::Exception::Exception
Exception(const char *stringFormat, Args &&...args)
Constructs a new Exception with a message using format specifiers.
Definition: Exception.h:85
std::string
STL class.
std::exception
STL class.
Elements::Exception::ExitCodeHelper< Last >::getCode
ExitCode getCode(const T &t)
Definition: Exception.h:151
Elements::Exception::exitCode
ExitCode exitCode() const noexcept
Definition: Exception.h:111
Elements::Exception::ExitCodeHelper< First, Rest... >::ExitCodeHelper
ExitCodeHelper(const First &, const Rest &... rest)
Definition: Exception.h:164
std::stringstream
STL class.
Exit.h
define a list of standard exit codes for executables
Elements::Exception::ExitCodeHelper< Last >::ExitCodeHelper
ExitCodeHelper(const Last &last)
Definition: Exception.h:146
Elements::ExitCode
ExitCode
Strongly typed exit numbers.
Definition: Exit.h:98
Elements::Exception::appendMessage
void appendMessage(const T &message)
Appends in the end of the exception message the parameter.
Definition: Exception.h:123
Elements::operator<<
ELEMENTS_API std::ostream & operator<<(std::ostream &, const Environment::Variable &)
Definition: Environment.cpp:328
Elements::Exception::ExitCodeHelper
Definition: Exception.h:141
ELEMENTS_API
#define ELEMENTS_API
Dummy definitions for the backward compatibility mode.
Definition: Export.h:74
std::enable_if
Elements::Exception::Exception
Exception(ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:53
Elements::Exception
Elements base exception class.
Definition: Exception.h:46
Elements::Exception::Exception
Exception(const std::string &message, ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:74
Elements::Units::e
constexpr double e
The base of the natural logarithm .
Definition: MathConstants.h:50
std::remove_reference
Elements::Exception::Exception
Exception(const char *message, ExitCode e=ExitCode::NOT_OK)
Definition: Exception.h:65
Elements::Exception::~Exception
virtual ~Exception() noexcept=default
std::stringstream::str
T str(T... args)
Elements::Exception::ExitCodeHelper< Last >::code
ExitCode code
Definition: Exception.h:147
std::is_base_of
Elements
Definition: Auxiliary.h:43