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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 5887d2b31 Wed Apr 24 13:03:27 2019 +0200 at miƩ abr 24 13:10:13 CEST 2019