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



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019