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://www.mrpt.org/                                |
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 MRPT_DEBUG_BREAKPOINT(_msg)  
00116   *  Only if compiled in debug (_DEBUG defined), calls mrpt::system::breakpoint() with the given message. 
00117   *  All MRPT exceptions use this macro, so mrpt::system::breakpoint() is the ideal point to set a breakpoint 
00118   *  and catch exception before they're actually raised.
00119   */
00120 #ifdef _DEBUG
00121 #       define MRPT_DEBUG_BREAKPOINT(_msg)  { mrpt::system::breakpoint(std::string(_msg)); }
00122 #else
00123 #       define MRPT_DEBUG_BREAKPOINT(_msg)  { }
00124 #endif
00125 
00126 /** \def THROW_EXCEPTION(msg)
00127  * \param msg This can be a char*, a std::string, or a literal string.
00128  * Defines a unified way of reporting exceptions
00129  * \sa MRPT_TRY_START, MRPT_TRY_END, THROW_EXCEPTION_CUSTOM_MSG1
00130  */
00131 #define THROW_EXCEPTION(msg)    \
00132         {\
00133                 std::ostringstream auxCompStr;\
00134                 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00135                 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00136                 auxCompStr << msg << std::endl; \
00137                 auxCompStr << mrpt::system::stack_trace(); \
00138                 MRPT_DEBUG_BREAKPOINT(msg) \
00139                 throw std::logic_error( auxCompStr.str() );\
00140         }\
00141 
00142 /** \def THROW_EXCEPTION_CUSTOM_MSG1
00143   * \param e The caught exception.
00144   *     \param msg Is a char* or literal string.
00145   */
00146 #define THROW_EXCEPTION_CUSTOM_MSG1(msg,param1) \
00147         {\
00148                 std::ostringstream auxCompStr;\
00149                 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00150                 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00151                 auxCompStr << mrpt::format(msg,param1)<< std::endl; \
00152                 auxCompStr << mrpt::system::stack_trace(); \
00153                 throw std::logic_error( auxCompStr.str() );\
00154         }\
00155 
00156 
00157 /** \def THROW_TYPED_EXCEPTION(msg,exceptionClass)
00158  * Defines a unified way of reporting exceptions of type different from "std::exception"
00159  * \sa MRPT_TRY_START, MRPT_TRY_END
00160  */
00161 #define THROW_TYPED_EXCEPTION(msg,exceptionClass)       \
00162         {\
00163                 std::ostringstream auxCompStr;\
00164                 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00165                 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00166                 auxCompStr << msg << std::endl; \
00167                 auxCompStr << mrpt::system::stack_trace(); \
00168                 throw exceptionClass( auxCompStr.str() );\
00169         }\
00170 
00171 /** \def THROW_EXCEPTION_CUSTOM_MSG1
00172   * \param e The caught exception.
00173   *     \param msg Is a char* or literal string.
00174   */
00175 #define THROW_TYPED_EXCEPTION_CUSTOM_MSG1(msg,param1,exceptionClass)    \
00176         {\
00177                 std::ostringstream auxCompStr;\
00178                 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00179                 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00180                 auxCompStr << mrpt::format(msg,param1)<< std::endl; \
00181                 auxCompStr << mrpt::system::stack_trace(); \
00182                 throw exceptionClass( auxCompStr.str() );\
00183         }\
00184 
00185 
00186 /** \def THROW_STACKED_EXCEPTION
00187  * \sa MRPT_TRY_START, MRPT_TRY_END
00188  */
00189 #define THROW_STACKED_EXCEPTION(e)      \
00190         {\
00191                 std::string str( e.what() );\
00192                 if (str.find("MRPT stack trace")==std::string::npos) \
00193                 { \
00194                         str+= __CURRENT_FUNCTION_NAME__;\
00195                         str+= mrpt::format(", line %i:\n", __LINE__ );\
00196                         if (str.size()>3000) { std::cerr << "TOO MANY STACKED EXCEPTIONS!: " << std::endl << str << std::endl; abort(); } \
00197                         throw std::logic_error( str );\
00198                 } \
00199                 else throw std::logic_error( e.what() );\
00200         }\
00201 
00202 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
00203   * \param e The caught exception.
00204   *     \param msg Is a char* or std::string.
00205   */
00206 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG1(e,msg)      \
00207         {\
00208                 std::ostringstream auxCompStr;\
00209                 auxCompStr << e.what() ;  \
00210                 auxCompStr << msg << std::endl; \
00211                 throw std::logic_error( auxCompStr.str() );\
00212         }\
00213 
00214 /** \def THROW_STACKED_EXCEPTION_CUSTOM_MSG
00215   * \param e The caught exception.
00216   *     \param stuff Is a printf-like sequence of params, e.g: "The error happens for x=%i",x
00217   */
00218 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG2(e,stuff,param1)     \
00219         {\
00220                 std::ostringstream auxCompStr;\
00221                 auxCompStr << e.what() ;  \
00222                 auxCompStr << mrpt::format( stuff, param1 ) << std::endl; \
00223                 throw std::logic_error( auxCompStr.str() );\
00224         }\
00225 
00226 /** For use in CSerializable implementations */
00227 #define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(V) THROW_EXCEPTION(mrpt::format("Cannot parse object: unknown serialization version number: '%i'",static_cast<int>(version)))
00228 
00229 
00230 #if MRPT_HAS_ASSERT
00231         /** Defines an assertion mechanism.
00232          * \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.
00233          * \sa MRPT_TRY_START, MRPT_TRY_END
00234          */
00235 #       define ASSERTMSG_(f,__ERROR_MSG) \
00236         { \
00237         if (!(f)) THROW_EXCEPTION( ::std::string( __ERROR_MSG ) ); \
00238         }
00239 
00240         /** Defines an assertion mechanism.
00241          * \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.
00242          * \sa MRPT_TRY_START, MRPT_TRY_END
00243          */
00244 #       define ASSERT_(f) \
00245                 ASSERTMSG_(f, std::string("Assert condition failed: ") + ::std::string(#f) )
00246 
00247 /** Throws an exception if the number is NaN, IND, or +/-INF, or return the same number otherwise.
00248   */
00249 #define MRPT_CHECK_NORMAL_NUMBER(v) \
00250         { \
00251                 if (math::isNaN(v)) THROW_EXCEPTION("Check failed (value is NaN)"); \
00252                 if (!math::isFinite(v)) THROW_EXCEPTION("Check failed (value is not finite)"); \
00253         }
00254 
00255         // The following macro is based on dclib:
00256         // Copyright (C) 2003  Davis E. King (davisking@users.sourceforge.net)
00257         // License: Boost Software License   See LICENSE.txt for the full license.
00258         namespace mrpt
00259         {
00260                 namespace utils
00261                 {
00262                         template <bool value> struct compile_time_assert;
00263                         template <> struct compile_time_assert<true> { enum {value=1};  };
00264                 }
00265         }
00266         #define MRPT_COMPILE_TIME_ASSERT(expression) \
00267                         typedef char BOOST_JOIN(MRPT_CTA, __LINE__)[::mrpt::utils::compile_time_assert<(bool)(expression)>::value];
00268 
00269         /** Assert comparing two values, reporting their actual values upon failure */
00270         #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()) } }
00271         #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()) } }
00272         #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()) } }
00273         #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()) } }
00274         #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()) } }
00275         #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()) } }
00276 
00277         #define ASSERT_FILE_EXISTS_(FIL)      ASSERTMSG_( mrpt::system::fileExists(FIL), std::string("Assert file existence failed: ") + ::std::string(FIL) )
00278         #define ASSERT_DIRECTORY_EXISTS_(DIR) ASSERTMSG_( mrpt::system::directoryExists(DIR), std::string("Assert directory existence failed: ") + ::std::string(DIR) )
00279 
00280 #else // MRPT_HAS_ASSERT
00281 #       define ASSERTMSG_(f,__ERROR_MSG)  { }
00282 #       define ASSERT_(f) { }
00283 #       define MRPT_CHECK_NORMAL_NUMBER(val) { }
00284 #       define MRPT_COMPILE_TIME_ASSERT(f) { }
00285 #       define ASSERT_EQUAL_( __A, __B) { }
00286 #       define ASSERT_NOT_EQUAL_( __A, __B) { }
00287 #       define ASSERT_BELOW_( __A, __B)  { }
00288 #       define ASSERT_ABOVE_( __A, __B)  { }
00289 #       define ASSERT_BELOWEQ_( __A, __B)  { }
00290 #       define ASSERT_ABOVEEQ_( __A, __B)  { }
00291 
00292 #       define ASSERT_FILE_EXISTS_(FIL)      { }
00293 #       define ASSERT_DIRECTORY_EXISTS_(DIR) { }
00294 #endif // MRPT_HAS_ASSERT
00295 
00296 /** Defines an assertion mechanism - only when compiled in debug.
00297  * \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.
00298  * \sa MRPT_TRY_START, MRPT_TRY_END
00299  */
00300 #ifdef _DEBUG
00301 #       define ASSERTDEB_(f) ASSERT_(f)
00302 #       define ASSERTDEBMSG_(f,__ERROR_MSG) ASSERTMSG_(f,__ERROR_MSG)
00303 #else
00304 #       define ASSERTDEB_(f) { }
00305 #       define ASSERTDEBMSG_(f,__ERROR_MSG) { }
00306 #endif
00307 
00308 
00309 /** Can be used to avoid "not used parameters" warnings from the compiler
00310  */
00311 #define MRPT_UNUSED_PARAM(a)            (void)(a)
00312 
00313 #if MRPT_HAS_STACKED_EXCEPTIONS
00314         /** The start of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an exception.
00315           * \sa MRPT_TRY_END,MRPT_TRY_END_WITH_CLEAN_UP
00316           */
00317 #       define MRPT_TRY_START   \
00318         try { \
00319 
00320         /** The end of a standard MRPT "try...catch()" block that allows tracing throw the call stack after an exception.
00321           * \sa MRPT_TRY_START,MRPT_TRY_END_WITH_CLEAN_UP
00322           */
00323 #       define MRPT_TRY_END     \
00324         } \
00325         catch (std::bad_alloc &) \
00326         { throw; } \
00327         catch (std::exception &e) \
00328         { \
00329                 THROW_STACKED_EXCEPTION(e); \
00330         } \
00331         catch (...) \
00332         { \
00333                 THROW_EXCEPTION("Unexpected runtime error!"); \
00334         } \
00335 
00336         /** 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.
00337           * \sa MRPT_TRY_END,MRPT_TRY_START
00338           */
00339 #       define MRPT_TRY_END_WITH_CLEAN_UP(stuff)        \
00340         } \
00341         catch (std::bad_alloc &) \
00342         { throw; } \
00343         catch (std::exception &e) \
00344         { \
00345                 {stuff} \
00346                 THROW_STACKED_EXCEPTION(e); \
00347         } \
00348         catch (...) \
00349         { \
00350                 { stuff } \
00351                 THROW_EXCEPTION("Unexpected runtime error!"); \
00352         } \
00353 
00354 #else
00355 #       define MRPT_TRY_START
00356 #       define MRPT_TRY_END
00357 #       define MRPT_TRY_END_WITH_CLEAN_UP(stuff)
00358 #endif
00359 
00360 #if MRPT_ENABLE_EMBEDDED_GLOBAL_PROFILER
00361 #       define  MRPT_PROFILE_FUNC_START  ::mrpt::utils::CProfilerProxy BOOST_JOIN(__dum_var,__LINE__)( __CURRENT_FUNCTION_NAME__);
00362 #else
00363 #       define  MRPT_PROFILE_FUNC_START
00364 #endif
00365 
00366 // General macros for use within each MRPT method/function. They provide:
00367 //  - Nested exception handling
00368 //  - Automatic profiling stats (in Debug only)
00369 // ---------------------------------------------------------
00370 #define MRPT_START  \
00371         MRPT_PROFILE_FUNC_START \
00372         MRPT_TRY_START
00373 
00374 #define MRPT_END  \
00375         MRPT_TRY_END
00376 
00377 #define MRPT_END_WITH_CLEAN_UP(stuff) \
00378         MRPT_TRY_END_WITH_CLEAN_UP(stuff)
00379 
00380 // Generic constants and defines:
00381 // ---------------------------------------------------------
00382 #ifndef M_PI
00383 #       define M_PI 3.14159265358979323846264338327950288               // PI constant
00384 #endif
00385 
00386 #ifndef M_2PI
00387 #       define M_2PI 6.283185307179586476925286766559   // The 2*PI constant
00388 #endif
00389 
00390 #define M_PIf  3.14159265358979f
00391 #define M_2PIf 6.28318530717959f
00392 
00393 #if defined(HAVE_LONG_DOUBLE) && !defined(M_PIl)
00394 #       define M_PIl 3.14159265358979323846264338327950288L
00395 #       define M_2PIl (2.0L*3.14159265358979323846264338327950288L)
00396 #endif
00397 
00398 
00399 // Define a decl. modifier for printf-like format checks at compile time:
00400 #ifdef __GNUC__
00401 #       define MRPT_printf_format_check(_FMT_,_VARARGS_)  __attribute__ ((__format__ (__printf__, _FMT_,_VARARGS_)))
00402 #else
00403 #       define MRPT_printf_format_check(_FMT_,_VARARGS_)
00404 #endif
00405 
00406 // Define a decl. modifier for scanf-like format checks at compile time:
00407 #ifdef __GNUC__
00408 #       define MRPT_scanf_format_check(_FMT_,_VARARGS_)  __attribute__ ((__format__ (__scanf__, _FMT_,_VARARGS_)))
00409 #else
00410 #       define MRPT_scanf_format_check(_FMT_,_VARARGS_)
00411 #endif
00412 
00413 
00414 /** Used after member declarations */
00415 #define MRPT_NO_THROWS          throw()
00416 
00417 /** Tells the compiler we really want to inline that function */
00418 #if (defined _MSC_VER) || (defined __INTEL_COMPILER)
00419 #define MRPT_FORCE_INLINE __forceinline
00420 #else
00421 #define MRPT_FORCE_INLINE inline
00422 #endif
00423 
00424 #endif



Page generated by Doxygen 1.7.5 for MRPT 0.9.5 SVN: at Thu Oct 13 21:25:36 UTC 2011