Main MRPT website > C++ reference for MRPT 1.9.9
mrpt_macros.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-2017, 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 #ifndef MRPT_MACROS_H
11 #define MRPT_MACROS_H
12 
13 #include <sstream> // ostringstream
14 #include <stdexcept> // logic_error
15 #include <mrpt/config.h> // HAVE_LONG_DOUBLE
16 
17 /** MRPT_CHECK_GCC_VERSION(MAJ,MIN) */
18 #if defined(__GNUC__) && defined(__GNUC_MINOR__)
19 #define MRPT_CHECK_GCC_VERSION(major, minor) \
20  ((__GNUC__ > (major)) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
21 #else
22 #define MRPT_CHECK_GCC_VERSION(major, minor) 0
23 #endif
24 
25 /** MRPT_CHECK_VISUALC_VERSION(Version) Version=8 for 2005, 9=2008, 10=2010,
26  * 11=2012, 12=2013, 14=2015 */
27 #ifndef _MSC_VER
28 #define MRPT_VISUALC_VERSION(major) 0
29 #define MRPT_CHECK_VISUALC_VERSION(major) 0
30 #else
31 /* (From wxWidgets macros):
32 Things used to be simple with the _MSC_VER value and the version number
33 increasing in lock step, but _MSC_VER value of 1900 is VC14 and not the
34 non existing (presumably for the superstitious reasons) VC13, so we now
35 need to account for this with an extra offset.
36 */
37 #define MRPT_VISUALC_VERSION(major) \
38  ((6 + (major >= 14 ? (-1) : 0) + major) * 100)
39 #define MRPT_CHECK_VISUALC_VERSION(major) \
40  (_MSC_VER >= MRPT_VISUALC_VERSION(major))
41 #endif
42 
43 #ifndef __has_feature
44 #define __has_feature(x) 0 // Compatibility with non-clang compilers.
45 #endif
46 #ifndef __has_extension
47 #define __has_extension __has_feature // Compatibility with pre-3.0 compilers.
48 #endif
49 
50 // A cross-compiler definition for "deprecated"-warnings
51 /** Usage: MRPT_DEPRECATED("Use XX instead") void myFunc(double); */
52 #if defined(__clang__) && defined(__has_extension)
53 #if __has_extension(attribute_deprecated_with_message)
54 #define MRPT_DEPRECATED(msg) __attribute__((deprecated(msg)))
55 #else
56 #define MRPT_DEPRECATED(msg) __attribute__((deprecated))
57 #endif
58 #elif MRPT_CHECK_GCC_VERSION(4, 5)
59 #define MRPT_DEPRECATED(msg) __attribute__((deprecated(msg)))
60 #elif MRPT_CHECK_VISUALC_VERSION(8)
61 #define MRPT_DEPRECATED(msg) __declspec(deprecated("deprecated: " msg))
62 #else
63 #define MRPT_DEPRECATED(msg)
64 #endif
65 
66 /** Declare MRPT_TODO(message) */
67 #if defined(_MSC_VER)
68 #define MRPT_DO_PRAGMA(x) __pragma(x)
69 #define __STR2__(x) #x
70 #define __STR1__(x) __STR2__(x)
71 #define __MSVCLOC__ __FILE__ "("__STR1__(__LINE__) ") : "
72 #define MRPT_MSG_PRAGMA(_msg) MRPT_DO_PRAGMA(message(__MSVCLOC__ _msg))
73 #elif defined(__GNUC__)
74 #define MRPT_DO_PRAGMA(x) _Pragma(#x)
75 #define MRPT_MSG_PRAGMA(_msg) MRPT_DO_PRAGMA(message(_msg))
76 #else
77 #define MRPT_DO_PRAGMA(x)
78 #define MRPT_MSG_PRAGMA(_msg)
79 #endif
80 
81 #define MRPT_WARNING(x) MRPT_MSG_PRAGMA("Warning: " x)
82 #define MRPT_TODO(x) MRPT_MSG_PRAGMA("TODO: " x)
83 
84 // Define a decl. modifier for printf-like format checks at compile time:
85 #ifdef __GNUC__
86 #define MRPT_printf_format_check(_FMT_, _VARARGS_) \
87  __attribute__((__format__(__printf__, _FMT_, _VARARGS_)))
88 #else
89 #define MRPT_printf_format_check(_FMT_, _VARARGS_)
90 #endif
91 // Define a decl. modifier for scanf-like format checks at compile time:
92 #ifdef __GNUC__
93 #define MRPT_scanf_format_check(_FMT_, _VARARGS_) \
94  __attribute__((__format__(__scanf__, _FMT_, _VARARGS_)))
95 #else
96 #define MRPT_scanf_format_check(_FMT_, _VARARGS_)
97 #endif
98 
99 /** A macro for obtaining the name of the current function: */
100 #if defined(_MSC_VER) && (_MSC_VER >= 1300)
101 #define __CURRENT_FUNCTION_NAME__ __FUNCTION__
102 #else
103 #define __CURRENT_FUNCTION_NAME__ __PRETTY_FUNCTION__
104 #endif
105 
106 /** \def THROW_EXCEPTION(msg)
107  * \param msg This can be a char*, a std::string, or a literal string.
108  * Defines a unified way of reporting exceptions
109  * \sa MRPT_TRY_START, MRPT_TRY_END, THROW_EXCEPTION_FMT
110  */
111 #define THROW_EXCEPTION(msg) \
112  { \
113  std::ostringstream auxCompStr; \
114  auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n"; \
115  auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ \
116  << ":\n"; \
117  auxCompStr << msg << std::endl; \
118  throw std::logic_error(auxCompStr.str()); \
119  }
120 
121 #define THROW_EXCEPTION_FMT(_FORMAT_STRING, ...) \
122  THROW_EXCEPTION(mrpt::format(_FORMAT_STRING, __VA_ARGS__))
123 
124 /** \def THROW_TYPED_EXCEPTION(msg,exceptionClass)
125  * Defines a unified way of reporting exceptions of type different than
126  * "std::exception"
127  * \sa MRPT_TRY_START, MRPT_TRY_END
128  */
129 #define THROW_TYPED_EXCEPTION(msg, exceptionClass) \
130  { \
131  std::ostringstream auxCompStr; \
132  auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n"; \
133  auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ \
134  << ":\n"; \
135  auxCompStr << msg << std::endl; \
136  throw exceptionClass(auxCompStr.str()); \
137  }
138 
139 #define THROW_TYPED_EXCEPTION_FMT(exceptionClass, _FORMAT_STRING, ...) \
140  THROW_TYPED_EXCEPTION( \
141  mrpt::format(_FORMAT_STRING, __VA_ARGS__), exceptionClass)
142 
143 /** \def THROW_STACKED_EXCEPTION
144  * \sa MRPT_TRY_START, MRPT_TRY_END
145  */
146 #define THROW_STACKED_EXCEPTION(e) \
147  { \
148  std::string _tse_str(mrpt::format("%s\n", e.what())); \
149  _tse_str += mrpt::format( \
150  " %s:%i: In `%s`\n", __FILE__, __LINE__, \
151  __CURRENT_FUNCTION_NAME__); \
152  throw std::logic_error(_tse_str); \
153  }
154 
155 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
156  * \param e The caught exception.
157  * \param msg Is a char* or std::string.
158  */
159 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG1(e, msg) \
160  { \
161  std::ostringstream auxCompStr; \
162  auxCompStr << e.what(); \
163  auxCompStr << msg << std::endl; \
164  throw std::logic_error(auxCompStr.str()); \
165  }
166 
167 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
168  * \param e The caught exception.
169  * \param stuff Is a printf-like sequence of params, e.g: "The error happens
170  *for x=%i",x
171  */
172 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG2(e, stuff, param1) \
173  { \
174  std::ostringstream auxCompStr; \
175  auxCompStr << e.what(); \
176  auxCompStr << mrpt::format(stuff, param1) << std::endl; \
177  throw std::logic_error(auxCompStr.str()); \
178  }
179 
180 /** For use in CSerializable implementations */
181 #define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V) \
182  THROW_EXCEPTION( \
183  mrpt::format( \
184  "Cannot parse object: unknown serialization version number: '%i'", \
185  static_cast<int>(__V)))
186 
187 #if MRPT_HAS_ASSERT
188 /** Defines an assertion mechanism.
189  * \note Do NOT put code that must be always executed inside this statement, but
190  * just comparisons. This is because users might require ASSERT_'s to be ignored
191  * for optimized releases.
192  * \sa MRPT_TRY_START, MRPT_TRY_END
193  */
194 #define ASSERTMSG_(f, __ERROR_MSG) \
195  { \
196  if (!(f)) THROW_EXCEPTION(::std::string(__ERROR_MSG)); \
197  }
198 
199 /** Defines an assertion mechanism.
200  * \note Do NOT put code that must be always executed inside this statement, but
201  * just comparisons. This is because users might require ASSERT_'s to be ignored
202  * for optimized releases.
203  * \sa MRPT_TRY_START, MRPT_TRY_END
204  */
205 #define ASSERT_(f) \
206  ASSERTMSG_(f, std::string("Assert condition failed: ") + ::std::string(#f))
207 
208 /** Throws an exception if the number is NaN, IND, or +/-INF, or return the same
209  * number otherwise. */
210 #define MRPT_CHECK_NORMAL_NUMBER(v) \
211  { \
212  ASSERT_(std::isfinite(v)); \
213  ASSERT_(!std::isnan(v)); \
214  }
215 
216 // Static asserts: use compiler version if we have a modern GCC (>=4.3) or MSVC
217 // (>=2010) version, otherwise rely on custom implementation:
218 #define MRPT_COMPILE_TIME_ASSERT(expression) \
219  static_assert(expression, #expression);
220 
221 /** Assert comparing two values, reporting their actual values upon failure */
222 #define ASSERT_EQUAL_(__A, __B) \
223  { \
224  if (__A != __B) \
225  { \
226  std::ostringstream __s__; \
227  __s__ << "ASSERT_EQUAL_(" << #__A << "," << #__B \
228  << ") failed with\n" \
229  << #__A << "=" << __A << "\n" \
230  << #__B << "=" << __B; \
231  THROW_EXCEPTION(__s__.str()) \
232  } \
233  }
234 #define ASSERT_NOT_EQUAL_(__A, __B) \
235  { \
236  if (__A == __B) \
237  { \
238  std::ostringstream __s__; \
239  __s__ << "ASSERT_NOT_EQUAL_(" << #__A << "," << #__B \
240  << ") failed with\n" \
241  << #__A << "=" << __A << "\n" \
242  << #__B << "=" << __B; \
243  THROW_EXCEPTION(__s__.str()) \
244  } \
245  }
246 #define ASSERT_BELOW_(__A, __B) \
247  { \
248  if (__A >= __B) \
249  { \
250  std::ostringstream __s__; \
251  __s__ << "ASSERT_BELOW_(" << #__A << "," << #__B \
252  << ") failed with\n" \
253  << #__A << "=" << __A << "\n" \
254  << #__B << "=" << __B; \
255  THROW_EXCEPTION(__s__.str()) \
256  } \
257  }
258 #define ASSERT_ABOVE_(__A, __B) \
259  { \
260  if (__A <= __B) \
261  { \
262  std::ostringstream __s__; \
263  __s__ << "ASSERT_ABOVE_(" << #__A << "," << #__B \
264  << ") failed with\n" \
265  << #__A << "=" << __A << "\n" \
266  << #__B << "=" << __B; \
267  THROW_EXCEPTION(__s__.str()) \
268  } \
269  }
270 #define ASSERT_BELOWEQ_(__A, __B) \
271  { \
272  if (__A > __B) \
273  { \
274  std::ostringstream __s__; \
275  __s__ << "ASSERT_BELOWEQ_(" << #__A << "," << #__B \
276  << ") failed with\n" \
277  << #__A << "=" << __A << "\n" \
278  << #__B << "=" << __B; \
279  THROW_EXCEPTION(__s__.str()) \
280  } \
281  }
282 #define ASSERT_ABOVEEQ_(__A, __B) \
283  { \
284  if (__A < __B) \
285  { \
286  std::ostringstream __s__; \
287  __s__ << "ASSERT_ABOVEEQ_(" << #__A << "," << #__B \
288  << ") failed with\n" \
289  << #__A << "=" << __A << "\n" \
290  << #__B << "=" << __B; \
291  THROW_EXCEPTION(__s__.str()) \
292  } \
293  }
294 
295 #define ASSERT_FILE_EXISTS_(FIL) \
296  ASSERTMSG_( \
297  mrpt::system::fileExists(FIL), \
298  std::string("Assert file existence failed: ") + ::std::string(FIL))
299 #define ASSERT_DIRECTORY_EXISTS_(DIR) \
300  ASSERTMSG_( \
301  mrpt::system::directoryExists(DIR), \
302  std::string("Assert directory existence failed: ") + \
303  ::std::string(DIR))
304 
305 #else // MRPT_HAS_ASSERT
306 #define ASSERTMSG_(f, __ERROR_MSG) \
307  { \
308  }
309 #define ASSERT_(f) \
310  { \
311  }
312 #define MRPT_CHECK_NORMAL_NUMBER(val) \
313  { \
314  }
315 #define MRPT_COMPILE_TIME_ASSERT(f) \
316  { \
317  }
318 #define ASSERT_EQUAL_(__A, __B) \
319  { \
320  }
321 #define ASSERT_NOT_EQUAL_(__A, __B) \
322  { \
323  }
324 #define ASSERT_BELOW_(__A, __B) \
325  { \
326  }
327 #define ASSERT_ABOVE_(__A, __B) \
328  { \
329  }
330 #define ASSERT_BELOWEQ_(__A, __B) \
331  { \
332  }
333 #define ASSERT_ABOVEEQ_(__A, __B) \
334  { \
335  }
336 
337 #define ASSERT_FILE_EXISTS_(FIL) \
338  { \
339  }
340 #define ASSERT_DIRECTORY_EXISTS_(DIR) \
341  { \
342  }
343 #endif // MRPT_HAS_ASSERT
344 
345 /** Defines an assertion mechanism - only when compiled in debug.
346  * \note Do NOT put code that must be always executed inside this statement, but
347  * just comparisons. This is because users might require ASSERT_'s to be ignored
348  * for optimized releases.
349  * \sa MRPT_TRY_START, MRPT_TRY_END
350  */
351 #ifdef _DEBUG
352 #define ASSERTDEB_(f) ASSERT_(f)
353 #define ASSERTDEBMSG_(f, __ERROR_MSG) ASSERTMSG_(f, __ERROR_MSG)
354 #else
355 #define ASSERTDEB_(f) \
356  { \
357  }
358 #define ASSERTDEBMSG_(f, __ERROR_MSG) \
359  { \
360  }
361 #endif
362 
363 /** Can be used to avoid "not used parameters" warnings from the compiler
364  */
365 #define MRPT_UNUSED_PARAM(a) (void)(a)
366 
367 #if MRPT_HAS_STACKED_EXCEPTIONS
368 /** The start of a standard MRPT "try...catch()" block that allows tracing throw
369  * the call stack after an exception.
370  * \sa MRPT_TRY_END,MRPT_TRY_END_WITH_CLEAN_UP
371  */
372 #define MRPT_TRY_START \
373  try \
374  {
375 /** The end of a standard MRPT "try...catch()" block that allows tracing throw
376  * the call stack after an exception.
377  * \sa MRPT_TRY_START,MRPT_TRY_END_WITH_CLEAN_UP
378  */
379 #define MRPT_TRY_END \
380  } \
381  catch (std::bad_alloc&) { throw; } \
382  catch (std::exception & e) { THROW_STACKED_EXCEPTION(e); } \
383  catch (...) { THROW_EXCEPTION("Unexpected runtime error!"); }
384 /** The end of a standard MRPT "try...catch()" block that allows tracing throw
385  * the call stack after an exception, including a "clean up" piece of code to be
386  * run before throwing the exceptions.
387  * \sa MRPT_TRY_END,MRPT_TRY_START
388  */
389 #define MRPT_TRY_END_WITH_CLEAN_UP(stuff) \
390  } \
391  catch (std::bad_alloc&) { throw; } \
392  catch (std::exception & e) \
393  { \
394  { \
395  stuff \
396  } \
397  THROW_STACKED_EXCEPTION(e); \
398  } \
399  catch (...) \
400  { \
401  { \
402  stuff \
403  } \
404  THROW_EXCEPTION("Unexpected runtime error!"); \
405  }
406 
407 #else
408 #define MRPT_TRY_START
409 #define MRPT_TRY_END
410 #define MRPT_TRY_END_WITH_CLEAN_UP(stuff)
411 #endif
412 
413 #if MRPT_ENABLE_EMBEDDED_GLOBAL_PROFILER
414 #define MRPT_PROFILE_FUNC_START \
415  ::mrpt::utils::CProfilerProxy BOOST_JOIN( \
416  __dum_var, __LINE__)(__CURRENT_FUNCTION_NAME__);
417 #else
418 #define MRPT_PROFILE_FUNC_START
419 #endif
420 
421 // General macros for use within each MRPT method/function. They provide:
422 // - Nested exception handling
423 // - Automatic profiling stats (in Debug only)
424 // ---------------------------------------------------------
425 #define MRPT_START \
426  MRPT_PROFILE_FUNC_START \
427  MRPT_TRY_START
428 
429 #define MRPT_END MRPT_TRY_END
430 
431 #define MRPT_END_WITH_CLEAN_UP(stuff) MRPT_TRY_END_WITH_CLEAN_UP(stuff)
432 
433 // Generic constants and defines:
434 // ---------------------------------------------------------
435 // M_PI: Rely on standard <cmath>
436 #ifndef M_2PI
437 #define M_2PI 6.283185307179586476925286766559 // The 2*PI constant
438 #endif
439 
440 #define M_PIf 3.14159265358979f
441 #define M_2PIf 6.28318530717959f
442 
443 #if defined(HAVE_LONG_DOUBLE) && !defined(M_PIl)
444 #define M_PIl 3.14159265358979323846264338327950288L
445 #define M_2PIl (2.0L * 3.14159265358979323846264338327950288L)
446 #endif
447 
448 // Define a decl. modifier for printf-like format checks at compile time:
449 #ifdef __GNUC__
450 #define MRPT_printf_format_check(_FMT_, _VARARGS_) \
451  __attribute__((__format__(__printf__, _FMT_, _VARARGS_)))
452 #else
453 #define MRPT_printf_format_check(_FMT_, _VARARGS_)
454 #endif
455 
456 // Define a decl. modifier for scanf-like format checks at compile time:
457 #ifdef __GNUC__
458 #define MRPT_scanf_format_check(_FMT_, _VARARGS_) \
459  __attribute__((__format__(__scanf__, _FMT_, _VARARGS_)))
460 #else
461 #define MRPT_scanf_format_check(_FMT_, _VARARGS_)
462 #endif
463 
464 /** Tells the compiler we really want to inline that function */
465 #if (defined _MSC_VER) || (defined __INTEL_COMPILER)
466 #define MRPT_FORCE_INLINE __forceinline
467 #else
468 #define MRPT_FORCE_INLINE inline
469 #endif
470 
471 /** Format specifier for size_t variables in a OS-independent, processor
472  * architecture-independent way
473  *
474  * See
475  * https://stackoverflow.com/questions/40202990/print-a-size-t-in-a-os-independent-architecture-independent-way
476  * for the initial post
477  */
478 #ifdef _MSC_VER /* TODO Untested MSC detection */
479 #define PRIuSIZE Iu
480 #else
481 #define PRIuSIZE zu
482 #endif
483 #define QUOTE(name) #name
484 #define STR(macro) QUOTE(macro)
485 #define USIZE_STR STR(PRIuSIZE)
486 
487 /** Determines whether this is an X86 or AMD64 platform */
488 #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || \
489  defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \
490  defined(__i386__) || defined(__i386) || defined(_M_I86) || \
491  defined(i386) || defined(_M_IX86) || defined(_X86_)
492 #define MRPT_IS_X86_AMD64 1
493 #endif
494 
495 namespace mrpt
496 {
497 // Redeclared here for convenience:
498 std::string format(const char* fmt, ...) MRPT_printf_format_check(1, 2);
499 }
500 
501 #endif
#define MRPT_printf_format_check(_FMT_, _VARARGS_)
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
GLsizei const GLchar ** string
Definition: glext.h:4101
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019