Coverage Report

Created: 2026-09-04 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rapidjson/include/rapidjson/document.h
Line
Count
Source
1
// Tencent is pleased to support the open source community by making RapidJSON available.
2
// 
3
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4
//
5
// Licensed under the MIT License (the "License"); you may not use this file except
6
// in compliance with the License. You may obtain a copy of the License at
7
//
8
// http://opensource.org/licenses/MIT
9
//
10
// Unless required by applicable law or agreed to in writing, software distributed 
11
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
12
// CONDITIONS OF ANY KIND, either express or implied. See the License for the 
13
// specific language governing permissions and limitations under the License.
14
15
#ifndef RAPIDJSON_DOCUMENT_H_
16
#define RAPIDJSON_DOCUMENT_H_
17
18
/*! \file document.h */
19
20
#include "reader.h"
21
#include "internal/meta.h"
22
#include "internal/strfunc.h"
23
#include "memorystream.h"
24
#include "encodedstream.h"
25
#include <new>      // placement new
26
#include <limits>
27
#ifdef __cpp_lib_three_way_comparison
28
#include <compare>
29
#endif
30
31
RAPIDJSON_DIAG_PUSH
32
#ifdef __clang__
33
RAPIDJSON_DIAG_OFF(padded)
34
RAPIDJSON_DIAG_OFF(switch-enum)
35
RAPIDJSON_DIAG_OFF(c++98-compat)
36
#elif defined(_MSC_VER)
37
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
38
RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
39
#endif
40
41
#ifdef __GNUC__
42
RAPIDJSON_DIAG_OFF(effc++)
43
#endif // __GNUC__
44
45
#ifdef GetObject
46
// see https://github.com/Tencent/rapidjson/issues/1448
47
// a former included windows.h might have defined a macro called GetObject, which affects
48
// GetObject defined here. This ensures the macro does not get applied
49
#pragma push_macro("GetObject")
50
#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
51
#undef GetObject
52
#endif
53
54
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
55
#include <iterator> // std::random_access_iterator_tag
56
#endif
57
58
#if RAPIDJSON_USE_MEMBERSMAP
59
#include <map> // std::multimap
60
#endif
61
62
RAPIDJSON_NAMESPACE_BEGIN
63
64
// Forward declaration.
65
template <typename Encoding, typename Allocator>
66
class GenericValue;
67
68
template <typename Encoding, typename Allocator, typename StackAllocator>
69
class GenericDocument;
70
71
/*! \def RAPIDJSON_DEFAULT_ALLOCATOR
72
    \ingroup RAPIDJSON_CONFIG
73
    \brief Allows to choose default allocator.
74
75
    User can define this to use CrtAllocator or MemoryPoolAllocator.
76
*/
77
#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
78
#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
79
#endif
80
81
/*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
82
    \ingroup RAPIDJSON_CONFIG
83
    \brief Allows to choose default stack allocator for Document.
84
85
    User can define this to use CrtAllocator or MemoryPoolAllocator.
86
*/
87
#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
88
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
89
#endif
90
91
/*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
92
    \ingroup RAPIDJSON_CONFIG
93
    \brief User defined kDefaultObjectCapacity value.
94
95
    User can define this as any natural number.
96
*/
97
#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
98
// number of objects that rapidjson::Value allocates memory for by default
99
#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
100
#endif
101
102
/*! \def RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
103
    \ingroup RAPIDJSON_CONFIG
104
    \brief User defined kDefaultArrayCapacity value.
105
106
    User can define this as any natural number.
107
*/
108
#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
109
// number of array elements that rapidjson::Value allocates memory for by default
110
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
111
#endif
112
113
//! Name-value pair in a JSON object value.
114
/*!
115
    This class was internal to GenericValue. It used to be a inner struct.
116
    But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
117
    https://code.google.com/p/rapidjson/issues/detail?id=64
118
*/
119
template <typename Encoding, typename Allocator> 
120
class GenericMember {
121
public:
122
    GenericValue<Encoding, Allocator> name;     //!< name of member (must be a string)
123
    GenericValue<Encoding, Allocator> value;    //!< value of member.
124
125
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
126
    //! Move constructor in C++11
127
    GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
128
        : name(std::move(rhs.name)),
129
          value(std::move(rhs.value))
130
    {
131
    }
132
133
    //! Move assignment in C++11
134
    GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
135
        return *this = static_cast<GenericMember&>(rhs);
136
    }
137
#endif
138
139
    //! Assignment with move semantics.
140
    /*! \param rhs Source of the assignment. Its name and value will become a null value after assignment.
141
    */
142
    GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
143
        if (RAPIDJSON_LIKELY(this != &rhs)) {
144
            name = rhs.name;
145
            value = rhs.value;
146
        }
147
        return *this;
148
    }
149
150
    // swap() for std::sort() and other potential use in STL.
151
    friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
152
        a.name.Swap(b.name);
153
        a.value.Swap(b.value);
154
    }
155
156
private:
157
    //! Copy constructor is not permitted.
158
    GenericMember(const GenericMember& rhs);
159
};
160
161
///////////////////////////////////////////////////////////////////////////////
162
// GenericMemberIterator
163
164
#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
165
166
//! (Constant) member iterator for a JSON object value
167
/*!
168
    \tparam Const Is this a constant iterator?
169
    \tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)
170
    \tparam Allocator   Allocator type for allocating memory of object, array and string.
171
172
    This class implements a Random Access Iterator for GenericMember elements
173
    of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
174
175
    \note This iterator implementation is mainly intended to avoid implicit
176
        conversions from iterator values to \c NULL,
177
        e.g. from GenericValue::FindMember.
178
179
    \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
180
        pointer-based implementation, if your platform doesn't provide
181
        the C++ <iterator> header.
182
183
    \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
184
 */
185
template <bool Const, typename Encoding, typename Allocator>
186
class GenericMemberIterator {
187
188
    friend class GenericValue<Encoding,Allocator>;
189
    template <bool, typename, typename> friend class GenericMemberIterator;
190
191
    typedef GenericMember<Encoding,Allocator> PlainType;
192
    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
193
194
public:
195
    //! Iterator type itself
196
    typedef GenericMemberIterator Iterator;
197
    //! Constant iterator type
198
    typedef GenericMemberIterator<true,Encoding,Allocator>  ConstIterator;
199
    //! Non-constant iterator type
200
    typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
201
202
    /** \name std::iterator_traits support */
203
    //@{
204
    typedef ValueType      value_type;
205
    typedef ValueType *    pointer;
206
    typedef ValueType &    reference;
207
    typedef std::ptrdiff_t difference_type;
208
    typedef std::random_access_iterator_tag iterator_category;
209
    //@}
210
211
    //! Pointer to (const) GenericMember
212
    typedef pointer         Pointer;
213
    //! Reference to (const) GenericMember
214
    typedef reference       Reference;
215
    //! Signed integer type (e.g. \c ptrdiff_t)
216
    typedef difference_type DifferenceType;
217
218
    //! Default constructor (singular value)
219
    /*! Creates an iterator pointing to no element.
220
        \note All operations, except for comparisons, are undefined on such values.
221
     */
222
    GenericMemberIterator() : ptr_() {}
223
224
    //! Iterator conversions to more const
225
    /*!
226
        \param it (Non-const) iterator to copy from
227
228
        Allows the creation of an iterator from another GenericMemberIterator
229
        that is "less const".  Especially, creating a non-constant iterator
230
        from a constant iterator are disabled:
231
        \li const -> non-const (not ok)
232
        \li const -> const (ok)
233
        \li non-const -> const (ok)
234
        \li non-const -> non-const (ok)
235
236
        \note If the \c Const template parameter is already \c false, this
237
            constructor effectively defines a regular copy-constructor.
238
            Otherwise, the copy constructor is implicitly defined.
239
    */
240
    GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
241
    Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
242
243
    //! @name stepping
244
    //@{
245
4
    Iterator& operator++(){ ++ptr_; return *this; }
rapidjson::GenericMemberIterator<true, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator++()
Line
Count
Source
245
4
    Iterator& operator++(){ ++ptr_; return *this; }
Unexecuted instantiation: rapidjson::GenericMemberIterator<false, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator++()
246
    Iterator& operator--(){ --ptr_; return *this; }
247
    Iterator  operator++(int){ Iterator old(*this); ++ptr_; return old; }
248
    Iterator  operator--(int){ Iterator old(*this); --ptr_; return old; }
249
    //@}
250
251
    //! @name increment/decrement
252
    //@{
253
    Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
254
    Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
255
256
    Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
257
    Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
258
    //@}
259
260
    //! @name relations
261
    //@{
262
    template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
263
8
    template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
bool rapidjson::GenericMemberIterator<true, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator!=<true>(rapidjson::GenericMemberIterator<true, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> > const&) const
Line
Count
Source
263
8
    template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
Unexecuted instantiation: bool rapidjson::GenericMemberIterator<false, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator!=<false>(rapidjson::GenericMemberIterator<false, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> > const&) const
264
    template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
265
    template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
266
    template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
267
    template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
268
269
#ifdef __cpp_lib_three_way_comparison
270
    template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
271
#endif
272
    //@}
273
274
    //! @name dereference
275
    //@{
276
    Reference operator*() const { return *ptr_; }
277
20
    Pointer   operator->() const { return ptr_; }
rapidjson::GenericMemberIterator<true, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator->() const
Line
Count
Source
277
20
    Pointer   operator->() const { return ptr_; }
Unexecuted instantiation: rapidjson::GenericMemberIterator<false, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator->() const
278
    Reference operator[](DifferenceType n) const { return ptr_[n]; }
279
    //@}
280
281
    //! Distance
282
    DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
283
284
private:
285
    //! Internal constructor from plain pointer
286
12
    explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
287
288
    Pointer ptr_; //!< raw pointer
289
};
290
291
#else // RAPIDJSON_NOMEMBERITERATORCLASS
292
293
// class-based member iterator implementation disabled, use plain pointers
294
295
template <bool Const, typename Encoding, typename Allocator>
296
class GenericMemberIterator;
297
298
//! non-const GenericMemberIterator
299
template <typename Encoding, typename Allocator>
300
class GenericMemberIterator<false,Encoding,Allocator> {
301
public:
302
    //! use plain pointer as iterator type
303
    typedef GenericMember<Encoding,Allocator>* Iterator;
304
};
305
//! const GenericMemberIterator
306
template <typename Encoding, typename Allocator>
307
class GenericMemberIterator<true,Encoding,Allocator> {
308
public:
309
    //! use plain const pointer as iterator type
310
    typedef const GenericMember<Encoding,Allocator>* Iterator;
311
};
312
313
#endif // RAPIDJSON_NOMEMBERITERATORCLASS
314
315
///////////////////////////////////////////////////////////////////////////////
316
// GenericStringRef
317
318
//! Reference to a constant string (not taking a copy)
319
/*!
320
    \tparam CharType character type of the string
321
322
    This helper class is used to automatically infer constant string
323
    references for string literals, especially from \c const \b (!)
324
    character arrays.
325
326
    The main use is for creating JSON string values without copying the
327
    source string via an \ref Allocator.  This requires that the referenced
328
    string pointers have a sufficient lifetime, which exceeds the lifetime
329
    of the associated GenericValue.
330
331
    \b Example
332
    \code
333
    Value v("foo");   // ok, no need to copy & calculate length
334
    const char foo[] = "foo";
335
    v.SetString(foo); // ok
336
337
    const char* bar = foo;
338
    // Value x(bar); // not ok, can't rely on bar's lifetime
339
    Value x(StringRef(bar)); // lifetime explicitly guaranteed by user
340
    Value y(StringRef(bar, 3));  // ok, explicitly pass length
341
    \endcode
342
343
    \see StringRef, GenericValue::SetString
344
*/
345
template<typename CharType>
346
struct GenericStringRef {
347
    typedef CharType Ch; //!< character type of the string
348
349
    //! Create string reference from \c const character array
350
#ifndef __clang__ // -Wdocumentation
351
    /*!
352
        This constructor implicitly creates a constant string reference from
353
        a \c const character array.  It has better performance than
354
        \ref StringRef(const CharType*) by inferring the string \ref length
355
        from the array length, and also supports strings containing null
356
        characters.
357
358
        \tparam N length of the string, automatically inferred
359
360
        \param str Constant character array, lifetime assumed to be longer
361
            than the use of the string in e.g. a GenericValue
362
363
        \post \ref s == str
364
365
        \note Constant complexity.
366
        \note There is a hidden, private overload to disallow references to
367
            non-const character arrays to be created via this constructor.
368
            By this, e.g. function-scope arrays used to be filled via
369
            \c snprintf are excluded from consideration.
370
            In such cases, the referenced string should be \b copied to the
371
            GenericValue instead.
372
     */
373
#endif
374
    template<SizeType N>
375
    GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
376
        : s(str), length(N-1) {}
377
378
    //! Explicitly create string reference from \c const character pointer
379
#ifndef __clang__ // -Wdocumentation
380
    /*!
381
        This constructor can be used to \b explicitly  create a reference to
382
        a constant string pointer.
383
384
        \see StringRef(const CharType*)
385
386
        \param str Constant character pointer, lifetime assumed to be longer
387
            than the use of the string in e.g. a GenericValue
388
389
        \post \ref s == str
390
391
        \note There is a hidden, private overload to disallow references to
392
            non-const character arrays to be created via this constructor.
393
            By this, e.g. function-scope arrays used to be filled via
394
            \c snprintf are excluded from consideration.
395
            In such cases, the referenced string should be \b copied to the
396
            GenericValue instead.
397
     */
398
#endif
399
    explicit GenericStringRef(const CharType* str)
400
        : s(str), length(NotNullStrLen(str)) {}
401
402
    //! Create constant string reference from pointer and length
403
#ifndef __clang__ // -Wdocumentation
404
    /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
405
        \param len length of the string, excluding the trailing NULL terminator
406
407
        \post \ref s == str && \ref length == len
408
        \note Constant complexity.
409
     */
410
#endif
411
    GenericStringRef(const CharType* str, SizeType len)
412
2.44M
        : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
413
414
    GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
415
416
    //! implicit conversion to plain CharType pointer
417
2.44M
    operator const Ch *() const { return s; }
418
419
    const Ch* const s; //!< plain CharType pointer
420
    const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
421
422
private:
423
    SizeType NotNullStrLen(const CharType* str) {
424
        RAPIDJSON_ASSERT(str != 0);
425
        return internal::StrLen(str);
426
    }
427
428
    /// Empty string - used when passing in a NULL pointer
429
    static const Ch emptyString[];
430
431
    //! Disallow construction from non-const array
432
    template<SizeType N>
433
    GenericStringRef(CharType (&str)[N]) /* = delete */;
434
    //! Copy assignment operator not permitted - immutable type
435
    GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
436
};
437
438
template<typename CharType>
439
const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
440
441
//! Mark a character pointer as constant string
442
/*! Mark a plain character pointer as a "string literal".  This function
443
    can be used to avoid copying a character string to be referenced as a
444
    value in a JSON GenericValue object, if the string's lifetime is known
445
    to be valid long enough.
446
    \tparam CharType Character type of the string
447
    \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
448
    \return GenericStringRef string reference object
449
    \relatesalso GenericStringRef
450
451
    \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember
452
*/
453
template<typename CharType>
454
inline GenericStringRef<CharType> StringRef(const CharType* str) {
455
    return GenericStringRef<CharType>(str);
456
}
457
458
//! Mark a character pointer as constant string
459
/*! Mark a plain character pointer as a "string literal".  This function
460
    can be used to avoid copying a character string to be referenced as a
461
    value in a JSON GenericValue object, if the string's lifetime is known
462
    to be valid long enough.
463
464
    This version has better performance with supplied length, and also
465
    supports string containing null characters.
466
467
    \tparam CharType character type of the string
468
    \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
469
    \param length The length of source string.
470
    \return GenericStringRef string reference object
471
    \relatesalso GenericStringRef
472
*/
473
template<typename CharType>
474
2.44M
inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
475
2.44M
    return GenericStringRef<CharType>(str, SizeType(length));
