Coverage Report

Created: 2023-06-07 06:59

/src/valijson/thirdparty/rapidjson/include/rapidjson/document.h
Line
Count
Source (jump to first uncovered line)
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
0
    GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
241
    Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
242
243
    //! @name stepping
244
    //@{
245
0
    Iterator& operator++(){ ++ptr_; return *this; }
Unexecuted instantiation: rapidjson::GenericMemberIterator<false, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator++()
Unexecuted instantiation: rapidjson::GenericMemberIterator<true, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator++()
246
    Iterator& operator--(){ --ptr_; return *this; }
247
0
    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
0
    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
0
    template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
263
0
    template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
Unexecuted instantiation: 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
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
0
    Pointer   operator->() const { return ptr_; }
Unexecuted instantiation: rapidjson::GenericMemberIterator<true, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::operator->() const
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
0
    DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
283
284
private:
285
    //! Internal constructor from plain pointer
286
0
    explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
Unexecuted instantiation: rapidjson::GenericMemberIterator<true, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::GenericMemberIterator(rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> > const*)
Unexecuted instantiation: rapidjson::GenericMemberIterator<false, rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >::GenericMemberIterator(rapidjson::GenericMember<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> >*)
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
0
        : 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
0
        : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
413
414
0
    GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
415
416
    //! implicit conversion to plain CharType pointer
417
0
    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
0
    SizeType NotNullStrLen(const CharType* str) {
424
0
        RAPIDJSON_ASSERT(str != 0);
425
0
        return internal::StrLen(str);
426
0
    }
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
0
inline GenericStringRef<CharType> StringRef(const CharType* str) {
455
0
    return GenericStringRef<CharType>(str);
456
0
}
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
0
inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
475
0
    return GenericStringRef<CharType>(str, SizeType(length));
476
0
}
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
206
    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
0
    explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
721
0
        static const uint16_t defaultFlags[] = {
722
0
            kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
723
0
            kNumberAnyFlag
724
0
        };
725
0
        RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
726
0
        data_.f.flags = defaultFlags[type];
727
728
        // Use ShortString to store empty string.
729
0
        if (type == kStringType)
730
0
            data_.ss.SetLength(0);
731
0
    }
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
0
        : data_() {
786
            // safe-guard against failing SFINAE
787
0
            RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
788
0
            data_.f.flags = b ? kTrueFlag : kFalseFlag;
789
0
    }
790
791
    //! Constructor for int value.
792
0
    explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
793
0
        data_.n.i64 = i;
794
0
        data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
795
0
    }
796
797
    //! Constructor for unsigned value.
798
0
    explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
799
0
        data_.n.u64 = u; 
800
0
        data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
801
0
    }
802
803
    //! Constructor for int64_t value.
804
0
    explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
805
0
        data_.n.i64 = i64;
806
0
        data_.f.flags = kNumberInt64Flag;
807
0
        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
0
        else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
815
0
            data_.f.flags |= kIntFlag;
816
0
    }
817
818
    //! Constructor for uint64_t value.
819
0
    explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
820
0
        data_.n.u64 = u64;
821
0
        data_.f.flags = kNumberUint64Flag;
822
0
        if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
823
0
            data_.f.flags |= kInt64Flag;
824
0
        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
825
0
            data_.f.flags |= kUintFlag;
826
0
        if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
827
0
            data_.f.flags |= kIntFlag;
828
0
    }
829
830
    //! Constructor for double value.
831
0
    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
    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
0
    explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
841
842
    //! Constructor for copy-string (i.e. do make a copy of string)
843
0
    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
206
    ~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
206
        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
206
    }
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
    GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
922
        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
            GenericValue temp;
927
            temp.RawAssign(rhs);
928
            this->~GenericValue();
929
            RawAssign(temp);
930
        }
931
        return *this;
932
    }
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
    //! Not-equal-to operator
1082
    /*! \return !(*this == rhs)
1083
     */
1084
    template <typename SourceAllocator>
1085
    bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1086
1087
    //! Not-equal-to operator with const C-string pointer
1088
    bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1089
1090
    //! Not-equal-to operator with arbitrary types
