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