476
2.44M
}
477
478
#if RAPIDJSON_HAS_STDSTRING
479
//! Mark a string object as constant string
480
/*! Mark a string object (e.g. \c std::string) as a "string literal".
481
    This function can be used to avoid copying a string to be referenced as a
482
    value in a JSON GenericValue object, if the string's lifetime is known
483
    to be valid long enough.
484
485
    \tparam CharType character type of the string
486
    \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
487
    \return GenericStringRef string reference object
488
    \relatesalso GenericStringRef
489
    \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
490
*/
491
template<typename CharType>
492
inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
493
    return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
494
}
495
#endif
496
497
///////////////////////////////////////////////////////////////////////////////
498
// GenericValue type traits
499
namespace internal {
500
501
template <typename T, typename Encoding = void, typename Allocator = void>
502
struct IsGenericValueImpl : FalseType {};
503
504
// select candidates according to nested encoding and allocator types
505
template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
506
    : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
507
508
// helper to match arbitrary GenericValue instantiations, including derived classes
509
template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
510
511
} // namespace internal
512
513
///////////////////////////////////////////////////////////////////////////////
514
// TypeHelper
515
516
namespace internal {
517
518
template <typename ValueType, typename T>
519
struct TypeHelper {};
520
521
template<typename ValueType> 
522
struct TypeHelper<ValueType, bool> {
523
    static bool Is(const ValueType& v) { return v.IsBool(); }
524
    static bool Get(const ValueType& v) { return v.GetBool(); }
525
    static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
526
    static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
527
};
528
529
template<typename ValueType> 
530
struct TypeHelper<ValueType, int> {
531
    static bool Is(const ValueType& v) { return v.IsInt(); }
532
    static int Get(const ValueType& v) { return v.GetInt(); }
533
    static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
534
    static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
535
};
536
537
template<typename ValueType> 
538
struct TypeHelper<ValueType, unsigned> {
539
    static bool Is(const ValueType& v) { return v.IsUint(); }
540
    static unsigned Get(const ValueType& v) { return v.GetUint(); }
541
    static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
542
    static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
543
};
544
545
#ifdef _MSC_VER
546
RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
547
template<typename ValueType>
548
struct TypeHelper<ValueType, long> {
549
    static bool Is(const ValueType& v) { return v.IsInt(); }
550
    static long Get(const ValueType& v) { return v.GetInt(); }
551
    static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
552
    static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
553
};
554
555
RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
556
template<typename ValueType>
557
struct TypeHelper<ValueType, unsigned long> {
558
    static bool Is(const ValueType& v) { return v.IsUint(); }
559
    static unsigned long Get(const ValueType& v) { return v.GetUint(); }
560
    static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
561
    static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
562
};
563
#endif
564
565
template<typename ValueType> 
566
struct TypeHelper<ValueType, int64_t> {
567
    static bool Is(const ValueType& v) { return v.IsInt64(); }
568
    static int64_t Get(const ValueType& v) { return v.GetInt64(); }
569
    static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
570
    static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
571
};
572
573
template<typename ValueType> 
574
struct TypeHelper<ValueType, uint64_t> {
575
    static bool Is(const ValueType& v) { return v.IsUint64(); }
576
    static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
577
    static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
578
    static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
579
};
580
581
template<typename ValueType> 
582
struct TypeHelper<ValueType, double> {
583
    static bool Is(const ValueType& v) { return v.IsDouble(); }
584
    static double Get(const ValueType& v) { return v.GetDouble(); }
585
    static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
586
    static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
587
};
588
589
template<typename ValueType> 
590
struct TypeHelper<ValueType, float> {
591
    static bool Is(const ValueType& v) { return v.IsFloat(); }
592
    static float Get(const ValueType& v) { return v.GetFloat(); }
593
    static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
594
    static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
595
};
596
597
template<typename ValueType> 
598
struct TypeHelper<ValueType, const typename ValueType::Ch*> {
599
    typedef const typename ValueType::Ch* StringType;
600
    static bool Is(const ValueType& v) { return v.IsString(); }
601
    static StringType Get(const ValueType& v) { return v.GetString(); }
602
    static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
603
    static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
604
};
605
606
#if RAPIDJSON_HAS_STDSTRING
607
template<typename ValueType> 
608
struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
609
    typedef std::basic_string<typename ValueType::Ch> StringType;
610
    static bool Is(const ValueType& v) { return v.IsString(); }
611
    static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
612
    static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
613
};
614
#endif
615
616
template<typename ValueType> 
617
struct TypeHelper<ValueType, typename ValueType::Array> {
618
    typedef typename ValueType::Array ArrayType;
619
    static bool Is(const ValueType& v) { return v.IsArray(); }
620
    static ArrayType Get(ValueType& v) { return v.GetArray(); }
621
    static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
622
    static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
623
};
624
625
template<typename ValueType> 
626
struct TypeHelper<ValueType, typename ValueType::ConstArray> {
627
    typedef typename ValueType::ConstArray ArrayType;
628
    static bool Is(const ValueType& v) { return v.IsArray(); }
629
    static ArrayType Get(const ValueType& v) { return v.GetArray(); }
630
};
631
632
template<typename ValueType> 
633
struct TypeHelper<ValueType, typename ValueType::Object> {
634
    typedef typename ValueType::Object ObjectType;
635
    static bool Is(const ValueType& v) { return v.IsObject(); }
636
    static ObjectType Get(ValueType& v) { return v.GetObject(); }
637
    static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
638
    static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
639
};
640
641
template<typename ValueType> 
642
struct TypeHelper<ValueType, typename ValueType::ConstObject> {
643
    typedef typename ValueType::ConstObject ObjectType;
644
    static bool Is(const ValueType& v) { return v.IsObject(); }
645
    static ObjectType Get(const ValueType& v) { return v.GetObject(); }
646
};
647
648
} // namespace internal
649
650
// Forward declarations
651
template <bool, typename> class GenericArray;
652
template <bool, typename> class GenericObject;
653
654
///////////////////////////////////////////////////////////////////////////////
655
// GenericValue
656
657
//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
658
/*!
659
    A JSON value can be one of 7 types. This class is a variant type supporting
660
    these types.
661
662
    Use the Value if UTF8 and default allocator
663
664
    \tparam Encoding    Encoding of the value. (Even non-string values need to have the same encoding in a document)
665
    \tparam Allocator   Allocator type for allocating memory of object, array and string.
666
*/
667
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
668
class GenericValue {
669
public:
670
    //! Name-value pair in an object.
671
    typedef GenericMember<Encoding, Allocator> Member;
672
    typedef Encoding EncodingType;                  //!< Encoding type from template parameter.
673
    typedef Allocator AllocatorType;                //!< Allocator type from template parameter.
674
    typedef typename Encoding::Ch Ch;               //!< Character type derived from Encoding.
675
    typedef GenericStringRef<Ch> StringRefType;     //!< Reference to a constant string
676
    typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator;  //!< Member iterator for iterating in object.
677
    typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator;  //!< Constant member iterator for iterating in object.
678
    typedef GenericValue* ValueIterator;            //!< Value iterator for iterating in array.
679
    typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
680
    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of itself.
681
    typedef GenericArray<false, ValueType> Array;
682
    typedef GenericArray<true, ValueType> ConstArray;
683
    typedef GenericObject<false, ValueType> Object;
684
    typedef GenericObject<true, ValueType> ConstObject;
685
686
    //!@name Constructors and destructor.
687
    //@{
688
689
    //! Default constructor creates a null value.
690
554
    GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
691
692
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
693
    //! Move constructor in C++11
694
    GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
695
        rhs.data_.f.flags = kNullFlag; // give up contents
696
    }
697
#endif
698
699
private:
700
    //! Copy constructor is not permitted.
701
    GenericValue(const GenericValue& rhs);
702
703
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
704
    //! Moving from a GenericDocument is not permitted.
705
    template <typename StackAllocator>
706
    GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
707
708
    //! Move assignment from a GenericDocument is not permitted.
709
    template <typename StackAllocator>
710
    GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
711
#endif
712
713
public:
714
715
    //! Constructor with JSON value type.
716
    /*! This creates a Value of specified type with default content.
717
        \param type Type of the value.
718
        \note Default content for number is zero.
719
    */
720
41.8k
    explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
721
41.8k
        static const uint16_t defaultFlags[] = {
722
41.8k
            kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
723
41.8k
            kNumberAnyFlag
724
41.8k
        };
725
41.8k
        RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
726
41.8k
        data_.f.flags = defaultFlags[type];
727
728
        // Use ShortString to store empty string.
729
41.8k
        if (type == kStringType)
730
0
            data_.ss.SetLength(0);
731
41.8k
    }
732
733
    //! Explicit copy constructor (with allocator)
734
    /*! Creates a copy of a Value by using the given Allocator
735
        \tparam SourceAllocator allocator of \c rhs
736
        \param rhs Value to copy from (read-only)
737
        \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
738
        \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
739
        \see CopyFrom()
740
    */
741
    template <typename SourceAllocator>
742
    GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
743
        switch (rhs.GetType()) {
744
        case kObjectType:
745
            DoCopyMembers(rhs, allocator, copyConstStrings);
746
            break;
747
        case kArrayType: {
748
                SizeType count = rhs.data_.a.size;
749
                GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
750
                const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
751
                for (SizeType i = 0; i < count; i++)
752
                    new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
753
                data_.f.flags = kArrayFlag;
754
                data_.a.size = data_.a.capacity = count;
755
                SetElementsPointer(le);
756
            }
757
            break;
758
        case kStringType:
759
            if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
760
                data_.f.flags = rhs.data_.f.flags;
761
                data_  = *reinterpret_cast<const Data*>(&rhs.data_);
762
            }
763
            else
764
                SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
765
            break;
766
        default:
767
            data_.f.flags = rhs.data_.f.flags;
768
            data_  = *reinterpret_cast<const Data*>(&rhs.data_);
769
            break;
770
        }
771
    }
772
773
    //! Constructor for boolean value.
774
    /*! \param b Boolean value
775
        \note This constructor is limited to \em real boolean values and rejects
776
            implicitly converted types like arbitrary pointers.  Use an explicit cast
777
            to \c bool, if you want to construct a boolean JSON value in such cases.
778
     */
779
#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
780
    template <typename T>
781
    explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT  // See #472
782
#else
783
    explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
784
#endif
785
2.76k
        : data_() {
786
            // safe-guard against failing SFINAE
787
2.76k
            RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
788
2.76k
            data_.f.flags = b ? kTrueFlag : kFalseFlag;
789
2.76k
    }
790
791
    //! Constructor for int value.
792
5.94k
    explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
793
5.94k
        data_.n.i64 = i;
794
5.94k
        data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
795
5.94k
    }
796
797
    //! Constructor for unsigned value.
798
7.28M
    explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
799
7.28M
        data_.n.u64 = u; 
