SimulationCraft
SimulationCraft is a tool to explore combat mechanics in the popular MMO RPG World of Warcraft (tm).
document.h
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef RAPIDJSON_DOCUMENT_H_
16 #define RAPIDJSON_DOCUMENT_H_
17 
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 MemoryPoolAllocator<CrtAllocator>
79 #endif
80 
87 #ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
88 #define RAPIDJSON_DEFAULT_STACK_ALLOCATOR 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
787  RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
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 
1082 
1084  template <typename SourceAllocator>
1085  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1086 
1088  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1089 
1091 
1093  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1094 
1095 #ifndef __cpp_lib_three_way_comparison
1096 
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  // This will generate -Wexit-time-destructors in clang
1234  // static GenericValue NullValue;
1235  // return NullValue;
1236 
1237  // Use static buffer and placement-new to prevent destruction
1238  static char buffer[sizeof(GenericValue)];
1239  return *new (buffer) GenericValue();
1240  }
1241  }
1242  template <typename SourceAllocator>
1243  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1244 
1245 #if RAPIDJSON_HAS_STDSTRING
1246  GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1248  const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1249 #endif
1250 
1252 
1253  ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1255 
1256  ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1258 
1259  MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1261 
1262  MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1263 
1265 
1270  GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1271  RAPIDJSON_ASSERT(IsObject());
1272  DoReserveMembers(newCapacity, allocator);
1273  return *this;
1274  }
1275 
1277 
1284  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1285 
1286 #if RAPIDJSON_HAS_STDSTRING
1287 
1295  bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1296 #endif
1297 
1299 
1307  template <typename SourceAllocator>
1308  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1309 
1311 
1322  MemberIterator FindMember(const Ch* name) {
1323  GenericValue n(StringRef(name));
1324  return FindMember(n);
1325  }
1326 
1327  ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1328 
1330 
1342  template <typename SourceAllocator>
1343  MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
1344  RAPIDJSON_ASSERT(IsObject());
1345  RAPIDJSON_ASSERT(name.IsString());
1346  return DoFindMember(name);
1347  }
1348  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1349 
1350 #if RAPIDJSON_HAS_STDSTRING
1351 
1358  MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1359  ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1360 #endif
1361 
1363 
1372  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1373  RAPIDJSON_ASSERT(IsObject());
1374  RAPIDJSON_ASSERT(name.IsString());
1375  DoAddMember(name, value, allocator);
1376  return *this;
1377  }
1378 
1380 
1388  GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1389  GenericValue v(value);
1390  return AddMember(name, v, allocator);
1391  }
1392 
1393 #if RAPIDJSON_HAS_STDSTRING
1394 
1403  GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1404  GenericValue v(value, allocator);
1405  return AddMember(name, v, allocator);
1406  }
1407 #endif
1408 
1410 
1426  template <typename T>
1427  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1428  AddMember(GenericValue& name, T value, Allocator& allocator) {
1429  GenericValue v(value);
1430  return AddMember(name, v, allocator);
1431  }
1432 
1433 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1434  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1435  return AddMember(name, value, allocator);
1436  }
1437  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1438  return AddMember(name, value, allocator);
1439  }
1440  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1441  return AddMember(name, value, allocator);
1442  }
1443  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1444  GenericValue n(name);
1445  return AddMember(n, value, allocator);
1446  }
1447 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1448 
1449 
1451 
1460  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1461  GenericValue n(name);
1462  return AddMember(n, value, allocator);
1463  }
1464 
1466 
1474  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1475  GenericValue v(value);
1476  return AddMember(name, v, allocator);
1477  }
1478 
1480 
1496  template <typename T>
1497  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1498  AddMember(StringRefType name, T value, Allocator& allocator) {
1499  GenericValue n(name);
1500  return AddMember(n, value, allocator);
1501  }
1502 
1504 
1507  void RemoveAllMembers() {
1508  RAPIDJSON_ASSERT(IsObject());
1509  DoClearMembers();
1510  }
1511 
1513 
1520  bool RemoveMember(const Ch* name) {
1521  GenericValue n(StringRef(name));
1522  return RemoveMember(n);
1523  }
1524 
1525 #if RAPIDJSON_HAS_STDSTRING
1526  bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1527 #endif
1528 
1529  template <typename SourceAllocator>
1530  bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1531  MemberIterator m = FindMember(name);
1532  if (m != MemberEnd()) {
1533  RemoveMember(m);
1534  return true;
1535  }
1536  else
1537  return false;
1538  }
1539 
1541 
1548  MemberIterator RemoveMember(MemberIterator m) {
1549  RAPIDJSON_ASSERT(IsObject());
1550  RAPIDJSON_ASSERT(data_.o.size > 0);
1551  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1552  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1553  return DoRemoveMember(m);
1554  }
1555 
1557 
1565  MemberIterator EraseMember(ConstMemberIterator pos) {
1566  return EraseMember(pos, pos +1);
1567  }
1568 
1570 
1578  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1579  RAPIDJSON_ASSERT(IsObject());
1580  RAPIDJSON_ASSERT(data_.o.size > 0);
1581  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1582  RAPIDJSON_ASSERT(first >= MemberBegin());
1583  RAPIDJSON_ASSERT(first <= last);
1584  RAPIDJSON_ASSERT(last <= MemberEnd());
1585  return DoEraseMembers(first, last);
1586  }
1587 
1589 
1593  bool EraseMember(const Ch* name) {
1594  GenericValue n(StringRef(name));
1595  return EraseMember(n);
1596  }
1597 
1598 #if RAPIDJSON_HAS_STDSTRING
1599  bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1600 #endif
1601 
1602  template <typename SourceAllocator>
1603  bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1604  MemberIterator m = FindMember(name);
1605  if (m != MemberEnd()) {
1606  EraseMember(m);
1607  return true;
1608  }
1609  else
1610  return false;
1611  }
1612 
1613  Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1614  Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1615  ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1616  ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1617 
1619 
1621 
1622 
1624 
1625  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1626 
1628  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1629 
1631  SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1632 
1634  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1635 
1637 
1640  void Clear() {
1641  RAPIDJSON_ASSERT(IsArray());
1642  GenericValue* e = GetElementsPointer();
1643  for (GenericValue* v = e; v != e + data_.a.size; ++v)
1644  v->~GenericValue();
1645  data_.a.size = 0;
1646  }
1647 
1649 
1653  GenericValue& operator[](SizeType index) {
1654  RAPIDJSON_ASSERT(IsArray());
1655  RAPIDJSON_ASSERT(index < data_.a.size);
1656  return GetElementsPointer()[index];
1657  }
1658  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1659 
1661 
1662  ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1664 
1665  ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1667 
1668  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1670 
1671  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1672 
1674 
1679  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1680  RAPIDJSON_ASSERT(IsArray());
1681  if (newCapacity > data_.a.capacity) {
1682  SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1683  data_.a.capacity = newCapacity;
1684  }
1685  return *this;
1686  }
1687 
1689 
1698  GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1699  RAPIDJSON_ASSERT(IsArray());
1700  if (data_.a.size >= data_.a.capacity)
1701  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1702  GetElementsPointer()[data_.a.size++].RawAssign(value);
1703  return *this;
1704  }
1705 
1706 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1707  GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1708  return PushBack(value, allocator);
1709  }
1710 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1711 
1713 
1721  GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1722  return (*this).template PushBack<StringRefType>(value, allocator);
1723  }
1724 
1726 
1742  template <typename T>
1743  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1744  PushBack(T value, Allocator& allocator) {
1745  GenericValue v(value);
1746  return PushBack(v, allocator);
1747  }
1748 
1750 
1753  GenericValue& PopBack() {
1754  RAPIDJSON_ASSERT(IsArray());
1755  RAPIDJSON_ASSERT(!Empty());
1756  GetElementsPointer()[--data_.a.size].~GenericValue();
1757  return *this;
1758  }
1759 
1761 
1767  ValueIterator Erase(ConstValueIterator pos) {
1768  return Erase(pos, pos + 1);
1769  }
1770 
1772 
1779  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1780  RAPIDJSON_ASSERT(IsArray());
1781  RAPIDJSON_ASSERT(data_.a.size > 0);
1782  RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1783  RAPIDJSON_ASSERT(first >= Begin());
1784  RAPIDJSON_ASSERT(first <= last);
1785  RAPIDJSON_ASSERT(last <= End());
1786  ValueIterator pos = Begin() + (first - Begin());
1787  for (ValueIterator itr = pos; itr != last; ++itr)
1788  itr->~GenericValue();
1789  std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1790  data_.a.size -= static_cast<SizeType>(last - first);
1791  return pos;
1792  }
1793 
1794  Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1795  ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1796 
1798 
1800 
1801 
1802  int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1803  unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1804  int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1805  uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1806 
1808 
1810  double GetDouble() const {
1811  RAPIDJSON_ASSERT(IsNumber());
1812  if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1813  if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1814  if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1815  if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1816  RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1817  }
1818 
1820 
1822  float GetFloat() const {
1823  return static_cast<float>(GetDouble());
1824  }
1825 
1826  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1827  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1828  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1829  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1830  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1831  GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1832 
1834 
1836 
1837 
1838  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
1839 
1841 
1843  SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
1844 
1846 
1853  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1854 
1856 
1860  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1861 
1863 
1870  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1871 
1873 
1878  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1879 
1881 
1886  GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1887 
1888 #if RAPIDJSON_HAS_STDSTRING
1889 
1896  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1897 #endif
1898 
1900 
1902 
1903 
1905 
1908  template <typename T>
1909  bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1910 
1911  template <typename T>
1912  T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1913 
1914  template <typename T>
1915  T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1916 
1917  template<typename T>
1918  ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1919 
1920  template<typename T>
1921  ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1922 
1923  GenericValue& SetRawOutput(bool state) { state ? data_.f.flags |= kRawOutputStrFlag : data_.f.flags &= ~kRawOutputStrFlag; return *this; }
1924 
1926 
1928 
1934  template <typename Handler>
1935  bool Accept(Handler& handler) const {
1936  switch(GetType()) {
1937  case kNullType: return handler.Null();
1938  case kFalseType: return handler.Bool(false);
1939  case kTrueType: return handler.Bool(true);
1940 
1941  case kObjectType:
1942  if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1943  return false;
1944  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1945  RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1946  if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1947  return false;
1948  if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1949  return false;
1950  }
1951  return handler.EndObject(data_.o.size);
1952 
1953  case kArrayType:
1954  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1955  return false;
1956  for (ConstValueIterator v = Begin(); v != End(); ++v)
1957  if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1958  return false;
1959  return handler.EndArray(data_.a.size);
1960 
1961  case kStringType:
1962  return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0, (data_.f.flags & kRawOutputStrFlag) != 0);
1963 
1964  default:
1965  RAPIDJSON_ASSERT(GetType() == kNumberType);
1966  if (IsDouble()) return handler.Double(data_.n.d);
1967  else if (IsInt()) return handler.Int(data_.n.i.i);
1968  else if (IsUint()) return handler.Uint(data_.n.u.u);
1969  else if (IsInt64()) return handler.Int64(data_.n.i64);
1970  else return handler.Uint64(data_.n.u64);
1971  }
1972  }
1973 
1974 private:
1975  template <typename, typename> friend class GenericValue;
1976  template <typename, typename, typename> friend class GenericDocument;
1977 
1978  enum {
1979  kBoolFlag = 0x0008,
1980  kNumberFlag = 0x0010,
1981  kIntFlag = 0x0020,
1982  kUintFlag = 0x0040,
1983  kInt64Flag = 0x0080,
1984  kUint64Flag = 0x0100,
1985  kDoubleFlag = 0x0200,
1986  kStringFlag = 0x0400,
1987  kCopyFlag = 0x0800,
1988  kInlineStrFlag = 0x1000,
1989  kRawOutputStrFlag = 0x8000,
1990 
1991  // Initial flags of different types.
1992  kNullFlag = kNullType,
1993  // These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types.
1994  kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
1995  kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
1996  kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
1997  kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
1998  kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
1999  kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
2000  kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
2001  kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
2002  kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
2003  kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
2004  kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2005  kObjectFlag = kObjectType,
2006  kArrayFlag = kArrayType,
2007 
2008  kTypeMask = 0x07
2009  };
2010 
2011  static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
2012  static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
2013 
2014  struct Flag {
2015 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2016  char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
2017 #elif RAPIDJSON_64BIT
2018  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
2019 #else
2020  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
2021 #endif
2022  uint16_t flags;
2023  };
2024 
2025  struct String {
2026  SizeType length;
2027  SizeType hashcode;
2028  const Ch* str;
2029  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2030 
2031  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
2032  // (excluding the terminating zero) and store a value to determine the length of the contained
2033  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
2034  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
2035  // the string terminator as well. For getting the string length back from that value just use
2036  // "MaxSize - str[LenPos]".
2037  // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2038  // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
2039  struct ShortString {
2040  enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2041  Ch str[MaxChars];
2042 
2043  inline static bool Usable(SizeType len) { return (MaxSize >= len); }
2044  inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2045  inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
2046  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2047 
2048  // By using proper binary layout, retrieval of different integer types do not need conversions.
2049  union Number {
2050 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2051  struct I {
2052  int i;
2053  char padding[4];
2054  }i;
2055  struct U {
2056  unsigned u;
2057  char padding2[4];
2058  }u;
2059 #else
2060  struct I {
2061  char padding[4];
2062  int i;
2063  }i;
2064  struct U {
2065  char padding2[4];
2066  unsigned u;
2067  }u;
2068 #endif
2069  int64_t i64;
2070  uint64_t u64;
2071  double d;
2072  }; // 8 bytes
2073 
2074  struct ObjectData {
2075  SizeType size;
2076  SizeType capacity;
2077  Member* members;
2078  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2079 
2080  struct ArrayData {
2081  SizeType size;
2082  SizeType capacity;
2083  GenericValue* elements;
2084  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2085 
2086  union Data {
2087  String s;
2088  ShortString ss;
2089  Number n;
2090  ObjectData o;
2091  ArrayData a;
2092  Flag f;
2093  }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2094 
2095  static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
2096  return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
2097  }
2098  static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
2099  return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2100  }
2101 
2102  RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2103  RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2104  RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2105  RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2106  RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2107  RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2108 
2109 #if RAPIDJSON_USE_MEMBERSMAP
2110 
2111  struct MapTraits {
2112  struct Less {
2113  bool operator()(const Data& s1, const Data& s2) const {
2114  SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
2115  int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2));
2116  return cmp < 0 || (cmp == 0 && n1 < n2);
2117  }
2118  };
2119  typedef std::pair<const Data, SizeType> Pair;
2120  typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
2121  typedef typename Map::iterator Iterator;
2122  };
2123  typedef typename MapTraits::Map Map;
2124  typedef typename MapTraits::Less MapLess;
2125  typedef typename MapTraits::Pair MapPair;
2126  typedef typename MapTraits::Iterator MapIterator;
2127 
2128  //
2129  // Layout of the members' map/array, re(al)located according to the needed capacity:
2130  //
2131  // {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]}
2132  //
2133  // (where <> stands for the RAPIDJSON_ALIGN-ment, if needed)
2134  //
2135 
2136  static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) {
2137  return RAPIDJSON_ALIGN(sizeof(Map*)) +
2138  RAPIDJSON_ALIGN(sizeof(SizeType)) +
2139  RAPIDJSON_ALIGN(capacity * sizeof(Member)) +
2140  capacity * sizeof(MapIterator);
2141  }
2142 
2143  static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) {
2144  return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
2145  RAPIDJSON_ALIGN(sizeof(Map*)));
2146  }
2147 
2148  static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) {
2149  return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
2150  RAPIDJSON_ALIGN(sizeof(Map*)) +
2151  RAPIDJSON_ALIGN(sizeof(SizeType)));
2152  }
2153 
2154  static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
2155  return reinterpret_cast<MapIterator*>(reinterpret_cast<uintptr_t>(&map) +
2156  RAPIDJSON_ALIGN(sizeof(Map*)) +
2157  RAPIDJSON_ALIGN(sizeof(SizeType)) +
2158  RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member)));
2159  }
2160 
2161  static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) {
2162  RAPIDJSON_ASSERT(members != 0);
2163  return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
2164  RAPIDJSON_ALIGN(sizeof(SizeType)) -
2165  RAPIDJSON_ALIGN(sizeof(Map*)));
2166  }
2167 
2168  // Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting..
2169  RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
2170 #if RAPIDJSON_HAS_CXX11
2171  MapIterator ret = std::move(rhs);
2172 #else
2173  MapIterator ret = rhs;
2174 #endif
2175  rhs.~MapIterator();
2176  return ret;
2177  }
2178 
2179  Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) {
2180  Map **newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
2181  GetMapCapacity(*newMap) = newCapacity;
2182  if (!oldMap) {
2183  *newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator);
2184  }
2185  else {
2186  *newMap = *oldMap;
2187  size_t count = (*oldMap)->size();
2188  std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
2189  static_cast<void*>(GetMapMembers(*oldMap)),
2190  count * sizeof(Member));
2191  MapIterator *oldIt = GetMapIterators(*oldMap),
2192  *newIt = GetMapIterators(*newMap);
2193  while (count--) {
2194  new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
2195  }
2196  Allocator::Free(oldMap);
2197  }
2198  return *newMap;
2199  }
2200 
2201  RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2202  return GetMapMembers(DoReallocMap(0, capacity, allocator));
2203  }
2204 
2205  void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2206  ObjectData& o = data_.o;
2207  if (newCapacity > o.capacity) {
2208  Member* oldMembers = GetMembersPointer();
2209  Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
2210  *&newMap = DoReallocMap(oldMap, newCapacity, allocator);
2211  RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
2212  o.capacity = newCapacity;
2213  }
2214  }
2215 
2216  template <typename SourceAllocator>
2217  MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2218  if (Member* members = GetMembersPointer()) {
2219  Map* &map = GetMap(members);
2220  MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
2221  if (mit != map->end()) {
2222  return MemberIterator(&members[mit->second]);
2223  }
2224  }
2225  return MemberEnd();
2226  }
2227 
2228  void DoClearMembers() {
2229  if (Member* members = GetMembersPointer()) {
2230  Map* &map = GetMap(members);
2231  MapIterator* mit = GetMapIterators(map);
2232  for (SizeType i = 0; i < data_.o.size; i++) {
2233  map->erase(DropMapIterator(mit[i]));
2234  members[i].~Member();
2235  }
2236  data_.o.size = 0;
2237  }
2238  }
2239 
2240  void DoFreeMembers() {
2241  if (Member* members = GetMembersPointer()) {
2242  GetMap(members)->~Map();
2243  for (SizeType i = 0; i < data_.o.size; i++) {
2244  members[i].~Member();
2245  }
2246  if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
2247  Map** map = &GetMap(members);
2248  Allocator::Free(*map);
2249  Allocator::Free(map);
2250  }
2251  }
2252  }
2253 
2254 #else // !RAPIDJSON_USE_MEMBERSMAP
2255 
2256  RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2257  return Malloc<Member>(allocator, capacity);
2258  }
2259 
2260  void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2261  ObjectData& o = data_.o;
2262  if (newCapacity > o.capacity) {
2263  Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2264  RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
2265  o.capacity = newCapacity;
2266  }
2267  }
2268 
2269  template <typename SourceAllocator>
2270  MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2271  MemberIterator member = MemberBegin();
2272  for ( ; member != MemberEnd(); ++member)
2273  if (name.StringEqual(member->name))
2274  break;
2275  return member;
2276  }
2277 
2278  void DoClearMembers() {
2279  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2280  m->~Member();
2281  data_.o.size = 0;
2282  }
2283 
2284  void DoFreeMembers() {
2285  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2286  m->~Member();
2287  Allocator::Free(GetMembersPointer());
2288  }
2289 
2290 #endif // !RAPIDJSON_USE_MEMBERSMAP
2291 
2292  void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
2293  ObjectData& o = data_.o;
2294  if (o.size >= o.capacity)
2295  DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
2296  Member* members = GetMembersPointer();
2297  Member* m = members + o.size;
2298  m->name.RawAssign(name);
2299  m->value.RawAssign(value);
2300 #if RAPIDJSON_USE_MEMBERSMAP
2301  Map* &map = GetMap(members);
2302  MapIterator* mit = GetMapIterators(map);
2303  new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
2304 #endif
2305  ++o.size;
2306  }
2307 
2308  MemberIterator DoRemoveMember(MemberIterator m) {
2309  ObjectData& o = data_.o;
2310  Member* members = GetMembersPointer();
2311 #if RAPIDJSON_USE_MEMBERSMAP
2312  Map* &map = GetMap(members);
2313  MapIterator* mit = GetMapIterators(map);
2314  SizeType mpos = static_cast<SizeType>(&*m - members);
2315  map->erase(DropMapIterator(mit[mpos]));
2316 #endif
2317  MemberIterator last(members + (o.size - 1));
2318  if (o.size > 1 && m != last) {
2319 #if RAPIDJSON_USE_MEMBERSMAP
2320  new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
2321  mit[mpos]->second = mpos;
2322 #endif
2323  *m = *last; // Move the last one to this place
2324  }
2325  else {
2326  m->~Member(); // Only one left, just destroy
2327  }
2328  --o.size;
2329  return m;
2330  }
2331 
2332  MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) {
2333  ObjectData& o = data_.o;
2334  MemberIterator beg = MemberBegin(),
2335  pos = beg + (first - beg),
2336  end = MemberEnd();
2337 #if RAPIDJSON_USE_MEMBERSMAP
2338  Map* &map = GetMap(GetMembersPointer());
2339  MapIterator* mit = GetMapIterators(map);
2340 #endif
2341  for (MemberIterator itr = pos; itr != last; ++itr) {
2342 #if RAPIDJSON_USE_MEMBERSMAP
2343  map->erase(DropMapIterator(mit[itr - beg]));
2344 #endif
2345  itr->~Member();
2346  }
2347 #if RAPIDJSON_USE_MEMBERSMAP
2348  if (first != last) {
2349  // Move remaining members/iterators
2350  MemberIterator next = pos + (last - first);
2351  for (MemberIterator itr = pos; next != end; ++itr, ++next) {
2352  std::memcpy(static_cast<void*>(&*itr), &*next, sizeof(Member));
2353  SizeType mpos = static_cast<SizeType>(itr - beg);
2354  new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
2355  mit[mpos]->second = mpos;
2356  }
2357  }
2358 #else
2359  std::memmove(static_cast<void*>(&*pos), &*last,
2360  static_cast<size_t>(end - last) * sizeof(Member));
2361 #endif
2362  o.size -= static_cast<SizeType>(last - first);
2363  return pos;
2364  }
2365 
2366  template <typename SourceAllocator>
2367  void DoCopyMembers(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings) {
2368  RAPIDJSON_ASSERT(rhs.GetType() == kObjectType);
2369 
2370  data_.f.flags = kObjectFlag;
2371  SizeType count = rhs.data_.o.size;
2372  Member* lm = DoAllocMembers(count, allocator);
2373  const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
2374 #if RAPIDJSON_USE_MEMBERSMAP
2375  Map* &map = GetMap(lm);
2376  MapIterator* mit = GetMapIterators(map);
2377 #endif
2378  for (SizeType i = 0; i < count; i++) {
2379  new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
2380  new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
2381 #if RAPIDJSON_USE_MEMBERSMAP
2382  new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
2383 #endif
2384  }
2385  data_.o.size = data_.o.capacity = count;
2386  SetMembersPointer(lm);
2387  }
2388 
2389  // Initialize this value as array with initial data, without calling destructor.
2390  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2391  data_.f.flags = kArrayFlag;
2392  if (count) {
2393  GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2394  SetElementsPointer(e);
2395  std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2396  }
2397  else
2398  SetElementsPointer(0);
2399  data_.a.size = data_.a.capacity = count;
2400  }
2401 
2403  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2404  data_.f.flags = kObjectFlag;
2405  if (count) {
2406  Member* m = DoAllocMembers(count, allocator);
2407  SetMembersPointer(m);
2408  std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2409 #if RAPIDJSON_USE_MEMBERSMAP
2410  Map* &map = GetMap(m);
2411  MapIterator* mit = GetMapIterators(map);
2412  for (SizeType i = 0; i < count; i++) {
2413  new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
2414  }
2415 #endif
2416  }
2417  else
2418  SetMembersPointer(0);
2419  data_.o.size = data_.o.capacity = count;
2420  }
2421 
2423  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2424  data_.f.flags = kConstStringFlag;
2425  SetStringPointer(s);
2426  data_.s.length = s.length;
2427  }
2428 
2430  void SetStringRaw(StringRefType s, Allocator& allocator) {
2431  Ch* str = 0;
2432  if (ShortString::Usable(s.length)) {
2433  data_.f.flags = kShortStringFlag;
2434  data_.ss.SetLength(s.length);
2435  str = data_.ss.str;
2436  } else {
2437  data_.f.flags = kCopyStringFlag;
2438  data_.s.length = s.length;
2439  str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2440  SetStringPointer(str);
2441  }
2442  std::memcpy(str, s, s.length * sizeof(Ch));
2443  str[s.length] = '\0';
2444  }
2445 
2447  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2448  data_ = rhs.data_;
2449  // data_.f.flags = rhs.data_.f.flags;
2450  rhs.data_.f.flags = kNullFlag;
2451  }
2452 
2453  template <typename SourceAllocator>
2454  bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2455  RAPIDJSON_ASSERT(IsString());
2456  RAPIDJSON_ASSERT(rhs.IsString());
2457 
2458  const SizeType len1 = GetStringLength();
2459  const SizeType len2 = rhs.GetStringLength();
2460  if(len1 != len2) { return false; }
2461 
2462  const Ch* const str1 = GetString();
2463  const Ch* const str2 = rhs.GetString();
2464  if(str1 == str2) { return true; } // fast path for constant string
2465 
2466  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2467  }
2468 
2469  Data data_;
2470 };
2471 
2473 typedef GenericValue<UTF8<> > Value;
2474 
2476 // GenericDocument
2477 
2479 
2486 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2487 class GenericDocument : public GenericValue<Encoding, Allocator> {
2488 public:
2489  typedef typename Encoding::Ch Ch;
2491  typedef Allocator AllocatorType;
2492 
2494 
2500  explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2501  GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2502  {
2503  if (!allocator_)
2504  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2505  }
2506 
2508 
2513  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2514  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2515  {
2516  if (!allocator_)
2517  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2518  }
2519 
2520 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2521  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2523  : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2524  allocator_(rhs.allocator_),
2525  ownAllocator_(rhs.ownAllocator_),
2526  stack_(std::move(rhs.stack_)),
2527  parseResult_(rhs.parseResult_)
2528  {
2529  rhs.allocator_ = 0;
2530  rhs.ownAllocator_ = 0;
2531  rhs.parseResult_ = ParseResult();
2532  }
2533 #endif
2534 
2535  ~GenericDocument() {
2536  // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
2537  // runs last and may access its elements or members which would be freed
2538  // with an allocator like MemoryPoolAllocator (CrtAllocator does not
2539  // free its data when destroyed, but MemoryPoolAllocator does).
2540  if (ownAllocator_) {
2541  ValueType::SetNull();
2542  }
2543  Destroy();
2544  }
2545 
2546 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2547  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2549  {
2550  // The cast to ValueType is necessary here, because otherwise it would
2551  // attempt to call GenericValue's templated assignment operator.
2552  ValueType::operator=(std::forward<ValueType>(rhs));
2553 
2554  // Calling the destructor here would prematurely call stack_'s destructor
2555  Destroy();
2556 
2557  allocator_ = rhs.allocator_;
2558  ownAllocator_ = rhs.ownAllocator_;
2559  stack_ = std::move(rhs.stack_);
2560  parseResult_ = rhs.parseResult_;
2561 
2562  rhs.allocator_ = 0;
2563  rhs.ownAllocator_ = 0;
2564  rhs.parseResult_ = ParseResult();
2565 
2566  return *this;
2567  }
2568 #endif
2569 
2571 
2576  GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2577  ValueType::Swap(rhs);
2578  stack_.Swap(rhs.stack_);
2579  internal::Swap(allocator_, rhs.allocator_);
2580  internal::Swap(ownAllocator_, rhs.ownAllocator_);
2581  internal::Swap(parseResult_, rhs.parseResult_);
2582  return *this;
2583  }
2584 
2585  // Allow Swap with ValueType.
2586  // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2587  using ValueType::Swap;
2588 
2590 
2601  friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2602 
2604 
2608  template <typename Generator>
2609  GenericDocument& Populate(Generator& g) {
2610  ClearStackOnExit scope(*this);
2611  if (g(*this)) {
2612  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2613  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2614  }
2615  return *this;
2616  }
2617 
2620 
2622 
2628  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2629  GenericDocument& ParseStream(InputStream& is) {
2631  stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2632  ClearStackOnExit scope(*this);
2633  parseResult_ = reader.template Parse<parseFlags>(is, *this);
2634  if (parseResult_) {
2635  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2636  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2637  }
2638  return *this;
2639  }
2640 
2642 
2647  template <unsigned parseFlags, typename InputStream>
2648  GenericDocument& ParseStream(InputStream& is) {
2649  return ParseStream<parseFlags, Encoding, InputStream>(is);
2650  }
2651 
2653 
2657  template <typename InputStream>
2658  GenericDocument& ParseStream(InputStream& is) {
2659  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2660  }
2662 
2665 
2667 
2671  template <unsigned parseFlags>
2674  return ParseStream<parseFlags | kParseInsituFlag>(s);
2675  }
2676 
2678 
2682  return ParseInsitu<kParseDefaultFlags>(str);
2683  }
2685 
2688 
2690 
2694  template <unsigned parseFlags, typename SourceEncoding>
2695  GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2696  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2698  return ParseStream<parseFlags, SourceEncoding>(s);
2699  }
2700 
2702 
2705  template <unsigned parseFlags>
2706  GenericDocument& Parse(const Ch* str) {
2707  return Parse<parseFlags, Encoding>(str);
2708  }
2709 
2711 
2713  GenericDocument& Parse(const Ch* str) {
2714  return Parse<kParseDefaultFlags>(str);
2715  }
2716 
2717  template <unsigned parseFlags, typename SourceEncoding>
2718  GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2719  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2720  MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2722  ParseStream<parseFlags, SourceEncoding>(is);
2723  return *this;
2724  }
2725 
2726  template <unsigned parseFlags>
2727  GenericDocument& Parse(const Ch* str, size_t length) {
2728  return Parse<parseFlags, Encoding>(str, length);
2729  }
2730 
2731  GenericDocument& Parse(const Ch* str, size_t length) {
2732  return Parse<kParseDefaultFlags>(str, length);
2733  }
2734 
2735 #if RAPIDJSON_HAS_STDSTRING
2736  template <unsigned parseFlags, typename SourceEncoding>
2737  GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2738  // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2739  return Parse<parseFlags, SourceEncoding>(str.c_str());
2740  }
2741 
2742  template <unsigned parseFlags>
2743  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2744  return Parse<parseFlags, Encoding>(str.c_str());
2745  }
2746 
2747  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2748  return Parse<kParseDefaultFlags>(str);
2749  }
2750 #endif // RAPIDJSON_HAS_STDSTRING
2751 
2753 
2756 
2758  bool HasParseError() const { return parseResult_.IsError(); }
2759 
2761  ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2762 
2764  size_t GetErrorOffset() const { return parseResult_.Offset(); }
2765 
2767 #ifndef __clang // -Wdocumentation
2768 
2777 #endif
2778  operator ParseResult() const { return parseResult_; }
2780 
2782  Allocator& GetAllocator() {
2783  RAPIDJSON_ASSERT(allocator_);
2784  return *allocator_;
2785  }
2786 
2788  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2789 
2790 private:
2791  // clear stack on any exit from ParseStream, e.g. due to exception
2792  struct ClearStackOnExit {
2793  explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2794  ~ClearStackOnExit() { d_.ClearStack(); }
2795  private:
2796  ClearStackOnExit(const ClearStackOnExit&);
2797  ClearStackOnExit& operator=(const ClearStackOnExit&);
2798  GenericDocument& d_;
2799  };
2800 
2801  // callers of the following private Handler functions
2802  // template <typename,typename,typename> friend class GenericReader; // for parsing
2803  template <typename, typename> friend class GenericValue; // for deep copying
2804 
2805 public:
2806  // Implementation of Handler
2807  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2808  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2809  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2810  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2811  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2812  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2813  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2814 
2815  bool RawNumber(const Ch* str, SizeType length, bool copy) {
2816  if (copy)
2817  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2818  else
2819  new (stack_.template Push<ValueType>()) ValueType(str, length);
2820  return true;
2821  }
2822 
2823  bool String(const Ch* str, SizeType length, bool copy) {
2824  if (copy)
2825  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2826  else
2827  new (stack_.template Push<ValueType>()) ValueType(str, length);
2828  return true;
2829  }
2830 
2831  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2832 
2833  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2834 
2835  bool EndObject(SizeType memberCount) {
2836  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2837  stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2838  return true;
2839  }
2840 
2841  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2842 
2843  bool EndArray(SizeType elementCount) {
2844  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2845  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2846  return true;
2847  }
2848 
2849 private:
2854 
2855  void ClearStack() {
2856  if (Allocator::kNeedFree)
2857  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2858  (stack_.template Pop<ValueType>(1))->~ValueType();
2859  else
2860  stack_.Clear();
2861  stack_.ShrinkToFit();
2862  }
2863 
2864  void Destroy() {
2865  RAPIDJSON_DELETE(ownAllocator_);
2866  }
2867 
2868  static const size_t kDefaultStackCapacity = 1024;
2869  Allocator* allocator_;
2870  Allocator* ownAllocator_;
2872  ParseResult parseResult_;
2873 };
2874 
2877 
2878 
2880 
2884 template <bool Const, typename ValueT>
2885 class GenericArray {
2886 public:
2887  typedef GenericArray<true, ValueT> ConstArray;
2888  typedef GenericArray<false, ValueT> Array;
2889  typedef ValueT PlainType;
2890  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2891  typedef ValueType* ValueIterator; // This may be const or non-const iterator
2892  typedef const ValueT* ConstValueIterator;
2893  typedef typename ValueType::AllocatorType AllocatorType;
2894  typedef typename ValueType::StringRefType StringRefType;
2895 
2896  template <typename, typename>
2897  friend class GenericValue;
2898 
2899  GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2900  GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2901  ~GenericArray() {}
2902 
2903  operator ValueType&() const { return value_; }
2904  SizeType Size() const { return value_.Size(); }
2905  SizeType Capacity() const { return value_.Capacity(); }
2906  bool Empty() const { return value_.Empty(); }
2907  void Clear() const { value_.Clear(); }
2908  ValueType& operator[](SizeType index) const { return value_[index]; }
2909  ValueIterator Begin() const { return value_.Begin(); }
2910  ValueIterator End() const { return value_.End(); }
2911  GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2912  GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2913 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2914  GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2915 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2916  GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2917  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; }
2918  GenericArray PopBack() const { value_.PopBack(); return *this; }
2919  ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2920  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2921 
2922 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2923  ValueIterator begin() const { return value_.Begin(); }
2924  ValueIterator end() const { return value_.End(); }
2925 #endif
2926 
2927 private:
2928  GenericArray();
2929  GenericArray(ValueType& value) : value_(value) {}
2930  ValueType& value_;
2931 };
2932 
2934 
2938 template <bool Const, typename ValueT>
2939 class GenericObject {
2940 public:
2941  typedef GenericObject<true, ValueT> ConstObject;
2942  typedef GenericObject<false, ValueT> Object;
2943  typedef ValueT PlainType;
2944  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2945  typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
2947  typedef typename ValueType::AllocatorType AllocatorType;
2948  typedef typename ValueType::StringRefType StringRefType;
2949  typedef typename ValueType::EncodingType EncodingType;
2950  typedef typename ValueType::Ch Ch;
2951 
2952  template <typename, typename>
2953  friend class GenericValue;
2954 
2955  GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2956  GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2957  ~GenericObject() {}
2958 
2959  operator ValueType&() const { return value_; }
2960  SizeType MemberCount() const { return value_.MemberCount(); }
2961  SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2962  bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2963  template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2964  template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2965 #if RAPIDJSON_HAS_STDSTRING
2966  ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2967 #endif
2968  MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2969  MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2970  GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2971  bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2972 #if RAPIDJSON_HAS_STDSTRING
2973  bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2974 #endif
2975  template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2976  MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2977  template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2978 #if RAPIDJSON_HAS_STDSTRING
2979  MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2980 #endif
2981  GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2982  GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2983 #if RAPIDJSON_HAS_STDSTRING
2984  GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2985 #endif
2986  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; }
2987 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2988  GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2989  GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2990  GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2991  GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2992 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2993  GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2994  GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2995  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; }
2996  void RemoveAllMembers() { value_.RemoveAllMembers(); }
2997  bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2998 #if RAPIDJSON_HAS_STDSTRING
2999  bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
3000 #endif
3001  template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
3002  MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
3003  MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
3004  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
3005  bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
3006 #if RAPIDJSON_HAS_STDSTRING
3007  bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
3008 #endif
3009  template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
3010 
3011 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
3012  MemberIterator begin() const { return value_.MemberBegin(); }
3013  MemberIterator end() const { return value_.MemberEnd(); }
3014 #endif
3015 
3016 private:
3017  GenericObject();
3018  GenericObject(ValueType& value) : value_(value) {}
3019  ValueType& value_;
3020 };
3021 
3023 RAPIDJSON_DIAG_POP
3024 
3025 #ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3026 #pragma pop_macro("GetObject")
3027 #undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3028 #endif
3029 
3030 #endif // RAPIDJSON_DOCUMENT_H_
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition: document.h:872
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:2576
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:123
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:2713
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition: document.h:861
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:2761
Definition: document.h:2080
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:2648
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2491
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:781
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2490
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:240
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:222
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:678
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:679
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:282
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:831
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:843
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:2447
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:2672
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:675
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:66
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:672
#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:2764
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:494
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:680
Definition: document.h:2039
ParseErrorCode
Error code of parsing.
Definition: error.h:64
#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
User defined kDefaultObjectCapacity value.
Definition: document.h:99
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:454
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:2681
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2513
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:946
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2782
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:399
Definition: document.h:502
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:420
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:375
A contiguous memory buffer with an optional growing ability.
Definition: core.h:778
Definition: document.h:509
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:2430
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition: rapidjson.h:687
Reference to a constant string (not taking a copy)
Definition: document.h:346
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2609
Represents an in-memory input byte stream.
Definition: memorystream.h:40
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:690
reference Reference
Reference to (const) GenericMember.
Definition: document.h:214
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:2403
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:196
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: document.h:2758
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:819
Definition: document.h:2014
Read-only string stream.
Definition: fwd.h:47
const Ch *const s
plain CharType pointer
Definition: document.h:419
pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:212
Name-value pair in a JSON object value.
Definition: document.h:120
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:411
#define RAPIDJSON_USE_MEMBERSMAP
Enable RapidJSON support for object members handling in a std::multimap.
Definition: rapidjson.h:180
Definition: document.h:2051
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:2601
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:2788
Definition: document.h:2086
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:142
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:507
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:846
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition: rapidjson.h:307
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:198
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
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:200
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
Definition: document.h:474
SizeType hashcode
reserved
Definition: document.h:2027
Helper class for accessing Value of array type.
Definition: document.h:651
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:2706
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2695
Definition: allocators.h:422
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:2658
Definition: document.h:2025
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:676
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:122
CharType Ch
character type of the string
Definition: document.h:347
Helper class for accessing Value of object type.
Definition: document.h:652
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:677
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:921
~GenericValue()
Destructor.
Definition: document.h:880
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
User defined kDefaultArrayCapacity value.
Definition: document.h:110
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:216
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:2629
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:720
Definition: document.h:2055
Definition: document.h:519
A read-write string stream.
Definition: fwd.h:52
Definition: document.h:2049
(Constant) member iterator for a JSON object value
Definition: document.h:186
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2500
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:2423
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:798
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:437
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2489
A document for parsing JSON text as DOM.
Definition: document.h:69
Definition: allocators.h:424
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition: document.h:834
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:792
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:673
Definition: document.h:2074
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator)
Definition: document.h:742
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:804
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:840
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:671
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:674