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