800
7.28M
        data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
801
7.28M
    }
802
803
    //! Constructor for int64_t value.
804
495
    explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
805
495
        data_.n.i64 = i64;
806
495
        data_.f.flags = kNumberInt64Flag;
807
495
        if (i64 >= 0) {
808
0
            data_.f.flags |= kNumberUint64Flag;
809
0
            if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
810
0
                data_.f.flags |= kUintFlag;
811
0
            if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
812
0
                data_.f.flags |= kIntFlag;
813
0
        }
814
495
        else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
815
0
            data_.f.flags |= kIntFlag;
816
495
    }
817
818
    //! Constructor for uint64_t value.
819
5.34k
    explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
820
5.34k
        data_.n.u64 = u64;
821
5.34k
        data_.f.flags = kNumberUint64Flag;
822
5.34k
        if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
823
5.22k
            data_.f.flags |= kInt64Flag;
824
5.34k
        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
825
0
            data_.f.flags |= kUintFlag;
826
5.34k
        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
827
0
            data_.f.flags |= kIntFlag;
828
5.34k
    }
829
830
    //! Constructor for double value.
831
17.7k
    explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
832
833
    //! Constructor for float value.
834
    explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
835
836
    //! Constructor for constant string (i.e. do not make a copy of string)
837
0
    GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
838
839
    //! Constructor for constant string (i.e. do not make a copy of string)
840
    explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
841
842
    //! Constructor for copy-string (i.e. do make a copy of string)
843
2.44M
    GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
844
845
    //! Constructor for copy-string (i.e. do make a copy of string)
846
    GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
847
848
#if RAPIDJSON_HAS_STDSTRING
849
    //! Constructor for copy-string from a string object (i.e. do make a copy of string)
850
    /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
851
     */
852
    GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
853
#endif
854
855
    //! Constructor for Array.
856
    /*!
857
        \param a An array obtained by \c GetArray().
858
        \note \c Array is always pass-by-value.
859
        \note the source array is moved into this value and the sourec array becomes empty.
860
    */
861
    GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
862
        a.value_.data_ = Data();
863
        a.value_.data_.f.flags = kArrayFlag;
864
    }
865
866
    //! Constructor for Object.
867
    /*!
868
        \param o An object obtained by \c GetObject().
869
        \note \c Object is always pass-by-value.
870
        \note the source object is moved into this value and the sourec object becomes empty.
871
    */
872
    GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
873
        o.value_.data_ = Data();
874
        o.value_.data_.f.flags = kObjectFlag;
875
    }
876
877
    //! Destructor.
878
    /*! Need to destruct elements of array, members of object, or copy-string.
879
    */
880
284
    ~GenericValue() {
881
        // With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release
882
        // their Allocator if it's refcounted (e.g. MemoryPoolAllocator).
883
284
        if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
884
0
                                     internal::IsRefCounted<Allocator>::Value)) {
885
0
            switch(data_.f.flags) {
886
0
            case kArrayFlag:
887
0
                {
888
0
                    GenericValue* e = GetElementsPointer();
889
0
                    for (GenericValue* v = e; v != e + data_.a.size; ++v)
890
0
                        v->~GenericValue();
891
0
                    if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
892
0
                        Allocator::Free(e);
893
0
                    }
894
0
                }
895
0
                break;
896
897
0
            case kObjectFlag:
898
0
                DoFreeMembers();
899
0
                break;
900
901
0
            case kCopyStringFlag:
902
0
                if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
903
0
                    Allocator::Free(const_cast<Ch*>(GetStringPointer()));
904
0
                }
905
0
                break;
906
907
0
            default:
908
0
                break;  // Do nothing for other types.
909
0
            }
910
0
        }
911
284
    }
912
913
    //@}
914
915
    //!@name Assignment operators
916
    //@{
917
918
    //! Assignment with move semantics.
919
    /*! \param rhs Source of the assignment. It will become a null value after assignment.
920
    */
921
34
    GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
922
34
        if (RAPIDJSON_LIKELY(this != &rhs)) {
923
            // Can't destroy "this" before assigning "rhs", otherwise "rhs"
924
            // could be used after free if it's an sub-Value of "this",
925
            // hence the temporary danse.
926
34
            GenericValue temp;
927
34
            temp.RawAssign(rhs);
928
34
            this->~GenericValue();
929
34
            RawAssign(temp);
930
34
        }
931
34
        return *this;
932
34
    }
933
934
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
935
    //! Move assignment in C++11
936
    GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
937
        return *this = rhs.Move();
938
    }
939
#endif
940
941
    //! Assignment of constant string reference (no copy)
942
    /*! \param str Constant string reference to be assigned
943
        \note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
944
        \see GenericStringRef, operator=(T)
945
    */
946
    GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
947
        GenericValue s(str);
948
        return *this = s;
949
    }
950
951
    //! Assignment with primitive types.
952
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
953
        \param value The value to be assigned.
954
955
        \note The source type \c T explicitly disallows all pointer types,
956
            especially (\c const) \ref Ch*.  This helps avoiding implicitly
957
            referencing character strings with insufficient lifetime, use
958
            \ref SetString(const Ch*, Allocator&) (for copying) or
959
            \ref StringRef() (to explicitly mark the pointer as constant) instead.
960
            All other pointer types would implicitly convert to \c bool,
961
            use \ref SetBool() instead.
962
    */
963
    template <typename T>
964
    RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
965
    operator=(T value) {
966
        GenericValue v(value);
967
        return *this = v;
968
    }
969
970
    //! Deep-copy assignment from Value
971
    /*! Assigns a \b copy of the Value to the current Value object
972
        \tparam SourceAllocator Allocator type of \c rhs
973
        \param rhs Value to copy from (read-only)
974
        \param allocator Allocator to use for copying
975
        \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
976
     */
977
    template <typename SourceAllocator>
978
    GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
979
        RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
980
        this->~GenericValue();
981
        new (this) GenericValue(rhs, allocator, copyConstStrings);
982
        return *this;
983
    }
984
985
    //! Exchange the contents of this value with those of other.
986
    /*!
987
        \param other Another value.
988
        \note Constant complexity.
989
    */
990
    GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
991
        GenericValue temp;
992
        temp.RawAssign(*this);
993
        RawAssign(other);
994
        other.RawAssign(temp);
995
        return *this;
996
    }
997
998
    //! free-standing swap function helper
999
    /*!
1000
        Helper function to enable support for common swap implementation pattern based on \c std::swap:
1001
        \code
1002
        void swap(MyClass& a, MyClass& b) {
1003
            using std::swap;
1004
            swap(a.value, b.value);
1005
            // ...
1006
        }
1007
        \endcode
1008
        \see Swap()
1009
     */
1010
    friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1011
1012
    //! Prepare Value for move semantics
1013
    /*! \return *this */
1014
    GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
1015
    //@}
1016
1017
    //!@name Equal-to and not-equal-to operators
1018
    //@{
1019
    //! Equal-to operator
1020
    /*!
1021
        \note If an object contains duplicated named member, comparing equality with any object is always \c false.
1022
        \note Complexity is quadratic in Object's member number and linear for the rest (number of all values in the subtree and total lengths of all strings).
1023
    */
1024
    template <typename SourceAllocator>
1025
    bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
1026
        typedef GenericValue<Encoding, SourceAllocator> RhsType;
1027
        if (GetType() != rhs.GetType())
1028
            return false;
1029
1030
        switch (GetType()) {
1031
        case kObjectType: // Warning: O(n^2) inner-loop
1032
            if (data_.o.size != rhs.data_.o.size)
1033
                return false;           
1034
            for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1035
                typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1036
                if (rhsMemberItr == rhs.MemberEnd() || (!(lhsMemberItr->value == rhsMemberItr->value)))
1037
                    return false;
1038
            }
1039
            return true;
1040
            
1041
        case kArrayType:
1042
            if (data_.a.size != rhs.data_.a.size)
1043
                return false;
1044
            for (SizeType i = 0; i < data_.a.size; i++)
1045
                if (!((*this)[i] == rhs[i]))
1046
                    return false;
1047
            return true;
1048
1049
        case kStringType:
1050
            return StringEqual(rhs);
1051
1052
        case kNumberType:
1053
            if (IsDouble() || rhs.IsDouble()) {
1054
                double a = GetDouble();     // May convert from integer to double.
1055
                double b = rhs.GetDouble(); // Ditto
1056
                return a >= b && a <= b;    // Prevent -Wfloat-equal
1057
            }
1058
            else
1059
                return data_.n.u64 == rhs.data_.n.u64;
1060
1061
        default:
1062
            return true;
1063
        }
1064
    }
1065
1066
    //! Equal-to operator with const C-string pointer
1067
    bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1068
1069
#if RAPIDJSON_HAS_STDSTRING
1070
    //! Equal-to operator with string object
1071
    /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
1072
     */
1073
    bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
1074
#endif
1075
1076
    //! Equal-to operator with primitive types
1077
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
1078
    */
1079
    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
1080
1081
#ifndef __cpp_impl_three_way_comparison
1082
    //! Not-equal-to operator
1083
    /*! \return !(*this == rhs)
1084
     */
1085
    template <typename SourceAllocator>
1086
    bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1087
1088
    //! Not-equal-to operator with const C-string pointer
1089
    bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1090
1091
    //! Not-equal-to operator with arbitrary types
1092
    /*! \return !(*this == rhs)
1093
     */
1094
    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1095
1096
    //! Equal-to operator with arbitrary types (symmetric version)
1097
    /*! \return (rhs == lhs)
1098
     */
1099
    template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1100
1101
    //! Not-Equal-to operator with arbitrary types (symmetric version)
1102
    /*! \return !(rhs == lhs)
1103
     */
1104
    template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1105
    //@}
1106
#endif
1107
1108
    //!@name Type
1109
    //@{
1110
1111
7.85k
    Type GetType()  const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1112
    bool IsNull()   const { return data_.f.flags == kNullFlag; }
1113
    bool IsFalse()  const { return data_.f.flags == kFalseFlag; }
1114
    bool IsTrue()   const { return data_.f.flags == kTrueFlag; }
1115
    bool IsBool()   const { return (data_.f.flags & kBoolFlag) != 0; }
1116
12
    bool IsObject() const { return data_.f.flags == kObjectFlag; }
1117
17.3k
    bool IsArray()  const { return data_.f.flags == kArrayFlag; }
1118
    bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1119
45
    bool IsInt()    const { return (data_.f.flags & kIntFlag) != 0; }
1120
0
    bool IsUint()   const { return (data_.f.flags & kUintFlag) != 0; }
1121
0
    bool IsInt64()  const { return (data_.f.flags & kInt64Flag) != 0; }
1122
    bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1123
549
    bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1124
3.45k
    bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1125
1126
    // Checks whether a number can be losslessly converted to a double.
1127
    bool IsLosslessDouble() const {
1128
        if (!IsNumber()) return false;
1129
        if (IsUint64()) {
1130
            uint64_t u = GetUint64();
1131
            volatile double d = static_cast<double>(u);
1132
            return (d >= 0.0)
1133
                && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1134
                && (u == static_cast<uint64_t>(d));
1135
        }
1136
        if (IsInt64()) {
1137
            int64_t i = GetInt64();
1138
            volatile double d = static_cast<double>(i);
1139
            return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1140
                && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1141
                && (i == static_cast<int64_t>(d));
1142
        }
1143
        return true; // double, int, uint are always lossless
1144
    }
1145
1146
    // Checks whether a number is a float (possible lossy).
1147
    bool IsFloat() const  {
1148
        if ((data_.f.flags & kDoubleFlag) == 0)
1149
            return false;
1150
        double d = GetDouble();
1151
        return d >= -3.4028234e38 && d <= 3.4028234e38;
1152
    }
1153
    // Checks whether a number can be losslessly converted to a float.
1154
    bool IsLosslessFloat() const {
1155
        if (!IsNumber()) return false;
1156
        double a = GetDouble();
1157
        if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1158
                || a > static_cast<double>((std::numeric_limits<float>::max)()))
1159
            return false;
1160
        double b = static_cast<double>(static_cast<float>(a));
1161
        return a >= b && a <= b;    // Prevent -Wfloat-equal
1162
    }
1163
1164
    //@}
1165
1166
    //!@name Null
1167
    //@{
1168
1169
108
    GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1170
1171
    //@}
1172
1173
    //!@name Bool
1174
    //@{
1175
1176
    bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1177
    //!< Set boolean value
1178
    /*! \post IsBool() == true */
1179
    GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1180
1181
    //@}
1182
1183
    //!@name Object
1184
    //@{
1185
1186
    //! Set this value as an empty object.
1187
    /*! \post IsObject() == true */
1188
    GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1189
1190
    //! Get the number of members in the object.
1191
    SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1192
1193
    //! Get the capacity of object.
1194
    SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1195
1196
    //! Check whether the object is empty.
1197
    bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1198
1199
    //! Get a value from an object associated with the name.
1200
    /*! \pre IsObject() == true
1201
        \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType))
1202
        \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
1203
        Since 0.2, if the name is not correct, it will assert.
1204
        If user is unsure whether a member exists, user should use HasMember() first.
1205
        A better approach is to use FindMember().
1206
        \note Linear time complexity.
1207
    */
1208
    template <typename T>
1209
    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1210
        GenericValue n(StringRef(name));
1211
        return (*this)[n];
1212
    }
1213
    template <typename T>
1214
    RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }
1215
1216
    //! Get a value from an object associated with the name.