1091
    /*! \return !(*this == rhs)
1092
     */
1093
    template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1094
1095
#ifndef __cpp_impl_three_way_comparison
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
0
    Type GetType()  const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1112
103
    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
206
    bool IsBool()   const { return (data_.f.flags & kBoolFlag) != 0; }
1116
412
    bool IsObject() const { return data_.f.flags == kObjectFlag; }
1117
206
    bool IsArray()  const { return data_.f.flags == kArrayFlag; }
1118
0
    bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1119
103
    bool IsInt()    const { return (data_.f.flags & kIntFlag) != 0; }
1120
103
    bool IsUint()   const { return (data_.f.flags & kUintFlag) != 0; }
1121
103
    bool IsInt64()  const { return (data_.f.flags & kInt64Flag) != 0; }
1122
103
    bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1123
103
    bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1124
206
    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
103
    GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1170
1171
    //@}
1172
1173
    //!@name Bool
1174
    //@{
1175
1176
0
    bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1177
    //!< Set boolean value
1178
    /*! \post IsBool() == true */
1179
0
    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
0
    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
0
    ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1269
    //! Const \em past-the-end member iterator
1270
    /*! \pre IsObject() == true */
1271
0
    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
0
    MemberIterator FindMember(const Ch* name) {
1338
0
        GenericValue n(StringRef(name));
1339
0
        return FindMember(n);
1340
0
    }
1341
1342
0
    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
0
    MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
1359
0
        RAPIDJSON_ASSERT(IsObject());
1360
0
        RAPIDJSON_ASSERT(name.IsString());
1361
0
        return DoFindMember(name);
1362
0
    }
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
0
    GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1388
0
        RAPIDJSON_ASSERT(IsObject());
1389
0
        RAPIDJSON_ASSERT(name.IsString());
1390
0
        DoAddMember(name, value, allocator);
1391
0
        return *this;
1392
0
    }
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
0
    GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1641
1642
    //! Get the number of elements in array.
1643
0
    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
0
    ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1678
    //! \em Past-the-end element iterator
1679
    /*! \pre IsArray() == true */
1680
0
    ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1681
    //! Constant element iterator
1682
    /*! \pre IsArray() == true */
1683
0
    ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1684
    //! Constant \em past-the-end element iterator
1685
    /*! \pre IsArray() == true */
1686
0
    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
0
    GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1695
0
        RAPIDJSON_ASSERT(IsArray());
1696
0
        if (newCapacity > data_.a.capacity) {
1697
0
            SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1698
0
            data_.a.capacity = newCapacity;
1699
0
        }
1700
0
        return *this;
1701
0
    }
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
0
    GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1714
0
        RAPIDJSON_ASSERT(IsArray());
1715
0
        if (data_.a.size >= data_.a.capacity)
1716
0
            Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1717
0
        GetElementsPointer()[data_.a.size++].RawAssign(value);
1718
0
        return *this;
1719
0
    }
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
0
    int GetInt() const          { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);   return data_.n.i.i;   }
1818
0
    unsigned GetUint() const    { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);  return data_.n.u.u;   }
