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