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