1819
0
    int64_t GetInt64() const    { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1820
0
    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
0
    double GetDouble() const {
1826
0
        RAPIDJSON_ASSERT(IsNumber());
1827
0
        if ((data_.f.flags & kDoubleFlag) != 0)                return data_.n.d;   // exact type, no conversion.
1828
0
        if ((data_.f.flags & kIntFlag) != 0)                   return data_.n.i.i; // int -> double
1829
0
        if ((data_.f.flags & kUintFlag) != 0)                  return data_.n.u.u; // unsigned -> double
1830
0
        if ((data_.f.flags & kInt64Flag) != 0)                 return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1831
0
        RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1832
0
    }
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
0
    GenericValue& SetInt(int i)             { this->~GenericValue(); new (this) GenericValue(i);    return *this; }
1842
0
    GenericValue& SetUint(unsigned u)       { this->~GenericValue(); new (this) GenericValue(u);    return *this; }
1843
0
    GenericValue& SetInt64(int64_t i64)     { this->~GenericValue(); new (this) GenericValue(i64);  return *this; }
1844
0
    GenericValue& SetUint64(uint64_t u64)   { this->~GenericValue(); new (this) GenericValue(u64);  return *this; }
1845
0
    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
0
    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
0
    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
0
    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
0
    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
    bool Accept(Handler& handler) const {
1949
        switch(GetType()) {
1950
        case kNullType:     return handler.Null();
1951
        case kFalseType:    return handler.Bool(false);
1952
        case kTrueType:     return handler.Bool(true);
1953
1954
        case kObjectType:
1955
            if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1956
                return false;
1957
            for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1958
                RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1959
                if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1960
                    return false;
1961
                if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1962
                    return false;
1963
            }
1964
            return handler.EndObject(data_.o.size);
1965
1966
        case kArrayType:
1967
            if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1968
                return false;
1969
            for (ConstValueIterator v = Begin(); v != End(); ++v)
1970
                if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1971
                    return false;
1972
            return handler.EndArray(data_.a.size);
1973
    
1974
        case kStringType:
1975
            return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1976
    
1977
        default:
1978
            RAPIDJSON_ASSERT(GetType() == kNumberType);
1979
            if (IsDouble())         return handler.Double(data_.n.d);
1980
            else if (IsInt())       return handler.Int(data_.n.i.i);
1981
            else if (IsUint())      return handler.Uint(data_.n.u.u);
1982
            else if (IsInt64())     return handler.Int64(data_.n.i64);
1983
            else                    return handler.Uint64(data_.n.u64);
1984
        }
1985
    }
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
0
        inline static bool Usable(SizeType len) { return                       (MaxSize >= len); }
2056
0
        inline void     SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize -  len); }
2057
0
        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
0
    static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
2108
0
        return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
2109
0
    }
2110
0
    static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
2111
0
        return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2112
0
    }
2113
2114
0
    RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2115
0
    RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2116
0
    RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2117
0
    RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2118
0
    RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2119
    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
    RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2269
        return Malloc<Member>(allocator, capacity);
2270
    }
2271
2272
0
    void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2273
0
        ObjectData& o = data_.o;
2274
0
        if (newCapacity > o.capacity) {
2275
0
            Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2276
0
            RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
2277
0
            o.capacity = newCapacity;
2278
0
        }
2279
0
    }
2280
2281
    template <typename SourceAllocator>
2282
0
    MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2283
0
        MemberIterator member = MemberBegin();
2284
0
        for ( ; member != MemberEnd(); ++member)
2285
0
            if (name.StringEqual(member->name))
2286
0
                break;
2287
0
        return member;
2288
0
    }
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
0
    void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
2305
0
        ObjectData& o = data_.o;
2306
0
        if (o.size >= o.capacity)
2307
0
            DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
2308
0
        Member* members = GetMembersPointer();
2309
0
        Member* m = members + o.size;
2310
0
        m->name.RawAssign(name);
2311
0
        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
0
        ++o.size;
2318
0
    }
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
    void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2403
        data_.f.flags = kArrayFlag;
2404
        if (count) {
2405
            GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2406
            SetElementsPointer(e);
2407
            std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2408
        }
2409
        else
2410
            SetElementsPointer(0);
2411
        data_.a.size = data_.a.capacity = count;
2412
    }
2413
2414
    //! Initialize this value as object with initial data, without calling destructor.
2415
    void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2416
        data_.f.flags = kObjectFlag;
2417
        if (count) {
2418
            Member* m = DoAllocMembers(count, allocator);
2419
            SetMembersPointer(m);
2420
            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
        }
2429
        else
2430
            SetMembersPointer(0);
2431
        data_.o.size = data_.o.capacity = count;
2432
    }
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
0
    void SetStringRaw(StringRefType s, Allocator& allocator) {
2443
0
        Ch* str = 0;
2444
0
        if (ShortString::Usable(s.length)) {
2445
0
            data_.f.flags = kShortStringFlag;
2446
0
            data_.ss.SetLength(s.length);
2447
0
            str = data_.ss.str;
2448
0
        } else {
2449
0
            data_.f.flags = kCopyStringFlag;
2450
0
            data_.s.length = s.length;
2451
0
            str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2452
0
            SetStringPointer(str);
2453
0
        }
2454
0
        std::memcpy(str, s, s.length * sizeof(Ch));
2455
0
        str[s.length] = '\0';
2456
0
    }
