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