1217
    /*! \pre IsObject() == true
1218
        \tparam SourceAllocator Allocator of the \c name value
1219
1220
        \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen().
1221
        And it can also handle strings with embedded null characters.
1222
1223
        \note Linear time complexity.
1224
    */
1225
    template <typename SourceAllocator>
1226
    GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1227
        MemberIterator member = FindMember(name);
1228
        if (member != MemberEnd())
1229
            return member->value;
1230
        else {
1231
            RAPIDJSON_ASSERT(false);    // see above note
1232
1233
#if RAPIDJSON_HAS_CXX11
1234
            // Use thread-local storage to prevent races between threads.
1235
            // Use static buffer and placement-new to prevent destruction, with
1236
            // alignas() to ensure proper alignment.
1237
            alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
1238
            return *new (buffer) GenericValue();
1239
#elif defined(_MSC_VER) && _MSC_VER < 1900
1240
            // There's no way to solve both thread locality and proper alignment
1241
            // simultaneously.
1242
            __declspec(thread) static char buffer[sizeof(GenericValue)];
1243
            return *new (buffer) GenericValue();
1244
#elif defined(__GNUC__) || defined(__clang__)
1245
            // This will generate -Wexit-time-destructors in clang, but that's
1246
            // better than having under-alignment.
1247
            __thread static GenericValue buffer;
1248
            return buffer;
1249
#else
1250
            // Don't know what compiler this is, so don't know how to ensure
1251
            // thread-locality.
1252
            static GenericValue buffer;
1253
            return buffer;
1254
#endif
1255
        }
1256
    }
1257
    template <typename SourceAllocator>
1258
    const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1259
1260
#if RAPIDJSON_HAS_STDSTRING
1261
    //! Get a value from an object associated with name (string object).
1262
    GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1263
    const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1264
#endif
1265
1266
    //! Const member iterator
1267
    /*! \pre IsObject() == true */
1268
4
    ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1269
    //! Const \em past-the-end member iterator
1270
    /*! \pre IsObject() == true */
1271
8
    ConstMemberIterator MemberEnd() const   { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1272
    //! Member iterator
1273
    /*! \pre IsObject() == true */
1274
0
    MemberIterator MemberBegin()            { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1275
    //! \em Past-the-end member iterator
1276
    /*! \pre IsObject() == true */
1277
0
    MemberIterator MemberEnd()              { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1278
1279
    //! Request the object to have enough capacity to store members.
1280
    /*! \param newCapacity  The capacity that the object at least need to have.
1281
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1282
        \return The value itself for fluent API.
1283
        \note Linear time complexity.
1284
    */
1285
    GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1286
        RAPIDJSON_ASSERT(IsObject());
1287
        DoReserveMembers(newCapacity, allocator);
1288
        return *this;
1289
    }
1290
1291
    //! Check whether a member exists in the object.
1292
    /*!
1293
        \param name Member name to be searched.
1294
        \pre IsObject() == true
1295
        \return Whether a member with that name exists.
1296
        \note It is better to use FindMember() directly if you need the obtain the value as well.
1297
        \note Linear time complexity.
1298
    */
1299
    bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1300
1301
#if RAPIDJSON_HAS_STDSTRING
1302
    //! Check whether a member exists in the object with string object.
1303
    /*!
1304
        \param name Member name to be searched.
1305
        \pre IsObject() == true
1306
        \return Whether a member with that name exists.
1307
        \note It is better to use FindMember() directly if you need the obtain the value as well.
1308
        \note Linear time complexity.
1309
    */
1310
    bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1311
#endif
1312
1313
    //! Check whether a member exists in the object with GenericValue name.
1314
    /*!
1315
        This version is faster because it does not need a StrLen(). It can also handle string with null character.
1316
        \param name Member name to be searched.
1317
        \pre IsObject() == true
1318
        \return Whether a member with that name exists.
1319
        \note It is better to use FindMember() directly if you need the obtain the value as well.
1320
        \note Linear time complexity.
1321
    */
1322
    template <typename SourceAllocator>
1323
    bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1324
1325
    //! Find member by name.
1326
    /*!
1327
        \param name Member name to be searched.
1328
        \pre IsObject() == true
1329
        \return Iterator to member, if it exists.
1330
            Otherwise returns \ref MemberEnd().
1331
1332
        \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
1333
            the requested member doesn't exist. For consistency with e.g.
1334
            \c std::map, this has been changed to MemberEnd() now.
1335
        \note Linear time complexity.
1336
    */
1337
    MemberIterator FindMember(const Ch* name) {
1338
        GenericValue n(StringRef(name));
1339
        return FindMember(n);
1340
    }
1341
1342
    ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1343
1344
    //! Find member by name.
1345
    /*!
1346
        This version is faster because it does not need a StrLen(). It can also handle string with null character.
1347
        \param name Member name to be searched.
1348
        \pre IsObject() == true
1349
        \return Iterator to member, if it exists.
1350
            Otherwise returns \ref MemberEnd().
1351
1352
        \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
1353
            the requested member doesn't exist. For consistency with e.g.
1354
            \c std::map, this has been changed to MemberEnd() now.
1355
        \note Linear time complexity.
1356
    */
1357
    template <typename SourceAllocator>
1358
    MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
1359
        RAPIDJSON_ASSERT(IsObject());
1360
        RAPIDJSON_ASSERT(name.IsString());
1361
        return DoFindMember(name);
1362
    }
1363
    template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1364
1365
#if RAPIDJSON_HAS_STDSTRING
1366
    //! Find member by string object name.
1367
    /*!
1368
        \param name Member name to be searched.
1369
        \pre IsObject() == true
1370
        \return Iterator to member, if it exists.
1371
            Otherwise returns \ref MemberEnd().
1372
    */
1373
    MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1374
    ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1375
#endif
1376
1377
    //! Add a member (name-value pair) to the object.
1378
    /*! \param name A string value as name of member.
1379
        \param value Value of any type.
1380
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1381
        \return The value itself for fluent API.
1382
        \note The ownership of \c name and \c value will be transferred to this object on success.
1383
        \pre  IsObject() && name.IsString()
1384
        \post name.IsNull() && value.IsNull()
1385
        \note Amortized Constant time complexity.
1386
    */
1387
    GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1388
        RAPIDJSON_ASSERT(IsObject());
1389
        RAPIDJSON_ASSERT(name.IsString());
1390
        DoAddMember(name, value, allocator);
1391
        return *this;
1392
    }
1393
1394
    //! Add a constant string value as member (name-value pair) to the object.
1395
    /*! \param name A string value as name of member.
1396
        \param value constant string reference as value of member.
1397
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1398
        \return The value itself for fluent API.
1399
        \pre  IsObject()
1400
        \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
1401
        \note Amortized Constant time complexity.
1402
    */
1403
    GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1404
        GenericValue v(value);
1405
        return AddMember(name, v, allocator);
1406
    }
1407
1408
#if RAPIDJSON_HAS_STDSTRING
1409
    //! Add a string object as member (name-value pair) to the object.
1410
    /*! \param name A string value as name of member.
1411
        \param value constant string reference as value of member.
1412
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1413
        \return The value itself for fluent API.
1414
        \pre  IsObject()
1415
        \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
1416
        \note Amortized Constant time complexity.
1417
    */
1418
    GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1419
        GenericValue v(value, allocator);
1420
        return AddMember(name, v, allocator);
1421
    }
1422
#endif
1423
1424
    //! Add any primitive value as member (name-value pair) to the object.
1425
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1426
        \param name A string value as name of member.
1427
        \param value Value of primitive type \c T as value of member
1428
        \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1429
        \return The value itself for fluent API.
1430
        \pre  IsObject()
1431
1432
        \note The source type \c T explicitly disallows all pointer types,
1433
            especially (\c const) \ref Ch*.  This helps avoiding implicitly
1434
            referencing character strings with insufficient lifetime, use
1435
            \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1436
            AddMember(StringRefType, StringRefType, Allocator&).
1437
            All other pointer types would implicitly convert to \c bool,
1438
            use an explicit cast instead, if needed.
1439
        \note Amortized Constant time complexity.
1440
    */
1441
    template <typename T>
1442
    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1443
    AddMember(GenericValue& name, T value, Allocator& allocator) {
1444
        GenericValue v(value);
1445
        return AddMember(name, v, allocator);
1446
    }
1447
1448
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1449
    GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1450
        return AddMember(name, value, allocator);
1451
    }
1452
    GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1453
        return AddMember(name, value, allocator);
1454
    }
1455
    GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1456
        return AddMember(name, value, allocator);
1457
    }
1458
    GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1459
        GenericValue n(name);
1460
        return AddMember(n, value, allocator);
1461
    }
1462
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1463
1464
1465
    //! Add a member (name-value pair) to the object.
1466
    /*! \param name A constant string reference as name of member.
1467
        \param value Value of any type.
1468
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1469
        \return The value itself for fluent API.
1470
        \note The ownership of \c value will be transferred to this object on success.
1471
        \pre  IsObject()
1472
        \post value.IsNull()
1473
        \note Amortized Constant time complexity.
1474
    */
1475
    GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1476
        GenericValue n(name);
1477
        return AddMember(n, value, allocator);
1478
    }
1479
1480
    //! Add a constant string value as member (name-value pair) to the object.
1481
    /*! \param name A constant string reference as name of member.
1482
        \param value constant string reference as value of member.
1483
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1484
        \return The value itself for fluent API.
1485
        \pre  IsObject()
1486
        \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.
1487
        \note Amortized Constant time complexity.
1488
    */
1489
    GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1490
        GenericValue v(value);
1491
        return AddMember(name, v, allocator);
1492
    }
1493
1494
    //! Add any primitive value as member (name-value pair) to the object.
1495
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1496
        \param name A constant string reference as name of member.
1497
        \param value Value of primitive type \c T as value of member
1498
        \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1499
        \return The value itself for fluent API.
1500
        \pre  IsObject()
1501
1502
        \note The source type \c T explicitly disallows all pointer types,
1503
            especially (\c const) \ref Ch*.  This helps avoiding implicitly
1504
            referencing character strings with insufficient lifetime, use
1505
            \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1506
            AddMember(StringRefType, StringRefType, Allocator&).
1507
            All other pointer types would implicitly convert to \c bool,
1508
            use an explicit cast instead, if needed.
1509
        \note Amortized Constant time complexity.
1510
    */
1511
    template <typename T>
1512
    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1513
    AddMember(StringRefType name, T value, Allocator& allocator) {
1514
        GenericValue n(name);
1515
        return AddMember(n, value, allocator);
1516
    }
1517
1518
    //! Remove all members in the object.
1519
    /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.
1520
        \note Linear time complexity.
1521
    */
1522
    void RemoveAllMembers() {
1523
        RAPIDJSON_ASSERT(IsObject()); 
1524
        DoClearMembers();
1525
    }
1526
1527
    //! Remove a member in object by its name.
1528
    /*! \param name Name of member to be removed.
1529
        \return Whether the member existed.
1530
        \note This function may reorder the object members. Use \ref
1531
            EraseMember(ConstMemberIterator) if you need to preserve the
1532
            relative order of the remaining members.
1533
        \note Linear time complexity.
1534
    */
1535
    bool RemoveMember(const Ch* name) {
1536
        GenericValue n(StringRef(name));
1537
        return RemoveMember(n);
1538
    }
1539
1540
#if RAPIDJSON_HAS_STDSTRING
1541
    bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1542
#endif
1543
1544
    template <typename SourceAllocator>
1545
    bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1546
        MemberIterator m = FindMember(name);
1547
        if (m != MemberEnd()) {
1548
            RemoveMember(m);
1549
            return true;
1550
        }
1551
        else
1552
            return false;
1553
    }
1554
1555
    //! Remove a member in object by iterator.
1556
    /*! \param m member iterator (obtained by FindMember() or MemberBegin()).
1557
        \return the new iterator after removal.
1558
        \note This function may reorder the object members. Use \ref
1559
            EraseMember(ConstMemberIterator) if you need to preserve the
1560
            relative order of the remaining members.
1561
        \note Constant time complexity.
1562
    */
1563
    MemberIterator RemoveMember(MemberIterator m) {
1564
        RAPIDJSON_ASSERT(IsObject());
1565
        RAPIDJSON_ASSERT(data_.o.size > 0);
1566
        RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1567
        RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1568
        return DoRemoveMember(m);
1569
    }
1570
1571
    //! Remove a member from an object by iterator.
1572
    /*! \param pos iterator to the member to remove
1573
        \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd()
1574
        \return Iterator following the removed element.
1575
            If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned.
1576
        \note This function preserves the relative order of the remaining object
1577
            members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator).
1578
        \note Linear time complexity.
1579
    */
1580
    MemberIterator EraseMember(ConstMemberIterator pos) {
1581
        return EraseMember(pos, pos +1);
1582
    }
1583
1584
    //! Remove members in the range [first, last) from an object.
1585
    /*! \param first iterator to the first member to remove
1586
        \param last  iterator following the last member to remove
1587
        \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd()
1588
        \return Iterator following the last removed element.
1589
        \note This function preserves the relative order of the remaining object
1590
            members.
1591
        \note Linear time complexity.
1592
    */
1593
    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1594
        RAPIDJSON_ASSERT(IsObject());
1595
        RAPIDJSON_ASSERT(data_.o.size > 0);
1596
        RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1597
        RAPIDJSON_ASSERT(first >= MemberBegin());
1598
        RAPIDJSON_ASSERT(first <= last);