2457
2458
    //! Assignment without calling destructor
2459
0
    void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2460
0
        data_ = rhs.data_;
2461
        // data_.f.flags = rhs.data_.f.flags;
2462
0
        rhs.data_.f.flags = kNullFlag;
2463
0
    }
2464
2465
    template <typename SourceAllocator>
2466
0
    bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2467
0
        RAPIDJSON_ASSERT(IsString());
2468
0
        RAPIDJSON_ASSERT(rhs.IsString());
2469
2470
0
        const SizeType len1 = GetStringLength();
2471
0
        const SizeType len2 = rhs.GetStringLength();
2472
0
        if(len1 != len2) { return false; }
2473
2474
0
        const Ch* const str1 = GetString();
2475
0
        const Ch* const str2 = rhs.GetString();
2476
0
        if(str1 == str2) { return true; } // fast path for constant string
2477
2478
0
        return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2479
0
    }
2480
2481
    Data data_;
2482
};
2483
2484
//! GenericValue with UTF8 encoding
2485
typedef GenericValue<UTF8<> > Value;
2486
2487
///////////////////////////////////////////////////////////////////////////////
2488
// GenericDocument 
2489
2490
//! A document for parsing JSON text as DOM.
2491
/*!
2492
    \note implements Handler concept
2493
    \tparam Encoding Encoding for both parsing and string storage.
2494
    \tparam Allocator Allocator for allocating memory for the DOM
2495
    \tparam StackAllocator Allocator for allocating memory for stack during parsing.
2496
    \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.
2497
*/
2498
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2499
class GenericDocument : public GenericValue<Encoding, Allocator> {
2500
public:
2501
    typedef typename Encoding::Ch Ch;                       //!< Character type derived from Encoding.
2502
    typedef GenericValue<Encoding, Allocator> ValueType;    //!< Value type of the document.
2503
    typedef Allocator AllocatorType;                        //!< Allocator type from template parameter.
2504
    typedef StackAllocator StackAllocatorType;              //!< StackAllocator type from template parameter.
2505
2506
    //! Constructor
2507
    /*! Creates an empty document of specified type.
2508
        \param type             Mandatory type of object to create.
2509
        \param allocator        Optional allocator for allocating memory.
2510
        \param stackCapacity    Optional initial capacity of stack in bytes.
2511
        \param stackAllocator   Optional allocator for allocating memory for stack.
2512
    */
2513
    explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2514
        GenericValue<Encoding, Allocator>(type),  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2515
    {
2516
        if (!allocator_)
2517
            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2518
    }
2519
2520
    //! Constructor
2521
    /*! Creates an empty document which type is Null. 
2522
        \param allocator        Optional allocator for allocating memory.
2523
        \param stackCapacity    Optional initial capacity of stack in bytes.
2524
        \param stackAllocator   Optional allocator for allocating memory for stack.
2525
    */
2526
    GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : 
2527
        allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2528
103
    {
2529
103
        if (!allocator_)
2530
103
            ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2531
103
    }
2532
2533
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2534
    //! Move constructor in C++11
2535
    GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2536
        : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2537
          allocator_(rhs.allocator_),
2538
          ownAllocator_(rhs.ownAllocator_),
2539
          stack_(std::move(rhs.stack_)),
2540
          parseResult_(rhs.parseResult_)
2541
    {
2542
        rhs.allocator_ = 0;
2543
        rhs.ownAllocator_ = 0;
2544
        rhs.parseResult_ = ParseResult();
2545
    }
2546
#endif
2547
2548
103
    ~GenericDocument() {
2549
        // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
2550
        // runs last and may access its elements or members which would be freed
2551
        // with an allocator like MemoryPoolAllocator (CrtAllocator does not
2552
        // free its data when destroyed, but MemoryPoolAllocator does).
2553
103
        if (ownAllocator_) {
2554
103
            ValueType::SetNull();
2555
103
        }
2556
103
        Destroy();
2557
103
    }
2558
2559
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2560
    //! Move assignment in C++11
2561
    GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2562
    {
2563
        // The cast to ValueType is necessary here, because otherwise it would
2564
        // attempt to call GenericValue's templated assignment operator.
2565
        ValueType::operator=(std::forward<ValueType>(rhs));
2566
2567
        // Calling the destructor here would prematurely call stack_'s destructor
2568
        Destroy();
2569
2570
        allocator_ = rhs.allocator_;
2571
        ownAllocator_ = rhs.ownAllocator_;
2572
        stack_ = std::move(rhs.stack_);
2573
        parseResult_ = rhs.parseResult_;
2574
2575
        rhs.allocator_ = 0;
2576
        rhs.ownAllocator_ = 0;
2577
        rhs.parseResult_ = ParseResult();
2578
2579
        return *this;
2580
    }
2581
#endif
2582
2583
    //! Exchange the contents of this document with those of another.
2584
    /*!
2585
        \param rhs Another document.
2586
        \note Constant complexity.
2587
        \see GenericValue::Swap
2588
    */
2589
    GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2590
        ValueType::Swap(rhs);
2591
        stack_.Swap(rhs.stack_);
2592
        internal::Swap(allocator_, rhs.allocator_);
2593
        internal::Swap(ownAllocator_, rhs.ownAllocator_);
2594
        internal::Swap(parseResult_, rhs.parseResult_);
2595
        return *this;
2596
    }
