1 // Tencent is pleased to support the open source community by making RapidJSON available. 2 // 3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. 4 // 5 // Licensed under the MIT License (the "License"); you may not use this file except 6 // in compliance with the License. You may obtain a copy of the License at 7 // 8 // http://opensource.org/licenses/MIT 9 // 10 // Unless required by applicable law or agreed to in writing, software distributed 11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 13 // specific language governing permissions and limitations under the License. 14 15 #ifndef RAPIDJSON_RAPIDJSON_H_ 16 #define RAPIDJSON_RAPIDJSON_H_ 17 18 /*!\file rapidjson.h 19 \brief common definitions and configuration 20 21 \see RAPIDJSON_CONFIG 22 */ 23 24 /*! \defgroup RAPIDJSON_CONFIG RapidJSON configuration 25 \brief Configuration macros for library features 26 27 Some RapidJSON features are configurable to adapt the library to a wide 28 variety of platforms, environments and usage scenarios. Most of the 29 features can be configured in terms of overridden or predefined 30 preprocessor macros at compile-time. 31 32 Some additional customization is available in the \ref RAPIDJSON_ERRORS APIs. 33 34 \note These macros should be given on the compiler command-line 35 (where applicable) to avoid inconsistent values when compiling 36 different translation units of a single application. 37 */ 38 39 #include <cstdlib> // malloc(), realloc(), free(), size_t 40 #include <cstring> // memset(), memcpy(), memmove(), memcmp() 41 42 /////////////////////////////////////////////////////////////////////////////// 43 // RAPIDJSON_VERSION_STRING 44 // 45 // ALWAYS synchronize the following 3 macros with corresponding variables in /CMakeLists.txt. 46 // 47 48 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 49 // token stringification 50 #define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x) 51 #define RAPIDJSON_DO_STRINGIFY(x) #x 52 53 // token concatenation 54 #define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y) 55 #define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y) 56 #define RAPIDJSON_DO_JOIN2(X, Y) X##Y 57 //!@endcond 58 59 /*! \def RAPIDJSON_MAJOR_VERSION 60 \ingroup RAPIDJSON_CONFIG 61 \brief Major version of RapidJSON in integer. 62 */ 63 /*! \def RAPIDJSON_MINOR_VERSION 64 \ingroup RAPIDJSON_CONFIG 65 \brief Minor version of RapidJSON in integer. 66 */ 67 /*! \def RAPIDJSON_PATCH_VERSION 68 \ingroup RAPIDJSON_CONFIG 69 \brief Patch version of RapidJSON in integer. 70 */ 71 /*! \def RAPIDJSON_VERSION_STRING 72 \ingroup RAPIDJSON_CONFIG 73 \brief Version of RapidJSON in "<major>.<minor>.<patch>" string format. 74 */ 75 #define RAPIDJSON_MAJOR_VERSION 1 76 #define RAPIDJSON_MINOR_VERSION 1 77 #define RAPIDJSON_PATCH_VERSION 0 78 #define RAPIDJSON_VERSION_STRING \ 79 RAPIDJSON_STRINGIFY(RAPIDJSON_MAJOR_VERSION.RAPIDJSON_MINOR_VERSION.RAPIDJSON_PATCH_VERSION) 80 81 /////////////////////////////////////////////////////////////////////////////// 82 // RAPIDJSON_NAMESPACE_(BEGIN|END) 83 /*! \def RAPIDJSON_NAMESPACE 84 \ingroup RAPIDJSON_CONFIG 85 \brief provide custom rapidjson namespace 86 87 In order to avoid symbol clashes and/or "One Definition Rule" errors 88 between multiple inclusions of (different versions of) RapidJSON in 89 a single binary, users can customize the name of the main RapidJSON 90 namespace. 91 92 In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE 93 to a custom name (e.g. \c MyRapidJSON) is sufficient. If multiple 94 levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref 95 RAPIDJSON_NAMESPACE_END need to be defined as well: 96 97 \code 98 // in some .cpp file 99 #define RAPIDJSON_NAMESPACE my::rapidjson 100 #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson { 101 #define RAPIDJSON_NAMESPACE_END } } 102 #include "rapidjson/..." 103 \endcode 104 105 \see rapidjson 106 */ 107 /*! \def RAPIDJSON_NAMESPACE_BEGIN 108 \ingroup RAPIDJSON_CONFIG 109 \brief provide custom rapidjson namespace (opening expression) 110 \see RAPIDJSON_NAMESPACE 111 */ 112 /*! \def RAPIDJSON_NAMESPACE_END 113 \ingroup RAPIDJSON_CONFIG 114 \brief provide custom rapidjson namespace (closing expression) 115 \see RAPIDJSON_NAMESPACE 116 */ 117 #ifndef RAPIDJSON_NAMESPACE 118 #define RAPIDJSON_NAMESPACE rapidjson 119 #endif 120 #ifndef RAPIDJSON_NAMESPACE_BEGIN 121 #define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE { 122 #endif 123 #ifndef RAPIDJSON_NAMESPACE_END 124 #define RAPIDJSON_NAMESPACE_END } 125 #endif 126 127 /////////////////////////////////////////////////////////////////////////////// 128 // __cplusplus macro 129 130 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 131 132 #if defined(_MSC_VER) 133 #define RAPIDJSON_CPLUSPLUS _MSVC_LANG 134 #else 135 #define RAPIDJSON_CPLUSPLUS __cplusplus 136 #endif 137 138 //!@endcond 139 140 /////////////////////////////////////////////////////////////////////////////// 141 // RAPIDJSON_HAS_STDSTRING 142 143 #ifndef RAPIDJSON_HAS_STDSTRING 144 #ifdef RAPIDJSON_DOXYGEN_RUNNING 145 #define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation 146 #else 147 #define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default 148 #endif 149 /*! \def RAPIDJSON_HAS_STDSTRING 150 \ingroup RAPIDJSON_CONFIG 151 \brief Enable RapidJSON support for \c std::string 152 153 By defining this preprocessor symbol to \c 1, several convenience functions for using 154 \ref rapidjson::GenericValue with \c std::string are enabled, especially 155 for construction and comparison. 156 157 \hideinitializer 158 */ 159 #endif // !defined(RAPIDJSON_HAS_STDSTRING) 160 161 #if RAPIDJSON_HAS_STDSTRING 162 #include <string> 163 #endif // RAPIDJSON_HAS_STDSTRING 164 165 /////////////////////////////////////////////////////////////////////////////// 166 // RAPIDJSON_USE_MEMBERSMAP 167 168 /*! \def RAPIDJSON_USE_MEMBERSMAP 169 \ingroup RAPIDJSON_CONFIG 170 \brief Enable RapidJSON support for object members handling in a \c std::multimap 171 172 By defining this preprocessor symbol to \c 1, \ref rapidjson::GenericValue object 173 members are stored in a \c std::multimap for faster lookup and deletion times, a 174 trade off with a slightly slower insertion time and a small object allocat(or)ed 175 memory overhead. 176 177 \hideinitializer 178 */ 179 #ifndef RAPIDJSON_USE_MEMBERSMAP 180 #define RAPIDJSON_USE_MEMBERSMAP 0 // not by default 181 #endif 182 183 /////////////////////////////////////////////////////////////////////////////// 184 // RAPIDJSON_NO_INT64DEFINE 185 186 /*! \def RAPIDJSON_NO_INT64DEFINE 187 \ingroup RAPIDJSON_CONFIG 188 \brief Use external 64-bit integer types. 189 190 RapidJSON requires the 64-bit integer types \c int64_t and \c uint64_t types 191 to be available at global scope. 192 193 If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to 194 prevent RapidJSON from defining its own types. 195 */ 196 #ifndef RAPIDJSON_NO_INT64DEFINE 197 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 198 #if defined(_MSC_VER) && (_MSC_VER < 1800) // Visual Studio 2013 199 #include "msinttypes/stdint.h" 200 #include "msinttypes/inttypes.h" 201 #else 202 // Other compilers should have this. 203 #include <stdint.h> 204 #include <inttypes.h> 205 #endif 206 //!@endcond 207 #ifdef RAPIDJSON_DOXYGEN_RUNNING 208 #define RAPIDJSON_NO_INT64DEFINE 209 #endif 210 #endif // RAPIDJSON_NO_INT64TYPEDEF 211 212 /////////////////////////////////////////////////////////////////////////////// 213 // RAPIDJSON_FORCEINLINE 214 215 #ifndef RAPIDJSON_FORCEINLINE 216 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 217 #if defined(_MSC_VER) && defined(NDEBUG) 218 #define RAPIDJSON_FORCEINLINE __forceinline 219 #elif defined(__GNUC__) && __GNUC__ >= 4 && defined(NDEBUG) 220 #define RAPIDJSON_FORCEINLINE __attribute__((always_inline)) 221 #else 222 #define RAPIDJSON_FORCEINLINE 223 #endif 224 //!@endcond 225 #endif // RAPIDJSON_FORCEINLINE 226 227 /////////////////////////////////////////////////////////////////////////////// 228 // RAPIDJSON_ENDIAN 229 #define RAPIDJSON_LITTLEENDIAN 0 //!< Little endian machine 230 #define RAPIDJSON_BIGENDIAN 1 //!< Big endian machine 231 232 //! Endianness of the machine. 233 /*! 234 \def RAPIDJSON_ENDIAN 235 \ingroup RAPIDJSON_CONFIG 236 237 GCC 4.6 provided macro for detecting endianness of the target machine. But other 238 compilers may not have this. User can define RAPIDJSON_ENDIAN to either 239 \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN. 240 241 Default detection implemented with reference to 242 \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html 243 \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp 244 */ 245 #ifndef RAPIDJSON_ENDIAN 246 // Detect with GCC 4.6's macro 247 # ifdef __BYTE_ORDER__ 248 # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 249 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 250 # elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 251 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN 252 # else 253 # error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. 254 # endif // __BYTE_ORDER__ 255 // Detect with GLIBC's endian.h 256 # elif defined(__GLIBC__) 257 # include <endian.h> 258 # if (__BYTE_ORDER == __LITTLE_ENDIAN) 259 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 260 # elif (__BYTE_ORDER == __BIG_ENDIAN) 261 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN 262 # else 263 # error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. 264 # endif // __GLIBC__ 265 // Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro 266 # elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) 267 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 268 # elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) 269 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN 270 // Detect with architecture macros 271 # elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__) 272 # define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN 273 # elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__bfin__) 274 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 275 # elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) 276 # define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN 277 # elif defined(RAPIDJSON_DOXYGEN_RUNNING) 278 # define RAPIDJSON_ENDIAN 279 # else 280 # error Unknown machine endianness detected. User needs to define RAPIDJSON_ENDIAN. 281 # endif 282 #endif // RAPIDJSON_ENDIAN 283 284 /////////////////////////////////////////////////////////////////////////////// 285 // RAPIDJSON_64BIT 286 287 //! Whether using 64-bit architecture 288 #ifndef RAPIDJSON_64BIT 289 #if defined(__LP64__) || (defined(__x86_64__) && defined(__ILP32__)) || defined(_WIN64) || defined(__EMSCRIPTEN__) 290 #define RAPIDJSON_64BIT 1 291 #else 292 #define RAPIDJSON_64BIT 0 293 #endif 294 #endif // RAPIDJSON_64BIT 295 296 /////////////////////////////////////////////////////////////////////////////// 297 // RAPIDJSON_ALIGN 298 299 //! Data alignment of the machine. 300 /*! \ingroup RAPIDJSON_CONFIG 301 \param x pointer to align 302 303 Some machines require strict data alignment. The default is 8 bytes. 304 User can customize by defining the RAPIDJSON_ALIGN function macro. 305 */ 306 #ifndef RAPIDJSON_ALIGN 307 #define RAPIDJSON_ALIGN(x) (((x) + static_cast<size_t>(7u)) & ~static_cast<size_t>(7u)) 308 #endif 309 310 /////////////////////////////////////////////////////////////////////////////// 311 // RAPIDJSON_UINT64_C2 312 313 //! Construct a 64-bit literal by a pair of 32-bit integer. 314 /*! 315 64-bit literal with or without ULL suffix is prone to compiler warnings. 316 UINT64_C() is C macro which cause compilation problems. 317 Use this macro to define 64-bit constants by a pair of 32-bit integer. 318 */ 319 #ifndef RAPIDJSON_UINT64_C2 320 #define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32)) 321 #endif 322 323 /////////////////////////////////////////////////////////////////////////////// 324 // RAPIDJSON_48BITPOINTER_OPTIMIZATION 325 326 //! Use only lower 48-bit address for some pointers. 327 /*! 328 \ingroup RAPIDJSON_CONFIG 329 330 This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address. 331 The higher 16-bit can be used for storing other data. 332 \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture. 333 */ 334 #ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION 335 #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64) 336 #define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1 337 #else 338 #define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0 339 #endif 340 #endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION 341 342 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1 343 #if RAPIDJSON_64BIT != 1 344 #error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1 345 #endif 346 #define RAPIDJSON_SETPOINTER(type, p, x) (p = reinterpret_cast<type *>((reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0xFFFF0000, 0x00000000))) | reinterpret_cast<uintptr_t>(reinterpret_cast<const void*>(x)))) 347 #define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF)))) 348 #else 349 #define RAPIDJSON_SETPOINTER(type, p, x) (p = (x)) 350 #define RAPIDJSON_GETPOINTER(type, p) (p) 351 #endif 352 353 /////////////////////////////////////////////////////////////////////////////// 354 // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD 355 356 /*! \def RAPIDJSON_SIMD 357 \ingroup RAPIDJSON_CONFIG 358 \brief Enable SSE2/SSE4.2/Neon optimization. 359 360 RapidJSON supports optimized implementations for some parsing operations 361 based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel 362 or ARM compatible processors. 363 364 To enable these optimizations, three different symbols can be defined; 365 \code 366 // Enable SSE2 optimization. 367 #define RAPIDJSON_SSE2 368 369 // Enable SSE4.2 optimization. 370 #define RAPIDJSON_SSE42 371 \endcode 372 373 // Enable ARM Neon optimization. 374 #define RAPIDJSON_NEON 375 \endcode 376 377 \c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined. 378 379 If any of these symbols is defined, RapidJSON defines the macro 380 \c RAPIDJSON_SIMD to indicate the availability of the optimized code. 381 */ 382 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \ 383 || defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING) 384 #define RAPIDJSON_SIMD 385 #endif 386 387 /////////////////////////////////////////////////////////////////////////////// 388 // RAPIDJSON_NO_SIZETYPEDEFINE 389 390 #ifndef RAPIDJSON_NO_SIZETYPEDEFINE 391 /*! \def RAPIDJSON_NO_SIZETYPEDEFINE 392 \ingroup RAPIDJSON_CONFIG 393 \brief User-provided \c SizeType definition. 394 395 In order to avoid using 32-bit size types for indexing strings and arrays, 396 define this preprocessor symbol and provide the type rapidjson::SizeType 397 before including RapidJSON: 398 \code 399 #define RAPIDJSON_NO_SIZETYPEDEFINE 400 namespace rapidjson { typedef ::std::size_t SizeType; } 401 #include "rapidjson/..." 402 \endcode 403 404 \see rapidjson::SizeType 405 */ 406 #ifdef RAPIDJSON_DOXYGEN_RUNNING 407 #define RAPIDJSON_NO_SIZETYPEDEFINE 408 #endif 409 RAPIDJSON_NAMESPACE_BEGIN 410 //! Size type (for string lengths, array sizes, etc.) 411 /*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms, 412 instead of using \c size_t. Users may override the SizeType by defining 413 \ref RAPIDJSON_NO_SIZETYPEDEFINE. 414 */ 415 typedef unsigned SizeType; 416 RAPIDJSON_NAMESPACE_END 417 #endif 418 419 // always import std::size_t to rapidjson namespace 420 RAPIDJSON_NAMESPACE_BEGIN 421 using std::size_t; 422 RAPIDJSON_NAMESPACE_END 423 424 /////////////////////////////////////////////////////////////////////////////// 425 // RAPIDJSON_ASSERT 426 427 //! Assertion. 428 /*! \ingroup RAPIDJSON_CONFIG 429 By default, rapidjson uses C \c assert() for internal assertions. 430 User can override it by defining RAPIDJSON_ASSERT(x) macro. 431 432 \note Parsing errors are handled and can be customized by the 433 \ref RAPIDJSON_ERRORS APIs. 434 */ 435 #ifndef RAPIDJSON_ASSERT 436 #include <cassert> 437 #define RAPIDJSON_ASSERT(x) assert(x) 438 #endif // RAPIDJSON_ASSERT 439 440 /////////////////////////////////////////////////////////////////////////////// 441 // RAPIDJSON_STATIC_ASSERT 442 443 // Prefer C++11 static_assert, if available 444 #ifndef RAPIDJSON_STATIC_ASSERT 445 #if RAPIDJSON_CPLUSPLUS >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 ) 446 #define RAPIDJSON_STATIC_ASSERT(x) \ 447 static_assert(x, RAPIDJSON_STRINGIFY(x)) 448 #endif // C++11 449 #endif // RAPIDJSON_STATIC_ASSERT 450 451 // Adopt C++03 implementation from boost 452 #ifndef RAPIDJSON_STATIC_ASSERT 453 #ifndef __clang__ 454 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 455 #endif 456 RAPIDJSON_NAMESPACE_BEGIN 457 template <bool x> struct STATIC_ASSERTION_FAILURE; 458 template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; }; 459 template <size_t x> struct StaticAssertTest {}; 460 RAPIDJSON_NAMESPACE_END 461 462 #if defined(__GNUC__) || defined(__clang__) 463 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused)) 464 #else 465 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE 466 #endif 467 #ifndef __clang__ 468 //!@endcond 469 #endif 470 471 /*! \def RAPIDJSON_STATIC_ASSERT 472 \brief (Internal) macro to check for conditions at compile-time 473 \param x compile-time condition 474 \hideinitializer 475 */ 476 #define RAPIDJSON_STATIC_ASSERT(x) \ 477 typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \ 478 sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \ 479 RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE 480 #endif // RAPIDJSON_STATIC_ASSERT 481 482 /////////////////////////////////////////////////////////////////////////////// 483 // RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY 484 485 //! Compiler branching hint for expression with high probability to be true. 486 /*! 487 \ingroup RAPIDJSON_CONFIG 488 \param x Boolean expression likely to be true. 489 */ 490 #ifndef RAPIDJSON_LIKELY 491 #if defined(__GNUC__) || defined(__clang__) 492 #define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1) 493 #else 494 #define RAPIDJSON_LIKELY(x) (x) 495 #endif 496 #endif 497 498 //! Compiler branching hint for expression with low probability to be true. 499 /*! 500 \ingroup RAPIDJSON_CONFIG 501 \param x Boolean expression unlikely to be true. 502 */ 503 #ifndef RAPIDJSON_UNLIKELY 504 #if defined(__GNUC__) || defined(__clang__) 505 #define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0) 506 #else 507 #define RAPIDJSON_UNLIKELY(x) (x) 508 #endif 509 #endif 510 511 /////////////////////////////////////////////////////////////////////////////// 512 // Helpers 513 514 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN 515 516 #define RAPIDJSON_MULTILINEMACRO_BEGIN do { 517 #define RAPIDJSON_MULTILINEMACRO_END \ 518 } while((void)0, 0) 519 520 // adopted from Boost 521 #define RAPIDJSON_VERSION_CODE(x,y,z) \ 522 (((x)*100000) + ((y)*100) + (z)) 523 524 #if defined(__has_builtin) 525 #define RAPIDJSON_HAS_BUILTIN(x) __has_builtin(x) 526 #else 527 #define RAPIDJSON_HAS_BUILTIN(x) 0 528 #endif 529 530 /////////////////////////////////////////////////////////////////////////////// 531 // RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF 532 533 #if defined(__GNUC__) 534 #define RAPIDJSON_GNUC \ 535 RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__) 536 #endif 537 538 #if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0)) 539 540 #define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x)) 541 #define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x) 542 #define RAPIDJSON_DIAG_OFF(x) \ 543 RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x))) 544 545 // push/pop support in Clang and GCC>=4.6 546 #if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) 547 #define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) 548 #define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) 549 #else // GCC >= 4.2, < 4.6 550 #define RAPIDJSON_DIAG_PUSH /* ignored */ 551 #define RAPIDJSON_DIAG_POP /* ignored */ 552 #endif 553 554 #elif defined(_MSC_VER) 555 556 // pragma (MSVC specific) 557 #define RAPIDJSON_PRAGMA(x) __pragma(x) 558 #define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x)) 559 560 #define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x) 561 #define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push) 562 #define RAPIDJSON_DIAG_POP RAPIDJSON_DIAG_PRAGMA(pop) 563 564 #else 565 566 #define RAPIDJSON_DIAG_OFF(x) /* ignored */ 567 #define RAPIDJSON_DIAG_PUSH /* ignored */ 568 #define RAPIDJSON_DIAG_POP /* ignored */ 569 570 #endif // RAPIDJSON_DIAG_* 571 572 /////////////////////////////////////////////////////////////////////////////// 573 // C++11 features 574 575 #ifndef RAPIDJSON_HAS_CXX11 576 #define RAPIDJSON_HAS_CXX11 (RAPIDJSON_CPLUSPLUS >= 201103L) 577 #endif 578 579 #ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS 580 #if RAPIDJSON_HAS_CXX11 581 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 582 #elif defined(__clang__) 583 #if __has_feature(cxx_rvalue_references) && \ 584 (defined(_MSC_VER) || defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306) 585 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 586 #else 587 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 588 #endif 589 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ 590 (defined(_MSC_VER) && _MSC_VER >= 1600) || \ 591 (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) 592 593 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1 594 #else 595 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0 596 #endif 597 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 598 599 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 600 #include <utility> // std::move 601 #endif 602 603 #ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT 604 #if RAPIDJSON_HAS_CXX11 605 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 606 #elif defined(__clang__) 607 #define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept) 608 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ 609 (defined(_MSC_VER) && _MSC_VER >= 1900) || \ 610 (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) 611 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 1 612 #else 613 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 0 614 #endif 615 #endif 616 #ifndef RAPIDJSON_NOEXCEPT 617 #if RAPIDJSON_HAS_CXX11_NOEXCEPT 618 #define RAPIDJSON_NOEXCEPT noexcept 619 #else 620 #define RAPIDJSON_NOEXCEPT throw() 621 #endif // RAPIDJSON_HAS_CXX11_NOEXCEPT 622 #endif 623 624 // no automatic detection, yet 625 #ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS 626 #if (defined(_MSC_VER) && _MSC_VER >= 1700) 627 #define RAPIDJSON_HAS_CXX11_TYPETRAITS 1 628 #else 629 #define RAPIDJSON_HAS_CXX11_TYPETRAITS 0 630 #endif 631 #endif 632 633 #ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR 634 #if defined(__clang__) 635 #define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for) 636 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \ 637 (defined(_MSC_VER) && _MSC_VER >= 1700) || \ 638 (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x5140 && defined(__GXX_EXPERIMENTAL_CXX0X__)) 639 #define RAPIDJSON_HAS_CXX11_RANGE_FOR 1 640 #else 641 #define RAPIDJSON_HAS_CXX11_RANGE_FOR 0 642 #endif 643 #endif // RAPIDJSON_HAS_CXX11_RANGE_FOR 644 645 /////////////////////////////////////////////////////////////////////////////// 646 // C++17 features 647 648 #ifndef RAPIDJSON_HAS_CXX17 649 #define RAPIDJSON_HAS_CXX17 (RAPIDJSON_CPLUSPLUS >= 201703L) 650 #endif 651 652 #if RAPIDJSON_HAS_CXX17 653 # define RAPIDJSON_DELIBERATE_FALLTHROUGH [[fallthrough]] 654 #elif defined(__has_cpp_attribute) 655 # if __has_cpp_attribute(clang::fallthrough) 656 # define RAPIDJSON_DELIBERATE_FALLTHROUGH [[clang::fallthrough]] 657 # elif __has_cpp_attribute(fallthrough) 658 # define RAPIDJSON_DELIBERATE_FALLTHROUGH __attribute__((fallthrough)) 659 # else 660 # define RAPIDJSON_DELIBERATE_FALLTHROUGH 661 # endif 662 #else 663 # define RAPIDJSON_DELIBERATE_FALLTHROUGH 664 #endif 665 666 //!@endcond 667 668 //! Assertion (in non-throwing contexts). 669 /*! \ingroup RAPIDJSON_CONFIG 670 Some functions provide a \c noexcept guarantee, if the compiler supports it. 671 In these cases, the \ref RAPIDJSON_ASSERT macro cannot be overridden to 672 throw an exception. This macro adds a separate customization point for 673 such cases. 674 675 Defaults to C \c assert() (as \ref RAPIDJSON_ASSERT), if \c noexcept is 676 supported, and to \ref RAPIDJSON_ASSERT otherwise. 677 */ 678 679 /////////////////////////////////////////////////////////////////////////////// 680 // RAPIDJSON_NOEXCEPT_ASSERT 681 682 #ifndef RAPIDJSON_NOEXCEPT_ASSERT 683 #ifdef RAPIDJSON_ASSERT_THROWS 684 #include <cassert> 685 #define RAPIDJSON_NOEXCEPT_ASSERT(x) assert(x) 686 #else 687 #define RAPIDJSON_NOEXCEPT_ASSERT(x) RAPIDJSON_ASSERT(x) 688 #endif // RAPIDJSON_ASSERT_THROWS 689 #endif // RAPIDJSON_NOEXCEPT_ASSERT 690 691 /////////////////////////////////////////////////////////////////////////////// 692 // malloc/realloc/free 693 694 #ifndef RAPIDJSON_MALLOC 695 ///! customization point for global \c malloc 696 #define RAPIDJSON_MALLOC(size) std::malloc(size) 697 #endif 698 #ifndef RAPIDJSON_REALLOC 699 ///! customization point for global \c realloc 700 #define RAPIDJSON_REALLOC(ptr, new_size) std::realloc(ptr, new_size) 701 #endif 702 #ifndef RAPIDJSON_FREE 703 ///! customization point for global \c free 704 #define RAPIDJSON_FREE(ptr) std::free(ptr) 705 #endif 706 707 /////////////////////////////////////////////////////////////////////////////// 708 // new/delete 709 710 #ifndef RAPIDJSON_NEW 711 ///! customization point for global \c new 712 #define RAPIDJSON_NEW(TypeName) new TypeName 713 #endif 714 #ifndef RAPIDJSON_DELETE 715 ///! customization point for global \c delete 716 #define RAPIDJSON_DELETE(x) delete x 717 #endif 718 719 /////////////////////////////////////////////////////////////////////////////// 720 // Type 721 722 /*! \namespace rapidjson 723 \brief main RapidJSON namespace 724 \see RAPIDJSON_NAMESPACE 725 */ 726 RAPIDJSON_NAMESPACE_BEGIN 727 728 //! Type of JSON value 729 enum Type { 730 kNullType = 0, //!< null 731 kFalseType = 1, //!< false 732 kTrueType = 2, //!< true 733 kObjectType = 3, //!< object 734 kArrayType = 4, //!< array 735 kStringType = 5, //!< string 736 kNumberType = 6 //!< number 737 }; 738 739 RAPIDJSON_NAMESPACE_END 740 741 #endif // RAPIDJSON_RAPIDJSON_H_ 742