1599
        RAPIDJSON_ASSERT(last <= MemberEnd());
1600
        return DoEraseMembers(first, last);
1601
    }
1602
1603
    //! Erase a member in object by its name.
1604
    /*! \param name Name of member to be removed.
1605
        \return Whether the member existed.
1606
        \note Linear time complexity.
1607
    */
1608
    bool EraseMember(const Ch* name) {
1609
        GenericValue n(StringRef(name));
1610
        return EraseMember(n);
1611
    }
1612
1613
#if RAPIDJSON_HAS_STDSTRING
1614
    bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1615
#endif
1616
1617
    template <typename SourceAllocator>
1618
    bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1619
        MemberIterator m = FindMember(name);
1620
        if (m != MemberEnd()) {
1621
            EraseMember(m);
1622
            return true;
1623
        }
1624
        else
1625
            return false;
1626
    }
1627
1628
    Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1629
    Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1630
    ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1631
    ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1632
1633
    //@}
1634
1635
    //!@name Array
1636
    //@{
1637
1638
    //! Set this value as an empty array.
1639
    /*! \post IsArray == true */
1640
    GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1641
1642
    //! Get the number of elements in array.
1643
    SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1644
1645
    //! Get the capacity of array.
1646
    SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1647
1648
    //! Check whether the array is empty.
1649
    bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1650
1651
    //! Remove all elements in the array.
1652
    /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
1653
        \note Linear time complexity.
1654
    */
1655
    void Clear() {
1656
        RAPIDJSON_ASSERT(IsArray()); 
1657
        GenericValue* e = GetElementsPointer();
1658
        for (GenericValue* v = e; v != e + data_.a.size; ++v)
1659
            v->~GenericValue();
1660
        data_.a.size = 0;
1661
    }
1662
1663
    //! Get an element from array by index.
1664
    /*! \pre IsArray() == true
1665
        \param index Zero-based index of element.
1666
        \see operator[](T*)
1667
    */
1668
    GenericValue& operator[](SizeType index) {
1669
        RAPIDJSON_ASSERT(IsArray());
1670
        RAPIDJSON_ASSERT(index < data_.a.size);
1671
        return GetElementsPointer()[index];
1672
    }
1673
    const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1674
1675
    //! Element iterator
1676
    /*! \pre IsArray() == true */
1677
5.02k
    ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1678
    //! \em Past-the-end element iterator
1679
    /*! \pre IsArray() == true */
1680
12.2k
    ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1681
    //! Constant element iterator
1682
    /*! \pre IsArray() == true */
1683
5.02k
    ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1684
    //! Constant \em past-the-end element iterator
1685
    /*! \pre IsArray() == true */
1686
12.2k
    ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1687
1688
    //! Request the array to have enough capacity to store elements.
1689
    /*! \param newCapacity  The capacity that the array at least need to have.
1690
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1691
        \return The value itself for fluent API.
1692
        \note Linear time complexity.
1693
    */
1694
    GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1695
        RAPIDJSON_ASSERT(IsArray());
1696
        if (newCapacity > data_.a.capacity) {
1697
            SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1698
            data_.a.capacity = newCapacity;
1699
        }
1700
        return *this;
1701
    }
1702
1703
    //! Append a GenericValue at the end of the array.
1704
    /*! \param value        Value to be appended.
1705
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1706
        \pre IsArray() == true
1707
        \post value.IsNull() == true
1708
        \return The value itself for fluent API.
1709
        \note The ownership of \c value will be transferred to this array on success.
1710
        \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1711
        \note Amortized constant time complexity.
1712
    */
1713
    GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1714
        RAPIDJSON_ASSERT(IsArray());
1715
        if (data_.a.size >= data_.a.capacity)
1716
            Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1717
        GetElementsPointer()[data_.a.size++].RawAssign(value);
1718
        return *this;
1719
    }
1720
1721
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1722
    GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1723
        return PushBack(value, allocator);
1724
    }
1725
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1726
1727
    //! Append a constant string reference at the end of the array.
1728
    /*! \param value        Constant string reference to be appended.
1729
        \param allocator    Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().
1730
        \pre IsArray() == true
1731
        \return The value itself for fluent API.
1732
        \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1733
        \note Amortized constant time complexity.
1734
        \see GenericStringRef
1735
    */
1736
    GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1737
        return (*this).template PushBack<StringRefType>(value, allocator);
1738
    }
1739
1740
    //! Append a primitive value at the end of the array.
1741
    /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1742
        \param value Value of primitive type T to be appended.
1743
        \param allocator    Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1744
        \pre IsArray() == true
1745
        \return The value itself for fluent API.
1746
        \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1747
1748
        \note The source type \c T explicitly disallows all pointer types,
1749
            especially (\c const) \ref Ch*.  This helps avoiding implicitly
1750
            referencing character strings with insufficient lifetime, use
1751
            \ref PushBack(GenericValue&, Allocator&) or \ref
1752
            PushBack(StringRefType, Allocator&).
1753
            All other pointer types would implicitly convert to \c bool,
1754
            use an explicit cast instead, if needed.
1755
        \note Amortized constant time complexity.
1756
    */
1757
    template <typename T>
1758
    RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1759
    PushBack(T value, Allocator& allocator) {
1760
        GenericValue v(value);
1761
        return PushBack(v, allocator);
1762
    }
1763
1764
    //! Remove the last element in the array.
1765
    /*!
1766
        \note Constant time complexity.
1767
    */
1768
    GenericValue& PopBack() {
1769
        RAPIDJSON_ASSERT(IsArray());
1770
        RAPIDJSON_ASSERT(!Empty());
1771
        GetElementsPointer()[--data_.a.size].~GenericValue();
1772
        return *this;
1773
    }
1774
1775
    //! Remove an element of array by iterator.
1776
    /*!
1777
        \param pos iterator to the element to remove
1778
        \pre IsArray() == true && \ref Begin() <= \c pos < \ref End()
1779
        \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.
1780
        \note Linear time complexity.
1781
    */
1782
    ValueIterator Erase(ConstValueIterator pos) {
1783
        return Erase(pos, pos + 1);
1784
    }
1785
1786
    //! Remove elements in the range [first, last) of the array.
1787
    /*!
1788
        \param first iterator to the first element to remove
1789
        \param last  iterator following the last element to remove
1790
        \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End()
1791
        \return Iterator following the last removed element.
1792
        \note Linear time complexity.
1793
    */
1794
    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1795
        RAPIDJSON_ASSERT(IsArray());
1796
        RAPIDJSON_ASSERT(data_.a.size > 0);
1797
        RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1798
        RAPIDJSON_ASSERT(first >= Begin());
1799
        RAPIDJSON_ASSERT(first <= last);
1800
        RAPIDJSON_ASSERT(last <= End());
1801
        ValueIterator pos = Begin() + (first - Begin());
1802
        for (ValueIterator itr = pos; itr != last; ++itr)
1803
            itr->~GenericValue();
1804
        std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1805
        data_.a.size -= static_cast<SizeType>(last - first);
1806
        return pos;
1807
    }
1808
1809
    Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1810
    ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1811
1812
    //@}
1813
1814
    //!@name Number
1815
    //@{
1816
1817
    int GetInt() const          { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);   return data_.n.i.i;   }
1818
    unsigned GetUint() const    { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);  return data_.n.u.u;   }
1819
    int64_t GetInt64() const    { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1820
    uint64_t GetUint64() const  { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1821
1822
    //! Get the value as double type.
1823
    /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless.
1824
    */
1825
    double GetDouble() const {
1826
        RAPIDJSON_ASSERT(IsNumber());
1827
        if ((data_.f.flags & kDoubleFlag) != 0)                return data_.n.d;   // exact type, no conversion.
1828
        if ((data_.f.flags & kIntFlag) != 0)                   return data_.n.i.i; // int -> double
1829
        if ((data_.f.flags & kUintFlag) != 0)                  return data_.n.u.u; // unsigned -> double
1830
        if ((data_.f.flags & kInt64Flag) != 0)                 return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1831
        RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1832
    }
1833
1834
    //! Get the value as float type.
1835
    /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless.
1836
    */
1837
    float GetFloat() const {
1838
        return static_cast<float>(GetDouble());
1839
    }
1840
1841
    GenericValue& SetInt(int i)             { this->~GenericValue(); new (this) GenericValue(i);    return *this; }
1842
    GenericValue& SetUint(unsigned u)       { this->~GenericValue(); new (this) GenericValue(u);    return *this; }
1843
    GenericValue& SetInt64(int64_t i64)     { this->~GenericValue(); new (this) GenericValue(i64);  return *this; }
1844
    GenericValue& SetUint64(uint64_t u64)   { this->~GenericValue(); new (this) GenericValue(u64);  return *this; }
1845
    GenericValue& SetDouble(double d)       { this->~GenericValue(); new (this) GenericValue(d);    return *this; }
1846
    GenericValue& SetFloat(float f)         { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1847
1848
    //@}
1849
1850
    //!@name String
1851
    //@{
1852
1853
1.72k
    const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
1854
1855
    //! Get the length of string.
1856
    /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
1857
    */
1858
1.72k
    SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
1859
1860
    //! Set this value as a string without copying source string.
1861
    /*! This version has better performance with supplied length, and also support string containing null character.
1862
        \param s source string pointer. 
1863
        \param length The length of source string, excluding the trailing null terminator.
1864
        \return The value itself for fluent API.
1865
        \post IsString() == true && GetString() == s && GetStringLength() == length
1866
        \see SetString(StringRefType)
1867
    */
1868
    GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1869
1870
    //! Set this value as a string without copying source string.
1871
    /*! \param s source string reference
1872
        \return The value itself for fluent API.
1873
        \post IsString() == true && GetString() == s && GetStringLength() == s.length
1874
    */
1875
    GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1876
1877
    //! Set this value as a string by copying from source string.
1878
    /*! This version has better performance with supplied length, and also support string containing null character.
1879
        \param s source string. 
1880
        \param length The length of source string, excluding the trailing null terminator.
1881
        \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1882
        \return The value itself for fluent API.
1883
        \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1884
    */
1885
    GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1886
1887
    //! Set this value as a string by copying from source string.
1888
    /*! \param s source string. 
1889
        \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1890
        \return The value itself for fluent API.
1891
        \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1892
    */
1893
    GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1894
1895
    //! Set this value as a string by copying from source string.
1896
    /*! \param s source string reference
1897
        \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1898
        \return The value itself for fluent API.
1899
        \post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1900
    */
1901
    GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1902
1903
#if RAPIDJSON_HAS_STDSTRING
1904
    //! Set this value as a string by copying from source string.
1905
    /*! \param s source string.
1906
        \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1907
        \return The value itself for fluent API.
1908
        \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()
1909
        \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
1910
    */
1911
    GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1912
#endif
1913
1914
    //@}
1915
1916
    //!@name Array
1917
    //@{
1918
1919
    //! Templated version for checking whether this value is type T.
1920
    /*!
1921
        \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string<Ch>
1922
    */
1923
    template <typename T>
1924
    bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1925
1926
    template <typename T>
1927
    T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1928
1929
    template <typename T>
1930
    T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1931
1932
    template<typename T>
1933
    ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1934
1935
    template<typename T>
1936
    ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1937
1938
    //@}
1939
1940
    //! Generate events of this value to a Handler.
1941
    /*! This function adopts the GoF visitor pattern.
1942
        Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.
1943
        It can also be used to deep clone this value via GenericDocument, which is also a Handler.
1944
        \tparam Handler type of handler.
1945
        \param handler An object implementing concept Handler.
1946
    */
1947
    template <typename Handler>
1948
7.30k
    bool Accept(Handler& handler) const {
1949
7.30k
        switch(GetType()) {
1950
4
        case kNullType:     return handler.Null();
1951
0
        case kFalseType:    return handler.Bool(false);
1952
4
        case kTrueType:     return handler.Bool(true);
1953
1954
4
        case kObjectType:
1955
4
            if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1956
0
                return false;
1957
8
            for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1958
4
                RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1959
4
                if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1960
0
                    return false;
1961
4
                if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1962
0
                    return false;
1963
4
            }
1964
4
            return handler.EndObject(data_.o.size);
1965
1966
5.02k
        case kArrayType:
1967
5.02k
            if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1968
0
                return false;
1969
12.2k
            for (ConstValueIterator v = Begin(); v != End(); ++v)
1970
7.26k
                if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1971
0
                    return false;
1972
5.02k
            return handler.EndArray(data_.a.size);
1973
    
1974
1.72k
        case kStringType:
1975
1.72k
            return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1976
    
1977
549
        default:
1978
549
            RAPIDJSON_ASSERT(GetType() == kNumberType);
1979
549
            if (IsDouble())         return handler.Double(data_.n.d);
1980
45
            else if (IsInt())       return handler.Int(data_.n.i.i);
1981
0
            else if (IsUint())      return handler.Uint(data_.n.u.u);
1982
0
            else if (IsInt64())     return handler.Int64(data_.n.i64);
1983
0
            else                    return handler.Uint64(data_.n.u64);
1984
7.30k
        }
1985
7.30k
    }
1986
1987
private:
1988
    template <typename, typename> friend class GenericValue;
1989
    template <typename, typename, typename> friend class GenericDocument;
1990
1991
    enum {
1992
        kBoolFlag       = 0x0008,
1993
        kNumberFlag     = 0x0010,
1994
        kIntFlag        = 0x0020,
1995
        kUintFlag       = 0x0040,
1996
        kInt64Flag      = 0x0080,
1997
        kUint64Flag     = 0x0100,
1998
        kDoubleFlag     = 0x0200,
1999
        kStringFlag     = 0x0400,
2000
        kCopyFlag       = 0x0800,
2001
        kInlineStrFlag  = 0x1000,
2002
2003
        // Initial flags of different types.
2004
        kNullFlag = kNullType,
2005
        // These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types.
2006
        kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
2007
        kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
2008
        kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
2009
        kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
2010
        kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
2011
        kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
2012
        kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
2013
        kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
2014
        kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
2015
        kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
2016
        kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2017
        kObjectFlag = kObjectType,
2018
        kArrayFlag = kArrayType,
2019
2020
        kTypeMask = 0x07
2021
    };
2022
2023
    static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
2024
    static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
2025
2026
    struct Flag {
2027
#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2028
        char payload[sizeof(SizeType) * 2 + 6];     // 2 x SizeType + lower 48-bit pointer
2029
#elif RAPIDJSON_64BIT
2030
        char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
2031
#else
2032
        char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
2033
#endif
2034
        uint16_t flags;
2035
    };
2036
2037
    struct String {
2038
        SizeType length;
2039
        SizeType hashcode;  //!< reserved
2040
        const Ch* str;
2041
    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2042
2043
    // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
2044
    // (excluding the terminating zero) and store a value to determine the length of the contained
2045
    // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
2046
    // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
2047
    // the string terminator as well. For getting the string length back from that value just use
2048
    // "MaxSize - str[LenPos]".
2049
    // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2050
    // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
2051
    struct ShortString {
2052
        enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2053
        Ch str[MaxChars];
2054
2055
2.44M
        inline static bool Usable(SizeType len) { return                       (MaxSize >= len); }
2056
2.43M
        inline void     SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize -  len); }
2057
1.68k
        inline SizeType GetLength() const       { return  static_cast<SizeType>(MaxSize -  str[LenPos]); }
2058
    };  // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2059
2060
    // By using proper binary layout, retrieval of different integer types do not need conversions.
2061
    union Number {
2062
#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2063
        struct I {
2064
            int i;
2065
            char padding[4];
2066
        }i;
2067
        struct U {
2068
            unsigned u;
2069
            char padding2[4];
2070
        }u;
2071
#else
2072
        struct I {
2073
            char padding[4];
2074
            int i;
2075
        }i;
2076
        struct U {
2077
            char padding2[4];
2078
            unsigned u;
2079
        }u;
2080
#endif
2081
        int64_t i64;
2082
        uint64_t u64;
2083
        double d;
2084
    };  // 8 bytes
2085
2086
    struct ObjectData {
2087
        SizeType size;
2088
        SizeType capacity;
2089
        Member* members;
2090
    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2091
2092
    struct ArrayData {
2093
        SizeType size;
2094
        SizeType capacity;
2095
        GenericValue* elements;
2096
    };  // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2097
2098
    union Data {
2099
        String s;
2100
        ShortString ss;
2101
        Number n;
2102
        ObjectData o;
2103
        ArrayData a;
2104
        Flag f;
2105
    };  // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2106
2107
1.72k
    static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
2108
1.72k
        return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
2109
1.72k
    }
2110
1.72k
    static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
2111
1.72k
        return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2112
1.72k
    }
