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