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
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
406namespace 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
#define MRPT_printf_format_check(_FMT_, _VARARGS_)
Definition: mrpt_macros.h:379
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.



Page generated by Doxygen 1.9.5 for MRPT 1.4.0 SVN: at Tue Dec 27 00:53:09 UTC 2022