2113
2114
0
    RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2115
2.30k
    RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2116
17.3k
    RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2117
23.8k
    RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2118
12
    RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2119
8
    RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2120
2121
#if RAPIDJSON_USE_MEMBERSMAP
2122
2123
    struct MapTraits {
2124
        struct Less {
2125
            bool operator()(const Data& s1, const Data& s2) const {
2126
                SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
2127
                int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2));
2128
                return cmp < 0 || (cmp == 0 && n1 < n2);
2129
            }
2130
        };
2131
        typedef std::pair<const Data, SizeType> Pair;
2132
        typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
2133
        typedef typename Map::iterator Iterator;
2134
    };
2135
    typedef typename MapTraits::Map         Map;
2136
    typedef typename MapTraits::Less        MapLess;
2137
    typedef typename MapTraits::Pair        MapPair;
2138
    typedef typename MapTraits::Iterator    MapIterator;
2139
2140
    //
2141
    // Layout of the members' map/array, re(al)located according to the needed capacity:
2142
    //
2143
    //    {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]}
2144
    //
2145
    // (where <> stands for the RAPIDJSON_ALIGN-ment, if needed)
2146
    //
2147
2148
    static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) {
2149
        return RAPIDJSON_ALIGN(sizeof(Map*)) +
2150
               RAPIDJSON_ALIGN(sizeof(SizeType)) +
2151
               RAPIDJSON_ALIGN(capacity * sizeof(Member)) +
2152
               capacity * sizeof(MapIterator);
2153
    }
2154
2155
    static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) {
2156
        return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
2157
                                            RAPIDJSON_ALIGN(sizeof(Map*)));
2158
    }
2159
2160
    static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) {
2161
        return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
2162
                                         RAPIDJSON_ALIGN(sizeof(Map*)) +
2163
                                         RAPIDJSON_ALIGN(sizeof(SizeType)));
2164
    }
2165
2166
    static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
2167
        return reinterpret_cast<MapIterator*>(reinterpret_cast<uintptr_t>(&map) +
2168
                                              RAPIDJSON_ALIGN(sizeof(Map*)) +
2169
                                              RAPIDJSON_ALIGN(sizeof(SizeType)) +
2170
                                              RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member)));
2171
    }
2172
2173
    static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) {
2174
        RAPIDJSON_ASSERT(members != 0);
2175
        return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
2176
                                        RAPIDJSON_ALIGN(sizeof(SizeType)) -
2177
                                        RAPIDJSON_ALIGN(sizeof(Map*)));
2178
    }
2179
2180
    // Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting..
2181
    RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
2182
#if RAPIDJSON_HAS_CXX11
2183
        MapIterator ret = std::move(rhs);
2184
#else
2185
        MapIterator ret = rhs;
2186
#endif
2187
        rhs.~MapIterator();
2188
        return ret;
2189
    }
2190
2191
    Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) {
2192
        Map **newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
2193
        GetMapCapacity(*newMap) = newCapacity;
2194
        if (!oldMap) {
2195
            *newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator);
2196
        }
2197
        else {
2198
            *newMap = *oldMap;
2199
            size_t count = (*oldMap)->size();
2200
            std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
2201
                        static_cast<void*>(GetMapMembers(*oldMap)),
2202
                        count * sizeof(Member));
2203
            MapIterator *oldIt = GetMapIterators(*oldMap),
2204
                        *newIt = GetMapIterators(*newMap);
2205
            while (count--) {
2206
                new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
2207
            }
2208
            Allocator::Free(oldMap);
2209
        }
2210
        return *newMap;
2211
    }
2212
2213
    RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2214
        return GetMapMembers(DoReallocMap(0, capacity, allocator));
2215
    }
2216
2217
    void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2218
        ObjectData& o = data_.o;
2219
        if (newCapacity > o.capacity) {
2220
            Member* oldMembers = GetMembersPointer();
2221
            Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
2222
                *&newMap = DoReallocMap(oldMap, newCapacity, allocator);
2223
            RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
2224
            o.capacity = newCapacity;
2225
        }
2226
    }
2227
2228
    template <typename SourceAllocator>
2229
    MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2230
        if (Member* members = GetMembersPointer()) {
2231
            Map* &map = GetMap(members);
2232
            MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
2233
            if (mit != map->end()) {
2234
                return MemberIterator(&members[mit->second]);
2235
            }
2236
        }
2237
        return MemberEnd();
2238
    }
2239
2240
    void DoClearMembers() {
2241
        if (Member* members = GetMembersPointer()) {
2242
            Map* &map = GetMap(members);
2243
            MapIterator* mit = GetMapIterators(map);
2244
            for (SizeType i = 0; i < data_.o.size; i++) {
2245
                map->erase(DropMapIterator(mit[i]));
2246
                members[i].~Member();
2247
            }
2248
            data_.o.size = 0;
2249
        }
2250
    }
2251
2252
    void DoFreeMembers() {
2253
        if (Member* members = GetMembersPointer()) {
2254
            GetMap(members)->~Map();
2255
            for (SizeType i = 0; i < data_.o.size; i++) {
2256
                members[i].~Member();
2257
            }
2258
            if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
2259
                Map** map = &GetMap(members);
2260
                Allocator::Free(*map);
2261
                Allocator::Free(map);
2262
            }
2263
        }
2264
    }
2265
2266
#else // !RAPIDJSON_USE_MEMBERSMAP
2267
2268
8
    RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2269
8
        return Malloc<Member>(allocator, capacity);
2270
8
    }
2271
2272
    void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2273
        ObjectData& o = data_.o;
2274
        if (newCapacity > o.capacity) {
2275
            Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2276
            RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
2277
            o.capacity = newCapacity;
2278
        }
2279
    }
2280
2281
    template <typename SourceAllocator>
2282
    MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2283
        MemberIterator member = MemberBegin();
2284
        for ( ; member != MemberEnd(); ++member)
2285
            if (name.StringEqual(member->name))
2286
                break;
2287
        return member;
2288
    }
2289
2290
    void DoClearMembers() {
2291
        for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2292
            m->~Member();
2293
        data_.o.size = 0;
2294
    }
2295
2296
0
    void DoFreeMembers() {
2297
0
        for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2298
0
            m->~Member();
2299
0
        Allocator::Free(GetMembersPointer());
2300
0
    }
2301
2302
#endif // !RAPIDJSON_USE_MEMBERSMAP
2303
2304
    void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
2305
        ObjectData& o = data_.o;
2306
        if (o.size >= o.capacity)
2307
            DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
2308
        Member* members = GetMembersPointer();
2309
        Member* m = members + o.size;
2310
        m->name.RawAssign(name);
2311
        m->value.RawAssign(value);
2312
#if RAPIDJSON_USE_MEMBERSMAP
2313
        Map* &map = GetMap(members);
2314
        MapIterator* mit = GetMapIterators(map);
2315
        new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
2316
#endif
2317
        ++o.size;
2318
    }
2319
2320
    MemberIterator DoRemoveMember(MemberIterator m) {
2321
        ObjectData& o = data_.o;
2322
        Member* members = GetMembersPointer();
2323
#if RAPIDJSON_USE_MEMBERSMAP
2324
        Map* &map = GetMap(members);
2325
        MapIterator* mit = GetMapIterators(map);
2326
        SizeType mpos = static_cast<SizeType>(&*m - members);
2327
        map->erase(DropMapIterator(mit[mpos]));
2328
#endif
2329
        MemberIterator last(members + (o.size - 1));
2330
        if (o.size > 1 && m != last) {
2331
#if RAPIDJSON_USE_MEMBERSMAP
2332
            new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
2333
            mit[mpos]->second = mpos;
2334
#endif
2335
            *m = *last; // Move the last one to this place
2336
        }
2337
        else {
2338
            m->~Member(); // Only one left, just destroy
2339
        }
2340
        --o.size;
2341
        return m;
2342
    }
2343
2344
    MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) {
2345
        ObjectData& o = data_.o;
2346
        MemberIterator beg = MemberBegin(),
2347
                       pos = beg + (first - beg),
2348
                       end = MemberEnd();
2349
#if RAPIDJSON_USE_MEMBERSMAP
2350
        Map* &map = GetMap(GetMembersPointer());
2351
        MapIterator* mit = GetMapIterators(map);
2352
#endif
2353
        for (MemberIterator itr = pos; itr != last; ++itr) {
2354
#if RAPIDJSON_USE_MEMBERSMAP
2355
            map->erase(DropMapIterator(mit[itr - beg]));
2356
#endif
2357
            itr->~Member();
2358
        }
2359
#if RAPIDJSON_USE_MEMBERSMAP
2360
        if (first != last) {
2361
            // Move remaining members/iterators
2362
            MemberIterator next = pos + (last - first);
2363
            for (MemberIterator itr = pos; next != end; ++itr, ++next) {
2364
                std::memcpy(static_cast<void*>(&*itr), &*next, sizeof(Member));
2365
                SizeType mpos = static_cast<SizeType>(itr - beg);
2366
                new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
2367
                mit[mpos]->second = mpos;
2368
            }
2369
        }
2370
#else
2371
        std::memmove(static_cast<void*>(&*pos), &*last,
2372
                     static_cast<size_t>(end - last) * sizeof(Member));
2373
#endif
2374
        o.size -= static_cast<SizeType>(last - first);
2375
        return pos;
2376
    }
2377
2378
    template <typename SourceAllocator>
2379
    void DoCopyMembers(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings) {
2380
        RAPIDJSON_ASSERT(rhs.GetType() == kObjectType);
2381
2382
        data_.f.flags = kObjectFlag;
2383
        SizeType count = rhs.data_.o.size;
2384
        Member* lm = DoAllocMembers(count, allocator);
2385
        const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
2386
#if RAPIDJSON_USE_MEMBERSMAP
2387
        Map* &map = GetMap(lm);
2388
        MapIterator* mit = GetMapIterators(map);
2389
#endif
2390
        for (SizeType i = 0; i < count; i++) {
2391
            new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
2392
            new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
2393
#if RAPIDJSON_USE_MEMBERSMAP
2394
            new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
2395
#endif
2396
        }
2397
        data_.o.size = data_.o.capacity = count;
2398
        SetMembersPointer(lm);
2399
    }
2400
2401
    // Initialize this value as array with initial data, without calling destructor.
2402
23.8k
    void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2403