2597
2598
    // Allow Swap with ValueType.
2599
    // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2600
    using ValueType::Swap;
2601
2602
    //! free-standing swap function helper
2603
    /*!
2604
        Helper function to enable support for common swap implementation pattern based on \c std::swap:
2605
        \code
2606
        void swap(MyClass& a, MyClass& b) {
2607
            using std::swap;
2608
            swap(a.doc, b.doc);
2609
            // ...
2610
        }
2611
        \endcode
2612
        \see Swap()
2613
     */
2614
    friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2615
2616
    //! Populate this document by a generator which produces SAX events.
2617
    /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.
2618
        \param g Generator functor which sends SAX events to the parameter.
2619
        \return The document itself for fluent API.
2620
    */
2621
    template <typename Generator>
2622
    GenericDocument& Populate(Generator& g) {
2623
        ClearStackOnExit scope(*this);
2624
        if (g(*this)) {
2625
            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2626
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2627
        }
2628
        return *this;
2629
    }
2630
2631
    //!@name Parse from stream
2632
    //!@{
2633
2634
    //! Parse JSON text from an input stream (with Encoding conversion)
2635
    /*! \tparam parseFlags Combination of \ref ParseFlag.
2636
        \tparam SourceEncoding Encoding of input stream
2637
        \tparam InputStream Type of input stream, implementing Stream concept
2638
        \param is Input stream to be parsed.
2639
        \return The document itself for fluent API.
2640
    */
2641
    template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2642
    GenericDocument& ParseStream(InputStream& is) {
2643
        GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2644
            stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2645
        ClearStackOnExit scope(*this);
2646
        parseResult_ = reader.template Parse<parseFlags>(is, *this);
2647
        if (parseResult_) {
2648
            RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2649
            ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2650
        }
2651
        return *this;
2652
    }
2653
2654
    //! Parse JSON text from an input stream
2655
    /*! \tparam parseFlags Combination of \ref ParseFlag.
2656
        \tparam InputStream Type of input stream, implementing Stream concept
2657
        \param is Input stream to be parsed.
2658
        \return The document itself for fluent API.
2659
    */
2660
    template <unsigned parseFlags, typename InputStream>
2661
    GenericDocument& ParseStream(InputStream& is) {
2662
        return ParseStream<parseFlags, Encoding, InputStream>(is);
2663
    }
2664
2665
    //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
2666
    /*! \tparam InputStream Type of input stream, implementing Stream concept
2667
        \param is Input stream to be parsed.
2668
        \return The document itself for fluent API.
2669
    */
2670
    template <typename InputStream>
