00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef UTILSDEFS_H
00029 #define UTILSDEFS_H
00030
00031
00032
00033
00034
00035
00036 #if defined(_MSC_VER)
00037 #pragma warning(disable:4786) // (Compiler: Visual C++) Disable warning for too long debug names:
00038 #pragma warning(disable:4702) // (Compiler: Visual C++) Disable warning for unreachable code (I don't know why some of these errors appear in the STANDARD LIBRARY headers with Visual Studio 2003!):
00039 #pragma warning(disable:4244) // (Compiler: Visual C++) Conversion double->float
00040 #pragma warning(disable:4305)
00041 #pragma warning(disable:4267)
00042 #pragma warning(disable:4290) // Visual C++ does not implement decl. specifiers: throw(A,B,...)
00043 #pragma warning(disable:4251) // Visual C++ 2003+ warnings on STL classes when exporting to DLL...
00044 #pragma warning(disable:4275)
00045 #if (_MSC_VER >= 1400 )
00046
00047 #define _SCL_SECURE_NO_WARNINGS
00048 #pragma warning(disable:4996)
00049
00050 #if !defined(_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
00051 #define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
00052 #endif
00053 #endif
00054 #endif
00055
00056 #if defined(__BORLANDC__)
00057 #pragma warn -8027 // (Compiler: Borland C++) Disable a warning for inline functions
00058 #pragma warn -8012 // (Compiler: Borland C++) Disable a warning for override of virtual functions, while in reality there are many virtual function with different parameters
00059 #pragma warn -8022
00060 #endif
00061
00062 #include <mrpt/config.h>
00063 #include <mrpt/system/os.h>
00064
00065 #include <mrpt/utils/boost_join.h>
00066
00067
00068
00069
00070
00071
00072 #include <mrpt/base/link_pragmas.h>
00073
00074
00075
00076 #if defined(__GNUC__) && (__GNUC__ - 0 > 3 || (__GNUC__ - 0 == 3 && __GNUC_MINOR__ - 0 >= 2))
00077
00078 # define MRPT_DEPRECATED_PRE(_MSG)
00079
00080
00081 # define MRPT_DEPRECATED_POST(_MSG) __attribute__ ((deprecated))
00082 # elif defined(_MSC_VER) && (_MSC_VER >= 1300)
00083
00084 # define MRPT_DEPRECATED_PRE(_MSG) __declspec(deprecated (_MSG))
00085 # define MRPT_DEPRECATED_POST(_MSG)
00086 # else
00087 # define MRPT_DEPRECATED_PRE(_MSG)
00088 # define MRPT_DEPRECATED_POST(_MSG)
00089 # endif
00090
00091
00092 #define MRPT_DECLARE_DEPRECATED_FUNCTION(__MSG, __FUNC) MRPT_DEPRECATED_PRE(__MSG) __FUNC MRPT_DEPRECATED_POST(__MSG)
00093
00094
00095 #if defined(_MSC_VER)
00096 #define MRPT_DO_PRAGMA(x) __pragma(x)
00097 #define __STR2__(x) #x
00098 #define __STR1__(x) __STR2__(x)
00099 #define __MSVCLOC__ __FILE__ "("__STR1__(__LINE__)") : "
00100 #define MRPT_MSG_PRAGMA(_msg) MRPT_DO_PRAGMA(message (__MSVCLOC__ _msg))
00101 #elif defined(__GNUC__)
00102 #define MRPT_DO_PRAGMA(x) _Pragma (#x)
00103 #define MRPT_MSG_PRAGMA(_msg) MRPT_DO_PRAGMA(message (_msg))
00104 #else
00105 #define MRPT_DO_PRAGMA(x)
00106 #define MRPT_MSG_PRAGMA(_msg)
00107 #endif
00108
00109 #define MRPT_WARNING(x) MRPT_MSG_PRAGMA("Warning: " #x)
00110 #define MRPT_TODO(x) MRPT_MSG_PRAGMA("TODO: " #x)
00111
00112
00113 #ifdef __GNUC__
00114 # define MRPT_printf_format_check(_FMT_,_VARARGS_) __attribute__ ((__format__ (__printf__, _FMT_,_VARARGS_)))
00115 #else
00116 # define MRPT_printf_format_check(_FMT_,_VARARGS_)
00117 #endif
00118
00119 #ifdef __GNUC__
00120 # define MRPT_scanf_format_check(_FMT_,_VARARGS_) __attribute__ ((__format__ (__scanf__, _FMT_,_VARARGS_)))
00121 #else
00122 # define MRPT_scanf_format_check(_FMT_,_VARARGS_)
00123 #endif
00124
00125
00126 #define MRPT_NO_THROWS throw()
00127
00128
00129
00130 #if defined(_MSC_VER)
00131 #define MRPT_ALIGN16 __declspec(align(16))
00132 #define MRPT_ALIGN32 __declspec(align(32))
00133 #elif defined(__GNUC__)
00134 #define MRPT_ALIGN16 __attribute__((aligned(16)))
00135 #define MRPT_ALIGN32 __attribute__((aligned(32)))
00136 #else
00137 #define MRPT_ALIGN16
00138 #define MRPT_ALIGN32
00139 #endif
00140
00141
00142 #if defined(_DEBUG) && defined(_MSC_VER) && (_MSC_VER>=1400)
00143 #define _CRTDBG_MAP_ALLOC
00144 #include <stdlib.h>
00145 #include <crtdbg.h>
00146 #endif
00147
00148
00149 #include <cstddef>
00150 #include <stdlib.h>
00151 #include <cstdlib>
00152 #include <cmath>
00153
00154 #if HAVE_ALLOCA_H
00155 #include <alloca.h>
00156 #endif
00157
00158
00159 #include <vector>
00160 #include <set>
00161 #include <algorithm>
00162 #include <iterator>
00163 #include <iostream>
00164 #include <iomanip>
00165 #include <fstream>
00166 #include <cstring>
00167 #include <exception>
00168 #include <stdexcept>
00169 #include <limits>
00170 #include <sstream>
00171
00172
00173 #include <mrpt/otherlibs/stlplus/smart_ptr.hpp>
00174
00175
00176 #include <mrpt/utils/types.h>
00177
00178
00179
00180 namespace mrpt
00181 {
00182
00183
00184
00185
00186
00187 std::string BASE_IMPEXP format(const char *fmt, ...) MRPT_printf_format_check(1,2);
00188
00189 namespace utils
00190 {
00191 class CFileStream;
00192 void BASE_IMPEXP global_profiler_enter(const char *func_name) MRPT_NO_THROWS;
00193 void BASE_IMPEXP global_profiler_leave(const char *func_name) MRPT_NO_THROWS;
00194
00195 struct CProfilerProxy {
00196 const char*f;
00197 CProfilerProxy(const char*func_name) : f(func_name) { global_profiler_enter(f); }
00198 ~CProfilerProxy() { global_profiler_leave(f); }
00199 };
00200 }
00201 namespace system
00202 {
00203
00204 std::string BASE_IMPEXP extractFileName(const std::string &filePath);
00205 std::string BASE_IMPEXP stack_trace(bool calling_from_exception);
00206 }
00207
00208 namespace math
00209 {
00210 bool BASE_IMPEXP isNaN(float v) MRPT_NO_THROWS;
00211 bool BASE_IMPEXP isNaN(double v) MRPT_NO_THROWS;
00212 bool BASE_IMPEXP isFinite(float v) MRPT_NO_THROWS;
00213 bool BASE_IMPEXP isFinite(double v) MRPT_NO_THROWS;
00214 }
00215 }
00216
00217
00218
00219
00220 #if defined(__BORLANDC__)
00221 #define __CURRENT_FUNCTION_NAME__ __FUNC__
00222 #elif defined(_MSC_VER) && (_MSC_VER>=1300)
00223 #define __CURRENT_FUNCTION_NAME__ __FUNCTION__
00224 #elif defined(_MSC_VER) && (_MSC_VER<1300)
00225
00226 #define __CURRENT_FUNCTION_NAME__ ::system::extractFileName(__FILE__).c_str()
00227 #else
00228 #define __CURRENT_FUNCTION_NAME__ __PRETTY_FUNCTION__
00229 #endif
00230
00231
00232
00233
00234
00235
00236
00237 #define THROW_EXCEPTION(msg) \
00238 {\
00239 std::ostringstream auxCompStr;\
00240 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00241 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00242 auxCompStr << msg << std::endl; \
00243 auxCompStr << mrpt::system::stack_trace(); \
00244 throw std::logic_error( auxCompStr.str() );\
00245 }\
00246
00247
00248
00249
00250
00251 #define THROW_EXCEPTION_CUSTOM_MSG1(msg,param1) \
00252 {\
00253 std::ostringstream auxCompStr;\
00254 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00255 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00256 auxCompStr << mrpt::format(msg,param1)<< std::endl; \
00257 auxCompStr << mrpt::system::stack_trace(); \
00258 throw std::logic_error( auxCompStr.str() );\
00259 }\
00260
00261
00262
00263
00264
00265
00266 #define THROW_TYPED_EXCEPTION(msg,exceptionClass) \
00267 {\
00268 std::ostringstream auxCompStr;\
00269 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00270 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00271 auxCompStr << msg << std::endl; \
00272 auxCompStr << mrpt::system::stack_trace(); \
00273 throw exceptionClass( auxCompStr.str() );\
00274 }\
00275
00276
00277
00278
00279
00280 #define THROW_TYPED_EXCEPTION_CUSTOM_MSG1(msg,param1,exceptionClass) \
00281 {\
00282 std::ostringstream auxCompStr;\
00283 auxCompStr << "\n\n =============== MRPT EXCEPTION =============\n";\
00284 auxCompStr << __CURRENT_FUNCTION_NAME__ << ", line " << __LINE__ << ":\n";\
00285 auxCompStr << mrpt::format(msg,param1)<< std::endl; \
00286 auxCompStr << mrpt::system::stack_trace(); \
00287 throw exceptionClass( auxCompStr.str() );\
00288 }\
00289
00290
00291
00292
00293
00294 #define THROW_STACKED_EXCEPTION(e) \
00295 {\
00296 std::string str( e.what() );\
00297 if (str.find("MRPT stack trace")==std::string::npos) \
00298 { \
00299 str+= __CURRENT_FUNCTION_NAME__;\
00300 str+= mrpt::format(", line %i:\n", __LINE__ );\
00301 if (str.size()>3000) { std::cerr << "TOO MANY STACKED EXCEPTIONS!: " << std::endl << str << std::endl; abort(); } \
00302 throw std::logic_error( str );\
00303 } \
00304 else throw std::logic_error( e.what() );\
00305 }\
00306
00307
00308
00309
00310
00311 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG1(e,msg) \
00312 {\
00313 std::ostringstream auxCompStr;\
00314 auxCompStr << e.what() ; \
00315 auxCompStr << msg << std::endl; \
00316 throw std::logic_error( auxCompStr.str() );\
00317 }\
00318
00319
00320
00321
00322
00323 #define THROW_STACKED_EXCEPTION_CUSTOM_MSG2(e,stuff,param1) \
00324 {\
00325 std::ostringstream auxCompStr;\
00326 auxCompStr << e.what() ; \
00327 auxCompStr << mrpt::format( stuff, param1 ) << std::endl; \
00328 throw std::logic_error( auxCompStr.str() );\
00329 }\
00330
00331
00332 #define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(V) THROW_EXCEPTION(mrpt::format("Cannot parse object: unknown serialization version number: '%i'",static_cast<int>(version)))
00333
00334
00335 #if MRPT_HAS_ASSERT
00336
00337
00338
00339
00340 # define ASSERTMSG_(f,__ERROR_MSG) \
00341 { \
00342 if (!(f)) THROW_EXCEPTION( ::std::string( __ERROR_MSG ) ); \
00343 }
00344
00345
00346
00347
00348
00349 # define ASSERT_(f) \
00350 ASSERTMSG_(f, "Assert condition failed: " + ::std::string(#f) )
00351
00352
00353
00354 #define MRPT_CHECK_NORMAL_NUMBER(v) \
00355 { \
00356 if (math::isNaN(v)) THROW_EXCEPTION("Check failed (value is NaN)"); \
00357 if (!math::isFinite(v)) THROW_EXCEPTION("Check failed (value is not finite)"); \
00358 }
00359
00360
00361
00362
00363 namespace mrpt
00364 {
00365 namespace utils
00366 {
00367 template <bool value> struct compile_time_assert;
00368 template <> struct compile_time_assert<true> { enum {value=1}; };
00369 }
00370 }
00371 #define MRPT_COMPILE_TIME_ASSERT(expression) \
00372 typedef char BOOST_JOIN(MRPT_CTA, __LINE__)[::mrpt::utils::compile_time_assert<(bool)(expression)>::value];
00373
00374 #else
00375 # define ASSERTMSG_(f,__ERROR_MSG) { }
00376 # define ASSERT_(f) { }
00377 # define MRPT_CHECK_NORMAL_NUMBER(val) { }
00378 # define MRPT_COMPILE_TIME_ASSERT(f) { }
00379 #endif
00380
00381
00382
00383
00384
00385 #ifdef _DEBUG
00386 # define ASSERTDEB_(f) ASSERT_(f)
00387 # define ASSERTDEBMSG_(f,__ERROR_MSG) ASSERTMSG_(f,__ERROR_MSG)
00388 #else
00389 # define ASSERTDEB_(f) { }
00390 # define ASSERTDEBMSG_(f,__ERROR_MSG) { }
00391 #endif
00392
00393
00394
00395
00396
00397 #define MRPT_UNUSED_PARAM(a) (void)(a)
00398
00399 #if MRPT_HAS_STACKED_EXCEPTIONS
00400
00401
00402
00403 # define MRPT_TRY_START \
00404 try { \
00405
00406
00407
00408
00409 # define MRPT_TRY_END \
00410 } \
00411 catch (std::bad_alloc &e) \
00412 { \
00413 std::cerr << "MRPT CRITICAL ERROR: Out of memory:\n" << e.what() << std::endl; \
00414 exit(-1); throw std::runtime_error("dummy"); \
00415 } \
00416 catch (std::exception &e) \
00417 { \
00418 THROW_STACKED_EXCEPTION(e); \
00419 } \
00420 catch (...) \
00421 { \
00422 THROW_EXCEPTION("Unexpected runtime error!"); \
00423 } \
00424
00425
00426
00427
00428 # define MRPT_TRY_END_WITH_CLEAN_UP(stuff) \
00429 } \
00430 catch (std::bad_alloc &e) \
00431 { \
00432 std::cerr << "MRPT CRITICAL ERROR: Out of memory:\n" << e.what() << std::endl; \
00433 exit(-1); throw std::runtime_error("dummy"); \
00434 } \
00435 catch (std::exception &e) \
00436 { \
00437 {stuff} \
00438 THROW_STACKED_EXCEPTION(e); \
00439 } \
00440 catch (...) \
00441 { \
00442 { stuff } \
00443 THROW_EXCEPTION("Unexpected runtime error!"); \
00444 } \
00445
00446 #else
00447 # define MRPT_TRY_START
00448 # define MRPT_TRY_END
00449 # define MRPT_TRY_END_WITH_CLEAN_UP(stuff)
00450 #endif
00451
00452 #if MRPT_ENABLE_EMBEDDED_GLOBAL_PROFILER
00453 # define MRPT_PROFILE_FUNC_START ::mrpt::utils::CProfilerProxy BOOST_JOIN(__dum_var,__LINE__)( __CURRENT_FUNCTION_NAME__);
00454 #else
00455 # define MRPT_PROFILE_FUNC_START
00456 #endif
00457
00458
00459
00460
00461
00462 #define MRPT_START \
00463 MRPT_PROFILE_FUNC_START \
00464 MRPT_TRY_START
00465
00466 #define MRPT_END \
00467 MRPT_TRY_END
00468
00469 #define MRPT_END_WITH_CLEAN_UP(stuff) \
00470 MRPT_TRY_END_WITH_CLEAN_UP(stuff)
00471
00472
00473
00474
00475 #ifndef M_PI
00476 # define M_PI 3.14159265358979323846264338327950288 // PI constant
00477 #endif
00478
00479 #ifndef M_2PI
00480 # define M_2PI 6.283185307179586476925286766559 // The 2*PI constant
00481 #endif
00482
00483 #define M_PIf 3.14159265358979f
00484 #define M_2PIf 6.28318530717959f
00485
00486 #if defined(HAVE_LONG_DOUBLE) && !defined(M_PIl)
00487 # define M_PIl 3.14159265358979323846264338327950288L
00488 # define M_2PIl (2.0L*3.14159265358979323846264338327950288L)
00489 #endif
00490
00491
00492
00493 #if defined(MRPT_OS_WINDOWS) && !defined(NOMINMAX)
00494 # define NOMINMAX
00495 # ifdef max
00496 # undef max
00497 # undef min
00498 # endif
00499 #endif
00500
00501
00502
00503
00504 #if defined(_MSC_VER) && (_MSC_VER<1300)
00505 # ifndef max
00506 namespace std
00507 {
00508 template<class T> inline const T max(const T& A,const T& B) { return A>B ? A:B; }
00509 template<class T> inline const T min(const T& A,const T& B) { return A<B ? A:B; }
00510 }
00511 # else
00512 # define MAX3_MSVC6_VERSION
00513 # endif
00514 #endif
00515
00516
00517 #ifndef MAX3_MSVC6_VERSION
00518 template<typename T> inline const T min3(const T& A, const T& B,const T& C) { return std::min<T>(A, std::min<T>(B,C) ); }
00519 template<typename T> inline const T max3(const T& A, const T& B,const T& C) { return std::max<T>(A, std::max<T>(B,C) ); }
00520 #else
00521 # define max3(A,B,C) max(A,max(B,C))
00522 # define min3(A,B,C) min(A,min(B,C))
00523 #endif
00524
00525 namespace mrpt
00526 {
00527 namespace math
00528 {
00529
00530
00531
00532
00533 template <class MATRIXLIKE>
00534 inline size_t size( const MATRIXLIKE& m, int dim )
00535 {
00536 if (dim==1)
00537 return m.getRowCount();
00538 else if (dim==2)
00539 return m.getColCount();
00540 else THROW_EXCEPTION_CUSTOM_MSG1("size: Queried matrix dimension must be 1 or 2. Called with i=%i",dim);
00541 }
00542 }
00543
00544
00545 namespace utils
00546 {
00547
00548 inline double DEG2RAD(const double x) { return x*M_PI/180.0; }
00549
00550
00551 inline float DEG2RAD(const float x) { return x*M_PIf/180.0f; }
00552
00553
00554 inline float DEG2RAD(const int x) { return x*M_PIf/180.0f; }
00555
00556
00557 inline double RAD2DEG(const double x) { return x*180.0/M_PI; }
00558
00559
00560 inline float RAD2DEG(const float x) { return x*180.0f/M_PIf; }
00561
00562 # ifdef HAVE_LONG_DOUBLE
00563
00564 inline long double DEG2RAD(const long double x) { return x*M_PIl/180.0; }
00565
00566 inline long double RAD2DEG(const long double x) { return x*180.0/M_PIl; }
00567 # endif
00568
00569
00570 template <typename T>
00571 inline int sign(T x) { return x<0 ? -1:1; }
00572
00573
00574 template <typename T>
00575 inline int signWithZero(T x) { return x==0?0:sign(x);}
00576
00577
00578 template <typename T>
00579 inline int round(const T value)
00580 {
00581 #if MRPT_HAS_SSE2
00582 __m128d t = _mm_set_sd( value );
00583 return _mm_cvtsd_si32(t);
00584 #elif (defined WIN32 || defined _WIN32) && !defined WIN64 && !defined _WIN64 && defined _MSC_VER
00585 int t;
00586 __asm
00587 {
00588 fld value;
00589 fistp t;
00590 }
00591 return t;
00592 #elif defined HAVE_LRINT || defined __GNUC__
00593 return static_cast<int>(lrint(value));
00594 #else
00595 return static_cast<int>(value + 0.5);
00596 #endif
00597 }
00598
00599
00600 template <typename T>
00601 inline long round_long(const T value)
00602 {
00603 #if MRPT_HAS_SSE2 && MRPT_WORD_SIZE==64
00604 __m128d t = _mm_set_sd( value );
00605 return _mm_cvtsd_si64(t);
00606 #elif (defined WIN32 || defined _WIN32) && !defined WIN64 && !defined _WIN64 && defined _MSC_VER
00607 long t;
00608 __asm
00609 {
00610 fld value;
00611 fistp t;
00612 }
00613 return t;
00614 #elif defined HAVE_LRINT || defined __GNUC__
00615 return lrint(value);
00616 #else
00617 return static_cast<long>(value + 0.5);
00618 #endif
00619 }
00620
00621
00622 template <typename T>
00623 inline int fix(T x) { return x>0 ? static_cast<int>(floor(static_cast<double>(x))) : static_cast<int>(ceil(static_cast<double>(x))) ; }
00624
00625
00626 template<class T>
00627 inline T square(const T& x) { return x*x; }
00628
00629
00630
00631 template <class R, class P>
00632 inline R* getAs(stlplus::smart_ptr_clone<P> &o) { return static_cast<R*>( & (*o) ); }
00633
00634
00635 template <class R, class P>
00636 inline const R* getAs(const stlplus::smart_ptr_clone<P> &o) { return static_cast<const R*>( & (*o) ); }
00637
00638
00639
00640 template <class T> void reverseBytes(const T &v_in, T& v_out)
00641 {
00642 v_out = v_in;
00643 uint8_t *ptr = reinterpret_cast<uint8_t*>(&v_out);
00644 std::reverse(ptr,ptr+sizeof(T));
00645 }
00646
00647
00648 template <typename T,typename K>
00649 inline void keep_min(T &var, const K test_val) {
00650 if (test_val<var) var = test_val;
00651 }
00652
00653
00654 template <typename T,typename K>
00655 inline void keep_max(T &var, const K test_val) {
00656 if (test_val>var) var = test_val;
00657 }
00658
00659
00660 template <class T>
00661 void delete_safe(T *& ptr) {
00662 if (ptr) {
00663 delete ptr;
00664 ptr = NULL;
00665 }
00666 }
00667
00668 }
00669 }
00670 #endif