MeshProtocolSimulator  1.0.0
document.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef RAPIDJSON_DOCUMENT_H_
16 #define RAPIDJSON_DOCUMENT_H_
17 
20 #include "reader.h"
21 #include "internal/meta.h"
22 #include "internal/strfunc.h"
23 #include "memorystream.h"
24 #include "encodedstream.h"
25 #include <new> // placement new
26 #include <limits>
27 
28 RAPIDJSON_DIAG_PUSH
29 #ifdef _MSC_VER
30 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
31 RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
32 #endif
33 
34 #ifdef __clang__
35 RAPIDJSON_DIAG_OFF(padded)
36 RAPIDJSON_DIAG_OFF(switch-enum)
37 RAPIDJSON_DIAG_OFF(c++98-compat)
38 #endif
39 
40 #ifdef __GNUC__
41 RAPIDJSON_DIAG_OFF(effc++)
42 #if __GNUC__ >= 6
43 RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions
44 #endif
45 #endif // __GNUC__
46 
47 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
48 #include <iterator> // std::iterator, std::random_access_iterator_tag
49 #endif
50 
51 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
52 #include <utility> // std::move
53 #endif
54 
56 
57 // Forward declaration.
58 template <typename Encoding, typename Allocator>
60 
61 template <typename Encoding, typename Allocator, typename StackAllocator>
63 
65 
70 template <typename Encoding, typename Allocator>
71 struct GenericMember {
74 };
75 
77 // GenericMemberIterator
78 
79 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
80 
82 
100 template <bool Const, typename Encoding, typename Allocator>
102  : public std::iterator<std::random_access_iterator_tag
103  , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
104 
105  friend class GenericValue<Encoding,Allocator>;
106  template <bool, typename, typename> friend class GenericMemberIterator;
107 
109  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
110  typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
111 
112 public:
119 
121  typedef typename BaseType::pointer Pointer;
123  typedef typename BaseType::reference Reference;
125  typedef typename BaseType::difference_type DifferenceType;
126 
128 
131  GenericMemberIterator() : ptr_() {}
132 
134 
149  GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
150  Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
151 
153 
154  Iterator& operator++(){ ++ptr_; return *this; }
155  Iterator& operator--(){ --ptr_; return *this; }
156  Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
157  Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
159 
161 
162  Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
163  Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
164 
165  Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
166  Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
168 
170 
171  bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
172  bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
173  bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
174  bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
175  bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
176  bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
178 
180 
181  Reference operator*() const { return *ptr_; }
182  Pointer operator->() const { return ptr_; }
183  Reference operator[](DifferenceType n) const { return ptr_[n]; }
185 
187  DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
188 
189 private:
191  explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
192 
193  Pointer ptr_;
194 };
195 
196 #else // RAPIDJSON_NOMEMBERITERATORCLASS
197 
198 // class-based member iterator implementation disabled, use plain pointers
199 
200 template <bool Const, typename Encoding, typename Allocator>
201 struct GenericMemberIterator;
202 
204 template <typename Encoding, typename Allocator>
208 };
210 template <typename Encoding, typename Allocator>
214 };
215 
216 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
217 
219 // GenericStringRef
220 
222 
248 template<typename CharType>
250  typedef CharType Ch;
251 
253 #ifndef __clang__ // -Wdocumentation
254 
276 #endif
277  template<SizeType N>
278  GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
279  : s(str), length(N-1) {}
280 
282 #ifndef __clang__ // -Wdocumentation
283 
301 #endif
302  explicit GenericStringRef(const CharType* str)
303  : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); }
304 
306 #ifndef __clang__ // -Wdocumentation
307 
313 #endif
314  GenericStringRef(const CharType* str, SizeType len)
315  : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); }
316 
317  GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
318 
319  GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; }
320 
322  operator const Ch *() const { return s; }
323 
324  const Ch* const s;
325  const SizeType length;
326 
327 private:
329  template<SizeType N>
330  GenericStringRef(CharType (&str)[N]) /* = delete */;
331 };
332 
334 
345 template<typename CharType>
346 inline GenericStringRef<CharType> StringRef(const CharType* str) {
347  return GenericStringRef<CharType>(str, internal::StrLen(str));
348 }
349 
351 
365 template<typename CharType>
366 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
367  return GenericStringRef<CharType>(str, SizeType(length));
368 }
369 
370 #if RAPIDJSON_HAS_STDSTRING
371 
383 template<typename CharType>
384 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
385  return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
386 }
387 #endif
388 
390 // GenericValue type traits
391 namespace internal {
392 
393 template <typename T, typename Encoding = void, typename Allocator = void>
394 struct IsGenericValueImpl : FalseType {};
395 
396 // select candidates according to nested encoding and allocator types
397 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
398  : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
399 
400 // helper to match arbitrary GenericValue instantiations, including derived classes
401 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
402 
403 } // namespace internal
404 
406 // TypeHelper
407 
408 namespace internal {
409 
410 template <typename ValueType, typename T>
411 struct TypeHelper {};
412 
413 template<typename ValueType>
414 struct TypeHelper<ValueType, bool> {
415  static bool Is(const ValueType& v) { return v.IsBool(); }
416  static bool Get(const ValueType& v) { return v.GetBool(); }
417  static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
418  static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
419 };
420 
421 template<typename ValueType>
422 struct TypeHelper<ValueType, int> {
423  static bool Is(const ValueType& v) { return v.IsInt(); }
424  static int Get(const ValueType& v) { return v.GetInt(); }
425  static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
426  static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
427 };
428 
429 template<typename ValueType>
430 struct TypeHelper<ValueType, unsigned> {
431  static bool Is(const ValueType& v) { return v.IsUint(); }
432  static unsigned Get(const ValueType& v) { return v.GetUint(); }
433  static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
434  static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
435 };
436 
437 template<typename ValueType>
438 struct TypeHelper<ValueType, int64_t> {
439  static bool Is(const ValueType& v) { return v.IsInt64(); }
440  static int64_t Get(const ValueType& v) { return v.GetInt64(); }
441  static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
442  static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
443 };
444 
445 template<typename ValueType>
446 struct TypeHelper<ValueType, uint64_t> {
447  static bool Is(const ValueType& v) { return v.IsUint64(); }
448  static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
449  static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
450  static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
451 };
452 
453 template<typename ValueType>
454 struct TypeHelper<ValueType, double> {
455  static bool Is(const ValueType& v) { return v.IsDouble(); }
456  static double Get(const ValueType& v) { return v.GetDouble(); }
457  static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
458  static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
459 };
460 
461 template<typename ValueType>
462 struct TypeHelper<ValueType, float> {
463  static bool Is(const ValueType& v) { return v.IsFloat(); }
464  static float Get(const ValueType& v) { return v.GetFloat(); }
465  static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
466  static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
467 };
468 
469 template<typename ValueType>
470 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
471  typedef const typename ValueType::Ch* StringType;
472  static bool Is(const ValueType& v) { return v.IsString(); }
473  static StringType Get(const ValueType& v) { return v.GetString(); }
474  static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
475  static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
476 };
477 
478 #if RAPIDJSON_HAS_STDSTRING
479 template<typename ValueType>
480 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
481  typedef std::basic_string<typename ValueType::Ch> StringType;
482  static bool Is(const ValueType& v) { return v.IsString(); }
483  static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
484  static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
485 };
486 #endif
487 
488 template<typename ValueType>
489 struct TypeHelper<ValueType, typename ValueType::Array> {
490  typedef typename ValueType::Array ArrayType;
491  static bool Is(const ValueType& v) { return v.IsArray(); }
492  static ArrayType Get(ValueType& v) { return v.GetArray(); }
493  static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
494  static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
495 };
496 
497 template<typename ValueType>
498 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
499  typedef typename ValueType::ConstArray ArrayType;
500  static bool Is(const ValueType& v) { return v.IsArray(); }
501  static ArrayType Get(const ValueType& v) { return v.GetArray(); }
502 };
503 
504 template<typename ValueType>
505 struct TypeHelper<ValueType, typename ValueType::Object> {
506  typedef typename ValueType::Object ObjectType;
507  static bool Is(const ValueType& v) { return v.IsObject(); }
508  static ObjectType Get(ValueType& v) { return v.GetObject(); }
509  static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
510  static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; }
511 };
512 
513 template<typename ValueType>
514 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
515  typedef typename ValueType::ConstObject ObjectType;
516  static bool Is(const ValueType& v) { return v.IsObject(); }
517  static ObjectType Get(const ValueType& v) { return v.GetObject(); }
518 };
519 
520 } // namespace internal
521 
522 // Forward declarations
523 template <bool, typename> class GenericArray;
524 template <bool, typename> class GenericObject;
525 
527 // GenericValue
528 
530 
539 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
540 class GenericValue {
541 public:
546  typedef typename Encoding::Ch Ch;
557 
559 
560 
562  GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
563 
564 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
565  GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
567  rhs.data_.f.flags = kNullFlag; // give up contents
568  }
569 #endif
570 
571 private:
573  GenericValue(const GenericValue& rhs);
574 
575 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
576  template <typename StackAllocator>
579 
581  template <typename StackAllocator>
583 #endif
584 
585 public:
586 
588 
592  explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
593  static const uint16_t defaultFlags[7] = {
594  kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
595  kNumberAnyFlag
596  };
597  RAPIDJSON_ASSERT(type <= kNumberType);
598  data_.f.flags = defaultFlags[type];
599 
600  // Use ShortString to store empty string.
601  if (type == kStringType)
602  data_.ss.SetLength(0);
603  }
604 
606 
612  template< typename SourceAllocator >
614 
616 
621 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
622  template <typename T>
623  explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
624 #else
625  explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
626 #endif
627  : data_() {
628  // safe-guard against failing SFINAE
630  data_.f.flags = b ? kTrueFlag : kFalseFlag;
631  }
632 
634  explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
635  data_.n.i64 = i;
636  data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
637  }
638 
640  explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
641  data_.n.u64 = u;
642  data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
643  }
644 
646  explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
647  data_.n.i64 = i64;
648  data_.f.flags = kNumberInt64Flag;
649  if (i64 >= 0) {
650  data_.f.flags |= kNumberUint64Flag;
651  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
652  data_.f.flags |= kUintFlag;
653  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
654  data_.f.flags |= kIntFlag;
655  }
656  else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
657  data_.f.flags |= kIntFlag;
658  }
659 
661  explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
662  data_.n.u64 = u64;
663  data_.f.flags = kNumberUint64Flag;
664  if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
665  data_.f.flags |= kInt64Flag;
666  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
667  data_.f.flags |= kUintFlag;
668  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
669  data_.f.flags |= kIntFlag;
670  }
671 
673  explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
674 
676  GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
677 
679  explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
680 
682  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
683 
685  GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
686 
687 #if RAPIDJSON_HAS_STDSTRING
688 
691  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
692 #endif
693 
695 
700  GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
701  a.value_.data_ = Data();
702  a.value_.data_.f.flags = kArrayFlag;
703  }
704 
706 
711  GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
712  o.value_.data_ = Data();
713  o.value_.data_.f.flags = kObjectFlag;
714  }
715 
717 
720  if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
721  switch(data_.f.flags) {
722  case kArrayFlag:
723  {
724  GenericValue* e = GetElementsPointer();
725  for (GenericValue* v = e; v != e + data_.a.size; ++v)
726  v->~GenericValue();
727  Allocator::Free(e);
728  }
729  break;
730 
731  case kObjectFlag:
732  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
733  m->~Member();
734  Allocator::Free(GetMembersPointer());
735  break;
736 
737  case kCopyStringFlag:
738  Allocator::Free(const_cast<Ch*>(GetStringPointer()));
739  break;
740 
741  default:
742  break; // Do nothing for other types.
743  }
744  }
745  }
746 
748 
750 
751 
753 
755  GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
756  RAPIDJSON_ASSERT(this != &rhs);
757  this->~GenericValue();
758  RawAssign(rhs);
759  return *this;
760  }
761 
762 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
763  GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
765  return *this = rhs.Move();
766  }
767 #endif
768 
770 
774  GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
775  GenericValue s(str);
776  return *this = s;
777  }
778 
780 
791  template <typename T>
792  RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
793  operator=(T value) {
794  GenericValue v(value);
795  return *this = v;
796  }
797 
799 
804  template <typename SourceAllocator>
805  GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {
806  RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
807  this->~GenericValue();
808  new (this) GenericValue(rhs, allocator);
809  return *this;
810  }
811 
813 
817  GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
818  GenericValue temp;
819  temp.RawAssign(*this);
820  RawAssign(other);
821  other.RawAssign(temp);
822  return *this;
823  }
824 
826 
837  friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
838 
840 
841  GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
843 
845 
846 
851  template <typename SourceAllocator>
852  bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
854  if (GetType() != rhs.GetType())
855  return false;
856 
857  switch (GetType()) {
858  case kObjectType: // Warning: O(n^2) inner-loop
859  if (data_.o.size != rhs.data_.o.size)
860  return false;
861  for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
862  typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
863  if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
864  return false;
865  }
866  return true;
867 
868  case kArrayType:
869  if (data_.a.size != rhs.data_.a.size)
870  return false;
871  for (SizeType i = 0; i < data_.a.size; i++)
872  if ((*this)[i] != rhs[i])
873  return false;
874  return true;
875 
876  case kStringType:
877  return StringEqual(rhs);
878 
879  case kNumberType:
880  if (IsDouble() || rhs.IsDouble()) {
881  double a = GetDouble(); // May convert from integer to double.
882  double b = rhs.GetDouble(); // Ditto
883  return a >= b && a <= b; // Prevent -Wfloat-equal
884  }
885  else
886  return data_.n.u64 == rhs.data_.n.u64;
887 
888  default:
889  return true;
890  }
891  }
892 
894  bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
895 
896 #if RAPIDJSON_HAS_STDSTRING
897 
900  bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
901 #endif
902 
904 
906  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
907 
909 
911  template <typename SourceAllocator>
912  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
913 
915  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
916 
918 
920  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
921 
923 
925  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
926 
928 
930  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
932 
934 
935 
936  Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
937  bool IsNull() const { return data_.f.flags == kNullFlag; }
938  bool IsFalse() const { return data_.f.flags == kFalseFlag; }
939  bool IsTrue() const { return data_.f.flags == kTrueFlag; }
940  bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
941  bool IsObject() const { return data_.f.flags == kObjectFlag; }
942  bool IsArray() const { return data_.f.flags == kArrayFlag; }
943  bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
944  bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
945  bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
946  bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
947  bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
948  bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
949  bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
950 
951  // Checks whether a number can be losslessly converted to a double.
952  bool IsLosslessDouble() const {
953  if (!IsNumber()) return false;
954  if (IsUint64()) {
955  uint64_t u = GetUint64();
956  volatile double d = static_cast<double>(u);
957  return (d >= 0.0)
958  && (d < static_cast<double>(std::numeric_limits<uint64_t>::max()))
959  && (u == static_cast<uint64_t>(d));
960  }
961  if (IsInt64()) {
962  int64_t i = GetInt64();
963  volatile double d = static_cast<double>(i);
964  return (d >= static_cast<double>(std::numeric_limits<int64_t>::min()))
965  && (d < static_cast<double>(std::numeric_limits<int64_t>::max()))
966  && (i == static_cast<int64_t>(d));
967  }
968  return true; // double, int, uint are always lossless
969  }
970 
971  // Checks whether a number is a float (possible lossy).
972  bool IsFloat() const {
973  if ((data_.f.flags & kDoubleFlag) == 0)
974  return false;
975  double d = GetDouble();
976  return d >= -3.4028234e38 && d <= 3.4028234e38;
977  }
978  // Checks whether a number can be losslessly converted to a float.
979  bool IsLosslessFloat() const {
980  if (!IsNumber()) return false;
981  double a = GetDouble();
982  if (a < static_cast<double>(-std::numeric_limits<float>::max())
983  || a > static_cast<double>(std::numeric_limits<float>::max()))
984  return false;
985  double b = static_cast<double>(static_cast<float>(a));
986  return a >= b && a <= b; // Prevent -Wfloat-equal
987  }
988 
990 
992 
993 
994  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
995 
997 
999 
1000 
1001  bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1003 
1004  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1005 
1007 
1009 
1010 
1012 
1013  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1014 
1016  SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1017 
1019  bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1020 
1022 
1030  template <typename T>
1031  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1032  GenericValue n(StringRef(name));
1033  return (*this)[n];
1034  }
1035  template <typename T>
1036  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]; }
1037 
1039 
1047  template <typename SourceAllocator>
1048  GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1049  MemberIterator member = FindMember(name);
1050  if (member != MemberEnd())
1051  return member->value;
1052  else {
1053  RAPIDJSON_ASSERT(false); // see above note
1054 
1055  // This will generate -Wexit-time-destructors in clang
1056  // static GenericValue NullValue;
1057  // return NullValue;
1058 
1059  // Use static buffer and placement-new to prevent destruction
1060  static char buffer[sizeof(GenericValue)];
1061  return *new (buffer) GenericValue();
1062  }
1063  }
1064  template <typename SourceAllocator>
1065  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1066 
1067 #if RAPIDJSON_HAS_STDSTRING
1068  GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1070  const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1071 #endif
1072 
1074 
1075  ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1077 
1078  ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1080 
1081  MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1083 
1084  MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1085 
1087 
1094  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1095 
1096 #if RAPIDJSON_HAS_STDSTRING
1097 
1105  bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1106 #endif
1107 
1109 
1117  template <typename SourceAllocator>
1118  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1119 
1121 
1132  MemberIterator FindMember(const Ch* name) {
1133  GenericValue n(StringRef(name));
1134  return FindMember(n);
1135  }
1136 
1137  ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1138 
1140 
1152  template <typename SourceAllocator>
1154  RAPIDJSON_ASSERT(IsObject());
1155  RAPIDJSON_ASSERT(name.IsString());
1156  MemberIterator member = MemberBegin();
1157  for ( ; member != MemberEnd(); ++member)
1158  if (name.StringEqual(member->name))
1159  break;
1160  return member;
1161  }
1162  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1163 
1164 #if RAPIDJSON_HAS_STDSTRING
1165 
1172  MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1173  ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1174 #endif
1175 
1177 
1186  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1187  RAPIDJSON_ASSERT(IsObject());
1188  RAPIDJSON_ASSERT(name.IsString());
1189 
1190  ObjectData& o = data_.o;
1191  if (o.size >= o.capacity) {
1192  if (o.capacity == 0) {
1193  o.capacity = kDefaultObjectCapacity;
1194  SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))));
1195  }
1196  else {
1197  SizeType oldCapacity = o.capacity;
1198  o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
1199  SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member))));
1200  }
1201  }
1202  Member* members = GetMembersPointer();
1203  members[o.size].name.RawAssign(name);
1204  members[o.size].value.RawAssign(value);
1205  o.size++;
1206  return *this;
1207  }
1208 
1210 
1218  GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1219  GenericValue v(value);
1220  return AddMember(name, v, allocator);
1221  }
1222 
1223 #if RAPIDJSON_HAS_STDSTRING
1224 
1233  GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1234  GenericValue v(value, allocator);
1235  return AddMember(name, v, allocator);
1236  }
1237 #endif
1238 
1240 
1256  template <typename T>
1257  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1258  AddMember(GenericValue& name, T value, Allocator& allocator) {
1259  GenericValue v(value);
1260  return AddMember(name, v, allocator);
1261  }
1262 
1263 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1264  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1265  return AddMember(name, value, allocator);
1266  }
1267  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1268  return AddMember(name, value, allocator);
1269  }
1270  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1271  return AddMember(name, value, allocator);
1272  }
1273  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1274  GenericValue n(name);
1275  return AddMember(n, value, allocator);
1276  }
1277 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1278 
1279 
1281 
1290  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1291  GenericValue n(name);
1292  return AddMember(n, value, allocator);
1293  }
1294 
1296 
1304  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1305  GenericValue v(value);
1306  return AddMember(name, v, allocator);
1307  }
1308 
1310 
1326  template <typename T>
1327  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1328  AddMember(StringRefType name, T value, Allocator& allocator) {
1329  GenericValue n(name);
1330  return AddMember(n, value, allocator);
1331  }
1332 
1334 
1337  void RemoveAllMembers() {
1338  RAPIDJSON_ASSERT(IsObject());
1339  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1340  m->~Member();
1341  data_.o.size = 0;
1342  }
1343 
1345 
1352  bool RemoveMember(const Ch* name) {
1353  GenericValue n(StringRef(name));
1354  return RemoveMember(n);
1355  }
1356 
1357 #if RAPIDJSON_HAS_STDSTRING
1358  bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1359 #endif
1360 
1361  template <typename SourceAllocator>
1362  bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1363  MemberIterator m = FindMember(name);
1364  if (m != MemberEnd()) {
1365  RemoveMember(m);
1366  return true;
1367  }
1368  else
1369  return false;
1370  }
1371 
1373 
1380  MemberIterator RemoveMember(MemberIterator m) {
1381  RAPIDJSON_ASSERT(IsObject());
1382  RAPIDJSON_ASSERT(data_.o.size > 0);
1383  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1384  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1385 
1386  MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1387  if (data_.o.size > 1 && m != last)
1388  *m = *last; // Move the last one to this place
1389  else
1390  m->~Member(); // Only one left, just destroy
1391  --data_.o.size;
1392  return m;
1393  }
1394 
1396 
1404  MemberIterator EraseMember(ConstMemberIterator pos) {
1405  return EraseMember(pos, pos +1);
1406  }
1407 
1409 
1417  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1418  RAPIDJSON_ASSERT(IsObject());
1419  RAPIDJSON_ASSERT(data_.o.size > 0);
1420  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1421  RAPIDJSON_ASSERT(first >= MemberBegin());
1422  RAPIDJSON_ASSERT(first <= last);
1423  RAPIDJSON_ASSERT(last <= MemberEnd());
1424 
1425  MemberIterator pos = MemberBegin() + (first - MemberBegin());
1426  for (MemberIterator itr = pos; itr != last; ++itr)
1427  itr->~Member();
1428  std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1429  data_.o.size -= static_cast<SizeType>(last - first);
1430  return pos;
1431  }
1432 
1434 
1438  bool EraseMember(const Ch* name) {
1439  GenericValue n(StringRef(name));
1440  return EraseMember(n);
1441  }
1442 
1443 #if RAPIDJSON_HAS_STDSTRING
1444  bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1445 #endif
1446 
1447  template <typename SourceAllocator>
1448  bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1449  MemberIterator m = FindMember(name);
1450  if (m != MemberEnd()) {
1451  EraseMember(m);
1452  return true;
1453  }
1454  else
1455  return false;
1456  }
1457 
1458  Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1459  ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1460 
1462 
1464 
1465 
1467 
1468  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1469 
1471  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1472 
1474  SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1475 
1477  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1478 
1480 
1483  void Clear() {
1484  RAPIDJSON_ASSERT(IsArray());
1485  GenericValue* e = GetElementsPointer();
1486  for (GenericValue* v = e; v != e + data_.a.size; ++v)
1487  v->~GenericValue();
1488  data_.a.size = 0;
1489  }
1490 
1492 
1496  GenericValue& operator[](SizeType index) {
1497  RAPIDJSON_ASSERT(IsArray());
1498  RAPIDJSON_ASSERT(index < data_.a.size);
1499  return GetElementsPointer()[index];
1500  }
1501  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1502 
1504 
1505  ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1507 
1508  ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1510 
1511  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1513 
1514  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1515 
1517 
1522  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1523  RAPIDJSON_ASSERT(IsArray());
1524  if (newCapacity > data_.a.capacity) {
1525  SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1526  data_.a.capacity = newCapacity;
1527  }
1528  return *this;
1529  }
1530 
1532 
1541  GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1542  RAPIDJSON_ASSERT(IsArray());
1543  if (data_.a.size >= data_.a.capacity)
1544  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1545  GetElementsPointer()[data_.a.size++].RawAssign(value);
1546  return *this;
1547  }
1548 
1549 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1550  GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1551  return PushBack(value, allocator);
1552  }
1553 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1554 
1556 
1564  GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1565  return (*this).template PushBack<StringRefType>(value, allocator);
1566  }
1567 
1569 
1585  template <typename T>
1586  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1587  PushBack(T value, Allocator& allocator) {
1588  GenericValue v(value);
1589  return PushBack(v, allocator);
1590  }
1591 
1593 
1596  GenericValue& PopBack() {
1597  RAPIDJSON_ASSERT(IsArray());
1598  RAPIDJSON_ASSERT(!Empty());
1599  GetElementsPointer()[--data_.a.size].~GenericValue();
1600  return *this;
1601  }
1602 
1604 
1610  ValueIterator Erase(ConstValueIterator pos) {
1611  return Erase(pos, pos + 1);
1612  }
1613 
1615 
1623  RAPIDJSON_ASSERT(IsArray());
1624  RAPIDJSON_ASSERT(data_.a.size > 0);
1625  RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1626  RAPIDJSON_ASSERT(first >= Begin());
1627  RAPIDJSON_ASSERT(first <= last);
1628  RAPIDJSON_ASSERT(last <= End());
1629  ValueIterator pos = Begin() + (first - Begin());
1630  for (ValueIterator itr = pos; itr != last; ++itr)
1631  itr->~GenericValue();
1632  std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1633  data_.a.size -= static_cast<SizeType>(last - first);
1634  return pos;
1635  }
1636 
1637  Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1638  ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1639 
1641 
1643 
1644 
1645  int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1646  unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1647  int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1648  uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1649 
1651 
1653  double GetDouble() const {
1654  RAPIDJSON_ASSERT(IsNumber());
1655  if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1656  if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1657  if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1658  if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1659  RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1660  }
1661 
1663 
1665  float GetFloat() const {
1666  return static_cast<float>(GetDouble());
1667  }
1668 
1669  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1670  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1671  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1672  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1673  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1674  GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(f); return *this; }
1675 
1677 
1679 
1680 
1681  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1682 
1684 
1686  SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1687 
1689 
1696  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1697 
1699 
1703  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1704 
1706 
1713  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }
1714 
1716 
1721  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }
1722 
1723 #if RAPIDJSON_HAS_STDSTRING
1724 
1731  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }
1732 #endif
1733 
1735 
1737 
1738 
1740 
1743  template <typename T>
1744  bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1745 
1746  template <typename T>
1747  T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1748 
1749  template <typename T>
1750  T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1751 
1752  template<typename T>
1753  ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1754 
1755  template<typename T>
1756  ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1757 
1759 
1761 
1767  template <typename Handler>
1768  bool Accept(Handler& handler) const {
1769  switch(GetType()) {
1770  case kNullType: return handler.Null();
1771  case kFalseType: return handler.Bool(false);
1772  case kTrueType: return handler.Bool(true);
1773 
1774  case kObjectType:
1775  if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1776  return false;
1777  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1778  RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1779  if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1780  return false;
1781  if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1782  return false;
1783  }
1784  return handler.EndObject(data_.o.size);
1785 
1786  case kArrayType:
1787  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1788  return false;
1789  for (const GenericValue* v = Begin(); v != End(); ++v)
1790  if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1791  return false;
1792  return handler.EndArray(data_.a.size);
1793 
1794  case kStringType:
1795  return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1796 
1797  default:
1798  RAPIDJSON_ASSERT(GetType() == kNumberType);
1799  if (IsDouble()) return handler.Double(data_.n.d);
1800  else if (IsInt()) return handler.Int(data_.n.i.i);
1801  else if (IsUint()) return handler.Uint(data_.n.u.u);
1802  else if (IsInt64()) return handler.Int64(data_.n.i64);
1803  else return handler.Uint64(data_.n.u64);
1804  }
1805  }
1806 
1807 private:
1808  template <typename, typename> friend class GenericValue;
1809  template <typename, typename, typename> friend class GenericDocument;
1810 
1811  enum {
1812  kBoolFlag = 0x0008,
1813  kNumberFlag = 0x0010,
1814  kIntFlag = 0x0020,
1815  kUintFlag = 0x0040,
1816  kInt64Flag = 0x0080,
1817  kUint64Flag = 0x0100,
1818  kDoubleFlag = 0x0200,
1819  kStringFlag = 0x0400,
1820  kCopyFlag = 0x0800,
1821  kInlineStrFlag = 0x1000,
1822 
1823  // Initial flags of different types.
1824  kNullFlag = kNullType,
1825  kTrueFlag = kTrueType | kBoolFlag,
1826  kFalseFlag = kFalseType | kBoolFlag,
1827  kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
1828  kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
1829  kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
1830  kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
1831  kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
1832  kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
1833  kConstStringFlag = kStringType | kStringFlag,
1834  kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
1835  kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
1836  kObjectFlag = kObjectType,
1837  kArrayFlag = kArrayType,
1838 
1839  kTypeMask = 0x07
1840  };
1841 
1842  static const SizeType kDefaultArrayCapacity = 16;
1843  static const SizeType kDefaultObjectCapacity = 16;
1844 
1845  struct Flag {
1846 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
1847  char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
1848 #elif RAPIDJSON_64BIT
1849  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
1850 #else
1851  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
1852 #endif
1853  uint16_t flags;
1854  };
1855 
1856  struct String {
1857  SizeType length;
1859  const Ch* str;
1860  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1861 
1862  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1863  // (excluding the terminating zero) and store a value to determine the length of the contained
1864  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1865  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1866  // the string terminator as well. For getting the string length back from that value just use
1867  // "MaxSize - str[LenPos]".
1868  // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
1869  // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
1870  struct ShortString {
1871  enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
1872  Ch str[MaxChars];
1873 
1874  inline static bool Usable(SizeType len) { return (MaxSize >= len); }
1875  inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
1876  inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
1877  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1878 
1879  // By using proper binary layout, retrieval of different integer types do not need conversions.
1880  union Number {
1881 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
1882  struct I {
1883  int i;
1884  char padding[4];
1885  }i;
1886  struct U {
1887  unsigned u;
1888  char padding2[4];
1889  }u;
1890 #else
1891  struct I {
1892  char padding[4];
1893  int i;
1894  }i;
1895  struct U {
1896  char padding2[4];
1897  unsigned u;
1898  }u;
1899 #endif
1900  int64_t i64;
1901  uint64_t u64;
1902  double d;
1903  }; // 8 bytes
1904 
1905  struct ObjectData {
1906  SizeType size;
1907  SizeType capacity;
1908  Member* members;
1909  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1910 
1911  struct ArrayData {
1912  SizeType size;
1913  SizeType capacity;
1914  GenericValue* elements;
1915  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1916 
1917  union Data {
1918  String s;
1919  ShortString ss;
1920  Number n;
1921  ObjectData o;
1922  ArrayData a;
1923  Flag f;
1924  }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
1925 
1926  RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
1927  RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
1928  RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
1929  RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
1930  RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
1931  RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
1932 
1933  // Initialize this value as array with initial data, without calling destructor.
1934  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
1935  data_.f.flags = kArrayFlag;
1936  if (count) {
1937  GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
1938  SetElementsPointer(e);
1939  std::memcpy(e, values, count * sizeof(GenericValue));
1940  }
1941  else
1942  SetElementsPointer(0);
1943  data_.a.size = data_.a.capacity = count;
1944  }
1945 
1947  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
1948  data_.f.flags = kObjectFlag;
1949  if (count) {
1950  Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
1951  SetMembersPointer(m);
1952  std::memcpy(m, members, count * sizeof(Member));
1953  }
1954  else
1955  SetMembersPointer(0);
1956  data_.o.size = data_.o.capacity = count;
1957  }
1958 
1960  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
1961  data_.f.flags = kConstStringFlag;
1962  SetStringPointer(s);
1963  data_.s.length = s.length;
1964  }
1965 
1967  void SetStringRaw(StringRefType s, Allocator& allocator) {
1968  Ch* str = 0;
1969  if (ShortString::Usable(s.length)) {
1970  data_.f.flags = kShortStringFlag;
1971  data_.ss.SetLength(s.length);
1972  str = data_.ss.str;
1973  } else {
1974  data_.f.flags = kCopyStringFlag;
1975  data_.s.length = s.length;
1976  str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
1977  SetStringPointer(str);
1978  }
1979  std::memcpy(str, s, s.length * sizeof(Ch));
1980  str[s.length] = '\0';
1981  }
1982 
1984  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
1985  data_ = rhs.data_;
1986  // data_.f.flags = rhs.data_.f.flags;
1987  rhs.data_.f.flags = kNullFlag;
1988  }
1989 
1990  template <typename SourceAllocator>
1991  bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
1992  RAPIDJSON_ASSERT(IsString());
1993  RAPIDJSON_ASSERT(rhs.IsString());
1994 
1995  const SizeType len1 = GetStringLength();
1996  const SizeType len2 = rhs.GetStringLength();
1997  if(len1 != len2) { return false; }
1998 
1999  const Ch* const str1 = GetString();
2000  const Ch* const str2 = rhs.GetString();
2001  if(str1 == str2) { return true; } // fast path for constant string
2002 
2003  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2004  }
2005 
2006  Data data_;
2007 };
2008 
2011 
2013 // GenericDocument
2014 
2016 
2023 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
2024 class GenericDocument : public GenericValue<Encoding, Allocator> {
2025 public:
2026  typedef typename Encoding::Ch Ch;
2029 
2031 
2037  explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2038  GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2039  {
2040  if (!allocator_)
2041  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
2042  }
2043 
2045 
2050  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2051  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2052  {
2053  if (!allocator_)
2054  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
2055  }
2056 
2057 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2058  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2060  : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2061  allocator_(rhs.allocator_),
2062  ownAllocator_(rhs.ownAllocator_),
2063  stack_(std::move(rhs.stack_)),
2064  parseResult_(rhs.parseResult_)
2065  {
2066  rhs.allocator_ = 0;
2067  rhs.ownAllocator_ = 0;
2068  rhs.parseResult_ = ParseResult();
2069  }
2070 #endif
2071 
2072  ~GenericDocument() {
2073  Destroy();
2074  }
2075 
2076 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2077  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2079  {
2080  // The cast to ValueType is necessary here, because otherwise it would
2081  // attempt to call GenericValue's templated assignment operator.
2082  ValueType::operator=(std::forward<ValueType>(rhs));
2083 
2084  // Calling the destructor here would prematurely call stack_'s destructor
2085  Destroy();
2086 
2087  allocator_ = rhs.allocator_;
2088  ownAllocator_ = rhs.ownAllocator_;
2089  stack_ = std::move(rhs.stack_);
2090  parseResult_ = rhs.parseResult_;
2091 
2092  rhs.allocator_ = 0;
2093  rhs.ownAllocator_ = 0;
2094  rhs.parseResult_ = ParseResult();
2095 
2096  return *this;
2097  }
2098 #endif
2099 
2101 
2106  GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2107  ValueType::Swap(rhs);
2108  stack_.Swap(rhs.stack_);
2109  internal::Swap(allocator_, rhs.allocator_);
2110  internal::Swap(ownAllocator_, rhs.ownAllocator_);
2111  internal::Swap(parseResult_, rhs.parseResult_);
2112  return *this;
2113  }
2114 
2116 
2127  friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2128 
2130 
2134  template <typename Generator>
2135  GenericDocument& Populate(Generator& g) {
2136  ClearStackOnExit scope(*this);
2137  if (g(*this)) {
2138  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2139  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2140  }
2141  return *this;
2142  }
2143 
2146 
2148 
2154  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2155  GenericDocument& ParseStream(InputStream& is) {
2157  stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2158  ClearStackOnExit scope(*this);
2159  parseResult_ = reader.template Parse<parseFlags>(is, *this);
2160  if (parseResult_) {
2161  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2162  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2163  }
2164  return *this;
2165  }
2166 
2168 
2173  template <unsigned parseFlags, typename InputStream>
2174  GenericDocument& ParseStream(InputStream& is) {
2175  return ParseStream<parseFlags, Encoding, InputStream>(is);
2176  }
2177 
2179 
2183  template <typename InputStream>
2184  GenericDocument& ParseStream(InputStream& is) {
2185  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2186  }
2188 
2191 
2193 
2197  template <unsigned parseFlags>
2200  return ParseStream<parseFlags | kParseInsituFlag>(s);
2201  }
2202 
2204 
2208  return ParseInsitu<kParseDefaultFlags>(str);
2209  }
2211 
2214 
2216 
2220  template <unsigned parseFlags, typename SourceEncoding>
2221  GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2222  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2224  return ParseStream<parseFlags, SourceEncoding>(s);
2225  }
2226 
2228 
2231  template <unsigned parseFlags>
2232  GenericDocument& Parse(const Ch* str) {
2233  return Parse<parseFlags, Encoding>(str);
2234  }
2235 
2237 
2239  GenericDocument& Parse(const Ch* str) {
2240  return Parse<kParseDefaultFlags>(str);
2241  }
2242 
2243  template <unsigned parseFlags, typename SourceEncoding>
2244  GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2245  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2246  MemoryStream ms(static_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2248  ParseStream<parseFlags, SourceEncoding>(is);
2249  return *this;
2250  }
2251 
2252  template <unsigned parseFlags>
2253  GenericDocument& Parse(const Ch* str, size_t length) {
2254  return Parse<parseFlags, Encoding>(str, length);
2255  }
2256 
2257  GenericDocument& Parse(const Ch* str, size_t length) {
2258  return Parse<kParseDefaultFlags>(str, length);
2259  }
2260 
2261 #if RAPIDJSON_HAS_STDSTRING
2262  template <unsigned parseFlags, typename SourceEncoding>
2263  GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2264  // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2265  return Parse<parseFlags, SourceEncoding>(str.c_str());
2266  }
2267 
2268  template <unsigned parseFlags>
2269  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2270  return Parse<parseFlags, Encoding>(str.c_str());
2271  }
2272 
2273  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2274  return Parse<kParseDefaultFlags>(str);
2275  }
2276 #endif // RAPIDJSON_HAS_STDSTRING
2277 
2279 
2282 
2284  bool HasParseError() const { return parseResult_.IsError(); }
2285 
2287  ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2288 
2290  size_t GetErrorOffset() const { return parseResult_.Offset(); }
2291 
2293 #ifndef __clang // -Wdocumentation
2294 
2303 #endif
2304  operator ParseResult() const { return parseResult_; }
2306 
2309  RAPIDJSON_ASSERT(allocator_);
2310  return *allocator_;
2311  }
2312 
2314  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2315 
2316 private:
2317  // clear stack on any exit from ParseStream, e.g. due to exception
2318  struct ClearStackOnExit {
2319  explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2320  ~ClearStackOnExit() { d_.ClearStack(); }
2321  private:
2322  ClearStackOnExit(const ClearStackOnExit&);
2323  ClearStackOnExit& operator=(const ClearStackOnExit&);
2324  GenericDocument& d_;
2325  };
2326 
2327  // callers of the following private Handler functions
2328  // template <typename,typename,typename> friend class GenericReader; // for parsing
2329  template <typename, typename> friend class GenericValue; // for deep copying
2330 
2331 public:
2332  // Implementation of Handler
2333  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2334  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2335  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2336  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2337  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2338  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2339  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2340 
2341  bool RawNumber(const Ch* str, SizeType length, bool copy) {
2342  if (copy)
2343  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2344  else
2345  new (stack_.template Push<ValueType>()) ValueType(str, length);
2346  return true;
2347  }
2348 
2349  bool String(const Ch* str, SizeType length, bool copy) {
2350  if (copy)
2351  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2352  else
2353  new (stack_.template Push<ValueType>()) ValueType(str, length);
2354  return true;
2355  }
2356 
2357  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2358 
2359  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2360 
2361  bool EndObject(SizeType memberCount) {
2362  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2363  stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2364  return true;
2365  }
2366 
2367  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2368 
2369  bool EndArray(SizeType elementCount) {
2370  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2371  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2372  return true;
2373  }
2374 
2375 private:
2380 
2381  void ClearStack() {
2382  if (Allocator::kNeedFree)
2383  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2384  (stack_.template Pop<ValueType>(1))->~ValueType();
2385  else
2386  stack_.Clear();
2387  stack_.ShrinkToFit();
2388  }
2389 
2390  void Destroy() {
2391  RAPIDJSON_DELETE(ownAllocator_);
2392  }
2393 
2394  static const size_t kDefaultStackCapacity = 1024;
2395  Allocator* allocator_;
2396  Allocator* ownAllocator_;
2398  ParseResult parseResult_;
2399 };
2400 
2403 
2404 // defined here due to the dependency on GenericDocument
2405 template <typename Encoding, typename Allocator>
2406 template <typename SourceAllocator>
2407 inline
2409 {
2410  switch (rhs.GetType()) {
2411  case kObjectType:
2412  case kArrayType: { // perform deep copy via SAX Handler
2414  rhs.Accept(d);
2415  RawAssign(*d.stack_.template Pop<GenericValue>(1));
2416  }
2417  break;
2418  case kStringType:
2419  if (rhs.data_.f.flags == kConstStringFlag) {
2420  data_.f.flags = rhs.data_.f.flags;
2421  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
2422  } else {
2423  SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
2424  }
2425  break;
2426  default:
2427  data_.f.flags = rhs.data_.f.flags;
2428  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
2429  break;
2430  }
2431 }
2432 
2434 
2438 template <bool Const, typename ValueT>
2439 class GenericArray {
2440 public:
2441  typedef GenericArray<true, ValueT> ConstArray;
2442  typedef GenericArray<false, ValueT> Array;
2443  typedef ValueT PlainType;
2444  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2445  typedef ValueType* ValueIterator; // This may be const or non-const iterator
2446  typedef const ValueT* ConstValueIterator;
2447  typedef typename ValueType::AllocatorType AllocatorType;
2448  typedef typename ValueType::StringRefType StringRefType;
2449 
2450  template <typename, typename>
2451  friend class GenericValue;
2452 
2453  GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2454  GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2455  ~GenericArray() {}
2456 
2457  SizeType Size() const { return value_.Size(); }
2458  SizeType Capacity() const { return value_.Capacity(); }
2459  bool Empty() const { return value_.Empty(); }
2460  void Clear() const { value_.Clear(); }
2461  ValueType& operator[](SizeType index) const { return value_[index]; }
2462  ValueIterator Begin() const { return value_.Begin(); }
2463  ValueIterator End() const { return value_.End(); }
2464  GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2465  GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2466 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2467  GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2468 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2469  GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2470  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; }
2471  GenericArray PopBack() const { value_.PopBack(); return *this; }
2472  ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2473  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2474 
2475 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2476  ValueIterator begin() const { return value_.Begin(); }
2477  ValueIterator end() const { return value_.End(); }
2478 #endif
2479 
2480 private:
2481  GenericArray();
2482  GenericArray(ValueType& value) : value_(value) {}
2483  ValueType& value_;
2484 };
2485 
2487 
2491 template <bool Const, typename ValueT>
2492 class GenericObject {
2493 public:
2494  typedef GenericObject<true, ValueT> ConstObject;
2495  typedef GenericObject<false, ValueT> Object;
2496  typedef ValueT PlainType;
2497  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2498  typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
2500  typedef typename ValueType::AllocatorType AllocatorType;
2501  typedef typename ValueType::StringRefType StringRefType;
2502  typedef typename ValueType::EncodingType EncodingType;
2503  typedef typename ValueType::Ch Ch;
2504 
2505  template <typename, typename>
2506  friend class GenericValue;
2507 
2508  GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2509  GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2510  ~GenericObject() {}
2511 
2512  SizeType MemberCount() const { return value_.MemberCount(); }
2513  bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2514  template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2515  template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2516 #if RAPIDJSON_HAS_STDSTRING
2517  ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2518 #endif
2519  MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2520  MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2521  bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2522 #if RAPIDJSON_HAS_STDSTRING
2523  bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2524 #endif
2525  template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2526  MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2527  template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2528 #if RAPIDJSON_HAS_STDSTRING
2529  MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2530 #endif
2531  GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2532  GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2533 #if RAPIDJSON_HAS_STDSTRING
2534  GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2535 #endif
2536  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; }
2537 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2538  GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2539  GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2540  GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2541  GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2542 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2543  GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2544  GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2545  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; }
2546  void RemoveAllMembers() { return value_.RemoveAllMembers(); }
2547  bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2548 #if RAPIDJSON_HAS_STDSTRING
2549  bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2550 #endif
2551  template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2552  MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2553  MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
2554  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2555  bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2556 #if RAPIDJSON_HAS_STDSTRING
2557  bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2558 #endif
2559  template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2560 
2561 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2562  MemberIterator begin() const { return value_.MemberBegin(); }
2563  MemberIterator end() const { return value_.MemberEnd(); }
2564 #endif
2565 
2566 private:
2567  GenericObject();
2568  GenericObject(ValueType& value) : value_(value) {}
2569  ValueType& value_;
2570 };
2571 
2573 RAPIDJSON_DIAG_POP
2574 
2575 #endif // RAPIDJSON_DOCUMENT_H_
GenericValue::MemberIterator
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:548
GenericDocument::ParseStream
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:2155
GenericStringRef::Ch
CharType Ch
character type of the string
Definition: document.h:250
GenericPointer
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: fwd.h:126
internal::TypeHelper
Definition: document.h:411
RAPIDJSON_NAMESPACE_END
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:119
GenericValue::Flag
Definition: document.h:1845
kNullType
@ kNullType
null
Definition: rapidjson.h:604
RAPIDJSON_NAMESPACE_BEGIN
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:116
internal::IsGenericValue
Definition: document.h:401
GenericDocument
A document for parsing JSON text as DOM.
Definition: document.h:62
GenericValue::String
Definition: document.h:1856
GenericDocument::GetParseError
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:2287
kFalseType
@ kFalseType
false
Definition: rapidjson.h:605
GenericStringRef::GenericStringRef
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:314
Allocator
Concept for allocating, resizing and freeing memory block.
Document
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2402
kArrayType
@ kArrayType
array
Definition: rapidjson.h:608
GenericValue::ConstValueIterator
const typedef GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:551
GenericValue::Number
Definition: document.h:1880
GenericStringRef::GenericStringRef
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:302
GenericDocument::ParseStream
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:2174
Type
Type
Type of JSON value.
Definition: rapidjson.h:603
GenericDocument::ParseInsitu
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:2198
GenericStringRef::s
const Ch *const s
plain CharType pointer
Definition: document.h:324
internal::IsGenericValueImpl
Definition: document.h:394
GenericStringRef::length
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:325
GenericValue::StringRefType
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:547
kObjectType
@ kObjectType
object
Definition: rapidjson.h:607
GenericValue::GenericValue
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition: document.h:711
GenericArray
Helper class for accessing Value of array type.
Definition: document.h:523
GenericValue::ConstMemberIterator
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:549
GenericDocument::GetErrorOffset
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:2290
ParseResult::Offset
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:116
GenericMemberIterator::DifferenceType
BaseType::difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:125
MemoryStream
Represents an in-memory input byte stream.
Definition: memorystream.h:40
GenericInsituStringStream
A read-write string stream.
Definition: fwd.h:52
SizeType
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:380
GenericMember::value
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:73
ParseResult::IsError
bool IsError() const
Whether the result is an error.
Definition: error.h:121
GenericValue::GenericValue
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:646
GenericValue::operator=
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:774
GenericValue::Ch
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:546
StringRef
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:346
GenericValue::GenericValue
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:676
kParseInsituFlag
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition: reader.h:147
kStringType
@ kStringType
string
Definition: rapidjson.h:609
GenericStringStream
Read-only string stream.
Definition: fwd.h:47
GenericValue::operator=
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:755
GenericValue::GenericValue
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:685
GenericDocument::GenericDocument
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2050
GenericDocument::GetAllocator
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2308
RAPIDJSON_ASSERT
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:402
GenericValue::Number::U
Definition: document.h:1886
GenericValue::ArrayData
Definition: document.h:1911
GenericStringRef::StringRef
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:346
GenericValue::GenericValue
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:640
ParseErrorCode
ParseErrorCode
Error code of parsing.
Definition: error.h:64
GenericDocument::Populate
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2135
GenericDocument::ParseInsitu
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:2207
GenericMemberIterator::Reference
BaseType::reference Reference
Reference to (const) GenericMember.
Definition: document.h:123
String
Definition: Simulation.h:220
kNumberType
@ kNumberType
number
Definition: rapidjson.h:610
GenericDocument::swap
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:2127
GenericDocument::GetStackCapacity
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:2314
GenericValue::RAPIDJSON_DISABLEIF_RETURN
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
GenericMemberIterator::GenericMemberIterator
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:131
GenericDocument::HasParseError
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: document.h:2284
GenericMemberIterator::operator-
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:187
ParseResult
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
reader.h
GenericValue::EncodingType
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:544
GenericValue::ObjectData
Definition: document.h:1905
GenericMember::name
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:72
GenericMemberIterator::NonConstIterator
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:118
GenericValue::GenericValue
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:623
GenericDocument::ParseStream
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:2184
Value
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2010
GenericValue::Data
Definition: document.h:1917
RAPIDJSON_NEW
#define RAPIDJSON_NEW(x)
! customization point for global new
Definition: rapidjson.h:586
GenericMemberIterator::ConstIterator
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:116
GenericMemberIterator::Pointer
BaseType::pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:121
RAPIDJSON_DELETE
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:590
GenericReader
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
GenericValue::GenericValue
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:682
internal::Stack< StackAllocator >
GenericValue
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:59
GenericValue::RawAssign
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:1984
EncodedInputStream
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
GenericValue::GenericValue
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:562
ParseResult::Code
ParseErrorCode Code() const
Get the error code.
Definition: error.h:114
GenericMember
Name-value pair in a JSON object value.
Definition: document.h:71
kTrueType
@ kTrueType
true
Definition: rapidjson.h:606
GenericDocument::GenericDocument
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2037
GenericValue::ShortString
Definition: document.h:1870
GenericValue::~GenericValue
~GenericValue()
Destructor.
Definition: document.h:719
GenericStringRef
Reference to a constant string (not taking a copy)
Definition: document.h:249
GenericValue::GenericValue
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:679
GenericValue::Member
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:543
GenericDocument::Ch
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2026
GenericValue::ValueType
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:552
GenericValue::AllocatorType
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:545
GenericObject
Helper class for accessing Value of object type.
Definition: document.h:524
GenericDocument::Parse
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:2232
GenericDocument::Parse
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2221
GenericMemberIterator
(Constant) member iterator for a JSON object value
Definition: document.h:101
GenericValue::ValueIterator
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:550
GenericValue::GenericValue
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:634
GenericValue::String::hashcode
SizeType hashcode
reserved
Definition: document.h:1858
GenericValue::SetObjectRaw
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:1947
GenericValue::GenericValue
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition: document.h:700
GenericValue::GenericValue
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:661
GenericValue::GenericValue
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:592
RAPIDJSON_UNLIKELY
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:468
GenericStringRef::GenericStringRef
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:278
GenericDocument::AllocatorType
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2028
GenericValue::SetStringRaw
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:1960
Encoding
Concept for encoding of Unicode characters.
GenericMemberIterator::Iterator
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:114
RAPIDJSON_UINT64_C2
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
GenericValue::GenericValue
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:673
GenericMemberIterator::GenericMemberIterator
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:149
GenericDocument::Swap
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:2106
GenericValue::SetStringRaw
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:1967
GenericDocument::ValueType
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2027
GenericDocument::Parse
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:2239
Handler
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
GenericValue::Number::I
Definition: document.h:1882
RAPIDJSON_STATIC_ASSERT
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:437