23.8k
        data_.f.flags = kArrayFlag;
2404
23.8k
        if (count) {
2405
23.8k
            GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2406
23.8k
            SetElementsPointer(e);
2407
23.8k
            std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2408
23.8k
        }
2409
50
        else
2410
50
            SetElementsPointer(0);
2411
23.8k
        data_.a.size = data_.a.capacity = count;
2412
23.8k
    }
2413
2414
    //! Initialize this value as object with initial data, without calling destructor.
2415
8
    void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2416
8
        data_.f.flags = kObjectFlag;
2417
8
        if (count) {
2418
8
            Member* m = DoAllocMembers(count, allocator);
2419
8
            SetMembersPointer(m);
2420
8
            std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2421
#if RAPIDJSON_USE_MEMBERSMAP
2422
            Map* &map = GetMap(m);
2423
            MapIterator* mit = GetMapIterators(map);
2424
            for (SizeType i = 0; i < count; i++) {
2425
                new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
2426
            }
2427
#endif
2428
8
        }
2429
0
        else
2430
0
            SetMembersPointer(0);
2431
8
        data_.o.size = data_.o.capacity = count;
2432
8
    }
2433
2434
    //! Initialize this value as constant string, without calling destructor.
2435
0
    void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2436
0
        data_.f.flags = kConstStringFlag;
2437
0
        SetStringPointer(s);
2438
0
        data_.s.length = s.length;
2439
0
    }
2440
2441
    //! Initialize this value as copy string with initial data, without calling destructor.
2442
2.44M
    void SetStringRaw(StringRefType s, Allocator& allocator) {
2443
2.44M
        Ch* str = 0;
2444
2.44M
        if (ShortString::Usable(s.length)) {
2445
2.43M
            data_.f.flags = kShortStringFlag;
2446
2.43M
            data_.ss.SetLength(s.length);
2447
2.43M
            str = data_.ss.str;
2448
2.43M
            std::memmove(str, s, s.length * sizeof(Ch));
2449
2.43M
        } else {
2450
2.30k
            data_.f.flags = kCopyStringFlag;
2451
2.30k
            data_.s.length = s.length;
2452
2.30k
            str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2453
2.30k
            SetStringPointer(str);
2454
2.30k
            std::memcpy(str, s, s.length * sizeof(Ch));
2455
2.30k
        }
2456
2.44M
        str[s.length] = '\0';
2457
2.44M
    }
2458
2459
    //! Assignment without calling destructor
2460
68
    void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2461
68
        data_ = rhs.data_;
2462
        // data_.f.flags = rhs.data_.f.flags;
2463
68
        rhs.data_.f.flags = kNullFlag;
2464
68
    }
2465
2466
    template <typename SourceAllocator>
2467
    bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2468
        RAPIDJSON_ASSERT(IsString());
2469
        RAPIDJSON_ASSERT(rhs.IsString());
2470
2471
        const SizeType len1 = GetStringLength();
2472
        const SizeType len2 = rhs.GetStringLength();
2473
        if(len1 != len2) { return false; }
2474
2475
        const Ch* const str1 = GetString();
2476
        const Ch* const str2 = rhs.GetString();
2477
        if(str1 == str2) { return true; } // fast path for constant string
2478
2479
        return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2480
    }
2481
2482
    Data data_;
2483
};
2484
2485
//! GenericValue with UTF8 encoding
2486
typedef GenericValue<UTF8<> > Value;
2487
2488
///////////////////////////////////////////////////////////////////////////////
2489
// GenericDocument 
2490
2491
//! A document for parsing JSON text as DOM.
2492
/*!
2493
    \note implements Handler concept
2494
    \tparam Encoding Encoding for both parsing and string storage.
2495
    \tparam Allocator Allocator for allocating memory for the DOM
2496
    \tparam StackAllocator Allocator for allocating memory for stack during parsing.
2497
    \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor.  To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue.
2498
*/
2499
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2500
class GenericDocument : public GenericValue<Encoding, Allocator> {
2501
public:
2502
    typedef typename Encoding::Ch Ch;                       //!< Character type derived from Encoding.
2503
    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of the document.
2504
    typedef Allocator AllocatorType;                        //!< Allocator type from template parameter.
2505
    typedef StackAllocator StackAllocatorType;              //!< StackAllocator type from template parameter.
2506
2507
    //! Constructor
2508
    /*! Creates an empty document of specified type.
2509
        \param type             Mandatory type of object to create.
2510
        \param allocator        Optional allocator for allocating memory.
2511
        \param stackCapacity    Optional initial capacity of stack in bytes.
2512
        \param stackAllocator   Optional allocator for allocating memory for stack.
2513
    */
2514
    explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2515
        GenericValue<Encoding, Allocator>(type),  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2516
    {
2517
        if (!allocator_)
2518
            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2519
    }
2520
2521
    //! Constructor
2522
    /*! Creates an empty document which type is Null. 
2523
        \param allocator        Optional allocator for allocating memory.
2524
        \param stackCapacity    Optional initial capacity of stack in bytes.
2525
        \param stackAllocator   Optional allocator for allocating memory for stack.
2526
    */
2527
    GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : 
2528
108
        allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2529
108
    {
2530
108
        if (!allocator_)
2531
108
            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2532
108
    }
2533
2534
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2535
    //! Move constructor in C++11
2536
    GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2537
        : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2538
          allocator_(rhs.allocator_),
2539
          ownAllocator_(rhs.ownAllocator_),
2540
          stack_(std::move(rhs.stack_)),
2541
          parseResult_(rhs.parseResult_)
2542
    {
2543
        rhs.allocator_ = 0;
2544
        rhs.ownAllocator_ = 0;
2545
        rhs.parseResult_ = ParseResult();
2546
    }
2547
#endif
2548
2549
108
    ~GenericDocument() {
2550
        // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
2551
        // runs last and may access its elements or members which would be freed
2552
        // with an allocator like MemoryPoolAllocator (CrtAllocator does not
2553
        // free its data when destroyed, but MemoryPoolAllocator does).
2554
108
        if (ownAllocator_) {
2555
108
            ValueType::SetNull();
2556
108
        }
2557
108
        Destroy();
2558
108
    }
2559
2560
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2561
    //! Move assignment in C++11
2562
    GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2563
    {
2564
        // The cast to ValueType is necessary here, because otherwise it would
2565
        // attempt to call GenericValue's templated assignment operator.
2566
        ValueType::operator=(std::forward<ValueType>(rhs));
2567
2568
        // Calling the destructor here would prematurely call stack_'s destructor
2569
        Destroy();
2570
2571
        allocator_ = rhs.allocator_;
2572
        ownAllocator_ = rhs.ownAllocator_;
2573
        stack_ = std::move(rhs.stack_);
2574
        parseResult_ = rhs.parseResult_;
2575
2576
        rhs.allocator_ = 0;
2577
        rhs.ownAllocator_ = 0;
2578
        rhs.parseResult_ = ParseResult();
2579
2580
        return *this;
2581
    }
2582
#endif
2583
2584
    //! Exchange the contents of this document with those of another.
2585
    /*!
2586
        \param rhs Another document.
2587
        \note Constant complexity.
2588
        \see GenericValue::Swap
2589
    */
2590
    GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2591
        ValueType::Swap(rhs);
2592
        stack_.Swap(rhs.stack_);
2593
        internal::Swap(allocator_, rhs.allocator_);
2594
        internal::Swap(ownAllocator_, rhs.ownAllocator_);
2595
        internal::Swap(parseResult_, rhs.parseResult_);
2596
        return *this;
2597
    }
2598
2599
    // Allow Swap with ValueType.
2600
    // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2601
    using ValueType::Swap;
2602
2603
    //! free-standing swap function helper
2604
    /*!
2605
        Helper function to enable support for common swap implementation pattern based on \c std::swap:
2606
        \code
2607
        void swap(MyClass& a, MyClass& b) {
2608
            using std::swap;
2609
            swap(a.doc, b.doc);
2610
            // ...
2611
        }
2612
        \endcode
2613
        \see Swap()
2614
     */
2615
    friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2616
2617
    //! Populate this document by a generator which produces SAX events.
2618
    /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.
2619
        \param g Generator functor which sends SAX events to the parameter.
2620
        \return The document itself for fluent API.
2621
    */
2622
    template <typename Generator>
2623
    GenericDocument& Populate(Generator& g) {
2624
        ClearStackOnExit scope(*this);
2625
        if (g(*this)) {
2626
            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2627
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2628
        }
2629
        return *this;
2630
    }
2631
2632
    //!@name Parse from stream
2633
    //!@{
2634
2635
    //! Parse JSON text from an input stream (with Encoding conversion)
2636
    /*! \tparam parseFlags Combination of \ref ParseFlag.
2637
        \tparam SourceEncoding Encoding of input stream
2638
        \tparam InputStream Type of input stream, implementing Stream concept
2639
        \param is Input stream to be parsed.
2640
        \return The document itself for fluent API.
2641
    */
2642
    template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2643
