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