rapidjson.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  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. Currently the default uses 4 bytes
  236. alignment on 32-bit platforms and 8 bytes alignment for 64-bit platforms.
  237. User can customize by defining the RAPIDJSON_ALIGN function macro.
  238. */
  239. #ifndef RAPIDJSON_ALIGN
  240. #if RAPIDJSON_64BIT == 1
  241. #define RAPIDJSON_ALIGN(x) (((x) + static_cast<uint64_t>(7u)) & ~static_cast<uint64_t>(7u))
  242. #else
  243. #define RAPIDJSON_ALIGN(x) (((x) + 3u) & ~3u)
  244. #endif
  245. #endif
  246. ///////////////////////////////////////////////////////////////////////////////
  247. // RAPIDJSON_UINT64_C2
  248. //! Construct a 64-bit literal by a pair of 32-bit integer.
  249. /*!
  250. 64-bit literal with or without ULL suffix is prone to compiler warnings.
  251. UINT64_C() is C macro which cause compilation problems.
  252. Use this macro to define 64-bit constants by a pair of 32-bit integer.
  253. */
  254. #ifndef RAPIDJSON_UINT64_C2
  255. #define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
  256. #endif
  257. ///////////////////////////////////////////////////////////////////////////////
  258. // RAPIDJSON_48BITPOINTER_OPTIMIZATION
  259. //! Use only lower 48-bit address for some pointers.
  260. /*!
  261. \ingroup RAPIDJSON_CONFIG
  262. This optimization uses the fact that current X86-64 architecture only implement lower 48-bit virtual address.
  263. The higher 16-bit can be used for storing other data.
  264. \c GenericValue uses this optimization to reduce its size form 24 bytes to 16 bytes in 64-bit architecture.
  265. */
  266. #ifndef RAPIDJSON_48BITPOINTER_OPTIMIZATION
  267. #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)
  268. #define RAPIDJSON_48BITPOINTER_OPTIMIZATION 1
  269. #else
  270. #define RAPIDJSON_48BITPOINTER_OPTIMIZATION 0
  271. #endif
  272. #endif // RAPIDJSON_48BITPOINTER_OPTIMIZATION
  273. #if RAPIDJSON_48BITPOINTER_OPTIMIZATION == 1
  274. #if RAPIDJSON_64BIT != 1
  275. #error RAPIDJSON_48BITPOINTER_OPTIMIZATION can only be set to 1 when RAPIDJSON_64BIT=1
  276. #endif
  277. #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))))
  278. #define RAPIDJSON_GETPOINTER(type, p) (reinterpret_cast<type *>(reinterpret_cast<uintptr_t>(p) & static_cast<uintptr_t>(RAPIDJSON_UINT64_C2(0x0000FFFF, 0xFFFFFFFF))))
  279. #else
  280. #define RAPIDJSON_SETPOINTER(type, p, x) (p = (x))
  281. #define RAPIDJSON_GETPOINTER(type, p) (p)
  282. #endif
  283. ///////////////////////////////////////////////////////////////////////////////
  284. // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_NEON/RAPIDJSON_SIMD
  285. /*! \def RAPIDJSON_SIMD
  286. \ingroup RAPIDJSON_CONFIG
  287. \brief Enable SSE2/SSE4.2/Neon optimization.
  288. RapidJSON supports optimized implementations for some parsing operations
  289. based on the SSE2, SSE4.2 or NEon SIMD extensions on modern Intel
  290. or ARM compatible processors.
  291. To enable these optimizations, three different symbols can be defined;
  292. \code
  293. // Enable SSE2 optimization.
  294. #define RAPIDJSON_SSE2
  295. // Enable SSE4.2 optimization.
  296. #define RAPIDJSON_SSE42
  297. \endcode
  298. // Enable ARM Neon optimization.
  299. #define RAPIDJSON_NEON
  300. \endcode
  301. \c RAPIDJSON_SSE42 takes precedence over SSE2, if both are defined.
  302. If any of these symbols is defined, RapidJSON defines the macro
  303. \c RAPIDJSON_SIMD to indicate the availability of the optimized code.
  304. */
  305. #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \
  306. || defined(RAPIDJSON_NEON) || defined(RAPIDJSON_DOXYGEN_RUNNING)
  307. #define RAPIDJSON_SIMD
  308. #endif
  309. ///////////////////////////////////////////////////////////////////////////////
  310. // RAPIDJSON_NO_SIZETYPEDEFINE
  311. #ifndef RAPIDJSON_NO_SIZETYPEDEFINE
  312. /*! \def RAPIDJSON_NO_SIZETYPEDEFINE
  313. \ingroup RAPIDJSON_CONFIG
  314. \brief User-provided \c SizeType definition.
  315. In order to avoid using 32-bit size types for indexing strings and arrays,
  316. define this preprocessor symbol and provide the type rapidjson::SizeType
  317. before including RapidJSON:
  318. \code
  319. #define RAPIDJSON_NO_SIZETYPEDEFINE
  320. namespace rapidjson { typedef ::std::size_t SizeType; }
  321. #include "rapidjson/..."
  322. \endcode
  323. \see rapidjson::SizeType
  324. */
  325. #ifdef RAPIDJSON_DOXYGEN_RUNNING
  326. #define RAPIDJSON_NO_SIZETYPEDEFINE
  327. #endif
  328. RAPIDJSON_NAMESPACE_BEGIN
  329. //! Size type (for string lengths, array sizes, etc.)
  330. /*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms,
  331. instead of using \c size_t. Users may override the SizeType by defining
  332. \ref RAPIDJSON_NO_SIZETYPEDEFINE.
  333. */
  334. typedef unsigned SizeType;
  335. RAPIDJSON_NAMESPACE_END
  336. #endif
  337. // always import std::size_t to rapidjson namespace
  338. RAPIDJSON_NAMESPACE_BEGIN
  339. using std::size_t;
  340. RAPIDJSON_NAMESPACE_END
  341. ///////////////////////////////////////////////////////////////////////////////
  342. // RAPIDJSON_ASSERT
  343. //! Assertion.
  344. /*! \ingroup RAPIDJSON_CONFIG
  345. By default, rapidjson uses C \c assert() for internal assertions.
  346. User can override it by defining RAPIDJSON_ASSERT(x) macro.
  347. \note Parsing errors are handled and can be customized by the
  348. \ref RAPIDJSON_ERRORS APIs.
  349. */
  350. #ifndef RAPIDJSON_ASSERT
  351. #include <cassert>
  352. #define RAPIDJSON_ASSERT(x) assert(x)
  353. #endif // RAPIDJSON_ASSERT
  354. ///////////////////////////////////////////////////////////////////////////////
  355. // RAPIDJSON_STATIC_ASSERT
  356. // Prefer C++11 static_assert, if available
  357. #ifndef RAPIDJSON_STATIC_ASSERT
  358. #if __cplusplus >= 201103L || ( defined(_MSC_VER) && _MSC_VER >= 1800 )
  359. #define RAPIDJSON_STATIC_ASSERT(x) \
  360. static_assert(x, RAPIDJSON_STRINGIFY(x))
  361. #endif // C++11
  362. #endif // RAPIDJSON_STATIC_ASSERT
  363. // Adopt C++03 implementation from boost
  364. #ifndef RAPIDJSON_STATIC_ASSERT
  365. #ifndef __clang__
  366. //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
  367. #endif
  368. RAPIDJSON_NAMESPACE_BEGIN
  369. template <bool x> struct STATIC_ASSERTION_FAILURE;
  370. template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
  371. template <size_t x> struct StaticAssertTest {};
  372. RAPIDJSON_NAMESPACE_END
  373. #if defined(__GNUC__) || defined(__clang__)
  374. #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
  375. #else
  376. #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
  377. #endif
  378. #ifndef __clang__
  379. //!@endcond
  380. #endif
  381. /*! \def RAPIDJSON_STATIC_ASSERT
  382. \brief (Internal) macro to check for conditions at compile-time
  383. \param x compile-time condition
  384. \hideinitializer
  385. */
  386. #define RAPIDJSON_STATIC_ASSERT(x) \
  387. typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \
  388. sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \
  389. RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
  390. #endif // RAPIDJSON_STATIC_ASSERT
  391. ///////////////////////////////////////////////////////////////////////////////
  392. // RAPIDJSON_LIKELY, RAPIDJSON_UNLIKELY
  393. //! Compiler branching hint for expression with high probability to be true.
  394. /*!
  395. \ingroup RAPIDJSON_CONFIG
  396. \param x Boolean expression likely to be true.
  397. */
  398. #ifndef RAPIDJSON_LIKELY
  399. #if defined(__GNUC__) || defined(__clang__)
  400. #define RAPIDJSON_LIKELY(x) __builtin_expect(!!(x), 1)
  401. #else
  402. #define RAPIDJSON_LIKELY(x) (x)
  403. #endif
  404. #endif
  405. //! Compiler branching hint for expression with low probability to be true.
  406. /*!
  407. \ingroup RAPIDJSON_CONFIG
  408. \param x Boolean expression unlikely to be true.
  409. */
  410. #ifndef RAPIDJSON_UNLIKELY
  411. #if defined(__GNUC__) || defined(__clang__)
  412. #define RAPIDJSON_UNLIKELY(x) __builtin_expect(!!(x), 0)
  413. #else
  414. #define RAPIDJSON_UNLIKELY(x) (x)
  415. #endif
  416. #endif
  417. ///////////////////////////////////////////////////////////////////////////////
  418. // Helpers
  419. //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
  420. #define RAPIDJSON_MULTILINEMACRO_BEGIN do {
  421. #define RAPIDJSON_MULTILINEMACRO_END \
  422. } while((void)0, 0)
  423. // adopted from Boost
  424. #define RAPIDJSON_VERSION_CODE(x,y,z) \
  425. (((x)*100000) + ((y)*100) + (z))
  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. #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
  470. #else
  471. #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
  472. #endif
  473. #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
  474. #ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
  475. #if defined(__clang__)
  476. #define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
  477. #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
  478. (defined(_MSC_VER) && _MSC_VER >= 1900)
  479. #define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
  480. #else
  481. #define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
  482. #endif
  483. #endif
  484. #if RAPIDJSON_HAS_CXX11_NOEXCEPT
  485. #define RAPIDJSON_NOEXCEPT noexcept
  486. #else
  487. #define RAPIDJSON_NOEXCEPT /* noexcept */
  488. #endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
  489. // no automatic detection, yet
  490. #ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
  491. #if (defined(_MSC_VER) && _MSC_VER >= 1700)
  492. #define RAPIDJSON_HAS_CXX11_TYPETRAITS 1
  493. #else
  494. #define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
  495. #endif
  496. #endif
  497. #ifndef RAPIDJSON_HAS_CXX11_RANGE_FOR
  498. #if defined(__clang__)
  499. #define RAPIDJSON_HAS_CXX11_RANGE_FOR __has_feature(cxx_range_for)
  500. #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
  501. (defined(_MSC_VER) && _MSC_VER >= 1700)
  502. #define RAPIDJSON_HAS_CXX11_RANGE_FOR 1
  503. #else
  504. #define RAPIDJSON_HAS_CXX11_RANGE_FOR 0
  505. #endif
  506. #endif // RAPIDJSON_HAS_CXX11_RANGE_FOR
  507. //!@endcond
  508. ///////////////////////////////////////////////////////////////////////////////
  509. // new/delete
  510. #ifndef RAPIDJSON_NEW
  511. ///! customization point for global \c new
  512. #define RAPIDJSON_NEW(TypeName) new TypeName
  513. #endif
  514. #ifndef RAPIDJSON_DELETE
  515. ///! customization point for global \c delete
  516. #define RAPIDJSON_DELETE(x) delete x
  517. #endif
  518. ///////////////////////////////////////////////////////////////////////////////
  519. // Type
  520. /*! \namespace rapidjson
  521. \brief main RapidJSON namespace
  522. \see RAPIDJSON_NAMESPACE
  523. */
  524. RAPIDJSON_NAMESPACE_BEGIN
  525. //! Type of JSON value
  526. enum Type {
  527. kNullType = 0, //!< null
  528. kFalseType = 1, //!< false
  529. kTrueType = 2, //!< true
  530. kObjectType = 3, //!< object
  531. kArrayType = 4, //!< array
  532. kStringType = 5, //!< string
  533. kNumberType = 6 //!< number
  534. };
  535. RAPIDJSON_NAMESPACE_END
  536. #endif // RAPIDJSON_RAPIDJSON_H_