COSC345-Eventures
document.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
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 
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 
63 
64 // Forward declaration.
65 template <typename Encoding, typename Allocator>
67 
68 template <typename Encoding, typename Allocator, typename StackAllocator>
70 
77 #ifndef RAPIDJSON_DEFAULT_ALLOCATOR
78 #define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
79 #endif
80 
87 #ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
88 #define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
89 #endif
90 
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 
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 
114 
119 template <typename Encoding, typename Allocator>
121 public:
124 
125 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
126  GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
128  : name(std::move(rhs.name)),
129  value(std::move(rhs.value))
130  {
131  }
132 
134  GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
135  return *this = static_cast<GenericMember&>(rhs);
136  }
137 #endif
138 
140 
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:
158  GenericMember(const GenericMember& rhs);
159 };
160 
162 // GenericMemberIterator
163 
164 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
165 
167 
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:
201 
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;
210 
212  typedef pointer Pointer;
214  typedef reference Reference;
216  typedef difference_type DifferenceType;
217 
219 
222  GenericMemberIterator() : ptr_() {}
223 
225 
240  GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
241  Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
242 
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; }
250 
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; }
259 
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 
275 
276  Reference operator*() const { return *ptr_; }
277  Pointer operator->() const { return ptr_; }
278  Reference operator[](DifferenceType n) const { return ptr_[n]; }
280 
282  DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
283 
284 private:
286  explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
287 
288  Pointer ptr_;
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>
297 
299 template <typename Encoding, typename Allocator>
300 class GenericMemberIterator<false,Encoding,Allocator> {
301 public:
304 };
306 template <typename Encoding, typename Allocator>
307 class GenericMemberIterator<true,Encoding,Allocator> {
308 public:
311 };
312 
313 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
314 
316 // GenericStringRef
317 
319 
345 template<typename CharType>
347  typedef CharType Ch;
348 
350 #ifndef __clang__ // -Wdocumentation
351 
373 #endif
374  template<SizeType N>
375  GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
376  : s(str), length(N-1) {}
377 
379 #ifndef __clang__ // -Wdocumentation
380 
398 #endif
399  explicit GenericStringRef(const CharType* str)
400  : s(str), length(NotNullStrLen(str)) {}
401 
403 #ifndef __clang__ // -Wdocumentation
404 
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 
417  operator const Ch *() const { return s; }
418 
419  const Ch* const s;
420  const SizeType length;
421 
422 private:
423  SizeType NotNullStrLen(const CharType* str) {
424  RAPIDJSON_ASSERT(str != 0);
425  return internal::StrLen(str);
426  }
427 
429  static const Ch emptyString[];
430 
432  template<SizeType N>
433  GenericStringRef(CharType (&str)[N]) /* = delete */;
435  GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
436 };
437 
438 template<typename CharType>
439 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
440 
442 
453 template<typename CharType>
454 inline GenericStringRef<CharType> StringRef(const CharType* str) {
455  return GenericStringRef<CharType>(str);
456 }
457 
459 
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 
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 
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 
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 
655 // GenericValue
656 
658 
667 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
668 class GenericValue {
669 public:
672  typedef Encoding EncodingType;
673  typedef Allocator AllocatorType;
674  typedef typename Encoding::Ch Ch;
685 
687 
688 
690  GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
691 
692 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
693  GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
695  rhs.data_.f.flags = kNullFlag; // give up contents
696  }
697 #endif
698 
699 private:
701  GenericValue(const GenericValue& rhs);
702 
703 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
704  template <typename StackAllocator>
707 
709  template <typename StackAllocator>
711 #endif
712 
713 public:
714 
716 
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 
734 
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 
774 
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 
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 
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 
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 
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 
831  explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
832 
834  explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
835 
837  GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
838 
840  explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
841 
843  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
844 
846  GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
847 
848 #if RAPIDJSON_HAS_STDSTRING
849 
852  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
853 #endif
854 
856 
861  GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
862  a.value_.data_ = Data();
863  a.value_.data_.f.flags = kArrayFlag;
864  }
865 
867 
872  GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
873  o.value_.data_ = Data();
874  o.value_.data_.f.flags = kObjectFlag;
875  }
876 
878 
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 
914 
916 
917 
919 
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  GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
937  return *this = rhs.Move();
938  }
939 #endif
940 
942 
946  GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
947  GenericValue s(str);
948  return *this = s;
949  }
950 
952 
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 
971 
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 
986 
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 
999 
1010  friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1011 
1013 
1014  GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
1016 
1018 
1019 
1024  template <typename SourceAllocator>
1025  bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
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 
1067  bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1068 
1069 #if RAPIDJSON_HAS_STDSTRING
1070 
1073  bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
1074 #endif
1075 
1077 
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 
1085  template <typename SourceAllocator>
1086  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1087 
1089  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1090 
1092 
1094  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1095 
1097 
1099  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1100 
1102 
1104  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1106 #endif
1107 
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 
1165 
1167 
1168 
1169  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1170 
1172 
1174 
1175 
1176  bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1178 
1179  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1180 
1182 
1184 
1185 
1187 
1188  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1189 
1191  SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1192 
1194  SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1195 
1197  bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1198 
1200 
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 
1217 
1225  template <typename SourceAllocator>
1226  GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1227  MemberIterator member = FindMember(name);
1228  if (member != MemberEnd())
1229  return member->value;
1230  else {
1231  RAPIDJSON_ASSERT(false); // see above note
1232 
1233 #if RAPIDJSON_HAS_CXX11
1234  // Use thread-local storage to prevent races between threads.
1235  // Use static buffer and placement-new to prevent destruction, with
1236  // alignas() to ensure proper alignment.
1237  alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
1238  return *new (buffer) GenericValue();
1239 #elif defined(_MSC_VER) && _MSC_VER < 1900
1240  // There's no way to solve both thread locality and proper alignment
1241  // simultaneously.
1242  __declspec(thread) static char buffer[sizeof(GenericValue)];
1243  return *new (buffer) GenericValue();
1244 #elif defined(__GNUC__) || defined(__clang__)
1245  // This will generate -Wexit-time-destructors in clang, but that's
1246  // better than having under-alignment.
1247  __thread static GenericValue buffer;
1248  return buffer;
1249 #else
1250  // Don't know what compiler this is, so don't know how to ensure
1251  // thread-locality.
1252  static GenericValue buffer;
1253  return buffer;
1254 #endif
1255  }
1256  }
1257  template <typename SourceAllocator>
1258  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1259 
1260 #if RAPIDJSON_HAS_STDSTRING
1261  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 
1267 
1268  ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1270 
1271  ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1273 
1274  MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1276 
1277  MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1278 
1280 
1285  GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1286  RAPIDJSON_ASSERT(IsObject());
1287  DoReserveMembers(newCapacity, allocator);
1288  return *this;
1289  }
1290 
1292 
1299  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1300 
1301 #if RAPIDJSON_HAS_STDSTRING
1302 
1310  bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1311 #endif
1312 
1314 
1322  template <typename SourceAllocator>
1323  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1324 
1326 
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 
1345 
1357  template <typename SourceAllocator>
1358  MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
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 
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 
1378 
1387  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1388  RAPIDJSON_ASSERT(IsObject());
1389  RAPIDJSON_ASSERT(name.IsString());
1390  DoAddMember(name, value, allocator);
1391  return *this;
1392  }
1393 
1395 
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 
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 
1425 
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 
1466 
1475  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1476  GenericValue n(name);
1477  return AddMember(n, value, allocator);
1478  }
1479 
1481 
1489  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1490  GenericValue v(value);
1491  return AddMember(name, v, allocator);
1492  }
1493 
1495 
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 
1519 
1522  void RemoveAllMembers() {
1523  RAPIDJSON_ASSERT(IsObject());
1524  DoClearMembers();
1525  }
1526 
1528 
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 
1556 
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 
1572 
1580  MemberIterator EraseMember(ConstMemberIterator pos) {
1581  return EraseMember(pos, pos +1);
1582  }
1583 
1585 
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 
1604 
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 
1634 
1636 
1637 
1639 
1640  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1641 
1643  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1644 
1646  SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1647 
1649  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1650 
1652 
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 
1664 
1668  GenericValue& operator[](SizeType index) {
1669  RAPIDJSON_ASSERT(IsArray());
1670  RAPIDJSON_ASSERT(index < data_.a.size);
1671  return GetElementsPointer()[index];
1672  }
1673  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1674 
1676 
1677  ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1679 
1680  ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1682 
1683  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1685 
1686  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1687 
1689 
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 
1704 
1713  GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
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 
1728 
1736  GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1737  return (*this).template PushBack<StringRefType>(value, allocator);
1738  }
1739 
1741 
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 
1765 
1768  GenericValue& PopBack() {
1769  RAPIDJSON_ASSERT(IsArray());
1770  RAPIDJSON_ASSERT(!Empty());
1771  GetElementsPointer()[--data_.a.size].~GenericValue();
1772  return *this;
1773  }
1774 
1776 
1782  ValueIterator Erase(ConstValueIterator pos) {
1783  return Erase(pos, pos + 1);
1784  }
1785 
1787 
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 
1813 
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 
1823 
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 
1835 
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 
1849 
1851 
1852 
1853  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
1854 
1856 
1858  SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
1859 
1861 
1868  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1869 
1871 
1875  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1876 
1878 
1885  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1886 
1888 
1893  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1894 
1896 
1901  GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1902 
1903 #if RAPIDJSON_HAS_STDSTRING
1904 
1911  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1912 #endif
1913 
1915 
1917 
1918 
1920 
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 
1939 
1941 
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;
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 
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 
2435  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2436  data_.f.flags = kConstStringFlag;
2437  SetStringPointer(s);
2438  data_.s.length = s.length;
2439  }
2440 
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  } else {
2449  data_.f.flags = kCopyStringFlag;
2450  data_.s.length = s.length;
2451  str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2452  SetStringPointer(str);
2453  }
2454  std::memcpy(str, s, s.length * sizeof(Ch));
2455  str[s.length] = '\0';
2456  }
2457 
2459  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2460  data_ = rhs.data_;
2461  // data_.f.flags = rhs.data_.f.flags;
2462  rhs.data_.f.flags = kNullFlag;
2463  }
2464 
2465  template <typename SourceAllocator>
2466  bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2467  RAPIDJSON_ASSERT(IsString());
2468  RAPIDJSON_ASSERT(rhs.IsString());
2469 
2470  const SizeType len1 = GetStringLength();
2471  const SizeType len2 = rhs.GetStringLength();
2472  if(len1 != len2) { return false; }
2473 
2474  const Ch* const str1 = GetString();
2475  const Ch* const str2 = rhs.GetString();
2476  if(str1 == str2) { return true; } // fast path for constant string
2477 
2478  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2479  }
2480 
2481  Data data_;
2482 };
2483 
2486 
2488 // GenericDocument
2489 
2491 
2498 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2499 class GenericDocument : public GenericValue<Encoding, Allocator> {
2500 public:
2501  typedef typename Encoding::Ch Ch;
2503  typedef Allocator AllocatorType;
2504  typedef StackAllocator StackAllocatorType;
2505 
2507 
2513  explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2514  GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2515  {
2516  if (!allocator_)
2517  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2518  }
2519 
2521 
2526  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2527  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2528  {
2529  if (!allocator_)
2530  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2531  }
2532 
2533 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2534  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2536  : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2537  allocator_(rhs.allocator_),
2538  ownAllocator_(rhs.ownAllocator_),
2539  stack_(std::move(rhs.stack_)),
2540  parseResult_(rhs.parseResult_)
2541  {
2542  rhs.allocator_ = 0;
2543  rhs.ownAllocator_ = 0;
2544  rhs.parseResult_ = ParseResult();
2545  }
2546 #endif
2547 
2548  ~GenericDocument() {
2549  // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
2550  // runs last and may access its elements or members which would be freed
2551  // with an allocator like MemoryPoolAllocator (CrtAllocator does not
2552  // free its data when destroyed, but MemoryPoolAllocator does).
2553  if (ownAllocator_) {
2554  ValueType::SetNull();
2555  }
2556  Destroy();
2557  }
2558 
2559 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2560  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2562  {
2563  // The cast to ValueType is necessary here, because otherwise it would
2564  // attempt to call GenericValue's templated assignment operator.
2565  ValueType::operator=(std::forward<ValueType>(rhs));
2566 
2567  // Calling the destructor here would prematurely call stack_'s destructor
2568  Destroy();
2569 
2570  allocator_ = rhs.allocator_;
2571  ownAllocator_ = rhs.ownAllocator_;
2572  stack_ = std::move(rhs.stack_);
2573  parseResult_ = rhs.parseResult_;
2574 
2575  rhs.allocator_ = 0;
2576  rhs.ownAllocator_ = 0;
2577  rhs.parseResult_ = ParseResult();
2578 
2579  return *this;
2580  }
2581 #endif
2582 
2584 
2589  GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2590  ValueType::Swap(rhs);
2591  stack_.Swap(rhs.stack_);
2592  internal::Swap(allocator_, rhs.allocator_);
2593  internal::Swap(ownAllocator_, rhs.ownAllocator_);
2594  internal::Swap(parseResult_, rhs.parseResult_);
2595  return *this;
2596  }
2597 
2598  // Allow Swap with ValueType.
2599  // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2600  using ValueType::Swap;
2601 
2603 
2614  friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2615 
2617 
2621  template <typename Generator>
2622  GenericDocument& Populate(Generator& g) {
2623  ClearStackOnExit scope(*this);
2624  if (g(*this)) {
2625  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2626  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2627  }
2628  return *this;
2629  }
2630 
2633 
2635 
2641  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2642  GenericDocument& ParseStream(InputStream& is) {
2644  stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2645  ClearStackOnExit scope(*this);
2646  parseResult_ = reader.template Parse<parseFlags>(is, *this);
2647  if (parseResult_) {
2648  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2649  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2650  }
2651  return *this;
2652  }
2653 
2655 
2660  template <unsigned parseFlags, typename InputStream>
2661  GenericDocument& ParseStream(InputStream& is) {
2662  return ParseStream<parseFlags, Encoding, InputStream>(is);
2663  }
2664 
2666 
2670  template <typename InputStream>
2671  GenericDocument& ParseStream(InputStream& is) {
2672  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2673  }
2675 
2678 
2680 
2684  template <unsigned parseFlags>
2687  return ParseStream<parseFlags | kParseInsituFlag>(s);
2688  }
2689 
2691 
2695  return ParseInsitu<kParseDefaultFlags>(str);
2696  }
2698 
2701 
2703 
2707  template <unsigned parseFlags, typename SourceEncoding>
2708  GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2709  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2711  return ParseStream<parseFlags, SourceEncoding>(s);
2712  }
2713 
2715 
2718  template <unsigned parseFlags>
2719  GenericDocument& Parse(const Ch* str) {
2720  return Parse<parseFlags, Encoding>(str);
2721  }
2722 
2724 
2726  GenericDocument& Parse(const Ch* str) {
2727  return Parse<kParseDefaultFlags>(str);
2728  }
2729 
2730  template <unsigned parseFlags, typename SourceEncoding>
2731  GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2732  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2733  MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2735  ParseStream<parseFlags, SourceEncoding>(is);
2736  return *this;
2737  }
2738 
2739  template <unsigned parseFlags>
2740  GenericDocument& Parse(const Ch* str, size_t length) {
2741  return Parse<parseFlags, Encoding>(str, length);
2742  }
2743 
2744  GenericDocument& Parse(const Ch* str, size_t length) {
2745  return Parse<kParseDefaultFlags>(str, length);
2746  }
2747 
2748 #if RAPIDJSON_HAS_STDSTRING
2749  template <unsigned parseFlags, typename SourceEncoding>
2750  GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2751  // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2752  return Parse<parseFlags, SourceEncoding>(str.c_str());
2753  }
2754 
2755  template <unsigned parseFlags>
2756  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2757  return Parse<parseFlags, Encoding>(str.c_str());
2758  }
2759 
2760  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2761  return Parse<kParseDefaultFlags>(str);
2762  }
2763 #endif // RAPIDJSON_HAS_STDSTRING
2764 
2766 
2769 
2771  bool HasParseError() const { return parseResult_.IsError(); }
2772 
2774  ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2775 
2777  size_t GetErrorOffset() const { return parseResult_.Offset(); }
2778 
2780 #ifndef __clang // -Wdocumentation
2781 
2790 #endif
2791  operator ParseResult() const { return parseResult_; }
2793 
2795  Allocator& GetAllocator() {
2796  RAPIDJSON_ASSERT(allocator_);
2797  return *allocator_;
2798  }
2799 
2801  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2802 
2803 private:
2804  // clear stack on any exit from ParseStream, e.g. due to exception
2805  struct ClearStackOnExit {
2806  explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2807  ~ClearStackOnExit() { d_.ClearStack(); }
2808  private:
2809  ClearStackOnExit(const ClearStackOnExit&);
2810  ClearStackOnExit& operator=(const ClearStackOnExit&);
2811  GenericDocument& d_;
2812  };
2813 
2814  // callers of the following private Handler functions
2815  // template <typename,typename,typename> friend class GenericReader; // for parsing
2816  template <typename, typename> friend class GenericValue; // for deep copying
2817 
2818 public:
2819  // Implementation of Handler
2820  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2821  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2822  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2823  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2824  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2825  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2826  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2827 
2828  bool RawNumber(const Ch* str, SizeType length, bool copy) {
2829  if (copy)
2830  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2831  else
2832  new (stack_.template Push<ValueType>()) ValueType(str, length);
2833  return true;
2834  }
2835 
2836  bool String(const Ch* str, SizeType length, bool copy) {
2837  if (copy)
2838  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2839  else
2840  new (stack_.template Push<ValueType>()) ValueType(str, length);
2841  return true;
2842  }
2843 
2844  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2845 
2846  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2847 
2848  bool EndObject(SizeType memberCount) {
2849  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2850  stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2851  return true;
2852  }
2853 
2854  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2855 
2856  bool EndArray(SizeType elementCount) {
2857  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2858  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2859  return true;
2860  }
2861 
2862 private:
2867 
2868  void ClearStack() {
2869  if (Allocator::kNeedFree)
2870  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2871  (stack_.template Pop<ValueType>(1))->~ValueType();
2872  else
2873  stack_.Clear();
2874  stack_.ShrinkToFit();
2875  }
2876 
2877  void Destroy() {
2878  RAPIDJSON_DELETE(ownAllocator_);
2879  }
2880 
2881  static const size_t kDefaultStackCapacity = 1024;
2882  Allocator* allocator_;
2883  Allocator* ownAllocator_;
2885  ParseResult parseResult_;
2886 };
2887 
2890 
2891 
2893 
2897 template <bool Const, typename ValueT>
2898 class GenericArray {
2899 public:
2900  typedef GenericArray<true, ValueT> ConstArray;
2901  typedef GenericArray<false, ValueT> Array;
2902  typedef ValueT PlainType;
2903  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2904  typedef ValueType* ValueIterator; // This may be const or non-const iterator
2905  typedef const ValueT* ConstValueIterator;
2906  typedef typename ValueType::AllocatorType AllocatorType;
2907  typedef typename ValueType::StringRefType StringRefType;
2908 
2909  template <typename, typename>
2910  friend class GenericValue;
2911 
2912  GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2913  GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2914  ~GenericArray() {}
2915 
2916  operator ValueType&() const { return value_; }
2917  SizeType Size() const { return value_.Size(); }
2918  SizeType Capacity() const { return value_.Capacity(); }
2919  bool Empty() const { return value_.Empty(); }
2920  void Clear() const { value_.Clear(); }
2921  ValueType& operator[](SizeType index) const { return value_[index]; }
2922  ValueIterator Begin() const { return value_.Begin(); }
2923  ValueIterator End() const { return value_.End(); }
2924  GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2925  GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2926 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2927  GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2928 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2929  GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2930  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2931  GenericArray PopBack() const { value_.PopBack(); return *this; }
2932  ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2933  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2934 
2935 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2936  ValueIterator begin() const { return value_.Begin(); }
2937  ValueIterator end() const { return value_.End(); }
2938 #endif
2939 
2940 private:
2941  GenericArray();
2942  GenericArray(ValueType& value) : value_(value) {}
2943  ValueType& value_;
2944 };
2945 
2947 
2951 template <bool Const, typename ValueT>
2952 class GenericObject {
2953 public:
2954  typedef GenericObject<true, ValueT> ConstObject;
2955  typedef GenericObject<false, ValueT> Object;
2956  typedef ValueT PlainType;
2957  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2958  typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
2960  typedef typename ValueType::AllocatorType AllocatorType;
2961  typedef typename ValueType::StringRefType StringRefType;
2962  typedef typename ValueType::EncodingType EncodingType;
2963  typedef typename ValueType::Ch Ch;
2964 
2965  template <typename, typename>
2966  friend class GenericValue;
2967 
2968  GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2969  GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2970  ~GenericObject() {}
2971 
2972  operator ValueType&() const { return value_; }
2973  SizeType MemberCount() const { return value_.MemberCount(); }
2974  SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2975  bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2976  template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2977  template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2978 #if RAPIDJSON_HAS_STDSTRING
2979  ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2980 #endif
2981  MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2982  MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2983  GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2984  bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2985 #if RAPIDJSON_HAS_STDSTRING
2986  bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2987 #endif
2988  template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2989  MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2990  template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2991 #if RAPIDJSON_HAS_STDSTRING
2992  MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2993 #endif
2994  GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2995  GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2996 #if RAPIDJSON_HAS_STDSTRING
2997  GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2998 #endif
2999  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3000 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3001  GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3002  GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3003  GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3004  GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3005 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
3006  GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3007  GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3008  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3009  void RemoveAllMembers() { value_.RemoveAllMembers(); }
3010  bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
3011 #if RAPIDJSON_HAS_STDSTRING
3012  bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
3013 #endif
3014  template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
3015  MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
3016  MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
3017  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
3018  bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
3019 #if RAPIDJSON_HAS_STDSTRING
3020  bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
3021 #endif
3022  template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
3023 
3024 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
3025  MemberIterator begin() const { return value_.MemberBegin(); }
3026  MemberIterator end() const { return value_.MemberEnd(); }
3027 #endif
3028 
3029 private:
3030  GenericObject();
3031  GenericObject(ValueType& value) : value_(value) {}
3032  ValueType& value_;
3033 };
3034 
3036 RAPIDJSON_DIAG_POP
3037 
3038 #ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3039 #pragma pop_macro("GetObject")
3040 #undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3041 #endif
3042 
3043 #endif // RAPIDJSON_DOCUMENT_H_
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:792
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:222
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:843
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2503
#define RAPIDJSON_USE_MEMBERSMAP
Enable RapidJSON support for object members handling in a std::multimap.
Definition: rapidjson.h:180
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2502
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:415
Definition: document.h:502
Represents an in-memory input byte stream.
Definition: memorystream.h:40
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition: document.h:872
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:437
reference Reference
Reference to (const) GenericMember.
Definition: document.h:214
Definition: document.h:2086
Definition: document.h:2063
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:320
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:122
object
Definition: rapidjson.h:733
Helper class for accessing Value of array type.
Definition: document.h:651
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:720
Read-only string stream.
Definition: fwd.h:47
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:2614
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition: document.h:834
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2622
(Constant) member iterator for a JSON object value
Definition: document.h:186
const Ch *const s
plain CharType pointer
Definition: document.h:419
array
Definition: rapidjson.h:734
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:196
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2501
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:2661
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:66
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:476
pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:212
false
Definition: rapidjson.h:731
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:282
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 HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: document.h:2771
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:198
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:679
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:672
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:123
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:2671
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition: rapidjson.h:687
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:2777
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:671
A document for parsing JSON text as DOM.
Definition: document.h:69
A read-write string stream.
Definition: fwd.h:52
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:804
Definition: document.h:2098
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
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2513
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:673
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:712
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2526
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:781
string
Definition: rapidjson.h:735
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:674
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:399
StackAllocator StackAllocatorType
StackAllocator type from template parameter.
Definition: document.h:2504
#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
User defined kDefaultObjectCapacity value.
Definition: document.h:99
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2485
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:677
ParseErrorCode
Error code of parsing.
Definition: error.h:64
Helper class for accessing Value of object type.
Definition: document.h:652
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:2685
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:375
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:675
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2795
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2889
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:680
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:420
number
Definition: rapidjson.h:736
SizeType hashcode
reserved
Definition: document.h:2039
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:716
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2708
~GenericValue()
Destructor.
Definition: document.h:880
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:2694
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:2801
Definition: document.h:2092
Definition: document.h:2061
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:2415
CharType Ch
character type of the string
Definition: document.h:347
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:494
Definition: document.h:2051
Definition: allocators.h:423
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:2774
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:454
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:676
Definition: document.h:2037
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:2442
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:2435
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:798
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:819
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:678
Name-value pair in a JSON object value.
Definition: document.h:120
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:840
Definition: document.h:2067
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:2719
true
Definition: rapidjson.h:732
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
User defined kDefaultArrayCapacity value.
Definition: document.h:110
Definition: document.h:519
Reference to a constant string (not taking a copy)
Definition: document.h:346
Definition: document.h:509
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:142
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:200
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:240
Definition: allocators.h:425
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition: rapidjson.h:307
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:690
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:831
Type
Type of JSON value.
Definition: rapidjson.h:729
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:946
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:2726
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:411
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:2459
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:507
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:2589
Definition: document.h:2026
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
In-situ(destructive) parsing.
Definition: reader.h:148
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:2642
null
Definition: rapidjson.h:730
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition: document.h:861