108
    GenericDocument& ParseStream(InputStream& is) {
2644
108
        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2645
108
            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2646
108
        ClearStackOnExit scope(*this);
2647
108
        parseResult_ = reader.template Parse<parseFlags>(is, *this);
2648
108
        if (parseResult_) {
2649
34
            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2650
34
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2651
34
        }
2652
108
        return *this;
2653
108
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::ParseStream<0u, rapidjson::UTF8<char>, rapidjson::GenericStringStream<rapidjson::UTF8<char> > >(rapidjson::GenericStringStream<rapidjson::UTF8<char> >&)
Line
Count
Source
2643
27
    GenericDocument& ParseStream(InputStream& is) {
2644
27
        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2645
27
            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2646
27
        ClearStackOnExit scope(*this);
2647
27
        parseResult_ = reader.template Parse<parseFlags>(is, *this);
2648
27
        if (parseResult_) {
2649
7
            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2650
7
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2651
7
        }
2652
27
        return *this;
2653
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::ParseStream<16u, rapidjson::UTF8<char>, rapidjson::GenericStringStream<rapidjson::UTF8<char> > >(rapidjson::GenericStringStream<rapidjson::UTF8<char> >&)
Line
Count
Source
2643
27
    GenericDocument& ParseStream(InputStream& is) {
2644
27
        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2645
27
            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2646
27
        ClearStackOnExit scope(*this);
2647
27
        parseResult_ = reader.template Parse<parseFlags>(is, *this);
2648
27
        if (parseResult_) {
2649
7
            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2650
7
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2651
7
        }
2652
27
        return *this;
2653
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::ParseStream<64u, rapidjson::UTF8<char>, rapidjson::GenericStringStream<rapidjson::UTF8<char> > >(rapidjson::GenericStringStream<rapidjson::UTF8<char> >&)
Line
Count
Source
2643
27
    GenericDocument& ParseStream(InputStream& is) {
2644
27
        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2645
27
            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2646
27
        ClearStackOnExit scope(*this);
2647
27
        parseResult_ = reader.template Parse<parseFlags>(is, *this);
2648
27
        if (parseResult_) {
2649
13
            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2650
13
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2651
13
        }
2652
27
        return *this;
2653
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::ParseStream<32u, rapidjson::UTF8<char>, rapidjson::GenericStringStream<rapidjson::UTF8<char> > >(rapidjson::GenericStringStream<rapidjson::UTF8<char> >&)
Line
Count
Source
2643
27
    GenericDocument& ParseStream(InputStream& is) {
2644
27
        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2645
27
            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2646
27
        ClearStackOnExit scope(*this);
2647
27
        parseResult_ = reader.template Parse<parseFlags>(is, *this);
2648
27
        if (parseResult_) {
2649
7
            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2650
7
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2651
7
        }
2652
27
        return *this;
2653
27
    }
2654
2655
    //! Parse JSON text from an input stream
2656
    /*! \tparam parseFlags Combination of \ref ParseFlag.
2657
        \tparam InputStream Type of input stream, implementing Stream concept
2658
        \param is Input stream to be parsed.
2659
        \return The document itself for fluent API.
2660
    */
2661
    template <unsigned parseFlags, typename InputStream>
2662
    GenericDocument& ParseStream(InputStream& is) {
2663
        return ParseStream<parseFlags, Encoding, InputStream>(is);
2664
    }
2665
2666
    //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
2667
    /*! \tparam InputStream Type of input stream, implementing Stream concept
2668
        \param is Input stream to be parsed.
2669
        \return The document itself for fluent API.
2670
    */
2671
    template <typename InputStream>
2672
    GenericDocument& ParseStream(InputStream& is) {
2673
        return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2674
    }
2675
    //!@}
2676
2677
    //!@name Parse in-place from mutable string
2678
    //!@{
2679
2680
    //! Parse JSON text from a mutable string
2681
    /*! \tparam parseFlags Combination of \ref ParseFlag.
2682
        \param str Mutable zero-terminated string to be parsed.
2683
        \return The document itself for fluent API.
2684
    */
2685
    template <unsigned parseFlags>
2686
    GenericDocument& ParseInsitu(Ch* str) {
2687
        GenericInsituStringStream<Encoding> s(str);
2688
        return ParseStream<parseFlags | kParseInsituFlag>(s);
2689
    }
2690
2691
    //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
2692
    /*! \param str Mutable zero-terminated string to be parsed.
2693
        \return The document itself for fluent API.
2694
    */
2695
    GenericDocument& ParseInsitu(Ch* str) {
2696
        return ParseInsitu<kParseDefaultFlags>(str);
2697
    }
2698
    //!@}
2699
2700
    //!@name Parse from read-only string
2701
    //!@{
2702
2703
    //! Parse JSON text from a read-only string (with Encoding conversion)
2704
    /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2705
        \tparam SourceEncoding Transcoding from input Encoding
2706
        \param str Read-only zero-terminated string to be parsed.
2707
    */
2708
    template <unsigned parseFlags, typename SourceEncoding>
2709
108
    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2710
108
        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2711
108
        GenericStringStream<SourceEncoding> s(str);
2712
108
        return ParseStream<parseFlags, SourceEncoding>(s);
2713
108
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::Parse<0u, rapidjson::UTF8<char> >(rapidjson::UTF8<char>::Ch const*)
Line
Count
Source
2709
27
    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2710
27
        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2711
27
        GenericStringStream<SourceEncoding> s(str);
2712
27
        return ParseStream<parseFlags, SourceEncoding>(s);
2713
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::Parse<16u, rapidjson::UTF8<char> >(rapidjson::UTF8<char>::Ch const*)
Line
Count
Source
2709
27
    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2710
27
        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2711
27
        GenericStringStream<SourceEncoding> s(str);
2712
27
        return ParseStream<parseFlags, SourceEncoding>(s);
2713
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::Parse<64u, rapidjson::UTF8<char> >(rapidjson::UTF8<char>::Ch const*)
Line
Count
Source
2709
27
    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2710
27
        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2711
27
        GenericStringStream<SourceEncoding> s(str);
2712
27
        return ParseStream<parseFlags, SourceEncoding>(s);
2713
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::Parse<32u, rapidjson::UTF8<char> >(rapidjson::UTF8<char>::Ch const*)
Line
Count
Source
2709
27
    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2710
27
        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2711
27
        GenericStringStream<SourceEncoding> s(str);
2712
27
        return ParseStream<parseFlags, SourceEncoding>(s);
2713
27
    }
2714
2715
    //! Parse JSON text from a read-only string
2716
    /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2717
        \param str Read-only zero-terminated string to be parsed.
2718
    */
2719
    template <unsigned parseFlags>
2720
108
    GenericDocument& Parse(const Ch* str) {
2721
108
        return Parse<parseFlags, Encoding>(str);
2722
108
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::Parse<0u>(char const*)
Line
Count
Source
2720
27
    GenericDocument& Parse(const Ch* str) {
2721
27
        return Parse<parseFlags, Encoding>(str);
2722
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::Parse<16u>(char const*)
Line
Count
Source
2720
27
    GenericDocument& Parse(const Ch* str) {
2721
27
        return Parse<parseFlags, Encoding>(str);
2722
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::Parse<64u>(char const*)
Line
Count
Source
2720
27
    GenericDocument& Parse(const Ch* str) {
2721
27
        return Parse<parseFlags, Encoding>(str);
2722
27
    }
rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>& rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator>::Parse<32u>(char const*)
Line
Count
Source
2720
27
    GenericDocument& Parse(const Ch* str) {
2721
27
        return Parse<parseFlags, Encoding>(str);
2722
27
    }
2723
2724
    //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
2725
    /*! \param str Read-only zero-terminated string to be parsed.
2726
    */
2727
    GenericDocument& Parse(const Ch* str) {
2728
        return Parse<kParseDefaultFlags>(str);
2729
    }
2730
2731
    template <unsigned parseFlags, typename SourceEncoding>
2732
    GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2733
        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2734
        MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2735
        EncodedInputStream<SourceEncoding, MemoryStream> is(ms);
2736
        ParseStream<parseFlags, SourceEncoding>(is);
2737
        return *this;
2738
    }
2739
2740
    template <unsigned parseFlags>
2741
    GenericDocument& Parse(const Ch* str, size_t length) {
2742
        return Parse<parseFlags, Encoding>(str, length);
2743
    }
2744
    
2745
    GenericDocument& Parse(const Ch* str, size_t length) {
2746
        return Parse<kParseDefaultFlags>(str, length);
2747
    }
2748
2749
#if RAPIDJSON_HAS_STDSTRING
2750
    template <unsigned parseFlags, typename SourceEncoding>
2751
    GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2752
        // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2753
        return Parse<parseFlags, SourceEncoding>(str.c_str());
2754
    }
2755
2756
    template <unsigned parseFlags>
2757
    GenericDocument& Parse(const std::basic_string<Ch>& str) {
2758
        return Parse<parseFlags, Encoding>(str.c_str());
2759
    }
2760
2761
    GenericDocument& Parse(const std::basic_string<Ch>& str) {
2762
        return Parse<kParseDefaultFlags>(str);
2763
    }
2764
#endif // RAPIDJSON_HAS_STDSTRING    
2765
2766
    //!@}
2767
2768
    //!@name Handling parse errors
2769
    //!@{
2770
2771
    //! Whether a parse error has occurred in the last parsing.
2772
    bool HasParseError() const { return parseResult_.IsError(); }
2773
2774
    //! Get the \ref ParseErrorCode of last parsing.
2775
    ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2776
2777
    //! Get the position of last parsing error in input, 0 otherwise.
2778
    size_t GetErrorOffset() const { return parseResult_.Offset(); }
2779
2780
    //! Implicit conversion to get the last parse result
2781
#ifndef __clang // -Wdocumentation
2782
    /*! \return \ref ParseResult of the last parse operation
2783
2784
        \code
2785
          Document doc;
2786
          ParseResult ok = doc.Parse(json);
2787
          if (!ok)
2788
            printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
2789
        \endcode
2790
     */
2791
#endif
2792
108
    operator ParseResult() const { return parseResult_; }
2793
    //!@}
2794
2795
    //! Get the allocator of this document.
2796
2.46M
    Allocator& GetAllocator() {
2797
2.46M
        RAPIDJSON_ASSERT(allocator_);
2798
2.46M
        return *allocator_;
2799
2.46M
    }
2800
2801
    //! Get the capacity of stack in bytes.
2802
    size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2803
2804
private:
2805
    // clear stack on any exit from ParseStream, e.g. due to exception
2806
    struct ClearStackOnExit {
2807
108
        explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2808
108
        ~ClearStackOnExit() { d_.ClearStack(); }
2809
    private:
2810
        ClearStackOnExit(const ClearStackOnExit&);
2811
        ClearStackOnExit& operator=(const ClearStackOnExit&);
2812
        GenericDocument& d_;
2813
    };
2814
2815
    // callers of the following private Handler functions
2816
    // template <typename,typename,typename> friend class GenericReader; // for parsing
2817
    template <typename, typename> friend class GenericValue; // for deep copying
2818
2819
public:
2820
    // Implementation of Handler
2821
304
    bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2822
2.76k
    bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2823
5.94k
    bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2824
7.28M
    bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2825
495
    bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2826
5.34k
    bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2827
17.7k
    bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2828
2829
2.44M
    bool RawNumber(const Ch* str, SizeType length, bool copy) { 
2830
2.44M
        if (copy) 
2831
2.44M
            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2832
0
        else
2833
0
            new (stack_.template Push<ValueType>()) ValueType(str, length);
2834
2.44M
        return true;
2835
2.44M
    }
2836
2837
68
    bool String(const Ch* str, SizeType length, bool copy) { 
2838
68
        if (copy) 
2839
68
            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2840
0
        else
2841
0
            new (stack_.template Push<ValueType>()) ValueType(str, length);
2842
68
        return true;
2843
68
    }
2844
2845
8
    bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2846
    
2847
8
    bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2848
2849
8
    bool EndObject(SizeType memberCount) {
2850
8
        typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2851
8
        stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2852
8
        return true;
2853
8
    }
2854
2855
41.8k
    bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2856
    
2857
23.8k
    bool EndArray(SizeType elementCount) {
2858
23.8k
        ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2859
23.8k
        stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2860
23.8k
        return true;
2861
23.8k
    }
2862
2863
private:
2864
    //! Prohibit copying
2865
    GenericDocument(const GenericDocument&);
2866
    //! Prohibit assignment
2867
    GenericDocument& operator=(const GenericDocument&);
2868
2869
108
    void ClearStack() {
2870
108
        if (Allocator::kNeedFree)
2871
0
            while (stack_.GetSize() > 0)    // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2872
0
                (stack_.template Pop<ValueType>(1))->~ValueType();
2873
108
        else
2874
108
            stack_.Clear();
2875
108
        stack_.ShrinkToFit();
2876
108
    }
2877
2878
108
    void Destroy() {
2879
108
        RAPIDJSON_DELETE(ownAllocator_);
2880
108
    }
2881
2882
    static const size_t kDefaultStackCapacity = 1024;
2883
    Allocator* allocator_;
2884
    Allocator* ownAllocator_;
2885
    internal::Stack<StackAllocator> stack_;
2886
    ParseResult parseResult_;
2887
};
2888
2889
//! GenericDocument with UTF8 encoding
2890
typedef GenericDocument<UTF8<> > Document;
2891
2892
2893
//! Helper class for accessing Value of array type.
2894
/*!
2895
    Instance of this helper class is obtained by \c GenericValue::GetArray().
2896
    In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2897
*/
2898
template <bool Const, typename ValueT>
2899
class GenericArray {
2900
public:
2901
    typedef GenericArray<true, ValueT> ConstArray;
2902
    typedef GenericArray<false, ValueT> Array;
2903
    typedef ValueT PlainType;
2904
    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2905
    typedef ValueType* ValueIterator;  // This may be const or non-const iterator
2906
    typedef const ValueT* ConstValueIterator;
2907
    typedef typename ValueType::AllocatorType AllocatorType;
2908
    typedef typename ValueType::StringRefType StringRefType;
2909
2910
    template <typename, typename>
2911
    friend class GenericValue;
2912
2913
    GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2914
    GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2915
    ~GenericArray() {}
2916
2917
    operator ValueType&() const { return value_; }
2918
    SizeType Size() const { return value_.Size(); }
2919
    SizeType Capacity() const { return value_.Capacity(); }
2920
    bool Empty() const { return value_.Empty(); }
2921
    void Clear() const { value_.Clear(); }
2922
    ValueType& operator[](SizeType index) const {  return value_[index]; }
2923
    ValueIterator Begin() const { return value_.Begin(); }
2924
    ValueIterator End() const { return value_.End(); }
2925
    GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2926
    GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2927
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2928
    GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2929
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2930
    GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2931
    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2932
    GenericArray PopBack() const { value_.PopBack(); return *this; }
2933
    ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2934
    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2935
2936
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2937
    ValueIterator begin() const { return value_.Begin(); }
2938
    ValueIterator end() const { return value_.End(); }
2939
#endif
2940
2941
private:
2942
    GenericArray();
2943
    GenericArray(ValueType& value) : value_(value) {}
2944
    ValueType& value_;
2945
};
2946
2947
//! Helper class for accessing Value of object type.
2948
/*!
2949
    Instance of this helper class is obtained by \c GenericValue::GetObject().
2950
    In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2951
*/
2952
template <bool Const, typename ValueT>
2953
class GenericObject {
2954
public:
2955
    typedef GenericObject<true, ValueT> ConstObject;
2956
    typedef GenericObject<false, ValueT> Object;
2957
    typedef ValueT PlainType;
2958
    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2959
    typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator;  // This may be const or non-const iterator
2960
    typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;
2961
    typedef typename ValueType::AllocatorType AllocatorType;
2962
    typedef typename ValueType::StringRefType StringRefType;
2963
    typedef typename ValueType::EncodingType EncodingType;
2964
    typedef typename ValueType::Ch Ch;
2965
2966
    template <typename, typename>
2967
    friend class GenericValue;
2968
2969
    GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2970
    GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2971
    ~GenericObject() {}
2972
2973
    operator ValueType&() const { return value_; }
2974
    SizeType MemberCount() const { return value_.MemberCount(); }
2975
    SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2976
    bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2977
    template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2978
    template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2979
#if RAPIDJSON_HAS_STDSTRING
2980
    ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2981
#endif
2982
    MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2983
    MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2984
    GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2985
    bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2986
#if RAPIDJSON_HAS_STDSTRING
2987
    bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2988
#endif
2989
    template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2990
    MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2991
    template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2992
#if RAPIDJSON_HAS_STDSTRING
2993
    MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2994
#endif
2995
    GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2996
    GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2997
#if RAPIDJSON_HAS_STDSTRING
2998
    GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2999
#endif
3000
    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3001
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3002
    GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3003
    GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3004
    GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3005
    GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3006
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
3007
    GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3008
    GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3009
    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3010
    void RemoveAllMembers() { value_.RemoveAllMembers(); }
3011
    bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
3012
#if RAPIDJSON_HAS_STDSTRING
3013
    bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
3014
#endif
3015
    template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
3016
    MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
3017
    MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
3018
    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
3019
    bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
3020
#if RAPIDJSON_HAS_STDSTRING
3021
    bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
3022
#endif
3023
    template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
3024
3025
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
3026
    MemberIterator begin() const { return value_.MemberBegin(); }
3027
    MemberIterator end() const { return value_.MemberEnd(); }
3028
#endif
3029
3030
private:
3031
    GenericObject();
3032
    GenericObject(ValueType& value) : value_(value) {}
3033
    ValueType& value_;
3034
};
3035
3036
RAPIDJSON_NAMESPACE_END
3037
RAPIDJSON_DIAG_POP
3038
3039
#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3040
#pragma pop_macro("GetObject")
3041
#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3042
#endif
3043
3044
#endif // RAPIDJSON_DOCUMENT_H_