2671
    GenericDocument& ParseStream(InputStream& is) {
2672
        return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2673
    }
2674
    //!@}
2675
2676
    //!@name Parse in-place from mutable string
2677
    //!@{
2678
2679
    //! Parse JSON text from a mutable string
2680
    /*! \tparam parseFlags Combination of \ref ParseFlag.
2681
        \param str Mutable zero-terminated string to be parsed.
2682
        \return The document itself for fluent API.
2683
    */
2684
    template <unsigned parseFlags>
2685
    GenericDocument& ParseInsitu(Ch* str) {
2686
        GenericInsituStringStream<Encoding> s(str);
2687
        return ParseStream<parseFlags | kParseInsituFlag>(s);
2688
    }
2689
2690
    //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
2691
    /*! \param str Mutable zero-terminated string to be parsed.
2692
        \return The document itself for fluent API.
2693
    */
2694
    GenericDocument& ParseInsitu(Ch* str) {
2695
        return ParseInsitu<kParseDefaultFlags>(str);
2696
    }
2697
    //!@}
2698
2699
    //!@name Parse from read-only string
2700
    //!@{
2701
2702
    //! Parse JSON text from a read-only string (with Encoding conversion)
2703
    /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2704
        \tparam SourceEncoding Transcoding from input Encoding
2705
        \param str Read-only zero-terminated string to be parsed.
2706
    */
2707
    template <unsigned parseFlags, typename SourceEncoding>
2708
    GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2709
        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2710
        GenericStringStream<SourceEncoding> s(str);
2711
        return ParseStream<parseFlags, SourceEncoding>(s);
2712
    }
2713
2714
    //! Parse JSON text from a read-only string
2715
    /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2716
        \param str Read-only zero-terminated string to be parsed.
2717
    */
2718
    template <unsigned parseFlags>
2719
    GenericDocument& Parse(const Ch* str) {
2720
        return Parse<parseFlags, Encoding>(str);
2721
    }
2722
2723
    //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
2724
    /*! \param str Read-only zero-terminated string to be parsed.
2725
    */
2726
    GenericDocument& Parse(const Ch* str) {
2727
        return Parse<kParseDefaultFlags>(str);
2728
    }
2729
2730
    template <unsigned parseFlags, typename SourceEncoding>
2731
    GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2732
        RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2733
        MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2734
        EncodedInputStream<SourceEncoding, MemoryStream> is(ms);
2735
        ParseStream<parseFlags, SourceEncoding>(is);
2736
        return *this;
2737
    }
2738
2739
    template <unsigned parseFlags>
2740
    GenericDocument& Parse(const Ch* str, size_t length) {
2741
        return Parse<parseFlags, Encoding>(str, length);
2742
    }
2743
    
2744
    GenericDocument& Parse(const Ch* str, size_t length) {
2745
        return Parse<kParseDefaultFlags>(str, length);
2746
    }
2747
2748
#if RAPIDJSON_HAS_STDSTRING
2749
    template <unsigned parseFlags, typename SourceEncoding>
2750
    GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2751
        // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2752
        return Parse<parseFlags, SourceEncoding>(str.c_str());
2753
    }
2754
2755
    template <unsigned parseFlags>
2756
    GenericDocument& Parse(const std::basic_string<Ch>& str) {
2757
        return Parse<parseFlags, Encoding>(str.c_str());
2758
    }
2759
2760
    GenericDocument& Parse(const std::basic_string<Ch>& str) {
2761
        return Parse<kParseDefaultFlags>(str);
2762
    }
2763
#endif // RAPIDJSON_HAS_STDSTRING    
2764
2765
    //!@}
2766
2767
    //!@name Handling parse errors
2768
    //!@{
2769
2770
    //! Whether a parse error has occurred in the last parsing.
2771
103
    bool HasParseError() const { return parseResult_.IsError(); }
2772
2773
    //! Get the \ref ParseErrorCode of last parsing.
2774
0
    ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2775
2776
    //! Get the position of last parsing error in input, 0 otherwise.
2777
0
    size_t GetErrorOffset() const { return parseResult_.Offset(); }
