rapidjson.h 23 KB

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