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