rapidjson.h 23 KB

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