2778
2779
    //! Implicit conversion to get the last parse result
2780
#ifndef __clang // -Wdocumentation
2781
    /*! \return \ref ParseResult of the last parse operation
2782
2783
        \code
2784
          Document doc;
2785
          ParseResult ok = doc.Parse(json);
2786
          if (!ok)
2787
            printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
2788
        \endcode
2789
     */
2790
#endif
2791
    operator ParseResult() const { return parseResult_; }
2792
    //!@}
2793
2794
    //! Get the allocator of this document.
2795
    Allocator& GetAllocator() {
2796
        RAPIDJSON_ASSERT(allocator_);
2797
        return *allocator_;
2798
    }
2799
2800
    //! Get the capacity of stack in bytes.
2801
    size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2802
2803
private:
2804
    // clear stack on any exit from ParseStream, e.g. due to exception
2805
    struct ClearStackOnExit {
2806
        explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2807
        ~ClearStackOnExit() { d_.ClearStack(); }
2808
    private:
2809
        ClearStackOnExit(const ClearStackOnExit&);
2810
        ClearStackOnExit& operator=(const ClearStackOnExit&);
2811
        GenericDocument& d_;
2812
    };
2813
2814
    // callers of the following private Handler functions
2815
    // template <typename,typename,typename> friend class GenericReader; // for parsing
2816
    template <typename, typename> friend class GenericValue; // for deep copying
2817
2818
public:
2819
    // Implementation of Handler
2820
    bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2821
    bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2822
    bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2823
    bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2824
    bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2825
    bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2826
    bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2827
2828
    bool RawNumber(const Ch* str, SizeType length, bool copy) { 
2829
        if (copy) 
2830
            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2831
        else
2832
            new (stack_.template Push<ValueType>()) ValueType(str, length);
2833
        return true;
2834
    }
2835
2836
    bool String(const Ch* str, SizeType length, bool copy) { 
2837
        if (copy) 
2838
            new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2839
        else
2840
            new (stack_.template Push<ValueType>()) ValueType(str, length);
2841
        return true;
2842
    }
2843
2844
    bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2845
    
2846
    bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2847
2848
    bool EndObject(SizeType memberCount) {
2849
        typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2850
        stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2851
        return true;
2852
    }
2853
2854
    bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2855
    
2856
    bool EndArray(SizeType elementCount) {
2857
        ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2858
        stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2859
        return true;
2860
    }
2861
2862
private:
2863
    //! Prohibit copying
2864
    GenericDocument(const GenericDocument&);
2865
    //! Prohibit assignment
2866
    GenericDocument& operator=(const GenericDocument&);
2867
2868
    void ClearStack() {
2869
        if (Allocator::kNeedFree)
2870
            while (stack_.GetSize() > 0)    // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2871
                (stack_.template Pop<ValueType>(1))->~ValueType();
2872
        else
2873
            stack_.Clear();
2874
        stack_.ShrinkToFit();
2875
    }
2876
2877
103
    void Destroy() {
2878
103
        RAPIDJSON_DELETE(ownAllocator_);
2879
103
    }
2880
2881
    static const size_t kDefaultStackCapacity = 1024;
2882
    Allocator* allocator_;
2883
    Allocator* ownAllocator_;
2884
    internal::Stack<StackAllocator> stack_;
2885
    ParseResult parseResult_;
