MRPT  1.9.9
exceptions.h
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #pragma once
11 
12 #include <string> // std::string, to_string()
13 #include <stdexcept> // logic_error
14 #include <mrpt/core/common.h>
15 #include <mrpt/core/format.h>
16 
17 /** \def THROW_TYPED_EXCEPTION(msg,exceptionClass) */
18 #define THROW_TYPED_EXCEPTION(msg, exceptionClass) \
19  throw exceptionClass( \
20  throw_typed_exception(msg, __CURRENT_FUNCTION_NAME__, __LINE__))
21 
22 template <typename T>
24  const T& msg, const char* function_name, unsigned int line)
25 {
26  std::string s = "\n\n =============== MRPT EXCEPTION =============\n";
27  s += function_name;
28  s += ", line ";
29  s += mrpt::to_string(line);
30  s += ":\n";
31  s += msg;
32  s += ":\n";
33  return s;
34 }
35 
36 /** \def THROW_EXCEPTION(msg);
37  * \param msg This can be a char*, a std::string, or a literal string.
38  * Defines a unified way of reporting exceptions
39  * \sa MRPT_TRY_START, MRPT_TRY_END, THROW_EXCEPTION_FMT
40  */
41 #define THROW_EXCEPTION(msg) THROW_TYPED_EXCEPTION(msg, std::logic_error);
42 
43 #define THROW_EXCEPTION_FMT(_FORMAT_STRING, ...) \
44  THROW_EXCEPTION(mrpt::format(_FORMAT_STRING, __VA_ARGS__));
45 
46 #define THROW_TYPED_EXCEPTION_FMT(exceptionClass, _FORMAT_STRING, ...) \
47  THROW_TYPED_EXCEPTION( \
48  mrpt::format(_FORMAT_STRING, __VA_ARGS__), exceptionClass)
49 
50 /** \def THROW_STACKED_EXCEPTION
51  * \sa MRPT_TRY_START, MRPT_TRY_END
52  */
53 #define THROW_STACKED_EXCEPTION(e) \
54  throw std::logic_error(throw_stacked_exception( \
55  e, __FILE__, __LINE__, __CURRENT_FUNCTION_NAME__))
56 
57 template <typename E>
59  E&& e, const char* file, unsigned long line, const char* funcName)
60 {
61  std::string s = e.what();
62  s += "\n";
63  s += file;
64  s += ":";
65  s += mrpt::to_string(line);
66  s += ": In `";
67  s += funcName;
68  s += "`\n";
69  return s;
70 }
71 
72 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
73  * \param e The caught exception.
74  * \param stuff Is a printf-like sequence of params, e.g: "The error happens
75  *for x=%i",x
76  */
77 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG2(e, stuff, param1) \
78  throw std::logic_error(throw_stacked_exception_custom_msg2(e, stuff, param1))
79 template <typename E, typename T>
81  E&& e, const char* stuff, T&& param1)
82 {
83  std::string s = e.what();
84  s += mrpt::format(stuff, param1);
85  s += "\n";
86  return s;
87 }
88 
89 /** For use in CSerializable implementations */
90 #define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V) \
91  THROW_EXCEPTION(mrpt::format( \
92  "Cannot parse object: unknown serialization version number: '%i'", \
93  static_cast<int>(__V)))
94 
95 /** Defines an assertion mechanism.
96  * \note Do NOT put code that must be always executed inside this statement, but
97  * just comparisons. This is because users might require ASSERT_'s to be ignored
98  * for optimized releases.
99  * \sa MRPT_TRY_START, MRPT_TRY_END
100  */
101 #define ASSERTMSG_(f, __ERROR_MSG) \
102  do \
103  { \
104  if (!(f)) THROW_EXCEPTION(::std::string(__ERROR_MSG)); \
105  } while (0)
106 
107 /** Defines an assertion mechanism.
108  * \note Do NOT put code that must be always executed inside this statement, but
109  * just comparisons. This is because users might require ASSERT_'s to be ignored
110  * for optimized releases.
111  * \sa MRPT_TRY_START, MRPT_TRY_END
112  */
113 #define ASSERT_(f) \
114  ASSERTMSG_(f, std::string("Assert condition failed: ") + ::std::string(#f))
115 
116 /** Throws an exception if the number is NaN, IND, or +/-INF, or return the same
117  * number otherwise. */
118 #define MRPT_CHECK_NORMAL_NUMBER(v) \
119  do \
120  { \
121  ASSERT_(std::isfinite(v)); \
122  ASSERT_(!std::isnan(v)); \
123  } while (0)
124 
125 // Static asserts: use compiler version if we have a modern GCC (>=4.3) or MSVC
126 // (>=2010) version, otherwise rely on custom implementation:
127 #define MRPT_COMPILE_TIME_ASSERT(expression) \
128  static_assert(expression, #expression)
129 
130 #define ASRT_FAIL(__CONDITIONSTR, __A, __B, __ASTR, __BSTR) \
131  THROW_EXCEPTION(asrt_fail(__CONDITIONSTR, __A, __B, __ASTR, __BSTR))
132 template <typename A, typename B>
134  std::string s, A&& a, B&& b, const char* astr, const char* bstr)
135 {
136  s += "(";
137  s += astr;
138  s += ",";
139  s += bstr;
140  s += ") failed with\n";
141  s += astr;
142  s += "=";
143  s += mrpt::to_string(a);
144  s += "\n";
145  s += bstr;
146  s += "=";
147  s += mrpt::to_string(b);
148  s += "\n";
149  return s;
150 }
151 
152 /** Assert comparing two values, reporting their actual values upon failure */
153 #define ASSERT_EQUAL_(__A, __B) \
154  do \
155  { \
156  if (__A != __B) ASRT_FAIL("ASSERT_EQUAL_", __A, __B, #__A, #__B) \
157  } while (0)
158 
159 #define ASSERT_NOT_EQUAL_(__A, __B) \
160  do \
161  { \
162  if (__A == __B) ASRT_FAIL("ASSERT_NOT_EQUAL_", __A, __B, #__A, #__B) \
163  } while (0)
164 
165 #define ASSERT_BELOW_(__A, __B) \
166  do \
167  { \
168  if (__A >= __B) ASRT_FAIL("ASSERT_BELOW_", __A, __B, #__A, #__B) \
169  } while (0)
170 
171 #define ASSERT_ABOVE_(__A, __B) \
172  do \
173  { \
174  if (__A <= __B) ASRT_FAIL("ASSERT_ABOVE_", __A, __B, #__A, #__B) \
175  } while (0)
176 
177 #define ASSERT_BELOWEQ_(__A, __B) \
178  do \
179  { \
180  if (__A > __B) ASRT_FAIL("ASSERT_BELOWEQ_", __A, __B, #__A, #__B) \
181  } while (0)
182 
183 #define ASSERT_ABOVEEQ_(__A, __B) \
184  do \
185  { \
186  if (__A < __B) ASRT_FAIL("ASSERT_ABOVEEQ_", __A, __B, #__A, #__B) \
187  } while (0)
188 
189 /** Defines an assertion mechanism - only when compiled in debug.
190  * \note Do NOT put code that must be always executed inside this statement, but
191  * just comparisons. This is because users might require ASSERT_'s to be ignored
192  * for optimized releases.
193  * \sa MRPT_TRY_START, MRPT_TRY_END
194  */
195 #ifdef _DEBUG
196 #define ASSERTDEB_(f) ASSERT_(f)
197 #define ASSERTDEBMSG_(f, __ERROR_MSG) ASSERTMSG_(f, __ERROR_MSG)
198 #define ASSERTDEB_EQUAL_(__A, __B) ASSERT_EQUAL_(__A, __B)
199 #define ASSERTDEB_NOT_EQUAL_(__A, __B) ASSERT_NOT_EQUAL_(__A, __B)
200 #define ASSERTDEB_BELOW_(__A, __B) ASSERT_BELOW_(__A, __B)
201 #define ASSERTDEB_ABOVE_(__A, __B) ASSERT_ABOVE_(__A, __B)
202 #define ASSERTDEB_BELOWEQ_(__A, __B) ASSERT_BELOWEQ_(__A, __B)
203 #define ASSERTDEB_ABOVEEQ_(__A, __B) ASSERT_ABOVEEQ_(__A, __B)
204 #else
205 #define ASSERTDEB_(f) \
206  { \
207  }
208 #define ASSERTDEBMSG_(f, __ERROR_MSG) \
209  { \
210  }
211 #define ASSERTDEB_EQUAL_(__A, __B) {}
212 #define ASSERTDEB_NOT_EQUAL_(__A, __B) {}
213 #define ASSERTDEB_BELOW_(__A, __B) {}
214 #define ASSERTDEB_ABOVE_(__A, __B) {}
215 #define ASSERTDEB_BELOWEQ_(__A, __B) {}
216 #define ASSERTDEB_ABOVEEQ_(__A, __B) {}
217 
218 #endif
219 
220 /** The start of a standard MRPT "try...catch()" block that allows tracing throw
221  * the call stack after an exception.
222  * \sa MRPT_TRY_END,MRPT_TRY_END_WITH_CLEAN_UP
223  */
224 #define MRPT_TRY_START \
225  try \
226  {
227 /** The end of a standard MRPT "try...catch()" block that allows tracing throw
228  * the call stack after an exception.
229  * \sa MRPT_TRY_START,MRPT_TRY_END_WITH_CLEAN_UP
230  */
231 #define MRPT_TRY_END \
232  } \
233  catch (std::bad_alloc&) { throw; } \
234  catch (std::exception & __excep) { THROW_STACKED_EXCEPTION(__excep); } \
235  catch (...) { THROW_EXCEPTION("Unexpected runtime error!"); }
236 /** The end of a standard MRPT "try...catch()" block that allows tracing throw
237  * the call stack after an exception, including a "clean up" piece of code to be
238  * run before throwing the exceptions.
239  * \sa MRPT_TRY_END,MRPT_TRY_START
240  */
241 #define MRPT_TRY_END_WITH_CLEAN_UP(stuff) \
242  } \
243  catch (std::bad_alloc&) { throw; } \
244  catch (std::exception & __excep) \
245  { \
246  {stuff} THROW_STACKED_EXCEPTION(__excep); \
247  } \
248  catch (...) { {stuff} THROW_EXCEPTION("Unexpected runtime error!"); }
249 
250 #if MRPT_ENABLE_EMBEDDED_GLOBAL_PROFILER
251 #define MRPT_PROFILE_FUNC_START \
252  ::mrpt::utils::CProfilerProxy BOOST_JOIN( \
253  __dum_var, __LINE__)(__CURRENT_FUNCTION_NAME__);
254 #else
255 #define MRPT_PROFILE_FUNC_START
256 #endif
257 
258 // General macros for use within each MRPT method/function. They provide:
259 // - Nested exception handling
260 // - Automatic profiling stats (in Debug only)
261 // ---------------------------------------------------------
262 #define MRPT_START \
263  MRPT_PROFILE_FUNC_START \
264  MRPT_TRY_START
265 
266 #define MRPT_END MRPT_TRY_END
267 
268 #define MRPT_END_WITH_CLEAN_UP(stuff) MRPT_TRY_END_WITH_CLEAN_UP(stuff)
std::string asrt_fail(std::string s, A &&a, B &&b, const char *astr, const char *bstr)
Definition: exceptions.h:133
std::string throw_stacked_exception_custom_msg2(E &&e, const char *stuff, T &&param1)
Definition: exceptions.h:80
GLdouble s
Definition: glext.h:3676
GLubyte GLubyte b
Definition: glext.h:6279
GLsizei const GLchar ** string
Definition: glext.h:4101
std::string throw_typed_exception(const T &msg, const char *function_name, unsigned int line)
Definition: exceptions.h:23
std::string throw_stacked_exception(E &&e, const char *file, unsigned long line, const char *funcName)
Definition: exceptions.h:58
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:16
std::string std::string to_string(T v)
Just like std::to_string(), but with an overloaded version for std::string arguments.
Definition: format.h:30
GLubyte GLubyte GLubyte a
Definition: glext.h:6279



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020