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