LCOV - code coverage report
Current view: top level - port - cpl_port.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 73 73 100.0 %
Date: 2026-03-25 02:32:38 Functions: 152 160 95.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  CPL - Common Portability Library
       4             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       5             :  * Purpose:  Include file providing low level portability services for CPL.
       6             :  *           This should be the first include file for any CPL based code.
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 1998, 2005, Frank Warmerdam <warmerdam@pobox.com>
      10             :  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #ifndef CPL_BASE_H_INCLUDED
      16             : #define CPL_BASE_H_INCLUDED
      17             : 
      18             : /**
      19             :  * \file cpl_port.h
      20             :  *
      21             :  * Core portability definitions for CPL.
      22             :  *
      23             :  */
      24             : 
      25             : /* -------------------------------------------------------------------- */
      26             : /*      The following apparently allow you to use strcpy() and other    */
      27             : /*      functions judged "unsafe" by microsoft in VS 8 (2005).          */
      28             : /* -------------------------------------------------------------------- */
      29             : #ifdef _MSC_VER
      30             : #ifndef _CRT_SECURE_NO_DEPRECATE
      31             : #define _CRT_SECURE_NO_DEPRECATE
      32             : #endif
      33             : #ifndef _CRT_NONSTDC_NO_DEPRECATE
      34             : #define _CRT_NONSTDC_NO_DEPRECATE
      35             : #endif
      36             : #endif
      37             : 
      38             : #include "cpl_config.h"
      39             : 
      40             : /* ==================================================================== */
      41             : /*      A few sanity checks, mainly to detect problems that sometimes   */
      42             : /*      arise with bad configured cross-compilation.                    */
      43             : /* ==================================================================== */
      44             : 
      45             : #if !defined(SIZEOF_INT) || SIZEOF_INT != 4
      46             : #error "Unexpected value for SIZEOF_INT"
      47             : #endif
      48             : 
      49             : #if !defined(SIZEOF_UNSIGNED_LONG) ||                                          \
      50             :     (SIZEOF_UNSIGNED_LONG != 4 && SIZEOF_UNSIGNED_LONG != 8)
      51             : #error "Unexpected value for SIZEOF_UNSIGNED_LONG"
      52             : #endif
      53             : 
      54             : #if !defined(SIZEOF_VOIDP)
      55             : #error "Unexpected value for SIZEOF_VOIDP"
      56             : #endif
      57             : 
      58             : /* ==================================================================== */
      59             : /*      This will disable most WIN32 stuff in a Cygnus build which      */
      60             : /*      defines unix to 1.                                              */
      61             : /* ==================================================================== */
      62             : 
      63             : #ifdef unix
      64             : #undef WIN32
      65             : #endif
      66             : 
      67             : /*! @cond Doxygen_Suppress */
      68             : #if defined(VSI_NEED_LARGEFILE64_SOURCE) && !defined(_LARGEFILE64_SOURCE)
      69             : #define _LARGEFILE64_SOURCE 1
      70             : #endif
      71             : 
      72             : /* ==================================================================== */
      73             : /*      If iconv() is available use extended recoding module.           */
      74             : /*      Stub implementation is always compiled in, because it works     */
      75             : /*      faster than iconv() for encodings it supports.                  */
      76             : /* ==================================================================== */
      77             : 
      78             : #if defined(HAVE_ICONV)
      79             : #define CPL_RECODE_ICONV
      80             : #endif
      81             : 
      82             : #define CPL_RECODE_STUB
      83             : /*! @endcond */
      84             : 
      85             : /* ==================================================================== */
      86             : /*      MinGW stuff                                                     */
      87             : /* ==================================================================== */
      88             : 
      89             : /* Needed for std=c11 on Solaris to have strcasecmp() */
      90             : #if defined(GDAL_COMPILATION) && defined(__sun__) &&                           \
      91             :     (__STDC_VERSION__ + 0) >= 201112L && (_XOPEN_SOURCE + 0) < 600
      92             : #ifdef _XOPEN_SOURCE
      93             : #undef _XOPEN_SOURCE
      94             : #endif
      95             : #define _XOPEN_SOURCE 600
      96             : #endif
      97             : 
      98             : /* ==================================================================== */
      99             : /*      Standard include files.                                         */
     100             : /* ==================================================================== */
     101             : 
     102             : #include <stdio.h>
     103             : #include <stdlib.h>
     104             : #include <math.h>
     105             : #include <stdarg.h>
     106             : #include <string.h>
     107             : #include <ctype.h>
     108             : #include <limits.h>
     109             : 
     110             : #include <time.h>
     111             : 
     112             : #include <errno.h>
     113             : 
     114             : #ifdef HAVE_LOCALE_H
     115             : #include <locale.h>
     116             : #endif
     117             : 
     118             : #ifdef HAVE_DIRECT_H
     119             : #include <direct.h>
     120             : #endif
     121             : 
     122             : #if !defined(_WIN32)
     123             : #include <strings.h>
     124             : #endif
     125             : 
     126             : #ifdef __cplusplus
     127             : extern "C++"
     128             : {
     129             : #include <cmath>
     130             : }
     131             : #endif
     132             : 
     133             : /* ==================================================================== */
     134             : /*      Base portability stuff ... this stuff may need to be            */
     135             : /*      modified for new platforms.                                     */
     136             : /* ==================================================================== */
     137             : 
     138             : /* MSVC fails to define a decent value of __cplusplus. Try to target VS2015*/
     139             : /* as a minimum */
     140             : 
     141             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
     142             : #if !(__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
     143             : #error Must have C++11 or newer.
     144             : #endif
     145             : #endif /* __cplusplus */
     146             : 
     147             : /*---------------------------------------------------------------------
     148             :  *        types for 16 and 32 bits integers, etc...
     149             :  *--------------------------------------------------------------------*/
     150             : #if UINT_MAX == 65535
     151             : typedef long GInt32;
     152             : typedef unsigned long GUInt32;
     153             : #else
     154             : /** Int32 type */
     155             : typedef int GInt32;
     156             : /** Unsigned int32 type */
     157             : typedef unsigned int GUInt32;
     158             : #endif
     159             : 
     160             : /** Int16 type */
     161             : typedef short GInt16;
     162             : /** Unsigned int16 type */
     163             : typedef unsigned short GUInt16;
     164             : /** Unsigned byte type */
     165             : typedef unsigned char GByte;
     166             : /** Signed int8 type */
     167             : typedef signed char GInt8;
     168             : /* hack for PDF driver and poppler >= 0.15.0 that defines incompatible "typedef
     169             :  * bool GBool" */
     170             : /* in include/poppler/goo/gtypes.h */
     171             : #ifndef CPL_GBOOL_DEFINED
     172             : /*! @cond Doxygen_Suppress */
     173             : #define CPL_GBOOL_DEFINED
     174             : /*! @endcond */
     175             : /** Type for boolean values (alias to int) */
     176             : typedef int GBool;
     177             : #endif
     178             : 
     179             : /*! @cond Doxygen_Suppress */
     180             : #ifdef __cplusplus
     181             : #define CPL_STATIC_CAST(type, expr) static_cast<type>(expr)
     182             : #define CPL_REINTERPRET_CAST(type, expr) reinterpret_cast<type>(expr)
     183             : #else
     184             : #define CPL_STATIC_CAST(type, expr) ((type)(expr))
     185             : #define CPL_REINTERPRET_CAST(type, expr) ((type)(expr))
     186             : #endif
     187             : /*! @endcond */
     188             : 
     189             : /* -------------------------------------------------------------------- */
     190             : /*      64bit support                                                   */
     191             : /* -------------------------------------------------------------------- */
     192             : 
     193             : /** Large signed integer type (generally 64-bit integer type).
     194             :  *  Use GInt64 when exactly 64 bit is needed */
     195             : typedef long long GIntBig;
     196             : /** Large unsigned integer type (generally 64-bit unsigned integer type).
     197             :  *  Use GUInt64 when exactly 64 bit is needed */
     198             : typedef unsigned long long GUIntBig;
     199             : 
     200             : /** Minimum GIntBig value */
     201             : #define GINTBIG_MIN (CPL_STATIC_CAST(GIntBig, 0x80000000) << 32)
     202             : /** Maximum GIntBig value */
     203             : #define GINTBIG_MAX ((CPL_STATIC_CAST(GIntBig, 0x7FFFFFFF) << 32) | 0xFFFFFFFFU)
     204             : /** Maximum GUIntBig value */
     205             : #define GUINTBIG_MAX                                                           \
     206             :     ((CPL_STATIC_CAST(GUIntBig, 0xFFFFFFFFU) << 32) | 0xFFFFFFFFU)
     207             : 
     208             : /*! @cond Doxygen_Suppress */
     209             : #define CPL_HAS_GINT64 1
     210             : /*! @endcond */
     211             : 
     212             : /* Note: we might want to use instead int64_t / uint64_t if they are available
     213             :  */
     214             : 
     215             : /** Signed 64 bit integer type */
     216             : typedef GIntBig GInt64;
     217             : /** Unsigned 64 bit integer type */
     218             : typedef GUIntBig GUInt64;
     219             : 
     220             : /** Minimum GInt64 value */
     221             : #define GINT64_MIN GINTBIG_MIN
     222             : /** Maximum GInt64 value */
     223             : #define GINT64_MAX GINTBIG_MAX
     224             : /** Minimum GUInt64 value */
     225             : #define GUINT64_MAX GUINTBIG_MAX
     226             : 
     227             : #if SIZEOF_VOIDP > 8
     228             : #include <stddef.h>  // ptrdiff_t
     229             : /** Integer type large enough to hold the difference between 2 addresses */
     230             : typedef ptrdiff_t GPtrDiff_t;
     231             : #elif SIZEOF_VOIDP == 8
     232             : /** Integer type large enough to hold the difference between 2 addresses */
     233             : typedef GIntBig GPtrDiff_t;
     234             : #else
     235             : /** Integer type large enough to hold the difference between 2 addresses */
     236             : typedef int GPtrDiff_t;
     237             : #endif
     238             : 
     239             : #ifdef GDAL_COMPILATION
     240             : #include <stdint.h>
     241             : typedef uintptr_t GUIntptr_t;
     242             : #define CPL_IS_ALIGNED(ptr, quant)                                             \
     243             :     ((CPL_REINTERPRET_CAST(GUIntptr_t, CPL_STATIC_CAST(const void *, ptr)) %   \
     244             :       (quant)) == 0)
     245             : 
     246             : #endif
     247             : 
     248             : #if (defined(__MSVCRT__) && !(defined(__MINGW64__) && __GNUC__ >= 10)) ||      \
     249             :     (defined(_WIN32) && defined(_MSC_VER))
     250             : #define CPL_FRMT_GB_WITHOUT_PREFIX "I64"
     251             : #else
     252             : /** Printf formatting suffix for GIntBig */
     253             : #define CPL_FRMT_GB_WITHOUT_PREFIX "ll"
     254             : #endif
     255             : 
     256             : /** Printf formatting for GIntBig */
     257             : #define CPL_FRMT_GIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "d"
     258             : /** Printf formatting for GUIntBig */
     259             : #define CPL_FRMT_GUIB "%" CPL_FRMT_GB_WITHOUT_PREFIX "u"
     260             : 
     261             : /*! @cond Doxygen_Suppress */
     262             : #ifdef COMPAT_WITH_ICC_CONVERSION_CHECK
     263             : #define CPL_INT64_FITS_ON_INT32(x) ((x) >= INT_MIN && (x) <= INT_MAX)
     264             : #else
     265             : #define CPL_INT64_FITS_ON_INT32(x)                                             \
     266             :     (CPL_STATIC_CAST(GIntBig, CPL_STATIC_CAST(int, x)) == (x))
     267             : #endif
     268             : /*! @endcond */
     269             : 
     270             : /* ==================================================================== */
     271             : /*      Other standard services.                                        */
     272             : /* ==================================================================== */
     273             : #ifdef __cplusplus
     274             : /** Macro to start a block of C symbols */
     275             : #define CPL_C_START                                                            \
     276             :     extern "C"                                                                 \
     277             :     {
     278             : /** Macro to end a block of C symbols */
     279             : #define CPL_C_END }
     280             : #else
     281             : #define CPL_C_START
     282             : #define CPL_C_END
     283             : #endif
     284             : 
     285             : #ifndef CPL_DLL
     286             : #if defined(_MSC_VER) && !defined(CPL_DISABLE_DLL)
     287             : #ifdef GDAL_COMPILATION
     288             : #define CPL_DLL __declspec(dllexport)
     289             : #else
     290             : #define CPL_DLL
     291             : #endif
     292             : #define CPL_INTERNAL
     293             : #else
     294             : #if defined(USE_GCC_VISIBILITY_FLAG)
     295             : #define CPL_DLL __attribute__((visibility("default")))
     296             : #if !defined(__MINGW32__)
     297             : #define CPL_INTERNAL __attribute__((visibility("hidden")))
     298             : #else
     299             : #define CPL_INTERNAL
     300             : #endif
     301             : #else
     302             : #define CPL_DLL
     303             : #define CPL_INTERNAL
     304             : #endif
     305             : #endif
     306             : 
     307             : // Marker for unstable API
     308             : #define CPL_UNSTABLE_API CPL_DLL
     309             : 
     310             : #endif
     311             : 
     312             : /*! @cond Doxygen_Suppress */
     313             : /* Should optional (normally private) interfaces be exported? */
     314             : #ifdef CPL_OPTIONAL_APIS
     315             : #define CPL_ODLL CPL_DLL
     316             : #else
     317             : #define CPL_ODLL
     318             : #endif
     319             : /*! @endcond */
     320             : 
     321             : #ifndef CPL_STDCALL
     322             : #if defined(_MSC_VER) && !defined(CPL_DISABLE_STDCALL)
     323             : #define CPL_STDCALL __stdcall
     324             : #else
     325             : #define CPL_STDCALL
     326             : #endif
     327             : #endif
     328             : 
     329             : /*! @cond Doxygen_Suppress */
     330             : #ifdef _MSC_VER
     331             : #define FORCE_CDECL __cdecl
     332             : #else
     333             : #define FORCE_CDECL
     334             : #endif
     335             : /*! @endcond */
     336             : 
     337             : /*! @cond Doxygen_Suppress */
     338             : /* TODO : support for other compilers needed */
     339             : #if (defined(__GNUC__) && !defined(__NO_INLINE__)) || defined(_MSC_VER)
     340             : #define HAS_CPL_INLINE 1
     341             : #define CPL_INLINE __inline
     342             : #elif defined(__SUNPRO_CC)
     343             : #define HAS_CPL_INLINE 1
     344             : #define CPL_INLINE inline
     345             : #else
     346             : #define CPL_INLINE
     347             : #endif
     348             : /*! @endcond*/
     349             : 
     350             : /** Macro to compute the minimum of 2 values */
     351             : #define CPL_MIN(a, b) (((a) < (b)) ? (a) : (b))
     352             : /** Macro to compute the maximum of 2 values */
     353             : #define CPL_MAX(a, b) (((a) > (b)) ? (a) : (b))
     354             : 
     355             : /** Macro to compute the absolute value */
     356             : #define CPL_ABS(x) (((x) < 0) ? (-1 * (x)) : (x))
     357             : 
     358             : /*! @cond Doxygen_Suppress */
     359             : 
     360             : #if defined(GDAL_COMPILATION)
     361             : #ifndef M_PI
     362             : #define M_PI 3.14159265358979323846
     363             : /* 3.1415926535897932384626433832795 */
     364             : #endif
     365             : 
     366             : #endif
     367             : /*! @endcond*/
     368             : 
     369             : /* -------------------------------------------------------------------- */
     370             : /*      Macro to test equality of two floating point values.            */
     371             : /*      We use fabs() function instead of ABS() macro to avoid side     */
     372             : /*      effects.                                                        */
     373             : /* -------------------------------------------------------------------- */
     374             : /*! @cond Doxygen_Suppress */
     375             : #ifndef CPLIsEqual
     376             : #define CPLIsEqual(x, y) (fabs((x) - (y)) < 0.0000000000001)
     377             : #endif
     378             : /*! @endcond */
     379             : 
     380             : /* -------------------------------------------------------------------- */
     381             : /*      Provide macros for case insensitive string comparisons.         */
     382             : /* -------------------------------------------------------------------- */
     383             : #ifndef EQUAL
     384             : 
     385             : #if defined(AFL_FRIENDLY) && defined(__GNUC__)
     386             : 
     387             : static inline int CPL_afl_friendly_memcmp(const void *ptr1, const void *ptr2,
     388             :                                           size_t len)
     389             :     __attribute__((always_inline));
     390             : 
     391             : static inline int CPL_afl_friendly_memcmp(const void *ptr1, const void *ptr2,
     392             :                                           size_t len)
     393             : {
     394             :     const unsigned char *bptr1 = (const unsigned char *)ptr1;
     395             :     const unsigned char *bptr2 = (const unsigned char *)ptr2;
     396             :     while (len--)
     397             :     {
     398             :         unsigned char b1 = *(bptr1++);
     399             :         unsigned char b2 = *(bptr2++);
     400             :         if (b1 != b2)
     401             :             return b1 - b2;
     402             :     }
     403             :     return 0;
     404             : }
     405             : 
     406             : static inline int CPL_afl_friendly_strcmp(const char *ptr1, const char *ptr2)
     407             :     __attribute__((always_inline));
     408             : 
     409             : static inline int CPL_afl_friendly_strcmp(const char *ptr1, const char *ptr2)
     410             : {
     411             :     const unsigned char *usptr1 = (const unsigned char *)ptr1;
     412             :     const unsigned char *usptr2 = (const unsigned char *)ptr2;
     413             :     while (1)
     414             :     {
     415             :         unsigned char ch1 = *(usptr1++);
     416             :         unsigned char ch2 = *(usptr2++);
     417             :         if (ch1 == 0 || ch1 != ch2)
     418             :             return ch1 - ch2;
     419             :     }
     420             : }
     421             : 
     422             : static inline int CPL_afl_friendly_strncmp(const char *ptr1, const char *ptr2,
     423             :                                            size_t len)
     424             :     __attribute__((always_inline));
     425             : 
     426             : static inline int CPL_afl_friendly_strncmp(const char *ptr1, const char *ptr2,
     427             :                                            size_t len)
     428             : {
     429             :     const unsigned char *usptr1 = (const unsigned char *)ptr1;
     430             :     const unsigned char *usptr2 = (const unsigned char *)ptr2;
     431             :     while (len--)
     432             :     {
     433             :         unsigned char ch1 = *(usptr1++);
     434             :         unsigned char ch2 = *(usptr2++);
     435             :         if (ch1 == 0 || ch1 != ch2)
     436             :             return ch1 - ch2;
     437             :     }
     438             :     return 0;
     439             : }
     440             : 
     441             : static inline int CPL_afl_friendly_strcasecmp(const char *ptr1,
     442             :                                               const char *ptr2)
     443             :     __attribute__((always_inline));
     444             : 
     445             : static inline int CPL_afl_friendly_strcasecmp(const char *ptr1,
     446             :                                               const char *ptr2)
     447             : {
     448             :     const unsigned char *usptr1 = (const unsigned char *)ptr1;
     449             :     const unsigned char *usptr2 = (const unsigned char *)ptr2;
     450             :     while (1)
     451             :     {
     452             :         unsigned char ch1 = *(usptr1++);
     453             :         unsigned char ch2 = *(usptr2++);
     454             :         ch1 = (unsigned char)toupper(ch1);
     455             :         ch2 = (unsigned char)toupper(ch2);
     456             :         if (ch1 == 0 || ch1 != ch2)
     457             :             return ch1 - ch2;
     458             :     }
     459             : }
     460             : 
     461             : static inline int CPL_afl_friendly_strncasecmp(const char *ptr1,
     462             :                                                const char *ptr2, size_t len)
     463             :     __attribute__((always_inline));
     464             : 
     465             : static inline int CPL_afl_friendly_strncasecmp(const char *ptr1,
     466             :                                                const char *ptr2, size_t len)
     467             : {
     468             :     const unsigned char *usptr1 = (const unsigned char *)ptr1;
     469             :     const unsigned char *usptr2 = (const unsigned char *)ptr2;
     470             :     while (len--)
     471             :     {
     472             :         unsigned char ch1 = *(usptr1++);
     473             :         unsigned char ch2 = *(usptr2++);
     474             :         ch1 = (unsigned char)toupper(ch1);
     475             :         ch2 = (unsigned char)toupper(ch2);
     476             :         if (ch1 == 0 || ch1 != ch2)
     477             :             return ch1 - ch2;
     478             :     }
     479             :     return 0;
     480             : }
     481             : 
     482             : static inline char *CPL_afl_friendly_strstr(const char *haystack,
     483             :                                             const char *needle)
     484             :     __attribute__((always_inline));
     485             : 
     486             : static inline char *CPL_afl_friendly_strstr(const char *haystack,
     487             :                                             const char *needle)
     488             : {
     489             :     const char *ptr_haystack = haystack;
     490             :     while (1)
     491             :     {
     492             :         const char *ptr_haystack2 = ptr_haystack;
     493             :         const char *ptr_needle = needle;
     494             :         while (1)
     495             :         {
     496             :             char ch1 = *(ptr_haystack2++);
     497             :             char ch2 = *(ptr_needle++);
     498             :             if (ch2 == 0)
     499             :                 return (char *)ptr_haystack;
     500             :             if (ch1 != ch2)
     501             :                 break;
     502             :         }
     503             :         if (*ptr_haystack == 0)
     504             :             return NULL;
     505             :         ptr_haystack++;
     506             :     }
     507             : }
     508             : 
     509             : #undef strcmp
     510             : #undef strncmp
     511             : #define memcmp CPL_afl_friendly_memcmp
     512             : #define strcmp CPL_afl_friendly_strcmp
     513             : #define strncmp CPL_afl_friendly_strncmp
     514             : #define strcasecmp CPL_afl_friendly_strcasecmp
     515             : #define strncasecmp CPL_afl_friendly_strncasecmp
     516             : #define strstr CPL_afl_friendly_strstr
     517             : 
     518             : #endif /* defined(AFL_FRIENDLY) && defined(__GNUC__) */
     519             : 
     520             : #if defined(_WIN32)
     521             : #define STRCASECMP(a, b) (_stricmp(a, b))
     522             : #define STRNCASECMP(a, b, n) (_strnicmp(a, b, n))
     523             : #else
     524             : /** Alias for strcasecmp() */
     525             : #define STRCASECMP(a, b) (strcasecmp(a, b))
     526             : /** Alias for strncasecmp() */
     527             : #define STRNCASECMP(a, b, n) (strncasecmp(a, b, n))
     528             : #endif
     529             : /** Alias for strncasecmp() == 0 */
     530             : #define EQUALN(a, b, n) (STRNCASECMP(a, b, n) == 0)
     531             : /** Alias for strcasecmp() == 0 */
     532             : #define EQUAL(a, b) (STRCASECMP(a, b) == 0)
     533             : #endif
     534             : 
     535             : /*---------------------------------------------------------------------
     536             :  * Does a string "a" start with string "b".  Search is case-sensitive or,
     537             :  * with CI, it is a case-insensitive comparison.
     538             :  *--------------------------------------------------------------------- */
     539             : #ifndef STARTS_WITH_CI
     540             : /** Returns whether a starts with b */
     541             : #define STARTS_WITH(a, b) (strncmp(a, b, strlen(b)) == 0)
     542             : /** Returns whether a starts with b (case insensitive comparison) */
     543             : #define STARTS_WITH_CI(a, b) EQUALN(a, b, strlen(b))
     544             : #endif
     545             : 
     546             : /*! @cond Doxygen_Suppress */
     547             : #ifndef CPL_THREADLOCAL
     548             : #define CPL_THREADLOCAL
     549             : #endif
     550             : /*! @endcond */
     551             : 
     552             : /*! @cond Doxygen_Suppress */
     553             : #ifndef __cplusplus
     554             : /* -------------------------------------------------------------------- */
     555             : /*      Handle isnan() and isinf().  Note that isinf() and isnan()      */
     556             : /*      are supposed to be macros according to C99, defined in math.h   */
     557             : /*      Some systems (i.e. Tru64) don't have isinf() at all, so if      */
     558             : /*      the macro is not defined we just assume nothing is infinite.    */
     559             : /*      This may mean we have no real CPLIsInf() on systems with isinf()*/
     560             : /*      function but no corresponding macro, but I can live with        */
     561             : /*      that since it isn't that important a test.                      */
     562             : /* -------------------------------------------------------------------- */
     563             : #ifdef _MSC_VER
     564             : #include <float.h>
     565             : #define CPLIsNan(x) _isnan(x)
     566             : #define CPLIsInf(x) (!_isnan(x) && !_finite(x))
     567             : #define CPLIsFinite(x) _finite(x)
     568             : #elif defined(__GNUC__) &&                                                     \
     569             :     (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4))
     570             : /* When including <cmath> in C++11 the isnan() macro is undefined, so that */
     571             : /* std::isnan() can work (#6489). This is a GCC specific workaround for now. */
     572             : #define CPLIsNan(x) __builtin_isnan(x)
     573             : #define CPLIsInf(x) __builtin_isinf(x)
     574             : #define CPLIsFinite(x) __builtin_isfinite(x)
     575             : #elif defined(isinf) || defined(__FreeBSD__)
     576             : /** Return whether a floating-pointer number is nan */
     577             : #define CPLIsNan(x) isnan(x)
     578             : /** Return whether a floating-pointer number is +/- infinity */
     579             : #define CPLIsInf(x) isinf(x)
     580             : /** Return whether a floating-pointer number is finite */
     581             : #define CPLIsFinite(x) (!isnan(x) && !isinf(x))
     582             : #elif defined(__sun__)
     583             : #include <ieeefp.h>
     584             : #define CPLIsNan(x) isnan(x)
     585             : #define CPLIsInf(x) (!finite(x) && !isnan(x))
     586             : #define CPLIsFinite(x) finite(x)
     587             : #else
     588             : #define CPLIsNan(x) ((x) != (x))
     589             : #define CPLIsInf(x) (0)
     590             : #define CPLIsFinite(x) (!isnan(x))
     591             : #endif
     592             : #endif
     593             : /*! @endcond */
     594             : 
     595             : /*! @cond Doxygen_Suppress */
     596             : /*---------------------------------------------------------------------
     597             :  *                         CPL_LSB and CPL_MSB
     598             :  * Only one of these 2 macros should be defined and specifies the byte
     599             :  * ordering for the current platform.
     600             :  * This should be defined in the Makefile, but if it is not then
     601             :  * the default is CPL_LSB (Intel ordering, LSB first).
     602             :  *--------------------------------------------------------------------*/
     603             : #if defined(WORDS_BIGENDIAN) && !defined(CPL_MSB) && !defined(CPL_LSB)
     604             : #define CPL_MSB
     605             : #endif
     606             : 
     607             : #if !(defined(CPL_LSB) || defined(CPL_MSB))
     608             : #define CPL_LSB
     609             : #endif
     610             : 
     611             : #if defined(CPL_LSB)
     612             : #define CPL_IS_LSB 1
     613             : #else
     614             : #define CPL_IS_LSB 0
     615             : #endif
     616             : /*! @endcond */
     617             : 
     618             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
     619             : 
     620             : /*! @cond Doxygen_Suppress */
     621             : extern "C++"
     622             : {
     623             : 
     624             :     template <bool b> struct CPLStaticAssert
     625             :     {
     626             :     };
     627             : 
     628             :     template <> struct CPLStaticAssert<true>
     629             :     {
     630   239446244 :         static void my_function()
     631             :         {
     632   239446244 :         }
     633             :     };
     634             : 
     635             : } /* extern "C++" */
     636             : 
     637             : #define CPL_STATIC_ASSERT(x) CPLStaticAssert<x>::my_function()
     638             : #define CPL_STATIC_ASSERT_IF_AVAILABLE(x) CPL_STATIC_ASSERT(x)
     639             : 
     640             : #else /* __cplusplus */
     641             : 
     642             : #define CPL_STATIC_ASSERT_IF_AVAILABLE(x)
     643             : 
     644             : #endif /* __cplusplus */
     645             : /*! @endcond */
     646             : 
     647             : /*---------------------------------------------------------------------
     648             :  *        Little endian <==> big endian byte swap macros.
     649             :  *--------------------------------------------------------------------*/
     650             : 
     651             : /** Byte-swap a 16bit unsigned integer */
     652             : #define CPL_SWAP16(x)                                                          \
     653             :     CPL_STATIC_CAST(GUInt16, (CPL_STATIC_CAST(GUInt16, x) << 8) |              \
     654             :                                  (CPL_STATIC_CAST(GUInt16, x) >> 8))
     655             : 
     656             : #ifdef __GNUC__
     657             : /** Byte-swap a 32bit unsigned integer */
     658             : #define CPL_SWAP32(x)                                                          \
     659             :     CPL_STATIC_CAST(GUInt32, __builtin_bswap32(CPL_STATIC_CAST(GUInt32, x)))
     660             : /** Byte-swap a 64bit unsigned integer */
     661             : #define CPL_SWAP64(x)                                                          \
     662             :     CPL_STATIC_CAST(GUInt64, __builtin_bswap64(CPL_STATIC_CAST(GUInt64, x)))
     663             : #elif defined(_MSC_VER)
     664             : #define CPL_SWAP32(x)                                                          \
     665             :     CPL_STATIC_CAST(GUInt32, _byteswap_ulong(CPL_STATIC_CAST(GUInt32, x)))
     666             : #define CPL_SWAP64(x)                                                          \
     667             :     CPL_STATIC_CAST(GUInt64, _byteswap_uint64(CPL_STATIC_CAST(GUInt64, x)))
     668             : #else
     669             : /** Byte-swap a 32bit unsigned integer */
     670             : #define CPL_SWAP32(x)                                                          \
     671             :     CPL_STATIC_CAST(GUInt32,                                                   \
     672             :                     ((CPL_STATIC_CAST(GUInt32, x) & 0x000000ffU) << 24) |      \
     673             :                         ((CPL_STATIC_CAST(GUInt32, x) & 0x0000ff00U) << 8) |   \
     674             :                         ((CPL_STATIC_CAST(GUInt32, x) & 0x00ff0000U) >> 8) |   \
     675             :                         ((CPL_STATIC_CAST(GUInt32, x) & 0xff000000U) >> 24))
     676             : 
     677             : /** Byte-swap a 64bit unsigned integer */
     678             : #define CPL_SWAP64(x)                                                          \
     679             :     ((CPL_STATIC_CAST(GUInt64, CPL_SWAP32(CPL_STATIC_CAST(GUInt32, x)))        \
     680             :       << 32) |                                                                 \
     681             :      (CPL_STATIC_CAST(GUInt64,                                                 \
     682             :                       CPL_SWAP32(CPL_STATIC_CAST(                              \
     683             :                           GUInt32, CPL_STATIC_CAST(GUInt64, x) >> 32)))))
     684             : 
     685             : #endif
     686             : 
     687             : /** Byte-swap a 16 bit pointer */
     688             : #define CPL_SWAP16PTR(x)                                                       \
     689             :     do                                                                         \
     690             :     {                                                                          \
     691             :         GUInt16 _n16;                                                          \
     692             :         void *_lx = x;                                                         \
     693             :         memcpy(&_n16, _lx, 2);                                                 \
     694             :         CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 ||                    \
     695             :                                        sizeof(*(x)) == 2);                     \
     696             :         _n16 = CPL_SWAP16(_n16);                                               \
     697             :         memcpy(_lx, &_n16, 2);                                                 \
     698             :     } while (0)
     699             : 
     700             : /** Byte-swap a 32 bit pointer */
     701             : #define CPL_SWAP32PTR(x)                                                       \
     702             :     do                                                                         \
     703             :     {                                                                          \
     704             :         GUInt32 _n32;                                                          \
     705             :         void *_lx = x;                                                         \
     706             :         memcpy(&_n32, _lx, 4);                                                 \
     707             :         CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 ||                    \
     708             :                                        sizeof(*(x)) == 4);                     \
     709             :         _n32 = CPL_SWAP32(_n32);                                               \
     710             :         memcpy(_lx, &_n32, 4);                                                 \
     711             :     } while (0)
     712             : 
     713             : /** Byte-swap a 64 bit pointer */
     714             : #define CPL_SWAP64PTR(x)                                                       \
     715             :     do                                                                         \
     716             :     {                                                                          \
     717             :         GUInt64 _n64;                                                          \
     718             :         void *_lx = x;                                                         \
     719             :         memcpy(&_n64, _lx, 8);                                                 \
     720             :         CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 ||                    \
     721             :                                        sizeof(*(x)) == 8);                     \
     722             :         _n64 = CPL_SWAP64(_n64);                                               \
     723             :         memcpy(_lx, &_n64, 8);                                                 \
     724             :     } while (0)
     725             : 
     726             : /** Byte-swap a 64 bit pointer */
     727             : #define CPL_SWAPDOUBLE(p) CPL_SWAP64PTR(p)
     728             : 
     729             : #ifdef CPL_MSB
     730             : #define CPL_MSBWORD16(x) (x)
     731             : #define CPL_LSBWORD16(x) CPL_SWAP16(x)
     732             : #define CPL_MSBWORD32(x) (x)
     733             : #define CPL_LSBWORD32(x) CPL_SWAP32(x)
     734             : #define CPL_MSBPTR16(x)                                                        \
     735             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2)
     736             : #define CPL_LSBPTR16(x) CPL_SWAP16PTR(x)
     737             : #define CPL_MSBPTR32(x)                                                        \
     738             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4)
     739             : #define CPL_LSBPTR32(x) CPL_SWAP32PTR(x)
     740             : #define CPL_MSBPTR64(x)                                                        \
     741             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8)
     742             : #define CPL_LSBPTR64(x) CPL_SWAP64PTR(x)
     743             : #else
     744             : /** Return a 16bit word from a originally LSB ordered word */
     745             : #define CPL_LSBWORD16(x) (x)
     746             : /** Return a 16bit word from a originally MSB ordered word */
     747             : #define CPL_MSBWORD16(x) CPL_SWAP16(x)
     748             : /** Return a 32bit word from a originally LSB ordered word */
     749             : #define CPL_LSBWORD32(x) (x)
     750             : /** Return a 32bit word from a originally MSB ordered word */
     751             : #define CPL_MSBWORD32(x) CPL_SWAP32(x)
     752             : /** Byte-swap if necessary a 16bit word at the location pointed from a
     753             :  * originally LSB ordered pointer */
     754             : #define CPL_LSBPTR16(x)                                                        \
     755             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 2)
     756             : /** Byte-swap if necessary a 16bit word at the location pointed from a
     757             :  * originally MSB ordered pointer */
     758             : #define CPL_MSBPTR16(x) CPL_SWAP16PTR(x)
     759             : /** Byte-swap if necessary a 32bit word at the location pointed from a
     760             :  * originally LSB ordered pointer */
     761             : #define CPL_LSBPTR32(x)                                                        \
     762             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 4)
     763             : /** Byte-swap if necessary a 32bit word at the location pointed from a
     764             :  * originally MSB ordered pointer */
     765             : #define CPL_MSBPTR32(x) CPL_SWAP32PTR(x)
     766             : /** Byte-swap if necessary a 64bit word at the location pointed from a
     767             :  * originally LSB ordered pointer */
     768             : #define CPL_LSBPTR64(x)                                                        \
     769             :     CPL_STATIC_ASSERT_IF_AVAILABLE(sizeof(*(x)) == 1 || sizeof(*(x)) == 8)
     770             : /** Byte-swap if necessary a 64bit word at the location pointed from a
     771             :  * originally MSB ordered pointer */
     772             : #define CPL_MSBPTR64(x) CPL_SWAP64PTR(x)
     773             : #endif
     774             : 
     775             : /** Return a Int16 from the 2 bytes ordered in LSB order at address x.
     776             :  * @deprecated Use rather CPL_LSBSINT16PTR or CPL_LSBUINT16PTR for explicit
     777             :  * signedness. */
     778             : #define CPL_LSBINT16PTR(x)                                                     \
     779             :     ((*CPL_REINTERPRET_CAST(const GByte *, x)) |                               \
     780             :      (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 1) << 8))
     781             : 
     782             : /** Return a Int32 from the 4 bytes ordered in LSB order at address x.
     783             :  * @deprecated Use rather CPL_LSBSINT32PTR or CPL_LSBUINT32PTR for explicit
     784             :  * signedness. */
     785             : #define CPL_LSBINT32PTR(x)                                                     \
     786             :     ((*CPL_REINTERPRET_CAST(const GByte *, x)) |                               \
     787             :      (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 1) << 8) |                  \
     788             :      (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 2) << 16) |                 \
     789             :      (*((CPL_REINTERPRET_CAST(const GByte *, x)) + 3) << 24))
     790             : 
     791             : /** Return a signed Int16 from the 2 bytes ordered in LSB order at address x */
     792             : #define CPL_LSBSINT16PTR(x) CPL_STATIC_CAST(GInt16, CPL_LSBINT16PTR(x))
     793             : 
     794             : /** Return a unsigned Int16 from the 2 bytes ordered in LSB order at address x
     795             :  */
     796             : #define CPL_LSBUINT16PTR(x) CPL_STATIC_CAST(GUInt16, CPL_LSBINT16PTR(x))
     797             : 
     798             : /** Return a signed Int32 from the 4 bytes ordered in LSB order at address x */
     799             : #define CPL_LSBSINT32PTR(x) CPL_STATIC_CAST(GInt32, CPL_LSBINT32PTR(x))
     800             : 
     801             : /** Return a unsigned Int32 from the 4 bytes ordered in LSB order at address x
     802             :  */
     803             : #define CPL_LSBUINT32PTR(x) CPL_STATIC_CAST(GUInt32, CPL_LSBINT32PTR(x))
     804             : 
     805             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
     806             : 
     807             : extern "C++"
     808             : {
     809             : #include <cstddef>
     810             : #include <cstdint>
     811             : 
     812             :     /*! @cond Doxygen_Suppress */
     813             :     // workaround before CWG2518/P2593R1
     814             :     template <class T> struct CPL_T_IsAlwaysFalse
     815             :     {
     816             :         static const bool value = false;
     817             :     };
     818             : 
     819             :     /*! @endcond */
     820             : 
     821             :     /** Return the provided value as a LSB ordered one.
     822             :      *
     823             :      * Only available for primitive types: [u]int[8|16|32|64], float and double.
     824             :      */
     825             :     template <class T> T CPL_AS_LSB(T)
     826             :     {
     827             :         // See https://youtu.be/b6j6SZiXmoo?t=1659 for rationale for CPL_T_IsAlwaysFalse
     828             :         static_assert(CPL_T_IsAlwaysFalse<T>::value, "Unsupported value for T");
     829             :     }
     830             : 
     831             :     /*! @cond Doxygen_Suppress */
     832           1 :     template <> inline int8_t CPL_AS_LSB<int8_t>(int8_t x)
     833             :     {
     834           1 :         return x;
     835             :     }
     836             : 
     837        8301 :     template <> inline uint8_t CPL_AS_LSB<uint8_t>(uint8_t x)
     838             :     {
     839        8301 :         return x;
     840             :     }
     841             : 
     842           1 :     template <> inline int16_t CPL_AS_LSB<int16_t>(int16_t x)
     843             :     {
     844           1 :         CPL_LSBPTR16(&x);
     845           1 :         return x;
     846             :     }
     847             : 
     848       23020 :     template <> inline uint16_t CPL_AS_LSB<uint16_t>(uint16_t x)
     849             :     {
     850       23020 :         CPL_LSBPTR16(&x);
     851       23020 :         return x;
     852             :     }
     853             : 
     854           5 :     template <> inline int32_t CPL_AS_LSB<int32_t>(int32_t x)
     855             :     {
     856           5 :         CPL_LSBPTR32(&x);
     857           5 :         return x;
     858             :     }
     859             : 
     860         209 :     template <> inline uint32_t CPL_AS_LSB<uint32_t>(uint32_t x)
     861             :     {
     862         209 :         CPL_LSBPTR32(&x);
     863         209 :         return x;
     864             :     }
     865             : 
     866           1 :     template <> inline int64_t CPL_AS_LSB<int64_t>(int64_t x)
     867             :     {
     868           1 :         CPL_LSBPTR64(&x);
     869           1 :         return x;
     870             :     }
     871             : 
     872        5228 :     template <> inline uint64_t CPL_AS_LSB<uint64_t>(uint64_t x)
     873             :     {
     874        5228 :         CPL_LSBPTR64(&x);
     875        5228 :         return x;
     876             :     }
     877             : 
     878           1 :     template <> inline float CPL_AS_LSB<float>(float x)
     879             :     {
     880           1 :         CPL_LSBPTR32(&x);
     881           1 :         return x;
     882             :     }
     883             : 
     884           1 :     template <> inline double CPL_AS_LSB<double>(double x)
     885             :     {
     886           1 :         CPL_LSBPTR64(&x);
     887           1 :         return x;
     888             :     }
     889             : 
     890             :     /*! @endcond */
     891             : 
     892             :     /** Return a primitive type from a memory buffer containing its LSB
     893             :      * ordered byte sequence
     894             :      *
     895             :      * Only available for primitive types: [u]int[8|16|32|64], float and double.
     896             :      */
     897       14172 :     template <class T> inline T CPL_FROM_LSB(const void *ptr)
     898             :     {
     899             :         T x;
     900       14172 :         memcpy(&x, ptr, sizeof(x));
     901       14172 :         return CPL_AS_LSB(x);
     902             :     }
     903             : 
     904             :     /** Return the byte swapped version of the provided value.
     905             :      *
     906             :      * Only available for primitive types: [u]int[8|16|32|64], float and double.
     907             :      */
     908             :     template <class T> T CPL_SWAP(T)
     909             :     {
     910             :         // See https://youtu.be/b6j6SZiXmoo?t=1659 for rationale for CPL_T_IsAlwaysFalse
     911             :         static_assert(CPL_T_IsAlwaysFalse<T>::value, "Unsupported value for T");
     912             :     }
     913             : 
     914             :     /*! @cond Doxygen_Suppress */
     915           1 :     template <> inline int8_t CPL_SWAP<int8_t>(int8_t x)
     916             :     {
     917           1 :         return x;
     918             :     }
     919             : 
     920           1 :     template <> inline uint8_t CPL_SWAP<uint8_t>(uint8_t x)
     921             :     {
     922           1 :         return x;
     923             :     }
     924             : 
     925          14 :     template <> inline uint16_t CPL_SWAP<uint16_t>(uint16_t x)
     926             :     {
     927          14 :         return CPL_SWAP16(x);
     928             :     }
     929             : 
     930          14 :     template <> inline int16_t CPL_SWAP<int16_t>(int16_t x)
     931             :     {
     932          14 :         uint16_t ux = CPL_SWAP16(x);
     933          14 :         memcpy(&x, &ux, sizeof(x));
     934          14 :         return x;
     935             :     }
     936             : 
     937          14 :     template <> inline uint32_t CPL_SWAP<uint32_t>(uint32_t x)
     938             :     {
     939          14 :         return CPL_SWAP32(x);
     940             :     }
     941             : 
     942          14 :     template <> inline int32_t CPL_SWAP<int32_t>(int32_t x)
     943             :     {
     944          14 :         uint32_t ux = CPL_SWAP32(x);
     945          14 :         memcpy(&x, &ux, sizeof(x));
     946          14 :         return x;
     947             :     }
     948             : 
     949          14 :     template <> inline uint64_t CPL_SWAP<uint64_t>(uint64_t x)
     950             :     {
     951          14 :         return CPL_SWAP64(x);
     952             :     }
     953             : 
     954          14 :     template <> inline int64_t CPL_SWAP<int64_t>(int64_t x)
     955             :     {
     956          14 :         uint64_t ux = CPL_SWAP64(x);
     957          14 :         memcpy(&x, &ux, sizeof(x));
     958          14 :         return x;
     959             :     }
     960             : 
     961           2 :     template <> inline float CPL_SWAP<float>(float x)
     962             :     {
     963           2 :         float ret = x;
     964           2 :         CPL_SWAP32PTR(&ret);
     965           2 :         return ret;
     966             :     }
     967             : 
     968           2 :     template <> inline double CPL_SWAP<double>(double x)
     969             :     {
     970           2 :         double ret = x;
     971           2 :         CPL_SWAP64PTR(&ret);
     972           2 :         return ret;
     973             :     }
     974             : 
     975             :     /*! @endcond */
     976             : }
     977             : #endif  // defined(__cplusplus) && defined(GDAL_COMPILATION)
     978             : 
     979             : /*! @cond Doxygen_Suppress */
     980             : /* Utility macro to explicitly mark intentionally unreferenced parameters. */
     981             : #ifndef UNREFERENCED_PARAM
     982             : #ifdef UNREFERENCED_PARAMETER /* May be defined by Windows API */
     983             : #define UNREFERENCED_PARAM(param) UNREFERENCED_PARAMETER(param)
     984             : #else
     985             : #define UNREFERENCED_PARAM(param) ((void)param)
     986             : #endif /* UNREFERENCED_PARAMETER */
     987             : #endif /* UNREFERENCED_PARAM */
     988             : /*! @endcond */
     989             : 
     990             : /* We exclude mingw64 4.6 which seems to be broken regarding this */
     991             : #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP) &&            \
     992             :     !(defined(__MINGW64__) && __GNUC__ == 4 && __GNUC_MINOR__ == 6)
     993             : /** Null terminated variadic */
     994             : #define CPL_NULL_TERMINATED __attribute__((__sentinel__))
     995             : #else
     996             : /** Null terminated variadic */
     997             : #define CPL_NULL_TERMINATED
     998             : #endif
     999             : 
    1000             : #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP)
    1001             : /** Tag a function to have printf() formatting */
    1002             : #define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx)                             \
    1003             :     __attribute__((__format__(__printf__, format_idx, arg_idx)))
    1004             : /** Tag a function to have scanf() formatting */
    1005             : #define CPL_SCAN_FUNC_FORMAT(format_idx, arg_idx)                              \
    1006             :     __attribute__((__format__(__scanf__, format_idx, arg_idx)))
    1007             : #else
    1008             : /** Tag a function to have printf() formatting */
    1009             : #define CPL_PRINT_FUNC_FORMAT(format_idx, arg_idx)
    1010             : /** Tag a function to have scanf() formatting */
    1011             : #define CPL_SCAN_FUNC_FORMAT(format_idx, arg_idx)
    1012             : #endif
    1013             : 
    1014             : #if defined(_MSC_VER) &&                                                       \
    1015             :     (defined(GDAL_COMPILATION) || defined(CPL_ENABLE_MSVC_ANNOTATIONS))
    1016             : #include <sal.h>
    1017             : /** Macro into which to wrap the format argument of a printf-like function.
    1018             :  * Only used if ANALYZE=1 is specified to nmake */
    1019             : #define CPL_FORMAT_STRING(arg) _Printf_format_string_ arg
    1020             : /** Macro into which to wrap the format argument of a sscanf-like function.
    1021             :  * Only used if ANALYZE=1 is specified to nmake */
    1022             : #define CPL_SCANF_FORMAT_STRING(arg) _Scanf_format_string_ arg
    1023             : #else
    1024             : /** Macro into which to wrap the format argument of a printf-like function */
    1025             : #define CPL_FORMAT_STRING(arg) arg
    1026             : /** Macro into which to wrap the format argument of a sscanf-like function. */
    1027             : #define CPL_SCANF_FORMAT_STRING(arg) arg
    1028             : #endif /* defined(_MSC_VER) && defined(GDAL_COMPILATION) */
    1029             : 
    1030             : #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP)
    1031             : /** Qualifier to warn when the return value of a function is not used */
    1032             : #define CPL_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
    1033             : #else
    1034             : /** Qualifier to warn when the return value of a function is not used */
    1035             : #define CPL_WARN_UNUSED_RESULT
    1036             : #endif
    1037             : 
    1038             : #if defined(__GNUC__) && __GNUC__ >= 4
    1039             : /** Qualifier for an argument that is unused */
    1040             : #define CPL_UNUSED __attribute((__unused__))
    1041             : #else
    1042             : /* TODO: add cases for other compilers */
    1043             : /** Qualifier for an argument that is unused */
    1044             : #define CPL_UNUSED
    1045             : #endif
    1046             : 
    1047             : #if defined(__GNUC__) && __GNUC__ >= 3 && !defined(DOXYGEN_SKIP)
    1048             : /** Qualifier for a function that does not return at all (terminates the
    1049             :  * process) */
    1050             : #define CPL_NO_RETURN __attribute__((noreturn))
    1051             : #else
    1052             : /** Qualifier for a function that does not return at all (terminates the
    1053             :  * process) */
    1054             : #define CPL_NO_RETURN
    1055             : #endif
    1056             : 
    1057             : /*! @cond Doxygen_Suppress */
    1058             : /* Clang __has_attribute */
    1059             : #ifndef __has_attribute
    1060             : #define __has_attribute(x) 0  // Compatibility with non-clang compilers.
    1061             : #endif
    1062             : 
    1063             : /*! @endcond */
    1064             : 
    1065             : #if ((defined(__GNUC__) &&                                                     \
    1066             :       (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))) ||            \
    1067             :      __has_attribute(returns_nonnull)) &&                                      \
    1068             :     !defined(DOXYGEN_SKIP) && !defined(__INTEL_COMPILER)
    1069             : /** Qualifier for a function that does not return NULL */
    1070             : #define CPL_RETURNS_NONNULL __attribute__((returns_nonnull))
    1071             : #else
    1072             : /** Qualifier for a function that does not return NULL */
    1073             : #define CPL_RETURNS_NONNULL
    1074             : #endif
    1075             : 
    1076             : #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(DOXYGEN_SKIP)
    1077             : /** restrict keyword to declare that pointers do not alias */
    1078             : #define CPL_RESTRICT __restrict__
    1079             : #else
    1080             : /** restrict keyword to declare that pointers do not alias */
    1081             : #define CPL_RESTRICT
    1082             : #endif
    1083             : 
    1084             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
    1085             : 
    1086             : /** To be used in public headers only. For non-public headers or .cpp files,
    1087             :  * use override directly. */
    1088             : #define CPL_OVERRIDE override
    1089             : 
    1090             : /** C++11 final qualifier */
    1091             : #define CPL_FINAL final
    1092             : 
    1093             : /** Mark that a class is explicitly recognized as non-final */
    1094             : #define CPL_NON_FINAL
    1095             : 
    1096             : /** Helper to remove the copy and assignment constructors so that the compiler
    1097             :    will not generate the default versions.
    1098             : 
    1099             :    Must be placed in the private section of a class and should be at the end.
    1100             : */
    1101             : #define CPL_DISALLOW_COPY_ASSIGN(ClassName)                                    \
    1102             :     ClassName(const ClassName &) = delete;                                     \
    1103             :     ClassName &operator=(const ClassName &) = delete;
    1104             : 
    1105             : #endif /* __cplusplus */
    1106             : 
    1107             : #ifdef CPL_DISABLE_WARN_DEPRECATED
    1108             : #define CPL_WARN_DEPRECATED(x)
    1109             : #elif !defined(DOXYGEN_SKIP) && !defined(CPL_WARN_DEPRECATED)
    1110             : #if defined(__has_extension)
    1111             : #if __has_extension(attribute_deprecated_with_message)
    1112             : /* Clang extension */
    1113             : #define CPL_WARN_DEPRECATED(x) __attribute__((deprecated(x)))
    1114             : #else
    1115             : #define CPL_WARN_DEPRECATED(x)
    1116             : #endif
    1117             : #elif defined(__GNUC__)
    1118             : #define CPL_WARN_DEPRECATED(x) __attribute__((deprecated))
    1119             : #else
    1120             : #define CPL_WARN_DEPRECATED(x)
    1121             : #endif
    1122             : #endif
    1123             : 
    1124             : #if !defined(_MSC_VER) && !defined(__APPLE__) && !defined(_FORTIFY_SOURCE)
    1125             : CPL_C_START
    1126             : #if defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF)
    1127             : int vsnprintf(char *str, size_t size, const char *fmt, va_list args)
    1128             :     CPL_WARN_DEPRECATED("Use CPLvsnprintf() instead");
    1129             : int snprintf(char *str, size_t size, const char *fmt, ...)
    1130             :     CPL_PRINT_FUNC_FORMAT(3, 4)
    1131             :         CPL_WARN_DEPRECATED("Use CPLsnprintf() instead");
    1132             : int sprintf(char *str, const char *fmt, ...) CPL_PRINT_FUNC_FORMAT(2, 3)
    1133             :     CPL_WARN_DEPRECATED("Use CPLsnprintf() instead");
    1134             : #elif defined(GDAL_COMPILATION) && !defined(DONT_DEPRECATE_SPRINTF)
    1135             : int sprintf(char *str, const char *fmt, ...) CPL_PRINT_FUNC_FORMAT(2, 3)
    1136             :     CPL_WARN_DEPRECATED("Use snprintf() or CPLsnprintf() instead");
    1137             : #endif /* defined(GDAL_COMPILATION) && defined(WARN_STANDARD_PRINTF) */
    1138             : CPL_C_END
    1139             : #endif /* !defined(_MSC_VER) && !defined(__APPLE__) */
    1140             : 
    1141             : #if defined(__cplusplus)
    1142             : #ifndef CPPCHECK
    1143             : /** Returns the size of C style arrays. */
    1144             : #define CPL_ARRAYSIZE(array)                                                   \
    1145             :     ((sizeof(array) / sizeof(*(array))) /                                      \
    1146             :      static_cast<size_t>(!(sizeof(array) % sizeof(*(array)))))
    1147             : #else
    1148             : /* simplified version for cppcheck */
    1149             : #define CPL_ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
    1150             : #endif
    1151             : 
    1152             : extern "C++"
    1153             : {
    1154    33001718 :     template <class T> static void CPL_IGNORE_RET_VAL(const T &)
    1155             :     {
    1156    32974500 :     }
    1157             : 
    1158    92297254 :     inline static bool CPL_TO_BOOL(int x)
    1159             :     {
    1160    92297254 :         return x != 0;
    1161             :     }
    1162             : } /* extern "C++" */
    1163             : 
    1164             : #endif /* __cplusplus */
    1165             : 
    1166             : #if (((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) ||              \
    1167             :       (defined(__clang__) && __clang_major__ >= 3)) &&                         \
    1168             :      !defined(_MSC_VER))
    1169             : #define HAVE_GCC_DIAGNOSTIC_PUSH
    1170             : #endif
    1171             : 
    1172             : #if ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) &&               \
    1173             :      !defined(_MSC_VER))
    1174             : #define HAVE_GCC_SYSTEM_HEADER
    1175             : #endif
    1176             : 
    1177             : /*! @cond Doxygen_Suppress */
    1178             : 
    1179             : #ifndef FALSE
    1180             : #define FALSE 0
    1181             : #endif
    1182             : 
    1183             : #ifndef TRUE
    1184             : #define TRUE 1
    1185             : #endif
    1186             : 
    1187             : #if __clang_major__ >= 4 || (__clang_major__ == 3 && __clang_minor__ >= 8)
    1188             : #define CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW                                   \
    1189             :     __attribute__((no_sanitize("unsigned-integer-overflow")))
    1190             : #else
    1191             : #define CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW
    1192             : #endif
    1193             : 
    1194             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) &&                 \
    1195             :     defined(GDAL_COMPILATION)
    1196             : extern "C++"
    1197             : {
    1198             :     template <class C, class A, class B>
    1199    25375322 :     CPL_NOSANITIZE_UNSIGNED_INT_OVERFLOW inline C CPLUnsanitizedAdd(A a, B b)
    1200             :     {
    1201    25375322 :         return a + b;
    1202             :     }
    1203             : }
    1204             : #endif
    1205             : 
    1206             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
    1207             : #define CPL_NULLPTR nullptr
    1208             : #else
    1209             : #define CPL_NULLPTR NULL
    1210             : #endif
    1211             : 
    1212             : #if defined(__cplusplus) && defined(GDAL_COMPILATION)
    1213             : extern "C++"
    1214             : {
    1215             :     namespace cpl
    1216             :     {
    1217             :     /** Function to indicate that the result of an arithmetic operation
    1218             :          * does fit on the specified type. Typically used to avoid warnings
    1219             :          * about potentially overflowing multiplications by static analyzers.
    1220             :          */
    1221   196365502 :     template <typename T> inline T fits_on(T t)
    1222             :     {
    1223   196365502 :         return t;
    1224             :     }
    1225             : 
    1226             :     /** Emulates the C++20 .contains() method */
    1227             :     template <typename C, typename V>
    1228     3986687 :     inline bool contains(const C &container, const V &value)
    1229             :     {
    1230     3986687 :         return container.find(value) != container.end();
    1231             :     }
    1232             : 
    1233             :     }  // namespace cpl
    1234             : }
    1235             : #endif
    1236             : 
    1237             : /*! @endcond */
    1238             : 
    1239             : /* This typedef is for C functions that take char** as argument, but */
    1240             : /* with the semantics of a const list. In C, char** is not implicitly cast to */
    1241             : /* const char* const*, contrary to C++. So when seen for C++, it is OK */
    1242             : /* to expose the prototypes as const char* const*, but for C we keep the */
    1243             : /* historical definition to avoid warnings. */
    1244             : #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS) &&                 \
    1245             :     !defined(DOXYGEN_SKIP)
    1246             : /** Type of a constant null-terminated list of nul terminated strings.
    1247             :  * Seen as char** from C and const char* const* from C++ */
    1248             : typedef const char *const *CSLConstList;
    1249             : #else
    1250             : /** Type of a constant null-terminated list of nul terminated strings.
    1251             :  * Seen as char** from C and const char* const* from C++ */
    1252             : typedef char **CSLConstList;
    1253             : #endif
    1254             : 
    1255             : #if defined(__cplusplus) && defined(GDAL_COMPILATION)
    1256             : #if defined(__GNUC__) && !defined(DOXYGEN_SKIP)
    1257             : /** Macro that evaluates to (cond), and possibly gives a hint to the compiler
    1258             :  * than (cond) is unlikely to be true.
    1259             :  */
    1260             : #define CPL_UNLIKELY(cond) __builtin_expect(static_cast<bool>(cond), 0)
    1261             : #else
    1262             : #define CPL_UNLIKELY(cond) (cond)
    1263             : #endif
    1264             : #endif
    1265             : 
    1266             : #endif /* ndef CPL_BASE_H_INCLUDED */

Generated by: LCOV version 1.14