document.h

Engine/source/persistence/rapidjson/document.h

More...

Classes:

class

Helper class for accessing Value of array type.

class

A document for parsing JSON text as DOM.

class

Name-value pair in a JSON object value.

class

(Constant) member iterator for a JSON object value

class

Helper class for accessing Value of object type.

class

Reference to a constant string (not taking a copy)

class

Represents a JSON value. Use Value for UTF8 encoding and default allocator.

Namespaces:

namespace

Public Typedefs

Document 

GenericDocument with UTF8 encoding.

Value 

GenericValue with UTF8 encoding.

Public Functions

GenericStringRef< CharType >
StringRef(const CharType * str)

Mark a character pointer as constant string.

GenericStringRef< CharType >
StringRef(const CharType * str, size_t length)

Mark a character pointer as constant string.

Detailed Description

Public Typedefs

typedef GenericDocument< UTF8<> > Document 

GenericDocument with UTF8 encoding.

typedef GenericValue< UTF8<> > Value 

GenericValue with UTF8 encoding.

Public Functions

StringRef(const CharType * str)

Mark a character pointer as constant string.

Mark a plain character pointer as a "string literal". This function can be used to avoid copying a character string to be referenced as a value in a JSON GenericValue object, if the string's lifetime is known to be valid long enough. Parameters:

CharType

Character type of the string

Parameters:
str

Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue

return:

GenericStringRef string reference object

see:

GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember

StringRef(const CharType * str, size_t length)

Mark a character pointer as constant string.

Mark a plain character pointer as a "string literal". This function can be used to avoid copying a character string to be referenced as a value in a JSON GenericValue object, if the string's lifetime is known to be valid long enough.

This version has better performance with supplied length, and also supports string containing null characters.

Parameters:

CharType

character type of the string

Parameters:
str

Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue

length

The length of source string.

return:

GenericStringRef string reference object

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