Main MRPT website > C++ reference
MRPT logo

mrpt_macros.h

Go to the documentation of this file.
00001 /* +---------------------------------------------------------------------------+
00002    |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
00003    |                                                                           |
00004    |                   http://mrpt.sourceforge.net/                            |
00005    |                                                                           |
00006    |   Copyright (C) 2005-2011  University of Malaga                           |
00007    |                                                                           |
00008    |    This software was written by the Machine Perception and Intelligent    |
00009    |      Robotics Lab, University of Malaga (Spain).                          |
00010    |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
00011    |                                                                           |
00012    |  This file is part of the MRPT project.                                   |
00013    |                                                                           |
00014    |     MRPT is free software: you can redistribute it and/or modify          |
00015    |     it under the terms of the GNU General Public License as published by  |
00016    |     the Free Software Foundation, either version 3 of the License, or     |
00017    |     (at your option) any later version.                                   |
00018    |                                                                           |
00019    |   MRPT is distributed in the hope that it will be useful,                 |
00020    |     but WITHOUT ANY WARRANTY; without even the implied warranty of        |
00021    |     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         |
00022    |     GNU General Public License for more details.                          |
00023    |                                                                           |
00024    |     You should have received a copy of the GNU General Public License     |
00025    |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
00026    |                                                                           |
00027    +---------------------------------------------------------------------------+ */
00028 
00029 #ifndef UTILSDEFS_H
00030 #error "This file is intended for include from utils_defs.h only!"
00031 #endif
00032 
00033 #ifndef MRPT_MACROS_H
00034 #define MRPT_MACROS_H
00035 
00036 // A cross-compiler definition for "deprecated"-warnings
00037 #if defined(__GNUC__) && (__GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 >= 2))
00038    /* gcc >= 3.2 */
00039 #   define MRPT_DEPRECATED_PRE(_MSG)
00040         // The "message" is not supported yet in GCC (JL: wait for gcc 4.4??)
00041         //#   define MRPT_DEPRECATED_POST(_MSG) __attribute__ ((deprecated(_MSG)))
00042 #   define MRPT_DEPRECATED_POST(_MSG) __attribute__ ((deprecated))
00043 # elif defined(_MSC_VER) && (_MSC_VER >= 1300)
00044   /* msvc >= 7 */
00045 #   define MRPT_DEPRECATED_PRE(_MSG)  __declspec(deprecated (_MSG))
00046 #   define MRPT_DEPRECATED_POST(_MSG)
00047 # else
00048 #  define MRPT_DEPRECATED_PRE(_MSG)
00049 #  define MRPT_DEPRECATED_POST(_MSG)
00050 # endif
00051 
00052 /** Usage: MRPT_DECLARE_DEPRECATED_FUNCTION("Use XX instead", void myFunc(double)); */
00053 #define MRPT_DECLARE_DEPRECATED_FUNCTION(__MSG, __FUNC) MRPT_DEPRECATED_PRE(__MSG) __FUNC MRPT_DEPRECATED_POST(__MSG)
00054 
00055 /** Declare MRPT_TODO(message)  */
00056 #if defined(_MSC_VER)
00057         #define MRPT_DO_PRAGMA(x) __pragma(x)
00058         #define __STR2__(x) #x
00059         #define __STR1__(x) __STR2__(x)
00060         #define __MSVCLOC__ __FILE__ "("__STR1__(__LINE__)") : "
00061         #define MRPT_MSG_PRAGMA(_msg) MRPT_DO_PRAGMA(message (__MSVCLOC__ _msg))
00062 #elif defined(__GNUC__)
00063         #define MRPT_DO_PRAGMA(x) _Pragma (#x)
00064         #define MRPT_MSG_PRAGMA(_msg) MRPT_DO_PRAGMA(message (_msg))
00065 #else
00066         #define MRPT_DO_PRAGMA(x)
00067         #define MRPT_MSG_PRAGMA(_msg)
00068 #endif
00069 
00070 #define MRPT_WARNING(x) MRPT_MSG_PRAGMA("Warning: " #x)
00071 #define MRPT_TODO(x)    MRPT_MSG_PRAGMA("TODO: " #x)
00072 
00073 // Define a decl. modifier for printf-like format checks at compile time:
00074 #ifdef __GNUC__
00075 #       define MRPT_printf_format_check(_FMT_,_VARARGS_)  __attribute__ ((__format__ (__printf__, _FMT_,_VARARGS_)))
00076 #else
00077 #       define MRPT_printf_format_check(_FMT_,_VARARGS_)
00078 #endif
00079 // Define a decl. modifier for scanf-like format checks at compile time:
00080 #ifdef __GNUC__
00081 #       define MRPT_scanf_format_check(_FMT_,_VARARGS_)  __attribute__ ((__format__ (__scanf__, _FMT_,_VARARGS_)))
00082 #else
00083 #       define MRPT_scanf_format_check(_FMT_,_VARARGS_)
00084 #endif
00085 
00086 /** Used after member declarations */
00087 #define MRPT_NO_THROWS          throw()
00088 
00089 
00090 // A cross-compiler definition for aligned memory structures:
00091 #if defined(_MSC_VER)
00092         #define MRPT_ALIGN16 __declspec(align(16))
00093         #define MRPT_ALIGN32 __declspec(align(32))
00094 #elif defined(__GNUC__)
00095         #define MRPT_ALIGN16 __attribute__((aligned(16)))
00096         #define MRPT_ALIGN32 __attribute__((aligned(32)))
00097 #else
00098         #define MRPT_ALIGN16
00099         #define MRPT_ALIGN32
00100 #endif
00101 
00102 /** A macro for obtaining the name of the current function:  */
00103 #if defined(__BORLANDC__)
00104                 #define __CURRENT_FUNCTION_NAME__       __FUNC__
00105 #elif defined(_MSC_VER) && (_MSC_VER>=1300)
00106                 #define __CURRENT_FUNCTION_NAME__       __FUNCTION__
00107 #elif defined(_MSC_VER) && (_MSC_VER<1300)
00108                 // Visual C++ 6 HAS NOT A __FUNCTION__ equivalent.
00109 #define __CURRENT_FUNCTION_NAME__       ::system::extractFileName(__FILE__).c_str()
00110 #else
00111                 #define __CURRENT_FUNCTION_NAME__       __PRETTY_FUNCTION__
00112 #endif
00113 
00114 
00115 /** \def THROW_EXCEPTION(msg)
00116  * \param msg This can be a char*, a std::string, or a literal string.
00117  * Defines a unified way of reporting exceptions
00118  * \sa MRPT_TRY_START, MRPT_TRY_END, THROW_EXCEPTION_CUSTOM_MSG1
00119  */
00120 #define THROW_EXCEPTION(msg)    \
00121         {\
00122                 std::ostringstream auxCompStr;\
00123                 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00124                 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00125                 auxCompStr << msg << std::endl; \
00126                 auxCompStr << mrpt::system::stack_trace(); \
00127                 throw std::logic_error( auxCompStr.str() );\
00128         }\
00129 
00130 /** \def THROW_EXCEPTION_CUSTOM_MSG1
00131   * \param e The caught exception.
00132   *     \param msg Is a char* or literal string.
00133   */
00134 #define THROW_EXCEPTION_CUSTOM_MSG1(msg,param1) \
00135         {\
00136                 std::ostringstream auxCompStr;\
00137                 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00138                 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00139                 auxCompStr << mrpt::format(msg,param1)<< std::endl; \
00140                 auxCompStr << mrpt::system::stack_trace(); \
00141                 throw std::logic_error( auxCompStr.str() );\
00142         }\
00143 
00144 
00145 /** \def THROW_TYPED_EXCEPTION(msg,exceptionClass)
00146  * Defines a unified way of reporting exceptions of type different from "std::exception"
00147  * \sa MRPT_TRY_START, MRPT_TRY_END
00148  */
00149 #define THROW_TYPED_EXCEPTION(msg,exceptionClass)       \
00150         {\
00151                 std::ostringstream auxCompStr;\
00152                 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00153                 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00154                 auxCompStr << msg << std::endl; \
00155                 auxCompStr << mrpt::system::stack_trace(); \
00156                 throw exceptionClass( auxCompStr.str() );\
00157         }\
00158 
00159 /** \def THROW_EXCEPTION_CUSTOM_MSG1
00160   * \param e The caught exception.
00161   *     \param msg Is a char* or literal string.
00162   */
00163 #define THROW_TYPED_EXCEPTION_CUSTOM_MSG1(msg,param1,exceptionClass)    \
00164         {\
00165                 std::ostringstream auxCompStr;\
00166                 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00167                 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00168                 auxCompStr << mrpt::format(msg,param1)<< std::endl; \
00169                 auxCompStr << mrpt::system::stack_trace(); \
00170                 throw exceptionClass( auxCompStr.str() );\
00171         }\
00172 
00173 
00174 /** \def THROW_STACKED_EXCEPTION
00175  * \sa MRPT_TRY_START, MRPT_TRY_END
00176  */
00177 #define THROW_STACKED_EXCEPTION(e)      \
00178         {\
00179                 std::string str( e.what() );\
00180                 if (str.find("MRPT stack trace")==std::string::npos) \
00181                 { \
00182                         str+= __CURRENT_FUNCTION_NAME__;\
00183                         str+= mrpt::format(", line %i:\n", __LINE__ );\
00184                         if (str.size()>3000) { std::cerr << "TOO MANY STACKED EXCEPTIONS!: " << std::endl << str << std::endl; abort(); } \
00185                         throw std::logic_error( str );\
00186                 } \
00187                 else throw std::logic_error( e.what() );\
00188         }\
00189 
00190 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
00191   * \param e The caught exception.
00192   *     \param msg Is a char* or std::string.
00193   */
00194 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG1(e,msg)      \
00195         {\
00196                 std::ostringstream auxCompStr;\
00197                 auxCompStr << e.what() ;  \
00198                 auxCompStr << msg << std::endl; \
00199                 throw std::logic_error( auxCompStr.str() );\
00200         }\
00201 
00202 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
00203   * \param e The caught exception.
00204   *     \param stuff Is a printf-like sequence of params, e.g: "The error happens for x=%i",x
00205   */
00206 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG2(e,stuff,param1)     \
00207         {\
00208                 std::ostringstream auxCompStr;\
00209                 auxCompStr << e.what() ;  \
00210                 auxCompStr << mrpt::format( stuff, param1 ) << std::endl; \
00211                 throw std::logic_error( auxCompStr.str() );\
00212         }\
00213 
00214 /** For use in CSerializable implementations */
00215 #define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(V) THROW_EXCEPTION(mrpt::format("Cannot parse object: unknown serialization version number: '%i'",static_cast<int>(version)))
00216 
00217 
00218 #if MRPT_HAS_ASSERT
00219         /** Defines an assertion mechanism.
00220          * \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.
00221          * \sa MRPT_TRY_START, MRPT_TRY_END
00222          */
00223 #       define ASSERTMSG_(f,__ERROR_MSG) \
00224         { \
00225         if (!(f)) THROW_EXCEPTION( ::std::string( __ERROR_MSG ) ); \
00226         }
00227 
00228         /** Defines an assertion mechanism.
00229          * \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.
00230          * \sa MRPT_TRY_START, MRPT_TRY_END
00231          */
00232 #       define ASSERT_(f) \
00233                 ASSERTMSG_(f, "Assert condition failed: " + ::std::string(#f) )
00234 
00235 /** Throws an exception if the number is NaN, IND, or +/-INF, or return the same number otherwise.
00236   */
00237 #define MRPT_CHECK_NORMAL_NUMBER(v) \
00238         { \
00239                 if (math::isNaN(v)) THROW_EXCEPTION("Check failed (value is NaN)"); \
00240                 if (!math::isFinite(v)) THROW_EXCEPTION("Check failed (value is not finite)"); \
00241         }
00242 
00243         // The following macro is based on dclib:
00244         // Copyright (C) 2003  Davis E. King (davisking@users.sourceforge.net)
00245         // License: Boost Software License   See LICENSE.txt for the full license.
00246         namespace mrpt
00247         {
00248                 namespace utils
00249                 {
00250                         template <bool value> struct compile_time_assert;
00251                         template <> struct compile_time_assert<true> { enum {value=1};  };
00252                 }
00253         }
00254         #define MRPT_COMPILE_TIME_ASSERT(expression) \
00255                         typedef char BOOST_JOIN(MRPT_CTA, __LINE__)[::mrpt::utils::compile_time_assert<(bool)(expression)>::value];
00256 
00257         /** Assert comparing two values, reporting their actual values upon failure */
00258         #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()) } }
00259         #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()) } }
00260         #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()) } }
00261         #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()) } }
00262         #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()) } }
00263         #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()) } }
00264 
00265 #else
00266 #       define ASSERTMSG_(f,__ERROR_MSG)  { }
00267 #       define ASSERT_(f) { }
00268 #       define MRPT_CHECK_NORMAL_NUMBER(val) { }
00269 #       define MRPT_COMPILE_TIME_ASSERT(f) { }
00270 #       define ASSERT_EQUAL_( __A, __B) { }
00271 #       define ASSERT_NOT_EQUAL_( __A, __B) { }
00272 #       define ASSERT_BELOW_( __A, __B)  { }
00273 #       define ASSERT_ABOVE_( __A, __B)  { }
00274 #       define ASSERT_BELOWEQ_( __A, __B)  { }
00275 #       define ASSERT_ABOVEEQ_( __A, __B)  { }
00276 #endif
00277 
00278 /** Defines an assertion mechanism - only when compiled in debug.
00279  * \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.
00280  * \sa MRPT_TRY_START, MRPT_TRY_END
00281  */
00282 #ifdef _DEBUG
00283 #       define ASSERTDEB_(f) ASSERT_(f)
00284 #       define ASSERTDEBMSG_(f,__ERROR_MSG) ASSERTMSG_(f,__ERROR_MSG)
00285 #else
00286 #       define ASSERTDEB_(f) { }
00287 #       define ASSERTDEBMSG_(f,__ERROR_MSG) { }
00288 #endif
00289 
00290 
00291 /** Can be used to avoid "not used parameters" warnings from the compiler
00292  */
00293 #define MRPT_UNUSED_PARAM(a)            (void)(a)
00294 
00295 #if MRPT_HAS_STACKED_EXCEPTIONS
00296         /** The start of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an exception.
00297           * \sa MRPT_TRY_END,MRPT_TRY_END_WITH_CLEAN_UP
00298           */
00299 #       define MRPT_TRY_START   \
00300         try { \
00301 
00302         /** The end of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an exception.
00303           * \sa MRPT_TRY_START,MRPT_TRY_END_WITH_CLEAN_UP
00304           */
00305 #       define MRPT_TRY_END     \
00306         } \
00307         catch (std::bad_alloc &) \
00308         { throw; } \
00309         catch (std::exception &e) \
00310         { \
00311                 THROW_STACKED_EXCEPTION(e); \
00312         } \
00313         catch (...) \
00314         { \
00315                 THROW_EXCEPTION("Unexpected runtime error!"); \
00316         } \
00317 
00318         /** 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.
00319           * \sa MRPT_TRY_END,MRPT_TRY_START
00320           */
00321 #       define MRPT_TRY_END_WITH_CLEAN_UP(stuff)        \
00322         } \
00323         catch (std::bad_alloc &) \
00324         { throw; } \
00325         catch (std::exception &e) \
00326         { \
00327                 {stuff} \
00328                 THROW_STACKED_EXCEPTION(e); \
00329         } \
00330         catch (...) \
00331         { \
00332                 { stuff } \
00333                 THROW_EXCEPTION("Unexpected runtime error!"); \
00334         } \
00335 
00336 #else
00337 #       define MRPT_TRY_START
00338 #       define MRPT_TRY_END
00339 #       define MRPT_TRY_END_WITH_CLEAN_UP(stuff)
00340 #endif
00341 
00342 #if MRPT_ENABLE_EMBEDDED_GLOBAL_PROFILER
00343 #       define  MRPT_PROFILE_FUNC_START  ::mrpt::utils::CProfilerProxy BOOST_JOIN(__dum_var,__LINE__)( __CURRENT_FUNCTION_NAME__);
00344 #else
00345 #       define  MRPT_PROFILE_FUNC_START
00346 #endif
00347 
00348 // General macros for use within each MRPT method/function. They provide:
00349 //  - Nested exception handling
00350 //  - Automatic profiling stats (in Debug only)
00351 // ---------------------------------------------------------
00352 #define MRPT_START  \
00353         MRPT_PROFILE_FUNC_START \
00354         MRPT_TRY_START
00355 
00356 #define MRPT_END  \
00357         MRPT_TRY_END
00358 
00359 #define MRPT_END_WITH_CLEAN_UP(stuff) \
00360         MRPT_TRY_END_WITH_CLEAN_UP(stuff)
00361 
00362 // Generic constants and defines:
00363 // ---------------------------------------------------------
00364 #ifndef M_PI
00365 #       define M_PI 3.14159265358979323846264338327950288               // PI constant
00366 #endif
00367 
00368 #ifndef M_2PI
00369 #       define M_2PI 6.283185307179586476925286766559   // The 2*PI constant
00370 #endif
00371 
00372 #define M_PIf  3.14159265358979f
00373 #define M_2PIf 6.28318530717959f
00374 
00375 #if defined(HAVE_LONG_DOUBLE) && !defined(M_PIl)
00376 #       define M_PIl 3.14159265358979323846264338327950288L
00377 #       define M_2PIl (2.0L*3.14159265358979323846264338327950288L)
00378 #endif
00379 
00380 
00381 // Define a decl. modifier for printf-like format checks at compile time:
00382 #ifdef __GNUC__
00383 #       define MRPT_printf_format_check(_FMT_,_VARARGS_)  __attribute__ ((__format__ (__printf__, _FMT_,_VARARGS_)))
00384 #else
00385 #       define MRPT_printf_format_check(_FMT_,_VARARGS_)
00386 #endif
00387 
00388 // Define a decl. modifier for scanf-like format checks at compile time:
00389 #ifdef __GNUC__
00390 #       define MRPT_scanf_format_check(_FMT_,_VARARGS_)  __attribute__ ((__format__ (__scanf__, _FMT_,_VARARGS_)))
00391 #else
00392 #       define MRPT_scanf_format_check(_FMT_,_VARARGS_)
00393 #endif
00394 
00395 
00396 /** Used after member declarations */
00397 #define MRPT_NO_THROWS          throw()
00398 
00399 #endif



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:40:17 UTC 2011