Main MRPT website > C++ reference for MRPT 1.4.0
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-2016, 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 /** Does the compiler support C++11? */
18 #if (__cplusplus>199711L || (defined(_MSC_VER) && (_MSC_VER >= 1700)) )
19 # define MRPT_HAS_CXX11 1
20 #else
21 # define MRPT_HAS_CXX11 0
22 #endif
23 
24 /** C++11 "override" for virtuals: */
25 #if MRPT_HAS_CXX11
26 # define MRPT_OVERRIDE override
27 #else
28 # define MRPT_OVERRIDE
29 #endif
30 // A cross-compiler definition for "deprecated"-warnings
31 #if defined(__GNUC__) && (__GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 >= 2))
32  /* gcc >= 3.2 */
33 # define MRPT_DEPRECATED_PRE(_MSG)
34  // The "message" is not supported yet in GCC (JL: wait for gcc 4.4??)
35  //# define MRPT_DEPRECATED_POST(_MSG) __attribute__ ((deprecated(_MSG)))
36 # define MRPT_DEPRECATED_POST(_MSG) __attribute__ ((deprecated))
37 # elif defined(_MSC_VER) && (_MSC_VER >= 1300)
38  /* msvc >= 7 */
39 # define MRPT_DEPRECATED_PRE(_MSG) __declspec(deprecated (_MSG))
40 # define MRPT_DEPRECATED_POST(_MSG)
41 # else
42 # define MRPT_DEPRECATED_PRE(_MSG)
43 # define MRPT_DEPRECATED_POST(_MSG)
44 # endif
45 
46 /** Usage: MRPT_DECLARE_DEPRECATED_FUNCTION("Use XX instead", void myFunc(double)); */
47 #define MRPT_DECLARE_DEPRECATED_FUNCTION(__MSG, __FUNC) MRPT_DEPRECATED_PRE(__MSG) __FUNC MRPT_DEPRECATED_POST(__MSG)
48 
49 /** Declare MRPT_TODO(message) */
50 #if defined(_MSC_VER)
51  #define MRPT_DO_PRAGMA(x) __pragma(x)
52  #define __STR2__(x) #x
53  #define __STR1__(x) __STR2__(x)
54  #define __MSVCLOC__ __FILE__ "("__STR1__(__LINE__)") : "
55  #define MRPT_MSG_PRAGMA(_msg) MRPT_DO_PRAGMA(message (__MSVCLOC__ _msg))
56 #elif defined(__GNUC__)
57  #define MRPT_DO_PRAGMA(x) _Pragma (#x)
58  #define MRPT_MSG_PRAGMA(_msg) MRPT_DO_PRAGMA(message (_msg))
59 #else
60  #define MRPT_DO_PRAGMA(x)
61  #define MRPT_MSG_PRAGMA(_msg)
62 #endif
63 
64 #define MRPT_WARNING(x) MRPT_MSG_PRAGMA("Warning: " x)
65 #define MRPT_TODO(x) MRPT_MSG_PRAGMA("TODO: " x)
66 
67 // Define a decl. modifier for printf-like format checks at compile time:
68 #ifdef __GNUC__
69 # define MRPT_printf_format_check(_FMT_,_VARARGS_) __attribute__ ((__format__ (__printf__, _FMT_,_VARARGS_)))
70 #else
71 # define MRPT_printf_format_check(_FMT_,_VARARGS_)
72 #endif
73 // Define a decl. modifier for scanf-like format checks at compile time:
74 #ifdef __GNUC__
75 # define MRPT_scanf_format_check(_FMT_,_VARARGS_) __attribute__ ((__format__ (__scanf__, _FMT_,_VARARGS_)))
76 #else
77 # define MRPT_scanf_format_check(_FMT_,_VARARGS_)
78 #endif
79 
80 /** Used after member declarations */
81 #define MRPT_NO_THROWS throw()
82 
83 
84 // A cross-compiler definition for aligned memory structures:
85 #if defined(_MSC_VER)
86  #define MRPT_ALIGN16 __declspec(align(16))
87  #define MRPT_ALIGN32 __declspec(align(32))
88 #elif defined(__GNUC__)
89  #define MRPT_ALIGN16 __attribute__((aligned(16)))
90  #define MRPT_ALIGN32 __attribute__((aligned(32)))
91 #else
92  #define MRPT_ALIGN16
93  #define MRPT_ALIGN32
94 #endif
95 
96 /** A macro for obtaining the name of the current function: */
97 #if defined(__BORLANDC__)
98  #define __CURRENT_FUNCTION_NAME__ __FUNC__
99 #elif defined(_MSC_VER) && (_MSC_VER>=1300)
100  #define __CURRENT_FUNCTION_NAME__ __FUNCTION__
101 #else
102  #define __CURRENT_FUNCTION_NAME__ __PRETTY_FUNCTION__
103 #endif
104 
105 /** \def THROW_EXCEPTION(msg)
106  * \param msg This can be a char*, a std::string, or a literal string.
107  * Defines a unified way of reporting exceptions
108  * \sa MRPT_TRY_START, MRPT_TRY_END, THROW_EXCEPTION_CUSTOM_MSG1
109  */
110 #define THROW_EXCEPTION(msg) \
111  {\
112  std::ostringstream auxCompStr;\
113  auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
114  auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
115  auxCompStr << msg << std::endl; \
116  throw std::logic_error( auxCompStr.str() );\
117  }\
118 
119 /** \def THROW_EXCEPTION_CUSTOM_MSG1
120  * \param e The caught exception.
121  * \param msg Is a char* or literal string.
122  */
123 #define THROW_EXCEPTION_CUSTOM_MSG1(msg,param1) \
124  {\
125  std::ostringstream auxCompStr;\
126  auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
127  auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
128  auxCompStr << mrpt::format(msg,param1)<< std::endl; \
129  throw std::logic_error( auxCompStr.str() );\
130  }\
131 
132 
133 /** \def THROW_TYPED_EXCEPTION(msg,exceptionClass)
134  * Defines a unified way of reporting exceptions of type different from "std::exception"
135  * \sa MRPT_TRY_START, MRPT_TRY_END
136  */
137 #define THROW_TYPED_EXCEPTION(msg,exceptionClass) \
138  {\
139  std::ostringstream auxCompStr;\
140  auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
141  auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
142  auxCompStr << msg << std::endl; \
143  throw exceptionClass( auxCompStr.str() );\
144  }\
145 
146 /** \def THROW_EXCEPTION_CUSTOM_MSG1
147  * \param e The caught exception.
148  * \param msg Is a char* or literal string.
149  */
150 #define THROW_TYPED_EXCEPTION_CUSTOM_MSG1(msg,param1,exceptionClass) \
151  {\
152  std::ostringstream auxCompStr;\
153  auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
154  auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
155  auxCompStr << mrpt::format(msg,param1)<< std::endl; \
156  throw exceptionClass( auxCompStr.str() );\
157  }\
158 
159 
160 /** \def THROW_STACKED_EXCEPTION
161  * \sa MRPT_TRY_START, MRPT_TRY_END
162  */
163 #define THROW_STACKED_EXCEPTION(e) \
164  {\
165  std::string str( e.what() );\
166  if (str.find("MRPT stack trace")==std::string::npos) \
167  { \
168  str+= __CURRENT_FUNCTION_NAME__;\
169  str+= mrpt::format(", line %i:\n", __LINE__ );\
170  throw std::logic_error( str );\
171  } \
172  else throw std::logic_error( e.what() );\
173  }\
174 
175 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
176  * \param e The caught exception.
177  * \param msg Is a char* or std::string.
178  */
179 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG1(e,msg) \
180  {\
181  std::ostringstream auxCompStr;\
182  auxCompStr << e.what() ; \
183  auxCompStr << msg << std::endl; \
184  throw std::logic_error( auxCompStr.str() );\
185  }\
186 
187 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
188  * \param e The caught exception.
189  * \param stuff Is a printf-like sequence of params, e.g: "The error happens for x=%i",x
190  */
191 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG2(e,stuff,param1) \
192  {\
193  std::ostringstream auxCompStr;\
194  auxCompStr << e.what() ; \
195  auxCompStr << mrpt::format( stuff, param1 ) << std::endl; \
196  throw std::logic_error( auxCompStr.str() );\
197  }\
198 
199 /** For use in CSerializable implementations */
200 #define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V) THROW_EXCEPTION(mrpt::format("Cannot parse object: unknown serialization version number: '%i'",static_cast<int>(__V)))
201 
202 
203 #if MRPT_HAS_ASSERT
204  /** Defines an assertion mechanism.
205  * \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.
206  * \sa MRPT_TRY_START, MRPT_TRY_END
207  */
208 # define ASSERTMSG_(f,__ERROR_MSG) \
209  { \
210  if (!(f)) THROW_EXCEPTION( ::std::string( __ERROR_MSG ) ); \
211  }
212 
213  /** Defines an assertion mechanism.
214  * \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.
215  * \sa MRPT_TRY_START, MRPT_TRY_END
216  */
217 # define ASSERT_(f) \
218  ASSERTMSG_(f, std::string("Assert condition failed: ") + ::std::string(#f) )
219 
220 /** Throws an exception if the number is NaN, IND, or +/-INF, or return the same number otherwise.
221  */
222 #define MRPT_CHECK_NORMAL_NUMBER(v) \
223  { \
224  if (math::isNaN(v)) THROW_EXCEPTION("Check failed (value is NaN)"); \
225  if (!math::isFinite(v)) THROW_EXCEPTION("Check failed (value is not finite)"); \
226  }
227 
228 // Static asserts: use compiler version if we have a modern GCC (>=4.3) or MSVC (>=2010) version, otherwise rely on custom implementation:
229 #if (defined(_MSC_VER) && (_MSC_VER>=1600 /*VS2010*/)) || (defined(__GNUC__) && __cplusplus>=201100L )
230  #define MRPT_COMPILE_TIME_ASSERT(expression) static_assert(expression,#expression);
231 #else
232  // The following macro is based on dclib:
233  // Copyright (C) 2003 Davis E. King (davisking@users.sourceforge.net)
234  // License: Boost Software License See LICENSE.txt for the full license.
235  namespace mrpt
236  {
237  namespace utils
238  {
239  template <bool value> struct compile_time_assert;
240  template <> struct compile_time_assert<true> { enum {value=1}; };
241  }
242  }
243  #define MRPT_COMPILE_TIME_ASSERT(expression) \
244  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__);
245 
246 #endif
247 
248  /** Assert comparing two values, reporting their actual values upon failure */
249  #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()) } }
250  #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()) } }
251  #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()) } }
252  #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()) } }
253  #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()) } }
254  #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()) } }
255 
256  #define ASSERT_FILE_EXISTS_(FIL) ASSERTMSG_( mrpt::system::fileExists(FIL), std::string("Assert file existence failed: ") + ::std::string(FIL) )
257  #define ASSERT_DIRECTORY_EXISTS_(DIR) ASSERTMSG_( mrpt::system::directoryExists(DIR), std::string("Assert directory existence failed: ") + ::std::string(DIR) )
258 
259 #else // MRPT_HAS_ASSERT
260 # define ASSERTMSG_(f,__ERROR_MSG) { }
261 # define ASSERT_(f) { }
262 # define MRPT_CHECK_NORMAL_NUMBER(val) { }
263 # define MRPT_COMPILE_TIME_ASSERT(f) { }
264 # define ASSERT_EQUAL_( __A, __B) { }
265 # define ASSERT_NOT_EQUAL_( __A, __B) { }
266 # define ASSERT_BELOW_( __A, __B) { }
267 # define ASSERT_ABOVE_( __A, __B) { }
268 # define ASSERT_BELOWEQ_( __A, __B) { }
269 # define ASSERT_ABOVEEQ_( __A, __B) { }
270 
271 # define ASSERT_FILE_EXISTS_(FIL) { }
272 # define ASSERT_DIRECTORY_EXISTS_(DIR) { }
273 #endif // MRPT_HAS_ASSERT
274 
275 /** Defines an assertion mechanism - only when compiled in debug.
276  * \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.
277  * \sa MRPT_TRY_START, MRPT_TRY_END
278  */
279 #ifdef _DEBUG
280 # define ASSERTDEB_(f) ASSERT_(f)
281 # define ASSERTDEBMSG_(f,__ERROR_MSG) ASSERTMSG_(f,__ERROR_MSG)
282 #else
283 # define ASSERTDEB_(f) { }
284 # define ASSERTDEBMSG_(f,__ERROR_MSG) { }
285 #endif
286 
287 
288 /** Can be used to avoid "not used parameters" warnings from the compiler
289  */
290 #define MRPT_UNUSED_PARAM(a) (void)(a)
291 
292 #if MRPT_HAS_STACKED_EXCEPTIONS
293  /** The start of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an exception.
294  * \sa MRPT_TRY_END,MRPT_TRY_END_WITH_CLEAN_UP
295  */
296 # define MRPT_TRY_START \
297  try { \
298 
299  /** The end of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an exception.
300  * \sa MRPT_TRY_START,MRPT_TRY_END_WITH_CLEAN_UP
301  */
302 # define MRPT_TRY_END \
303  } \
304  catch (std::bad_alloc &) \
305  { throw; } \
306  catch (std::exception &e) \
307  { \
308  THROW_STACKED_EXCEPTION(e); \
309  } \
310  catch (...) \
311  { \
312  THROW_EXCEPTION("Unexpected runtime error!"); \
313  } \
314 
315  /** 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.
316  * \sa MRPT_TRY_END,MRPT_TRY_START
317  */
318 # define MRPT_TRY_END_WITH_CLEAN_UP(stuff) \
319  } \
320  catch (std::bad_alloc &) \
321  { throw; } \
322  catch (std::exception &e) \
323  { \
324  {stuff} \
325  THROW_STACKED_EXCEPTION(e); \
326  } \
327  catch (...) \
328  { \
329  { stuff } \
330  THROW_EXCEPTION("Unexpected runtime error!"); \
331  } \
332 
333 #else
334 # define MRPT_TRY_START
335 # define MRPT_TRY_END
336 # define MRPT_TRY_END_WITH_CLEAN_UP(stuff)
337 #endif
338 
339 #if MRPT_ENABLE_EMBEDDED_GLOBAL_PROFILER
340 # define MRPT_PROFILE_FUNC_START ::mrpt::utils::CProfilerProxy BOOST_JOIN(__dum_var,__LINE__)( __CURRENT_FUNCTION_NAME__);
341 #else
342 # define MRPT_PROFILE_FUNC_START
343 #endif
344 
345 // General macros for use within each MRPT method/function. They provide:
346 // - Nested exception handling
347 // - Automatic profiling stats (in Debug only)
348 // ---------------------------------------------------------
349 #define MRPT_START \
350  MRPT_PROFILE_FUNC_START \
351  MRPT_TRY_START
352 
353 #define MRPT_END \
354  MRPT_TRY_END
355 
356 #define MRPT_END_WITH_CLEAN_UP(stuff) \
357  MRPT_TRY_END_WITH_CLEAN_UP(stuff)
358 
359 // Generic constants and defines:
360 // ---------------------------------------------------------
361 // M_PI: Rely on standard <cmath>
362 #ifndef M_2PI
363 # define M_2PI 6.283185307179586476925286766559 // The 2*PI constant
364 #endif
365 
366 #define M_PIf 3.14159265358979f
367 #define M_2PIf 6.28318530717959f
368 
369 #if defined(HAVE_LONG_DOUBLE) && !defined(M_PIl)
370 # define M_PIl 3.14159265358979323846264338327950288L
371 # define M_2PIl (2.0L*3.14159265358979323846264338327950288L)
372 #endif
373 
374 
375 // Define a decl. modifier for printf-like format checks at compile time:
376 #ifdef __GNUC__
377 # define MRPT_printf_format_check(_FMT_,_VARARGS_) __attribute__ ((__format__ (__printf__, _FMT_,_VARARGS_)))
378 #else
379 # define MRPT_printf_format_check(_FMT_,_VARARGS_)
380 #endif
381 
382 // Define a decl. modifier for scanf-like format checks at compile time:
383 #ifdef __GNUC__
384 # define MRPT_scanf_format_check(_FMT_,_VARARGS_) __attribute__ ((__format__ (__scanf__, _FMT_,_VARARGS_)))
385 #else
386 # define MRPT_scanf_format_check(_FMT_,_VARARGS_)
387 #endif
388 
389 
390 /** Used after member declarations */
391 #define MRPT_NO_THROWS throw()
392 
393 /** Tells the compiler we really want to inline that function */
394 #if (defined _MSC_VER) || (defined __INTEL_COMPILER)
395 #define MRPT_FORCE_INLINE __forceinline
396 #else
397 #define MRPT_FORCE_INLINE inline
398 #endif
399 
400 /** Determines whether this is an X86 or AMD64 platform */
401 #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_AMD64) || defined (_M_X64) \
402  || defined (__i386__)|| defined (__i386) || defined (_M_I86) || defined (i386) || defined(_M_IX86) || defined (_X86_)
403 # define MRPT_IS_X86_AMD64 1
404 #endif
405 
406 namespace mrpt
407 {
408  // Redeclared here for convenience:
409  std::string BASE_IMPEXP format(const char *fmt, ...) MRPT_printf_format_check(1,2);
410 }
411 
412 #endif
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
#define MRPT_printf_format_check(_FMT_, _VARARGS_)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.



Page generated by Doxygen 1.8.15 for MRPT 1.4.0 SVN: at Sat Aug 3 20:09:00 UTC 2019