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 
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 overriden 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_NAMESPACE_(BEGIN|END)
44 /*! \def RAPIDJSON_NAMESPACE
45     \ingroup RAPIDJSON_CONFIG
46     \brief   provide custom rapidjson namespace
47 
48     In order to avoid symbol clashes and/or "One Definition Rule" errors
49     between multiple inclusions of (different versions of) RapidJSON in
50     a single binary, users can customize the name of the main RapidJSON
51     namespace.
52 
53     In case of a single nesting level, defining \c RAPIDJSON_NAMESPACE
54     to a custom name (e.g. \c MyRapidJSON) is sufficient.  If multiple
55     levels are needed, both \ref RAPIDJSON_NAMESPACE_BEGIN and \ref
56     RAPIDJSON_NAMESPACE_END need to be defined as well:
57 
58     \code
59     // in some .cpp file
60     #define RAPIDJSON_NAMESPACE my::rapidjson
61     #define RAPIDJSON_NAMESPACE_BEGIN namespace my { namespace rapidjson {
62     #define RAPIDJSON_NAMESPACE_END   } }
63     #include "rapidjson/..."
64     \endcode
65 
66     \see rapidjson
67  */
68 /*! \def RAPIDJSON_NAMESPACE_BEGIN
69     \ingroup RAPIDJSON_CONFIG
70     \brief   provide custom rapidjson namespace (opening expression)
71     \see RAPIDJSON_NAMESPACE
72 */
73 /*! \def RAPIDJSON_NAMESPACE_END
74     \ingroup RAPIDJSON_CONFIG
75     \brief   provide custom rapidjson namespace (closing expression)
76     \see RAPIDJSON_NAMESPACE
77 */
78 #ifndef RAPIDJSON_NAMESPACE
79 #define RAPIDJSON_NAMESPACE rapidjson
80 #endif
81 #ifndef RAPIDJSON_NAMESPACE_BEGIN
82 #define RAPIDJSON_NAMESPACE_BEGIN namespace RAPIDJSON_NAMESPACE {
83 #endif
84 #ifndef RAPIDJSON_NAMESPACE_END
85 #define RAPIDJSON_NAMESPACE_END }
86 #endif
87 
88 ///////////////////////////////////////////////////////////////////////////////
89 // RAPIDJSON_NO_INT64DEFINE
90 
91 /*! \def RAPIDJSON_NO_INT64DEFINE
92     \ingroup RAPIDJSON_CONFIG
93     \brief Use external 64-bit integer types.
94 
95     RapidJSON requires the 64-bit integer types \c int64_t and  \c uint64_t types
96     to be available at global scope.
97 
98     If users have their own definition, define RAPIDJSON_NO_INT64DEFINE to
99     prevent RapidJSON from defining its own types.
100 */
101 #ifndef RAPIDJSON_NO_INT64DEFINE
102 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
103 #ifdef _MSC_VER
104 #include "msinttypes/stdint.h"
105 #include "msinttypes/inttypes.h"
106 #else
107 // Other compilers should have this.
108 #include <stdint.h>
109 #include <inttypes.h>
110 #endif
111 //!@endcond
112 #ifdef RAPIDJSON_DOXYGEN_RUNNING
113 #define RAPIDJSON_NO_INT64DEFINE
114 #endif
115 #endif // RAPIDJSON_NO_INT64TYPEDEF
116 
117 ///////////////////////////////////////////////////////////////////////////////
118 // RAPIDJSON_FORCEINLINE
119 
120 #ifndef RAPIDJSON_FORCEINLINE
121 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
122 #if defined(_MSC_VER) && !defined(NDEBUG)
123 #define RAPIDJSON_FORCEINLINE __forceinline
124 #elif defined(__GNUC__) && __GNUC__ >= 4 && !defined(NDEBUG)
125 #define RAPIDJSON_FORCEINLINE __attribute__((always_inline))
126 #else
127 #define RAPIDJSON_FORCEINLINE
128 #endif
129 //!@endcond
130 #endif // RAPIDJSON_FORCEINLINE
131 
132 ///////////////////////////////////////////////////////////////////////////////
133 // RAPIDJSON_ENDIAN
134 #define RAPIDJSON_LITTLEENDIAN  0   //!< Little endian machine
135 #define RAPIDJSON_BIGENDIAN     1   //!< Big endian machine
136 
137 //! Endianness of the machine.
138 /*!
139     \def RAPIDJSON_ENDIAN
140     \ingroup RAPIDJSON_CONFIG
141 
142     GCC 4.6 provided macro for detecting endianness of the target machine. But other
143     compilers may not have this. User can define RAPIDJSON_ENDIAN to either
144     \ref RAPIDJSON_LITTLEENDIAN or \ref RAPIDJSON_BIGENDIAN.
145 
146     Default detection implemented with reference to
147     \li https://gcc.gnu.org/onlinedocs/gcc-4.6.0/cpp/Common-Predefined-Macros.html
148     \li http://www.boost.org/doc/libs/1_42_0/boost/detail/endian.hpp
149 */
150 #ifndef RAPIDJSON_ENDIAN
151 // Detect with GCC 4.6's macro
152 #  ifdef __BYTE_ORDER__
153 #    if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
154 #      define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
155 #    elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
156 #      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
157 #    else
158 #      error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
159 #    endif // __BYTE_ORDER__
160 // Detect with GLIBC's endian.h
161 #  elif defined(__GLIBC__)
162 #    include <endian.h>
163 #    if (__BYTE_ORDER == __LITTLE_ENDIAN)
164 #      define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
165 #    elif (__BYTE_ORDER == __BIG_ENDIAN)
166 #      define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
167 #    else
168 #      error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
169 #   endif // __GLIBC__
170 // Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro
171 #  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
172 #    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
173 #  elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)
174 #    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
175 // Detect with architecture macros
176 #  elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
177 #    define RAPIDJSON_ENDIAN RAPIDJSON_BIGENDIAN
178 #  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__)
179 #    define RAPIDJSON_ENDIAN RAPIDJSON_LITTLEENDIAN
180 #  elif defined(RAPIDJSON_DOXYGEN_RUNNING)
181 #    define RAPIDJSON_ENDIAN
182 #  else
183 #    error Unknown machine endianess detected. User needs to define RAPIDJSON_ENDIAN.
184 #  endif
185 #endif // RAPIDJSON_ENDIAN
186 
187 ///////////////////////////////////////////////////////////////////////////////
188 // RAPIDJSON_64BIT
189 
190 //! Whether using 64-bit architecture
191 #ifndef RAPIDJSON_64BIT
192 #if defined(__LP64__) || defined(_WIN64)
193 #define RAPIDJSON_64BIT 1
194 #else
195 #define RAPIDJSON_64BIT 0
196 #endif
197 #endif // RAPIDJSON_64BIT
198 
199 ///////////////////////////////////////////////////////////////////////////////
200 // RAPIDJSON_ALIGN
201 
202 //! Data alignment of the machine.
203 /*! \ingroup RAPIDJSON_CONFIG
204     \param x pointer to align
205 
206     Some machines require strict data alignment. Currently the default uses 4 bytes
207     alignment. User can customize by defining the RAPIDJSON_ALIGN function macro.,
208 */
209 #ifndef RAPIDJSON_ALIGN
210 #define RAPIDJSON_ALIGN(x) ((x + 3u) & ~3u)
211 #endif
212 
213 ///////////////////////////////////////////////////////////////////////////////
214 // RAPIDJSON_UINT64_C2
215 
216 //! Construct a 64-bit literal by a pair of 32-bit integer.
217 /*!
218     64-bit literal with or without ULL suffix is prone to compiler warnings.
219     UINT64_C() is C macro which cause compilation problems.
220     Use this macro to define 64-bit constants by a pair of 32-bit integer.
221 */
222 #ifndef RAPIDJSON_UINT64_C2
223 #define RAPIDJSON_UINT64_C2(high32, low32) ((static_cast<uint64_t>(high32) << 32) | static_cast<uint64_t>(low32))
224 #endif
225 
226 ///////////////////////////////////////////////////////////////////////////////
227 // RAPIDJSON_SSE2/RAPIDJSON_SSE42/RAPIDJSON_SIMD
228 
229 /*! \def RAPIDJSON_SIMD
230     \ingroup RAPIDJSON_CONFIG
231     \brief Enable SSE2/SSE4.2 optimization.
232 
233     RapidJSON supports optimized implementations for some parsing operations
234     based on the SSE2 or SSE4.2 SIMD extensions on modern Intel-compatible
235     processors.
236 
237     To enable these optimizations, two different symbols can be defined;
238     \code
239     // Enable SSE2 optimization.
240     #define RAPIDJSON_SSE2
241 
242     // Enable SSE4.2 optimization.
243     #define RAPIDJSON_SSE42
244     \endcode
245 
246     \c RAPIDJSON_SSE42 takes precedence, if both are defined.
247 
248     If any of these symbols is defined, RapidJSON defines the macro
249     \c RAPIDJSON_SIMD to indicate the availability of the optimized code.
250 */
251 #if defined(RAPIDJSON_SSE2) || defined(RAPIDJSON_SSE42) \
252     || defined(RAPIDJSON_DOXYGEN_RUNNING)
253 #define RAPIDJSON_SIMD
254 #endif
255 
256 ///////////////////////////////////////////////////////////////////////////////
257 // RAPIDJSON_NO_SIZETYPEDEFINE
258 
259 #ifndef RAPIDJSON_NO_SIZETYPEDEFINE
260 /*! \def RAPIDJSON_NO_SIZETYPEDEFINE
261     \ingroup RAPIDJSON_CONFIG
262     \brief User-provided \c SizeType definition.
263 
264     In order to avoid using 32-bit size types for indexing strings and arrays,
265     define this preprocessor symbol and provide the type rapidjson::SizeType
266     before including RapidJSON:
267     \code
268     #define RAPIDJSON_NO_SIZETYPEDEFINE
269     namespace rapidjson { typedef ::std::size_t SizeType; }
270     #include "rapidjson/..."
271     \endcode
272 
273     \see rapidjson::SizeType
274 */
275 #ifdef RAPIDJSON_DOXYGEN_RUNNING
276 #define RAPIDJSON_NO_SIZETYPEDEFINE
277 #endif
278 RAPIDJSON_NAMESPACE_BEGIN
279 //! Size type (for string lengths, array sizes, etc.)
280 /*! RapidJSON uses 32-bit array/string indices even on 64-bit platforms,
281     instead of using \c size_t. Users may override the SizeType by defining
282     \ref RAPIDJSON_NO_SIZETYPEDEFINE.
283 */
284 typedef unsigned SizeType;
285 RAPIDJSON_NAMESPACE_END
286 #endif
287 
288 // always import std::size_t to rapidjson namespace
289 RAPIDJSON_NAMESPACE_BEGIN
290 using std::size_t;
291 RAPIDJSON_NAMESPACE_END
292 
293 ///////////////////////////////////////////////////////////////////////////////
294 // RAPIDJSON_ASSERT
295 
296 //! Assertion.
297 /*! \ingroup RAPIDJSON_CONFIG
298     By default, rapidjson uses C \c assert() for internal assertions.
299     User can override it by defining RAPIDJSON_ASSERT(x) macro.
300 
301     \note Parsing errors are handled and can be customized by the
302           \ref RAPIDJSON_ERRORS APIs.
303 */
304 #ifndef RAPIDJSON_ASSERT
305 #include <cassert>
306 #define RAPIDJSON_ASSERT(x) assert(x)
307 #endif // RAPIDJSON_ASSERT
308 
309 ///////////////////////////////////////////////////////////////////////////////
310 // RAPIDJSON_STATIC_ASSERT
311 
312 // Adopt from boost
313 #ifndef RAPIDJSON_STATIC_ASSERT
314 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
315 RAPIDJSON_NAMESPACE_BEGIN
316 template <bool x> struct STATIC_ASSERTION_FAILURE;
317 template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
318 template<int x> struct StaticAssertTest {};
319 RAPIDJSON_NAMESPACE_END
320 
321 #define RAPIDJSON_JOIN(X, Y) RAPIDJSON_DO_JOIN(X, Y)
322 #define RAPIDJSON_DO_JOIN(X, Y) RAPIDJSON_DO_JOIN2(X, Y)
323 #define RAPIDJSON_DO_JOIN2(X, Y) X##Y
324 
325 #if defined(__GNUC__)
326 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
327 #else
328 #define RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
329 #endif
330 //!@endcond
331 
332 /*! \def RAPIDJSON_STATIC_ASSERT
333     \brief (Internal) macro to check for conditions at compile-time
334     \param x compile-time condition
335     \hideinitializer
336  */
337 #define RAPIDJSON_STATIC_ASSERT(x) \
338     typedef ::RAPIDJSON_NAMESPACE::StaticAssertTest< \
339       sizeof(::RAPIDJSON_NAMESPACE::STATIC_ASSERTION_FAILURE<bool(x) >)> \
340     RAPIDJSON_JOIN(StaticAssertTypedef, __LINE__) RAPIDJSON_STATIC_ASSERT_UNUSED_ATTRIBUTE
341 #endif
342 
343 ///////////////////////////////////////////////////////////////////////////////
344 // Helpers
345 
346 //!@cond RAPIDJSON_HIDDEN_FROM_DOXYGEN
347 
348 #define RAPIDJSON_MULTILINEMACRO_BEGIN do {
349 #define RAPIDJSON_MULTILINEMACRO_END \
350 } while((void)0, 0)
351 
352 // adopted from Boost
353 #define RAPIDJSON_VERSION_CODE(x,y,z) \
354   (((x)*100000) + ((y)*100) + (z))
355 
356 // token stringification
357 #define RAPIDJSON_STRINGIFY(x) RAPIDJSON_DO_STRINGIFY(x)
358 #define RAPIDJSON_DO_STRINGIFY(x) #x
359 
360 ///////////////////////////////////////////////////////////////////////////////
361 // RAPIDJSON_DIAG_PUSH/POP, RAPIDJSON_DIAG_OFF
362 
363 #if defined(__GNUC__)
364 #define RAPIDJSON_GNUC \
365     RAPIDJSON_VERSION_CODE(__GNUC__,__GNUC_MINOR__,__GNUC_PATCHLEVEL__)
366 #endif
367 
368 #if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,2,0))
369 
370 #define RAPIDJSON_PRAGMA(x) _Pragma(RAPIDJSON_STRINGIFY(x))
371 #define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(GCC diagnostic x)
372 #define RAPIDJSON_DIAG_OFF(x) \
373     RAPIDJSON_DIAG_PRAGMA(ignored RAPIDJSON_STRINGIFY(RAPIDJSON_JOIN(-W,x)))
374 
375 // push/pop support in Clang and GCC>=4.6
376 #if defined(__clang__) || (defined(RAPIDJSON_GNUC) && RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0))
377 #define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
378 #define RAPIDJSON_DIAG_POP  RAPIDJSON_DIAG_PRAGMA(pop)
379 #else // GCC >= 4.2, < 4.6
380 #define RAPIDJSON_DIAG_PUSH /* ignored */
381 #define RAPIDJSON_DIAG_POP /* ignored */
382 #endif
383 
384 #elif defined(_MSC_VER)
385 
386 // pragma (MSVC specific)
387 #define RAPIDJSON_PRAGMA(x) __pragma(x)
388 #define RAPIDJSON_DIAG_PRAGMA(x) RAPIDJSON_PRAGMA(warning(x))
389 
390 #define RAPIDJSON_DIAG_OFF(x) RAPIDJSON_DIAG_PRAGMA(disable: x)
391 #define RAPIDJSON_DIAG_PUSH RAPIDJSON_DIAG_PRAGMA(push)
392 #define RAPIDJSON_DIAG_POP  RAPIDJSON_DIAG_PRAGMA(pop)
393 
394 #else
395 
396 #define RAPIDJSON_DIAG_OFF(x) /* ignored */
397 #define RAPIDJSON_DIAG_PUSH   /* ignored */
398 #define RAPIDJSON_DIAG_POP    /* ignored */
399 
400 #endif // RAPIDJSON_DIAG_*
401 
402 ///////////////////////////////////////////////////////////////////////////////
403 // C++11 features
404 
405 #ifndef RAPIDJSON_HAS_CXX11_RVALUE_REFS
406 #if defined(__clang__)
407 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS __has_feature(cxx_rvalue_references) && \
408     (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__) && __GLIBCXX__ >= 20080306)
409 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,3,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || \
410       (defined(_MSC_VER) && _MSC_VER >= 1600)
411 
412 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 1
413 #else
414 #define RAPIDJSON_HAS_CXX11_RVALUE_REFS 0
415 #endif
416 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
417 
418 #ifndef RAPIDJSON_HAS_CXX11_NOEXCEPT
419 #if defined(__clang__)
420 #define RAPIDJSON_HAS_CXX11_NOEXCEPT __has_feature(cxx_noexcept)
421 #elif (defined(RAPIDJSON_GNUC) && (RAPIDJSON_GNUC >= RAPIDJSON_VERSION_CODE(4,6,0)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
422 //    (defined(_MSC_VER) && _MSC_VER >= ????) // not yet supported
423 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 1
424 #else
425 #define RAPIDJSON_HAS_CXX11_NOEXCEPT 0
426 #endif
427 #endif
428 #if RAPIDJSON_HAS_CXX11_NOEXCEPT
429 #define RAPIDJSON_NOEXCEPT noexcept
430 #else
431 #define RAPIDJSON_NOEXCEPT /* noexcept */
432 #endif // RAPIDJSON_HAS_CXX11_NOEXCEPT
433 
434 // no automatic detection, yet
435 #ifndef RAPIDJSON_HAS_CXX11_TYPETRAITS
436 #define RAPIDJSON_HAS_CXX11_TYPETRAITS 0
437 #endif
438 
439 //!@endcond
440 
441 ///////////////////////////////////////////////////////////////////////////////
442 // new/delete
443 
444 #ifndef RAPIDJSON_NEW
445 ///! customization point for global \c new
446 #define RAPIDJSON_NEW(x) new x
447 #endif
448 #ifndef RAPIDJSON_DELETE
449 ///! customization point for global \c delete
450 #define RAPIDJSON_DELETE(x) delete x
451 #endif
452 
453 ///////////////////////////////////////////////////////////////////////////////
454 // Allocators and Encodings
455 
456 #include "allocators.h"
457 #include "encodings.h"
458 
459 /*! \namespace rapidjson
460     \brief main RapidJSON namespace
461     \see RAPIDJSON_NAMESPACE
462 */
463 RAPIDJSON_NAMESPACE_BEGIN
464 
465 ///////////////////////////////////////////////////////////////////////////////
466 //  Stream
467 
468 /*! \class rapidjson::Stream
469     \brief Concept for reading and writing characters.
470 
471     For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
472 
473     For write-only stream, only need to implement Put() and Flush().
474 
475 \code
476 concept Stream {
477     typename Ch;    //!< Character type of the stream.
478 
479     //! Read the current character from stream without moving the read cursor.
480     Ch Peek() const;
481 
482     //! Read the current character from stream and moving the read cursor to next character.
483     Ch Take();
484 
485     //! Get the current read cursor.
486     //! \return Number of characters read from start.
487     size_t Tell();
488 
489     //! Begin writing operation at the current read pointer.
490     //! \return The begin writer pointer.
491     Ch* PutBegin();
492 
493     //! Write a character.
494     void Put(Ch c);
495 
496     //! Flush the buffer.
497     void Flush();
498 
499     //! End the writing operation.
500     //! \param begin The begin write pointer returned by PutBegin().
501     //! \return Number of characters written.
502     size_t PutEnd(Ch* begin);
503 }
504 \endcode
505 */
506 
507 //! Provides additional information for stream.
508 /*!
509     By using traits pattern, this type provides a default configuration for stream.
510     For custom stream, this type can be specialized for other configuration.
511     See TEST(Reader, CustomStringStream) in readertest.cpp for example.
512 */
513 template<typename Stream>
514 struct StreamTraits {
515     //! Whether to make local copy of stream for optimization during parsing.
516     /*!
517         By default, for safety, streams do not use local copy optimization.
518         Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
519     */
520     enum { copyOptimization = 0 };
521 };
522 
523 //! Put N copies of a character to a stream.
524 template<typename Stream, typename Ch>
525 inline void PutN(Stream& stream, Ch c, size_t n) {
526     for (size_t i = 0; i < n; i++)
527         stream.Put(c);
528 }
529 
530 ///////////////////////////////////////////////////////////////////////////////
531 // StringStream
532 
533 //! Read-only string stream.
534 /*! \note implements Stream concept
535 */
536 template <typename Encoding>
537 struct GenericStringStream {
538     typedef typename Encoding::Ch Ch;
539 
540     GenericStringStream(const Ch *src) : src_(src), head_(src) {}
541 
542     Ch Peek() const { return *src_; }
543     Ch Take() { return *src_++; }
544     size_t Tell() const { return static_cast<size_t>(src_ - head_); }
545 
546     Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
547     void Put(Ch) { RAPIDJSON_ASSERT(false); }
548     void Flush() { RAPIDJSON_ASSERT(false); }
549     size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
550 
551     const Ch* src_;     //!< Current read position.
552     const Ch* head_;    //!< Original head of the string.
553 };
554 
555 template <typename Encoding>
556 struct StreamTraits<GenericStringStream<Encoding> > {
557     enum { copyOptimization = 1 };
558 };
559 
560 //! String stream with UTF8 encoding.
561 typedef GenericStringStream<UTF8<> > StringStream;
562 
563 ///////////////////////////////////////////////////////////////////////////////
564 // InsituStringStream
565 
566 //! A read-write string stream.
567 /*! This string stream is particularly designed for in-situ parsing.
568     \note implements Stream concept
569 */
570 template <typename Encoding>
571 struct GenericInsituStringStream {
572     typedef typename Encoding::Ch Ch;
573 
574     GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
575 
576     // Read
577     Ch Peek() { return *src_; }
578     Ch Take() { return *src_++; }
579     size_t Tell() { return static_cast<size_t>(src_ - head_); }
580 
581     // Write
582     void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
583 
584     Ch* PutBegin() { return dst_ = src_; }
585     size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
586     void Flush() {}
587 
588     Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
589     void Pop(size_t count) { dst_ -= count; }
590 
591     Ch* src_;
592     Ch* dst_;
593     Ch* head_;
594 };
595 
596 template <typename Encoding>
597 struct StreamTraits<GenericInsituStringStream<Encoding> > {
598     enum { copyOptimization = 1 };
599 };
600 
601 //! Insitu string stream with UTF8 encoding.
602 typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
603 
604 ///////////////////////////////////////////////////////////////////////////////
605 // Type
606 
607 //! Type of JSON value
608 enum Type {
609     kNullType = 0,      //!< null
610     kFalseType = 1,     //!< false
611     kTrueType = 2,      //!< true
612     kObjectType = 3,    //!< object
613     kArrayType = 4,     //!< array
614     kStringType = 5,    //!< string
615     kNumberType = 6     //!< number
616 };
617 
618 RAPIDJSON_NAMESPACE_END
619 
620 #endif // RAPIDJSON_RAPIDJSON_H_
621