|
GDAL
|
00001 /****************************************************************************** 00002 * $Id: cpl_port.h 38517 2017-05-20 11:35:37Z rouault $ 00003 * 00004 * Project: CPL - Common Portability Library 00005 * Author: Frank Warmerdam, warmerdam@pobox.com 00006 * Purpose: Include file providing low level portability services for CPL. 00007 * This should be the first include file for any CPL based code. 00008 * 00009 ****************************************************************************** 00010 * Copyright (c) 1998, 2005, Frank Warmerdam <warmerdam@pobox.com> 00011 * Copyright (c) 2008-2013, Even Rouault <even dot rouault at mines-paris dot org> 00012 * 00013 * Permission is hereby granted, free of charge, to any person obtaining a 00014 * copy of this software and associated documentation files (the "Software"), 00015 * to deal in the Software without restriction, including without limitation 00016 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00017 * and/or sell copies of the Software, and to permit persons to whom the 00018 * Software is furnished to do so, subject to the following conditions: 00019 * 00020 * The above copyright notice and this permission notice shall be included 00021 * in all copies or substantial portions of the Software. 00022 * 00023 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00024 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00025 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00026 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00027 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00028 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00029 * DEALINGS IN THE SOFTWARE. 00030 ****************************************************************************/ 00031 00032 #ifndef CPL_BASE_H_INCLUDED 00033 #define CPL_BASE_H_INCLUDED 00034 00042 /* ==================================================================== */ 00043 /* We will use WIN32 as a standard windows define. */ 00044 /* ==================================================================== */ 00045 #if defined(_WIN32) && !defined(WIN32) 00046 # define WIN32 00047 #endif 00048 00049 #if defined(_WINDOWS) && !defined(WIN32) 00050 # define WIN32 00051 #endif 00052 00053 /* -------------------------------------------------------------------- */ 00054 /* The following apparently allow you to use strcpy() and other */ 00055 /* functions judged "unsafe" by microsoft in VS 8 (2005). */ 00056 /* -------------------------------------------------------------------- */ 00057 #ifdef _MSC_VER 00058 # ifndef _CRT_SECURE_NO_DEPRECATE 00059 # define _CRT_SECURE_NO_DEPRECATE 00060 # endif 00061 # ifndef _CRT_NONSTDC_NO_DEPRECATE 00062 # define _CRT_NONSTDC_NO_DEPRECATE 00063 # endif 00064 #endif 00065 00066 #include "cpl_config.h" 00067 00068 /* ==================================================================== */ 00069 /* A few sanity checks, mainly to detect problems that sometimes */ 00070 /* arise with bad configured cross-compilation. */ 00071 /* ==================================================================== */ 00072 00073 #if !defined(SIZEOF_INT) || SIZEOF_INT != 4 00074 #error "Unexpected value for SIZEOF_INT" 00075 #endif 00076 00077 #if !defined(SIZEOF_UNSIGNED_LONG) || (SIZEOF_UNSIGNED_LONG != 4 && SIZEOF_UNSIGNED_LONG != 8) 00078 #error "Unexpected value for SIZEOF_UNSIGNED_LONG" 00079 #endif 00080 00081 #if !defined(SIZEOF_VOIDP) || (SIZEOF_VOIDP != 4 && SIZEOF_VOIDP != 8) 00082 #error "Unexpected value for SIZEOF_VOIDP" 00083 #endif 00084 00085 /* ==================================================================== */ 00086 /* This will disable most WIN32 stuff in a Cygnus build which */ 00087 /* defines unix to 1. */ 00088 /* ==================================================================== */ 00089 00090 #ifdef unix 00091 # undef WIN32 00092 #endif 00093 00095 #if defined(VSI_NEED_LARGEFILE64_SOURCE) && !defined(_LARGEFILE64_SOURCE) 00096 # define _LARGEFILE64_SOURCE 1 00097 #endif 00098 00099 /* ==================================================================== */ 00100 /* If iconv() is available use extended recoding module. */ 00101 /* Stub implementation is always compiled in, because it works */ 00102 /* faster than iconv() for encodings it supports. */ 00103 /* ==================================================================== */ 00104 00105 #if defined(HAVE_ICONV) 00106 # define CPL_RECODE_ICONV 00107 #endif 00108 00109 #define CPL_RECODE_STUB 00110 00112 /* ==================================================================== */ 00113 /* MinGW stuff */ 00114 /* ==================================================================== */ 00115 00116 /* We need __MSVCRT_VERSION__ >= 0x0700 to have "_aligned_malloc" */ 00117 /* Latest versions of mingw32 define it, but with older ones, */ 00118 /* we need to define it manually */ 00119 #if defined(__MINGW32__) 00120 #ifndef __MSVCRT_VERSION__ 00121 #define __MSVCRT_VERSION__ 0x0700 00122 #endif 00123 #endif 00124 00125 /* Needed for std=c11 on Solaris to have strcasecmp() */ 00126 #if defined(GDAL_COMPILATION) && defined(__sun__) && __STDC_VERSION__ >= 201112L && _XOPEN_SOURCE < 600 00127 #ifdef _XOPEN_SOURCE 00128 #undef _XOPEN_SOURCE 00129 #endif 00130 #define _XOPEN_SOURCE 600 00131 #endif 00132 00133 /* ==================================================================== */ 00134 /* Standard include files. */ 00135 /* ==================================================================== */ 00136 00137 #include <stdio.h> 00138 #include <stdlib.h> 00139 #include <math.h> 00140 #include <stdarg.h> 00141 #include <string.h> 00142 #include <ctype.h> 00143 #include <limits.h> 00144 00145 #include <time.h> 00146 00147 #if defined(HAVE_ERRNO_H) 00148 # include <errno.h> 00149 #endif 00150 00151 #ifdef HAVE_LOCALE_H 00152 # include <locale.h> 00153 #endif 00154 00155 #ifdef HAVE_DIRECT_H 00156 # include <direct.h> 00157 #endif 00158 00159 #if !defined(WIN32) 00160 # include <strings.h> 00161 #endif 00162 00163 #if defined(HAVE_LIBDBMALLOC) && defined(HAVE_DBMALLOC_H) && defined(DEBUG) 00164 # define DBMALLOC 00165 # include <dbmalloc.h> 00166 #endif 00167 00168 #if !defined(DBMALLOC) && defined(HAVE_DMALLOC_H) 00169 # define USE_DMALLOC 00170 # include <dmalloc.h> 00171 #endif 00172 00173 /* ==================================================================== */ 00174 /* Base portability stuff ... this stuff may need to be */ 00175 /* modified for new platforms. */ 00176 /* ==================================================================== */ 00177 00178 /* -------------------------------------------------------------------- */ 00179 /* Which versions of C++ are available. */ 00180 /* -------------------------------------------------------------------- */ 00181 00182 #ifdef __cplusplus 00183 # if __cplusplus >= 201103L 00184 # define HAVE_CXX11 1 00185 # endif 00186 /* TODO(schwehr): What are the correct tests for C++ 14 and 17? */ 00187 #endif /* __cplusplus */ 00188 00189 /*--------------------------------------------------------------------- 00190 * types for 16 and 32 bits integers, etc... 00191 *--------------------------------------------------------------------*/ 00192 #if UINT_MAX == 65535 00193 typedef long GInt32; 00194 typedef unsigned long GUInt32; 00195 #else 00196 00197 typedef int GInt32; 00199 typedef unsigned int GUInt32; 00200 #endif 00201 00203 typedef short GInt16; 00205 typedef unsigned short GUInt16; 00207 typedef unsigned char GByte; 00208 /* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef bool GBool" */ 00209 /* in include/poppler/goo/gtypes.h */ 00210 #ifndef CPL_GBOOL_DEFINED 00211 00212 #define CPL_GBOOL_DEFINED 00213 00215 typedef int GBool; 00216 #endif 00217 00218 /* -------------------------------------------------------------------- */ 00219 /* 64bit support */ 00220 /* -------------------------------------------------------------------- */ 00221 00222 #if defined(WIN32) && defined(_MSC_VER) 00223 00224 #define VSI_LARGE_API_SUPPORTED 00225 typedef __int64 GIntBig; 00226 typedef unsigned __int64 GUIntBig; 00227 00229 #define GINTBIG_MIN ((GIntBig)(0x80000000) << 32) 00230 00231 #define GINTBIG_MAX (((GIntBig)(0x7FFFFFFF) << 32) | 0xFFFFFFFFU) 00232 00233 #define GUINTBIG_MAX (((GUIntBig)(0xFFFFFFFFU) << 32) | 0xFFFFFFFFU) 00234 00235 #define CPL_HAS_GINT64 1 00236 00238 typedef GIntBig GInt64; 00240 typedef GUIntBig GUInt64; 00241 00242 #define GINT64_MIN GINTBIG_MIN 00243 #define GINT64_MAX GINTBIG_MAX 00244 #define GUINT64_MAX GUINTBIG_MAX 00245 00246 #elif HAVE_LONG_LONG 00247 00250 typedef long long GIntBig; 00253 typedef unsigned long long GUIntBig; 00254 00256 #define GINTBIG_MIN ((GIntBig)(0x80000000) << 32) 00257 00258 #define GINTBIG_MAX (((GIntBig)(0x7FFFFFFF) << 32) | 0xFFFFFFFFU) 00259 00260 #define GUINTBIG_MAX (((GUIntBig)(0xFFFFFFFFU) << 32) | 0xFFFFFFFFU) 00261 00263 #define CPL_HAS_GINT64 1 00264 00266 /* Note: we might want to use instead int64_t / uint64_t if they are available */ 00267 00269 typedef GIntBig GInt64; 00271 typedef GUIntBig GUInt64; 00272 00274 #define GINT64_MIN GINTBIG_MIN 00275 00276 #define GINT64_MAX GINTBIG_MAX 00277 00278 #define GUINT64_MAX GUINTBIG_MAX 00279 00280 #else 00281 00282 // NOTE: we don't really support such platforms ! Many things might break 00283 00284 typedef long GIntBig; 00285 typedef unsigned long GUIntBig; 00286 00287 #define GINTBIG_MIN INT_MIN 00288 #define GINTBIG_MAX INT_MAX 00289 #define GUINTBIG_MAX UINT_MAX 00290 #endif 00291 00292 #if SIZEOF_VOIDP == 8 00293 00294 typedef GIntBig GPtrDiff_t; 00295 #else 00296 00297 typedef int GPtrDiff_t; 00298 #endif 00299 00300 #ifdef GDAL_COMPILATION 00301 #if HAVE_UINTPTR_T 00302 #if !defined(_MSC_VER) || _MSC_VER > 1500 00303 #include <stdint.h> 00304 #endif 00305 typedef uintptr_t GUIntptr_t; 00306 #elif SIZEOF_VOIDP == 8 00307 typedef GUIntBig GUIntptr_t; 00308 #else 00309 typedef unsigned int GUIntptr_t; 00310 #endif 00311 00312 #define CPL_IS_ALIGNED(ptr, quant) (((GUIntptr_t)(ptr) % (quant)) == 0) 00313 00314 #endif 00315 00316 #if defined(__MSVCRT__) || (defined(WIN32) && defined(_MSC_VER)) 00317 #define CPL_FRMT_GB_WITHOUT_PREFIX "I64" 00318 #elif HAVE_LONG_LONG 00319 00320 #define CPL_FRMT_GB_WITHOUT_PREFIX "ll" 00321 #else 00322 #define CPL_FRMT_GB_WITHOUT_PREFIX "l" 00323 #endif 00324 00326 #define CPL_FRMT_GIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "d" 00327 00328 #define CPL_FRMT_GUIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "u" 00329 00331 /* Workaround VC6 bug */ 00332 #if defined(_MSC_VER) && (_MSC_VER <= 1200) 00333 #define GUINTBIG_TO_DOUBLE(x) (double)(GIntBig)(x) 00334 #else 00335 #define GUINTBIG_TO_DOUBLE(x) (double)(x) 00336 #endif 00337 00340 #ifdef COMPAT_WITH_ICC_CONVERSION_CHECK 00341 #define CPL_INT64_FITS_ON_INT32(x) ((x) >= INT_MIN && (x) <= INT_MAX) 00342 #else 00343 #define CPL_INT64_FITS_ON_INT32(x) (((GIntBig)(int)(x)) == (x)) 00344 #endif 00345 00347 /* ==================================================================== */ 00348 /* Other standard services. */ 00349 /* ==================================================================== */ 00350 #ifdef __cplusplus 00351 00352 # define CPL_C_START extern "C" { 00353 00354 # define CPL_C_END } 00355 #else 00356 # define CPL_C_START 00357 # define CPL_C_END 00358 #endif 00359 00360 #ifndef CPL_DLL 00361 #if defined(_MSC_VER) && !defined(CPL_DISABLE_DLL) 00362 # define CPL_DLL __declspec(dllexport) 00363 #else 00364 # if defined(USE_GCC_VISIBILITY_FLAG) 00365 # define CPL_DLL __attribute__ ((visibility("default"))) 00366 # else 00367 # define CPL_DLL 00368 # endif 00369 #endif 00370 #endif 00371 00373 /* Should optional (normally private) interfaces be exported? */ 00374 #ifdef CPL_OPTIONAL_APIS 00375 # define CPL_ODLL CPL_DLL 00376 #else 00377 # define CPL_ODLL 00378 #endif 00379 00381 #ifndef CPL_STDCALL 00382 #if defined(_MSC_VER) && !defined(CPL_DISABLE_STDCALL) 00383 # define CPL_STDCALL __stdcall 00384 #else 00385 # define CPL_STDCALL 00386 #endif 00387 #endif 00388 00390 #ifdef _MSC_VER 00391 # define FORCE_CDECL __cdecl 00392 #else 00393 # define FORCE_CDECL 00394 #endif 00395 00398 /* TODO : support for other compilers needed */ 00399 #if (defined(__GNUC__) && !defined(__NO_INLINE__)) || defined(_MSC_VER) 00400 #define HAS_CPL_INLINE 1 00401 #define CPL_INLINE __inline 00402 #elif defined(__SUNPRO_CC) 00403 #define HAS_CPL_INLINE 1 00404 #define CPL_INLINE inline 00405 #else 00406 #define CPL_INLINE 00407 #endif 00408 00411 // Define NULL_AS_NULLPTR together with -std=c++11 -Wzero-as-null-pointer-constant with GCC 00412 // to detect misuses of NULL 00413 #if defined(NULL_AS_NULLPTR) && HAVE_CXX11 00414 00415 #ifdef __GNUC__ 00416 // We need to include all that bunch of system headers, otherwise 00417 // as they include <stddef.h> with __need_NULL, this overrides our #define NULL nullptr 00418 // with #define NULL __null 00419 #include <locale.h> 00420 #include <unistd.h> 00421 #include <sys/types.h> 00422 #ifdef HAVE_ICONV 00423 #include <iconv.h> 00424 #endif 00425 #ifdef HAVE_MMAP 00426 #include <sys/mman.h> 00427 #endif 00428 #include <signal.h> 00429 #ifndef _WIN32 00430 #include <dlfcn.h> 00431 #include <netdb.h> 00432 #include <fcntl.h> 00433 #endif 00434 00435 extern "C++" { 00436 #include <string> 00437 #include <cstdio> 00438 #include <cstdlib> 00439 #include <cstring> 00440 #include <cstddef> 00441 #include <ostream> 00442 #include <iostream> 00443 #include <sstream> 00444 } 00445 #endif /* __GNUC__ */ 00446 00447 #undef NULL 00448 #define NULL nullptr 00449 #else /* defined(NULL_AS_NULLPTR) && HAVE_CXX11 */ 00450 #ifndef NULL 00451 # define NULL 0 00452 #endif 00453 #endif /* defined(NULL_AS_NULLPTR) && HAVE_CXX11 */ 00454 00456 #ifndef MAX 00457 00458 # define MIN(a,b) (((a)<(b)) ? (a) : (b)) 00459 00460 # define MAX(a,b) (((a)>(b)) ? (a) : (b)) 00461 #endif 00462 00463 #ifndef ABS 00464 00465 # define ABS(x) (((x)<0) ? (-1*(x)) : (x)) 00466 #endif 00467 00468 #ifndef M_PI 00469 00470 # define M_PI 3.14159265358979323846 00471 /* 3.1415926535897932384626433832795 */ 00472 #endif 00473 00474 /* -------------------------------------------------------------------- */ 00475 /* Macro to test equality of two floating point values. */ 00476 /* We use fabs() function instead of ABS() macro to avoid side */ 00477 /* effects. */ 00478 /* -------------------------------------------------------------------- */ 00480 #ifndef CPLIsEqual 00481 # define CPLIsEqual(x,y) (fabs((x) - (y)) < 0.0000000000001) 00482 #endif 00483 00485 /* -------------------------------------------------------------------- */ 00486 /* Provide macros for case insensitive string comparisons. */ 00487 /* -------------------------------------------------------------------- */ 00488 #ifndef EQUAL 00489 00490 #if defined(AFL_FRIENDLY) && defined(__GNUC__) 00491 00492 static inline int CPL_afl_friendly_memcmp(const void* ptr1, const void* ptr2, size_t len) 00493 __attribute__((always_inline)); 00494 00495 static inline int CPL_afl_friendly_memcmp(const void* ptr1, const void* ptr2, size_t len) 00496 { 00497 const unsigned char* bptr1 = (const unsigned char*)ptr1; 00498 const unsigned char* bptr2 = (const unsigned char*)ptr2; 00499 while( len-- ) 00500 { 00501 unsigned char b1 = *(bptr1++); 00502 unsigned char b2 = *(bptr2++); 00503 if( b1 != b2 ) return b1 - b2; 00504 } 00505 return 0; 00506 } 00507 00508 static inline int CPL_afl_friendly_strcmp(const char* ptr1, const char* ptr2) 00509 __attribute__((always_inline)); 00510 00511 static inline int CPL_afl_friendly_strcmp(const char* ptr1, const char* ptr2) 00512 { 00513 const unsigned char* usptr1 = (const unsigned char*)ptr1; 00514 const unsigned char* usptr2 = (const unsigned char*)ptr2; 00515 while( 1 ) 00516 { 00517 unsigned char ch1 = *(usptr1++); 00518 unsigned char ch2 = *(usptr2++); 00519 if( ch1 == 0 || ch1 != ch2 ) return ch1 - ch2; 00520 } 00521 } 00522 00523 static inline int CPL_afl_friendly_strncmp(const char* ptr1, const char* ptr2, size_t len) 00524 __attribute__((always_inline)); 00525 00526 static inline int CPL_afl_friendly_strncmp(const char* ptr1, const char* ptr2, size_t len) 00527 { 00528 const unsigned char* usptr1 = (const unsigned char*)ptr1; 00529 const unsigned char* usptr2 = (const unsigned char*)ptr2; 00530 while( len -- ) 00531 { 00532 unsigned char ch1 = *(usptr1++); 00533 unsigned char ch2 = *(usptr2++); 00534 if( ch1 == 0 || ch1 != ch2 ) return ch1 - ch2; 00535 } 00536 return 0; 00537 } 00538 00539 static inline int CPL_afl_friendly_strcasecmp(const char* ptr1, const char* ptr2) 00540 __attribute__((always_inline)); 00541 00542 static inline int CPL_afl_friendly_strcasecmp(const char* ptr1, const char* ptr2) 00543 { 00544 const unsigned char* usptr1 = (const unsigned char*)ptr1; 00545 const unsigned char* usptr2 = (const unsigned char*)ptr2; 00546 while( 1 ) 00547 { 00548 unsigned char ch1 = *(usptr1++); 00549 unsigned char ch2 = *(usptr2++); 00550 ch1 = (unsigned char)toupper(ch1); 00551 ch2 = (unsigned char)toupper(ch2); 00552 if( ch1 == 0 || ch1 != ch2 ) return ch1 - ch2; 00553 } 00554 } 00555 00556 static inline int CPL_afl_friendly_strncasecmp(const char* ptr1, const char* ptr2, size_t len) 00557 __attribute__((always_inline)); 00558 00559 static inline int CPL_afl_friendly_strncasecmp(const char* ptr1, const char* ptr2, size_t len) 00560 { 00561 const unsigned char* usptr1 = (const unsigned char*)ptr1; 00562 const unsigned char* usptr2 = (const unsigned char*)ptr2; 00563 while( len-- ) 00564 { 00565 unsigned char ch1 = *(usptr1++); 00566 unsigned char ch2 = *(usptr2++); 00567 ch1 = (unsigned char)toupper(ch1); 00568 ch2 = (unsigned char)toupper(ch2); 00569 if( ch1 == 0 || ch1 != ch2 ) return ch1 - ch2; 00570 } 00571 return 0; 00572 } 00573 00574 static inline char* CPL_afl_friendly_strstr(const char* haystack, const char* needle) 00575 __attribute__((always_inline)); 00576 00577 static inline char* CPL_afl_friendly_strstr(const char* haystack, const char* needle) 00578 { 00579 const char* ptr_haystack = haystack; 00580 while( 1 ) 00581 { 00582 const char* ptr_haystack2 = ptr_haystack; 00583 const char* ptr_needle = needle; 00584 while( 1 ) 00585 { 00586 char ch1 = *(ptr_haystack2++); 00587 char ch2 = *(ptr_needle++); 00588 if( ch2 == 0 ) 00589 return (char*)ptr_haystack; 00590 if( ch1 != ch2 ) 00591 break; 00592 } 00593 if( *ptr_haystack == 0 ) 00594 return NULL; 00595 ptr_haystack ++; 00596 } 00597 } 00598 00599 #undef strcmp 00600 #undef strncmp 00601 #define memcmp CPL_afl_friendly_memcmp 00602 #define strcmp CPL_afl_friendly_strcmp 00603 #define strncmp CPL_afl_friendly_strncmp 00604 #define strcasecmp CPL_afl_friendly_strcasecmp 00605 #define strncasecmp CPL_afl_friendly_strncasecmp 00606 #define strstr CPL_afl_friendly_strstr 00607 00608 #endif /* defined(AFL_FRIENDLY) && defined(__GNUC__) */ 00609 00610 # if defined(WIN32) 00611 # define STRCASECMP(a,b) (stricmp(a,b)) 00612 # define STRNCASECMP(a,b,n) (strnicmp(a,b,n)) 00613 # else 00614 00615 # define STRCASECMP(a,b) (strcasecmp(a,b)) 00616 00617 # define STRNCASECMP(a,b,n) (strncasecmp(a,b,n)) 00618 # endif 00619 00620 # define EQUALN(a,b,n) (STRNCASECMP(a,b,n)==0) 00621 00622 # define EQUAL(a,b) (STRCASECMP(a,b)==0) 00623 #endif 00624 00625 /*--------------------------------------------------------------------- 00626 * Does a string "a" start with string "b". Search is case-sensitive or, 00627 * with CI, it is a case-insensitive comparison. 00628 *--------------------------------------------------------------------- */ 00629 #ifndef STARTS_WITH_CI 00630 00631 #define STARTS_WITH(a,b) (strncmp(a,b,strlen(b)) == 0) 00632 00633 #define STARTS_WITH_CI(a,b) EQUALN(a,b,strlen(b)) 00634 #endif 00635 00637 #ifndef CPL_THREADLOCAL 00638 # define CPL_THREADLOCAL 00639 #endif 00640 00642 /* -------------------------------------------------------------------- */ 00643 /* Handle isnan() and isinf(). Note that isinf() and isnan() */ 00644 /* are supposed to be macros according to C99, defined in math.h */ 00645 /* Some systems (i.e. Tru64) don't have isinf() at all, so if */ 00646 /* the macro is not defined we just assume nothing is infinite. */ 00647 /* This may mean we have no real CPLIsInf() on systems with isinf()*/ 00648 /* function but no corresponding macro, but I can live with */ 00649 /* that since it isn't that important a test. */ 00650 /* -------------------------------------------------------------------- */ 00651 #ifdef _MSC_VER 00652 # include <float.h> 00653 # define CPLIsNan(x) _isnan(x) 00654 # define CPLIsInf(x) (!_isnan(x) && !_finite(x)) 00655 # define CPLIsFinite(x) _finite(x) 00656 #elif defined(__cplusplus) && defined(HAVE_STD_IS_NAN) && HAVE_STD_IS_NAN 00657 extern "C++" { 00658 #ifndef DOXYGEN_SKIP 00659 #include <cmath> 00660 #endif 00661 static inline int CPLIsNan(float f) { return std::isnan(f); } 00662 static inline int CPLIsNan(double f) { return std::isnan(f); } 00663 static inline int CPLIsInf(float f) { return std::isinf(f); } 00664 static inline int CPLIsInf(double f) { return std::isinf(f); } 00665 static inline int CPLIsFinite(float f) { return std::isfinite(f); } 00666 static inline int CPLIsFinite(double f) { return std::isfinite(f); } 00667 } 00668 #elif defined(__GNUC__) && ( __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 ) ) 00669 /* When including <cmath> in C++11 the isnan() macro is undefined, so that */ 00670 /* std::isnan() can work (#6489). This is a GCC specific workaround for now. */ 00671 # define CPLIsNan(x) __builtin_isnan(x) 00672 # define CPLIsInf(x) __builtin_isinf(x) 00673 # define CPLIsFinite(x) __builtin_isfinite(x) 00674 #else 00675 00676 #if defined(__cplusplus) && defined(__GNUC__) && defined(__linux) && !defined(__ANDROID__) 00677 /* so to not get warning about conversion from double to float with */ 00678 /* gcc -Wfloat-conversion when using isnan()/isinf() macros */ 00679 extern "C++" { 00680 static inline int CPLIsNan(float f) { return __isnanf(f); } 00681 static inline int CPLIsNan(double f) { return __isnan(f); } 00682 static inline int CPLIsInf(float f) { return __isinff(f); } 00683 static inline int CPLIsInf(double f) { return __isinf(f); } 00684 static inline int CPLIsFinite(float f) { return !__isnanf(f) && !__isinff(f); } 00685 static inline int CPLIsFinite(double f) { return !__isnan(f) && !__isinf(f); } 00686 } 00687 #else 00688 # define CPLIsNan(x) isnan(x) 00689 # if defined(isinf) || defined(__FreeBSD__) 00690 00691 # define CPLIsInf(x) isinf(x) 00692 00693 # define CPLIsFinite(x) (!isnan(x) && !isinf(x)) 00694 # elif defined(__sun__) 00695 # include <ieeefp.h> 00696 # define CPLIsInf(x) (!finite(x) && !isnan(x)) 00697 # define CPLIsFinite(x) finite(x) 00698 # else 00699 # define CPLIsInf(x) (0) 00700 # define CPLIsFinite(x) (!isnan(x)) 00701 # endif 00702 #endif 00703 #endif 00704 00706 /*--------------------------------------------------------------------- 00707 * CPL_LSB and CPL_MSB 00708 * Only one of these 2 macros should be defined and specifies the byte 00709 * ordering for the current platform. 00710 * This should be defined in the Makefile, but if it is not then 00711 * the default is CPL_LSB (Intel ordering, LSB first). 00712 *--------------------------------------------------------------------*/ 00713 #if defined(WORDS_BIGENDIAN) && !defined(CPL_MSB) && !defined(CPL_LSB) 00714 # define CPL_MSB 00715 #endif 00716 00717 #if ! ( defined(CPL_LSB) || defined(CPL_MSB) ) 00718 #define CPL_LSB 00719 #endif 00720 00721 #if defined(CPL_LSB) 00722 # define CPL_IS_LSB 1 00723 #else 00724 # define CPL_IS_LSB 0 00725 #endif 00726 00728 #ifdef __cplusplus 00729 00731 extern "C++" { 00732 00733 template <bool b> struct CPLStaticAssert {}; 00734 template<> struct CPLStaticAssert<true> 00735 { 00736 static void my_function() {} 00737 }; 00738 00739 } /* extern "C++" */ 00740 00741 #define CPL_STATIC_ASSERT(x) CPLStaticAssert<x>::my_function() 00742 #define CPL_STATIC_ASSERT_IF_AVAILABLE(x) CPL_STATIC_ASSERT(x) 00743 00744 #else /* __cplusplus */ 00745 00746 #define CPL_STATIC_ASSERT_IF_AVAILABLE(x) 00747 00748 #endif /* __cplusplus */ 00749 00751 /*--------------------------------------------------------------------- 00752 * Little endian <==> big endian byte swap macros. 00753 *--------------------------------------------------------------------*/ 00754 00756 #define CPL_SWAP16(x) ((GUInt16)( ((GUInt16)(x) << 8) | ((GUInt16)(x) >> 8) )) 00757 00758 #if defined(HAVE_GCC_BSWAP) && (defined(__i386__) || defined(__x86_64__)) 00759 /* Could potentially be extended to other architectures but must be checked */ 00760 /* that the intrinsic is indeed efficient */ 00761 /* GCC (at least 4.6 or above) need that include */ 00762 #include <x86intrin.h> 00764 #define CPL_SWAP32(x) ((GUInt32)(__builtin_bswap32((GUInt32)(x)))) 00765 00766 #define CPL_SWAP64(x) ((GUInt64)(__builtin_bswap64((GUInt64)(x)))) 00767 #elif defined(_MSC_VER) 00768 #define CPL_SWAP32(x) ((GUInt32)(_byteswap_ulong((GUInt32)(x)))) 00769 #define CPL_SWAP64(x) ((GUInt64)(_byteswap_uint64((GUInt64)(x)))) 00770 #else 00771 00772 #define CPL_SWAP32(x) \ 00773 ((GUInt32)( \ 00774 (((GUInt32)(x) & (GUInt32)0x000000ffUL) << 24) | \ 00775 (((GUInt32)(x) & (GUInt32)0x0000ff00UL) << 8) | \ 00776 (((GUInt32)(x) & (GUInt32)0x00ff0000UL) >> 8) | \ 00777 (((GUInt32)(x) & (GUInt32)0xff000000UL) >> 24) )) 00778 00780 #define CPL_SWAP64(x) \ 00781 (((GUInt64)(CPL_SWAP32((GUInt32)(x))) << 32) | \ 00782 (GUInt64)(CPL_SWAP32((GUInt32)((GUInt64)(x) >> 32)))) 00783 00784 #endif 00785 00787 #define CPL_SWAP16PTR(x) \ 00788 { \ 00789 GByte byTemp, *_pabyDataT = (GByte *) (x); \ 00790 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2); \ 00791 \ 00792 byTemp = _pabyDataT[0]; \ 00793 _pabyDataT[0] = _pabyDataT[1]; \ 00794 _pabyDataT[1] = byTemp; \ 00795 } 00796 00797 #if defined(MAKE_SANITIZE_HAPPY) || !(defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)) 00798 00800 #define CPL_SWAP32PTR(x) \ 00801 { \ 00802 GByte byTemp, *_pabyDataT = (GByte *) (x); \ 00803 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4); \ 00804 \ 00805 byTemp = _pabyDataT[0]; \ 00806 _pabyDataT[0] = _pabyDataT[3]; \ 00807 _pabyDataT[3] = byTemp; \ 00808 byTemp = _pabyDataT[1]; \ 00809 _pabyDataT[1] = _pabyDataT[2]; \ 00810 _pabyDataT[2] = byTemp; \ 00811 } 00812 00814 #define CPL_SWAP64PTR(x) \ 00815 { \ 00816 GByte byTemp, *_pabyDataT = (GByte *) (x); \ 00817 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8); \ 00818 \ 00819 byTemp = _pabyDataT[0]; \ 00820 _pabyDataT[0] = _pabyDataT[7]; \ 00821 _pabyDataT[7] = byTemp; \ 00822 byTemp = _pabyDataT[1]; \ 00823 _pabyDataT[1] = _pabyDataT[6]; \ 00824 _pabyDataT[6] = byTemp; \ 00825 byTemp = _pabyDataT[2]; \ 00826 _pabyDataT[2] = _pabyDataT[5]; \ 00827 _pabyDataT[5] = byTemp; \ 00828 byTemp = _pabyDataT[3]; \ 00829 _pabyDataT[3] = _pabyDataT[4]; \ 00830 _pabyDataT[4] = byTemp; \ 00831 } 00832 00833 #else 00834 00836 #define CPL_SWAP32PTR(x) \ 00837 { \ 00838 GUInt32 _n32; \ 00839 void* _lx = x; \ 00840 memcpy(&_n32, _lx, 4); \ 00841 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4); \ 00842 _n32 = CPL_SWAP32(_n32); \ 00843 memcpy(_lx, &_n32, 4); \ 00844 } 00845 00847 #define CPL_SWAP64PTR(x) \ 00848 { \ 00849 GUInt64 _n64; \ 00850 void* _lx = x; \ 00851 memcpy(&_n64, _lx, 8); \ 00852 CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8); \ 00853 _n64 = CPL_SWAP64(_n64); \ 00854 memcpy(_lx, &_n64, 8); \ 00855 } 00856 00857 #endif 00858 00860 #define CPL_SWAPDOUBLE(p) CPL_SWAP64PTR(p) 00861 00862 #ifdef CPL_MSB 00863 # define CPL_MSBWORD16(x) (x) 00864 # define CPL_LSBWORD16(x) CPL_SWAP16(x) 00865 # define CPL_MSBWORD32(x) (x) 00866 # define CPL_LSBWORD32(x) CPL_SWAP32(x) 00867 # define CPL_MSBPTR16(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2) 00868 # define CPL_LSBPTR16(x) CPL_SWAP16PTR(x) 00869 # define CPL_MSBPTR32(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4) 00870 # define CPL_LSBPTR32(x) CPL_SWAP32PTR(x) 00871 # define CPL_MSBPTR64(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8) 00872 # define CPL_LSBPTR64(x) CPL_SWAP64PTR(x) 00873 #else 00874 00875 # define CPL_LSBWORD16(x) (x) 00876 00877 # define CPL_MSBWORD16(x) CPL_SWAP16(x) 00878 00879 # define CPL_LSBWORD32(x) (x) 00880 00881 # define CPL_MSBWORD32(x) CPL_SWAP32(x) 00882 00883 # define CPL_LSBPTR16(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2) 00884 00885 # define CPL_MSBPTR16(x) CPL_SWAP16PTR(x) 00886 00887 # define CPL_LSBPTR32(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4) 00888 00889 # define CPL_MSBPTR32(x) CPL_SWAP32PTR(x) 00890 00891 # define CPL_LSBPTR64(x) CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8) 00892 00893 # define CPL_MSBPTR64(x) CPL_SWAP64PTR(x) 00894 #endif 00895 00899 #define CPL_LSBINT16PTR(x) ((*(GByte*)(x)) | (*(((GByte*)(x))+1) << 8)) 00900 00904 #define CPL_LSBINT32PTR(x) ((*(GByte*)(x)) | (*(((GByte*)(x))+1) << 8) | \ 00905 (*(((GByte*)(x))+2) << 16) | (*(((GByte*)(x))+3) << 24)) 00906 00908 #define CPL_LSBSINT16PTR(x) ((GInt16) CPL_LSBINT16PTR(x)) 00909 00911 #define CPL_LSBUINT16PTR(x) ((GUInt16)CPL_LSBINT16PTR(x)) 00912 00914 #define CPL_LSBSINT32PTR(x) ((GInt32) CPL_LSBINT32PTR(x)) 00915 00917 #define CPL_LSBUINT32PTR(x) ((GUInt32)CPL_LSBINT32PTR(x)) 00918 00920 /* Utility macro to explicitly mark intentionally unreferenced parameters. */ 00921 #ifndef UNREFERENCED_PARAM 00922 # ifdef UNREFERENCED_PARAMETER /* May be defined by Windows API */ 00923 # define UNREFERENCED_PARAM(param) UNREFERENCED_PARAMETER(param) 00924 # else 00925 # define UNREFERENCED_PARAM(param) ((void)param) 00926 # endif /* UNREFERENCED_PARAMETER */ 00927 #endif /* UNREFERENCED_PARAM */ 00928 00930 /*********************************************************************** 00931 * Define CPL_CVSID() macro. It can be disabled during a build by 00932 * defining DISABLE_CVSID in the compiler options. 00933 * 00934 * The cvsid_aw() function is just there to prevent reports of cpl_cvsid() 00935 * being unused. 00936 */ 00937 00939 #ifndef DISABLE_CVSID 00940 #if defined(__GNUC__) && __GNUC__ >= 4 00941 # define CPL_CVSID(string) static const char cpl_cvsid[] __attribute__((used)) = string; 00942 #else 00943 # define CPL_CVSID(string) static const char cpl_cvsid[] = string; \ 00944 static const char *cvsid_aw() { return( cvsid_aw() ? NULL : cpl_cvsid ); } 00945 #endif 00946 #else 00947 # define CPL_CVSID(string) 00948 #endif 00949 00951 /* We exclude mingw64 4.6 which seems to be broken regarding this */ 00952 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP) && !(defined(__MINGW64__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6) 00953 00954 # define CPL_NULL_TERMINATED __attribute__((__sentinel__)) 00955 #else 00956 00957 # define CPL_NULL_TERMINATED 00958 #endif 00959 00960 #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP) 00961 00962 #define CPL_PRINT_FUNC_FORMAT( format_idx, arg_idx ) __attribute__((__format__ (__printf__, format_idx, arg_idx))) 00963 00964 #define CPL_SCAN_FUNC_FORMAT( format_idx, arg_idx ) __attribute__((__format__ (__scanf__, format_idx, arg_idx))) 00965 #else 00966 00967 #define CPL_PRINT_FUNC_FORMAT( format_idx, arg_idx ) 00968 00969 #define CPL_SCAN_FUNC_FORMAT( format_idx, arg_idx ) 00970 #endif 00971 00972 #if defined(_MSC_VER) && _MSC_VER >= 1400 && (defined(GDAL_COMPILATION) || defined(CPL_ENABLE_MSVC_ANNOTATIONS)) 00973 #include <sal.h> 00974 # if _MSC_VER > 1400 00975 00977 # define CPL_FORMAT_STRING(arg) _Printf_format_string_ arg 00978 00980 # define CPL_SCANF_FORMAT_STRING(arg) _Scanf_format_string_ arg 00981 # else 00982 00983 # define CPL_FORMAT_STRING(arg) __format_string arg 00984 00985 # define CPL_SCANF_FORMAT_STRING(arg) arg 00986 # endif 00987 #else 00988 00989 # define CPL_FORMAT_STRING(arg) arg 00990 00991 # define CPL_SCANF_FORMAT_STRING(arg) arg 00992 #endif /* defined(_MSC_VER) && _MSC_VER >= 1400 && defined(GDAL_COMPILATION) */ 00993 00994 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP) 00995 00996 #define CPL_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 00997 #else 00998 00999 #define CPL_WARN_UNUSED_RESULT 01000 #endif 01001 01002 #if defined(__GNUC__) && __GNUC__ >= 4 01003 01004 # define CPL_UNUSED __attribute((__unused__)) 01005 #else 01006 /* TODO: add cases for other compilers */ 01008 # define CPL_UNUSED 01009 #endif 01010 01011 #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP) 01012 01013 #define CPL_NO_RETURN __attribute__((noreturn)) 01014 #else 01015 01016 #define CPL_NO_RETURN 01017 #endif 01018 01020 /* Clang __has_attribute */ 01021 #ifndef __has_attribute 01022 #define __has_attribute(x) 0 // Compatibility with non-clang compilers. 01023 #endif 01024 01027 #if ((defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) || __has_attribute(returns_nonnull)) && !defined(DOXYGEN_SKIP) && !defined(__INTEL_COMPILER) 01028 01029 # define CPL_RETURNS_NONNULL __attribute__((returns_nonnull)) 01030 #else 01031 01032 # define CPL_RETURNS_NONNULL 01033 #endif 01034 01035 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP) 01036 01037 #define CPL_RESTRICT __restrict__ 01038 #else 01039 01040 #define CPL_RESTRICT 01041 #endif 01042 01043 #ifdef __cplusplus 01044 01045 #if HAVE_CXX11 || _MSC_VER >= 1500 01046 01049 # define CPL_OVERRIDE override 01050 01051 #else 01052 01055 # define CPL_OVERRIDE 01056 01057 /* For GDAL source compilation only, ignore override if non C++11 compiler */ 01058 #ifdef GDAL_COMPILATION 01059 # define override 01060 #endif 01061 01062 #endif /* HAVE_CXX11 || _MSC_VER >= 1500 */ 01063 01064 #if HAVE_CXX11 01065 01066 # define CPL_FINAL final 01067 01073 # define CPL_DISALLOW_COPY_ASSIGN(ClassName) \ 01074 ClassName( const ClassName & ) = delete; \ 01075 ClassName &operator=( const ClassName & ) = delete; 01076 #else 01077 01078 # define CPL_FINAL 01079 01085 # define CPL_DISALLOW_COPY_ASSIGN(ClassName) \ 01086 ClassName( const ClassName & ); \ 01087 ClassName &operator=( const ClassName & ); 01088 #endif /* HAVE_CXX11 */ 01089 01090 #endif /* __cplusplus */ 01091 01092 #if !defined(DOXYGEN_SKIP) 01093 #if defined(__has_extension) 01094 #if __has_extension(attribute_deprecated_with_message) 01095 /* Clang extension */ 01096 #define CPL_WARN_DEPRECATED(x) __attribute__ ((deprecated(x))) 01097 #else 01098 #define CPL_WARN_DEPRECATED(x) 01099 #endif 01100 #elif defined(__GNUC__) 01101 #define CPL_WARN_DEPRECATED(x) __attribute__ ((deprecated)) 01102 #else 01103 #define CPL_WARN_DEPRECATED(x) 01104 #endif 01105 #endif 01106 01107 #if !defined(_MSC_VER) && !defined(__APPLE__) && !defined(_FORTIFY_SOURCE) 01108 CPL_C_START 01109 # if defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF) 01110 int vsnprintf(char *str, size_t size, const char* fmt, va_list args) 01111 CPL_WARN_DEPRECATED("Use CPLvsnprintf() instead"); 01112 int snprintf(char *str, size_t size, const char* fmt, ...) 01113 CPL_PRINT_FUNC_FORMAT(3,4) 01114 CPL_WARN_DEPRECATED("Use CPLsnprintf() instead"); 01115 int sprintf(char *str, const char* fmt, ...) 01116 CPL_PRINT_FUNC_FORMAT(2, 3) 01117 CPL_WARN_DEPRECATED("Use CPLsnprintf() instead"); 01118 # elif defined(GDAL_COMPILATION) && !defined(DONT_DEPRECATE_SPRINTF) 01119 int sprintf(char *str, const char* fmt, ...) 01120 CPL_PRINT_FUNC_FORMAT(2, 3) 01121 CPL_WARN_DEPRECATED("Use snprintf() or CPLsnprintf() instead"); 01122 # endif /* defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF) */ 01123 CPL_C_END 01124 #endif /* !defined(_MSC_VER) && !defined(__APPLE__) */ 01125 01126 #if defined(MAKE_SANITIZE_HAPPY) || !(defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)) 01127 01128 #define CPL_CPU_REQUIRES_ALIGNED_ACCESS 01129 01130 #endif 01131 01132 #ifdef __cplusplus 01133 01134 #define CPL_ARRAYSIZE(array) \ 01135 ((sizeof(array) / sizeof(*(array))) / \ 01136 static_cast<size_t>(!(sizeof(array) % sizeof(*(array))))) 01137 01138 extern "C++" { 01139 template<class T> static void CPL_IGNORE_RET_VAL(T) {} 01140 inline static bool CPL_TO_BOOL(int x) { return x != 0; } 01141 } /* extern "C++" */ 01142 01143 #endif /* __cplusplus */ 01144 01145 #if (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) || (defined(__clang__) && __clang_major__ >= 3)) && !defined(_MSC_VER)) 01146 #define HAVE_GCC_DIAGNOSTIC_PUSH 01147 #endif 01148 01149 #if ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) && !defined(_MSC_VER)) 01150 #define HAVE_GCC_SYSTEM_HEADER 01151 #endif 01152 01153 #if ((defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))) || __GNUC__ >= 7) && HAVE_CXX11 01154 01155 # define CPL_FALLTHROUGH [[clang::fallthrough]]; 01156 #else 01157 01158 # define CPL_FALLTHROUGH 01159 #endif 01160 01162 // Define DEBUG_BOOL to compile in "MSVC mode", ie error out when 01163 // a integer is assigned to a bool 01164 // WARNING: use only at compilation time, since it is know to not work 01165 // at runtime for unknown reasons (crash in MongoDB driver for example) 01166 #if defined(__cplusplus) && defined(DEBUG_BOOL) && !defined(DO_NOT_USE_DEBUG_BOOL) 01167 extern "C++" { 01168 class MSVCPedanticBool 01169 { 01170 01171 friend bool operator== (const bool& one, const MSVCPedanticBool& other); 01172 friend bool operator!= (const bool& one, const MSVCPedanticBool& other); 01173 01174 bool b; 01175 MSVCPedanticBool(int bIn); 01176 01177 public: 01178 /* b not initialized on purpose in default ctor to flag use. */ 01179 /* cppcheck-suppress uninitMemberVar */ 01180 MSVCPedanticBool() {} 01181 MSVCPedanticBool(bool bIn) : b(bIn) {} 01182 MSVCPedanticBool(const MSVCPedanticBool& other) : b(other.b) {} 01183 01184 MSVCPedanticBool& operator= (const MSVCPedanticBool& other) { b = other.b; return *this; } 01185 MSVCPedanticBool& operator&= (const MSVCPedanticBool& other) { b &= other.b; return *this; } 01186 MSVCPedanticBool& operator|= (const MSVCPedanticBool& other) { b |= other.b; return *this; } 01187 01188 bool operator== (const bool& other) const { return b == other; } 01189 bool operator!= (const bool& other) const { return b != other; } 01190 bool operator== (const MSVCPedanticBool& other) const { return b == other.b; } 01191 bool operator!= (const MSVCPedanticBool& other) const { return b != other.b; } 01192 01193 bool operator! () const { return !b; } 01194 operator bool() const { return b; } 01195 operator int() const { return b; } 01196 }; 01197 01198 inline bool operator== (const bool& one, const MSVCPedanticBool& other) { return one == other.b; } 01199 inline bool operator!= (const bool& one, const MSVCPedanticBool& other) { return one != other.b; } 01200 01201 /* We must include all C++ stuff before to avoid issues with templates that use bool */ 01202 #include <vector> 01203 #include <map> 01204 #include <set> 01205 #include <string> 01206 #include <cstddef> 01207 #include <limits> 01208 #include <sstream> 01209 #include <fstream> 01210 #include <algorithm> 01211 01212 } /* extern C++ */ 01213 01214 #undef FALSE 01215 #define FALSE false 01216 #undef TRUE 01217 #define TRUE true 01218 01219 /* In the very few cases we really need a "simple" type, fallback to bool */ 01220 #define EMULATED_BOOL int 01221 01222 /* Use our class instead of bool */ 01223 #define bool MSVCPedanticBool 01224 01225 /* "volatile bool" with the below substitution doesn't really work. */ 01226 /* Just for the sake of the debug, we don't really need volatile */ 01227 #define VOLATILE_BOOL bool 01228 01229 #else /* defined(__cplusplus) && defined(DEBUG_BOOL) */ 01230 01231 #ifndef FALSE 01232 # define FALSE 0 01233 #endif 01234 01235 #ifndef TRUE 01236 # define TRUE 1 01237 #endif 01238 01239 #define EMULATED_BOOL bool 01240 #define VOLATILE_BOOL volatile bool 01241 01242 #endif /* defined(__cplusplus) && defined(DEBUG_BOOL) */ 01243 01245 #endif /* ndef CPL_BASE_H_INCLUDED */
1.7.6.1.