2886
};
2887
2888
//! GenericDocument with UTF8 encoding
2889
typedef GenericDocument<UTF8<> > Document;
2890
2891
2892
//! Helper class for accessing Value of array type.
2893
/*!
2894
    Instance of this helper class is obtained by \c GenericValue::GetArray().
2895
    In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2896
*/
2897
template <bool Const, typename ValueT>
2898
class GenericArray {
2899
public:
2900
    typedef GenericArray<true, ValueT> ConstArray;
2901
    typedef GenericArray<false, ValueT> Array;
2902
    typedef ValueT PlainType;
2903
    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2904
    typedef ValueType* ValueIterator;  // This may be const or non-const iterator
2905
    typedef const ValueT* ConstValueIterator;
2906
    typedef typename ValueType::AllocatorType AllocatorType;
2907
    typedef typename ValueType::StringRefType StringRefType;
2908
2909
    template <typename, typename>
2910
    friend class GenericValue;
2911
2912
    GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2913
    GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2914
    ~GenericArray() {}
2915
2916
    operator ValueType&() const { return value_; }
2917
    SizeType Size() const { return value_.Size(); }
2918
    SizeType Capacity() const { return value_.Capacity(); }
2919
    bool Empty() const { return value_.Empty(); }
2920
    void Clear() const { value_.Clear(); }
2921
    ValueType& operator[](SizeType index) const {  return value_[index]; }
2922
    ValueIterator Begin() const { return value_.Begin(); }
2923
    ValueIterator End() const { return value_.End(); }
2924
    GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2925
    GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2926
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2927
    GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2928
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2929
    GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2930
    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; }
2931
    GenericArray PopBack() const { value_.PopBack(); return *this; }
2932
    ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2933
    ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2934
2935
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2936
    ValueIterator begin() const { return value_.Begin(); }
2937
    ValueIterator end() const { return value_.End(); }
2938
#endif
2939
2940
private:
2941
    GenericArray();
2942
    GenericArray(ValueType& value) : value_(value) {}
2943
    ValueType& value_;
2944
};
2945
2946
//! Helper class for accessing Value of object type.
2947
/*!
2948
    Instance of this helper class is obtained by \c GenericValue::GetObject().
2949
    In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2950
*/
2951
template <bool Const, typename ValueT>
2952
class GenericObject {
2953
public:
2954
    typedef GenericObject<true, ValueT> ConstObject;
2955
    typedef GenericObject<false, ValueT> Object;
2956
    typedef ValueT PlainType;
2957
    typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2958
    typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator;  // This may be const or non-const iterator
2959
    typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;
2960
    typedef typename ValueType::AllocatorType AllocatorType;
2961
    typedef typename ValueType::StringRefType StringRefType;
2962
    typedef typename ValueType::EncodingType EncodingType;
2963
    typedef typename ValueType::Ch Ch;
2964
2965
    template <typename, typename>
2966
    friend class GenericValue;
2967
2968
    GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2969
    GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2970
    ~GenericObject() {}
2971
2972
    operator ValueType&() const { return value_; }
2973
    SizeType MemberCount() const { return value_.MemberCount(); }
2974
    SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2975
    bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2976
    template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2977
    template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2978
#if RAPIDJSON_HAS_STDSTRING
2979
    ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2980
#endif
2981
    MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2982
    MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2983
    GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2984
    bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2985
#if RAPIDJSON_HAS_STDSTRING
2986
    bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2987
#endif
2988
    template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2989
    MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2990
    template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2991
#if RAPIDJSON_HAS_STDSTRING
2992
    MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2993
#endif
2994
    GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2995
    GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2996
#if RAPIDJSON_HAS_STDSTRING
2997
    GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2998
#endif
2999
    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; }
3000
#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3001
    GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
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(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3005
#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
3006
    GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3007
    GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3008
    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; }
3009
    void RemoveAllMembers() { value_.RemoveAllMembers(); }
3010
    bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
3011
#if RAPIDJSON_HAS_STDSTRING
3012
    bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
3013
#endif
3014
    template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
3015
    MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
3016
    MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
3017
    MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
3018
    bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
3019
#if RAPIDJSON_HAS_STDSTRING
3020
    bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
3021
#endif
3022
    template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
3023
3024
#if RAPIDJSON_HAS_CXX11_RANGE_FOR
3025
    MemberIterator begin() const { return value_.MemberBegin(); }
3026
    MemberIterator end() const { return value_.MemberEnd(); }
3027
#endif
3028
3029
private:
3030
    GenericObject();
3031
    GenericObject(ValueType& value) : value_(value) {}
3032
    ValueType& value_;
3033
};
3034
3035
RAPIDJSON_NAMESPACE_END
3036
RAPIDJSON_DIAG_POP
3037
3038
#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3039
#pragma pop_macro("GetObject")
3040
#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3041
#endif
3042
3043
#endif // RAPIDJSON_DOCUMENT_H_