NGL  6.5
The NCCA Graphics Library
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 <new> // placement new
24 
25 #ifdef _MSC_VER
26 RAPIDJSON_DIAG_PUSH
27 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
28 #elif defined(__GNUC__)
29 RAPIDJSON_DIAG_PUSH
30 RAPIDJSON_DIAG_OFF(effc++)
31 #endif
32 
34 // RAPIDJSON_HAS_STDSTRING
35 
36 #ifndef RAPIDJSON_HAS_STDSTRING
37 #ifdef RAPIDJSON_DOXYGEN_RUNNING
38 #define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
39 #else
40 #define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
41 #endif
42 
52 #endif // !defined(RAPIDJSON_HAS_STDSTRING)
53 
54 #if RAPIDJSON_HAS_STDSTRING
55 #include <string>
56 #endif // RAPIDJSON_HAS_STDSTRING
57 
58 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
59 #include <iterator> // std::iterator, std::random_access_iterator_tag
60 #endif
61 
62 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
63 #include <utility> // std::move
64 #endif
65 
67 
68 // Forward declaration.
69 template <typename Encoding, typename Allocator>
71 
72 template <typename Encoding, typename Allocator, typename StackAllocator>
74 
76 
81 template <typename Encoding, typename Allocator>
82 struct GenericMember {
85 };
86 
88 // GenericMemberIterator
89 
90 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
91 
93 
111 template <bool Const, typename Encoding, typename Allocator>
113  : public std::iterator<std::random_access_iterator_tag
114  , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
115 
116  friend class GenericValue<Encoding,Allocator>;
117  template <bool, typename, typename> friend class GenericMemberIterator;
118 
121  typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
122 
123 public:
130 
132  typedef typename BaseType::pointer Pointer;
134  typedef typename BaseType::reference Reference;
136  typedef typename BaseType::difference_type DifferenceType;
137 
139 
143 
145 
160  GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
161 
163 
164  Iterator& operator++(){ ++ptr_; return *this; }
165  Iterator& operator--(){ --ptr_; return *this; }
166  Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
167  Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
169 
171 
172  Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
173  Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
174 
175  Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
176  Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
178 
180 
181  bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
182  bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
183  bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
184  bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
185  bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
186  bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
188 
190 
191  Reference operator*() const { return *ptr_; }
192  Pointer operator->() const { return ptr_; }
193  Reference operator[](DifferenceType n) const { return ptr_[n]; }
195 
197  DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
198 
199 private:
201  explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
202 
203  Pointer ptr_;
204 };
205 
206 #else // RAPIDJSON_NOMEMBERITERATORCLASS
207 
208 // class-based member iterator implementation disabled, use plain pointers
209 
210 template <bool Const, typename Encoding, typename Allocator>
211 struct GenericMemberIterator;
212 
214 template <typename Encoding, typename Allocator>
215 struct GenericMemberIterator<false,Encoding,Allocator> {
218 };
220 template <typename Encoding, typename Allocator>
221 struct GenericMemberIterator<true,Encoding,Allocator> {
224 };
225 
226 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
227 
229 // GenericStringRef
230 
232 
258 template<typename CharType>
260  typedef CharType Ch;
261 
263 
285  template<SizeType N>
286  GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
287  : s(str), length(N-1) {}
288 
290 
308  explicit GenericStringRef(const CharType* str)
309  : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); }
310 
312 
318  GenericStringRef(const CharType* str, SizeType len)
319  : s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); }
320 
322  operator const Ch *() const { return s; }
323 
324  const Ch* const s;
325  const SizeType length;
326 
327 private:
329  GenericStringRef operator=(const GenericStringRef&);
331  template<SizeType N>
332  GenericStringRef(CharType (&str)[N]) /* = delete */;
333 };
334 
336 
347 template<typename CharType>
348 inline GenericStringRef<CharType> StringRef(const CharType* str) {
350 }
351 
353 
367 template<typename CharType>
368 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
369  return GenericStringRef<CharType>(str, SizeType(length));
370 }
371 
372 #if RAPIDJSON_HAS_STDSTRING
373 
385 template<typename CharType>
386 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
387  return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
388 }
389 #endif
390 
392 // GenericValue type traits
393 namespace internal {
394 
395 template <typename T, typename Encoding = void, typename Allocator = void>
396 struct IsGenericValueImpl : FalseType {};
397 
398 // select candidates according to nested encoding and allocator types
399 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
400  : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
401 
402 // helper to match arbitrary GenericValue instantiations, including derived classes
403 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
404 
405 } // namespace internal
406 
408 // GenericValue
409 
411 
420 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
421 class GenericValue {
422 public:
425  typedef Encoding EncodingType;
426  typedef Allocator AllocatorType;
427  typedef typename Encoding::Ch Ch;
434 
436 
437 
439  GenericValue() RAPIDJSON_NOEXCEPT : data_(), flags_(kNullFlag) {}
440 
441 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
442  GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_), flags_(rhs.flags_) {
444  rhs.flags_ = kNullFlag; // give up contents
445  }
446 #endif
447 
448 private:
450  GenericValue(const GenericValue& rhs);
451 
452 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
453  template <typename StackAllocator>
456 
458  template <typename StackAllocator>
460 #endif
461 
462 public:
463 
465 
469  explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() {
470  static const unsigned defaultFlags[7] = {
471  kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
472  kNumberAnyFlag
473  };
475  flags_ = defaultFlags[type];
476 
477  // Use ShortString to store empty string.
478  if (type == kStringType)
479  data_.ss.SetLength(0);
480  }
481 
483 
489  template< typename SourceAllocator >
490  GenericValue(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator & allocator);
491 
493 
498 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
499  template <typename T>
500  explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<T,bool>))) RAPIDJSON_NOEXCEPT
501 #else
502  explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
503 #endif
504  : data_(), flags_(b ? kTrueFlag : kFalseFlag) {
505  // safe-guard against failing SFINAE
507  }
508 
510  explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberIntFlag) {
511  data_.n.i64 = i;
512  if (i >= 0)
513  flags_ |= kUintFlag | kUint64Flag;
514  }
515 
517  explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUintFlag) {
518  data_.n.u64 = u;
519  if (!(u & 0x80000000))
520  flags_ |= kIntFlag | kInt64Flag;
521  }
522 
524  explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberInt64Flag) {
525  data_.n.i64 = i64;
526  if (i64 >= 0) {
527  flags_ |= kNumberUint64Flag;
528  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
529  flags_ |= kUintFlag;
530  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
531  flags_ |= kIntFlag;
532  }
533  else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
534  flags_ |= kIntFlag;
535  }
536 
538  explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUint64Flag) {
539  data_.n.u64 = u64;
540  if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
541  flags_ |= kInt64Flag;
542  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
543  flags_ |= kUintFlag;
544  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
545  flags_ |= kIntFlag;
546  }
547 
549  explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberDoubleFlag) { data_.n.d = d; }
550 
552  GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(StringRef(s, length)); }
553 
555  explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(s); }
556 
558  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s, length), allocator); }
559 
561  GenericValue(const Ch*s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); }
562 
563 #if RAPIDJSON_HAS_STDSTRING
564 
567  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); }
568 #endif
569 
571 
574  if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
575  switch(flags_) {
576  case kArrayFlag:
577  for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
578  v->~GenericValue();
579  Allocator::Free(data_.a.elements);
580  break;
581 
582  case kObjectFlag:
583  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
584  m->~Member();
585  Allocator::Free(data_.o.members);
586  break;
587 
588  case kCopyStringFlag:
589  Allocator::Free(const_cast<Ch*>(data_.s.str));
590  break;
591 
592  default:
593  break; // Do nothing for other types.
594  }
595  }
596  }
597 
599 
601 
602 
604 
606  GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
607  RAPIDJSON_ASSERT(this != &rhs);
608  this->~GenericValue();
609  RawAssign(rhs);
610  return *this;
611  }
612 
613 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
614  GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
616  return *this = rhs.Move();
617  }
618 #endif
619 
621 
625  GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
626  GenericValue s(str);
627  return *this = s;
628  }
629 
631 
642  template <typename T>
643  RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
644  operator=(T value) {
645  GenericValue v(value);
646  return *this = v;
647  }
648 
650 
655  template <typename SourceAllocator>
656  GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {
657  RAPIDJSON_ASSERT((void*)this != (void const*)&rhs);
658  this->~GenericValue();
659  new (this) GenericValue(rhs, allocator);
660  return *this;
661  }
662 
664 
668  GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
669  GenericValue temp;
670  temp.RawAssign(*this);
671  RawAssign(other);
672  other.RawAssign(temp);
673  return *this;
674  }
675 
677 
688  friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
689 
691 
692  GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
694 
696 
697 
702  template <typename SourceAllocator>
703  bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
705  if (GetType() != rhs.GetType())
706  return false;
707 
708  switch (GetType()) {
709  case kObjectType: // Warning: O(n^2) inner-loop
710  if (data_.o.size != rhs.data_.o.size)
711  return false;
712  for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
713  typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
714  if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
715  return false;
716  }
717  return true;
718 
719  case kArrayType:
720  if (data_.a.size != rhs.data_.a.size)
721  return false;
722  for (SizeType i = 0; i < data_.a.size; i++)
723  if ((*this)[i] != rhs[i])
724  return false;
725  return true;
726 
727  case kStringType:
728  return StringEqual(rhs);
729 
730  case kNumberType:
731  if (IsDouble() || rhs.IsDouble()) {
732  double a = GetDouble(); // May convert from integer to double.
733  double b = rhs.GetDouble(); // Ditto
734  return a >= b && a <= b; // Prevent -Wfloat-equal
735  }
736  else
737  return data_.n.u64 == rhs.data_.n.u64;
738 
739  default: // kTrueType, kFalseType, kNullType
740  return true;
741  }
742  }
743 
745  bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
746 
747 #if RAPIDJSON_HAS_STDSTRING
748 
751  bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
752 #endif
753 
755 
757  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
758 
760 
762  template <typename SourceAllocator>
763  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
764 
766  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
767 
769 
771  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
772 
774 
776  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
777 
779 
781  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
783 
785 
786 
787  Type GetType() const { return static_cast<Type>(flags_ & kTypeMask); }
788  bool IsNull() const { return flags_ == kNullFlag; }
789  bool IsFalse() const { return flags_ == kFalseFlag; }
790  bool IsTrue() const { return flags_ == kTrueFlag; }
791  bool IsBool() const { return (flags_ & kBoolFlag) != 0; }
792  bool IsObject() const { return flags_ == kObjectFlag; }
793  bool IsArray() const { return flags_ == kArrayFlag; }
794  bool IsNumber() const { return (flags_ & kNumberFlag) != 0; }
795  bool IsInt() const { return (flags_ & kIntFlag) != 0; }
796  bool IsUint() const { return (flags_ & kUintFlag) != 0; }
797  bool IsInt64() const { return (flags_ & kInt64Flag) != 0; }
798  bool IsUint64() const { return (flags_ & kUint64Flag) != 0; }
799  bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; }
800  bool IsString() const { return (flags_ & kStringFlag) != 0; }
801 
803 
805 
806 
807  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
808 
810 
812 
813 
814  bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; }
816 
817  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
818 
820 
822 
823 
825 
826  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
827 
829  SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
830 
832  bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
833 
835 
843  template <typename T>
844  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
845  GenericValue n(StringRef(name));
846  return (*this)[n];
847  }
848  template <typename T>
849  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]; }
850 
852 
860  template <typename SourceAllocator>
861  GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
862  MemberIterator member = FindMember(name);
863  if (member != MemberEnd())
864  return member->value;
865  else {
866  RAPIDJSON_ASSERT(false); // see above note
867  static GenericValue NullValue;
868  return NullValue;
869  }
870  }
871  template <typename SourceAllocator>
872  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
873 
874 #if RAPIDJSON_HAS_STDSTRING
875  GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
877  const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
878 #endif
879 
881 
882  ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); }
884 
885  ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members + data_.o.size); }
887 
888  MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members); }
890 
891  MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members + data_.o.size); }
892 
894 
901  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
902 
903 #if RAPIDJSON_HAS_STDSTRING
904 
912  bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
913 #endif
914 
916 
924  template <typename SourceAllocator>
925  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
926 
928 
939  MemberIterator FindMember(const Ch* name) {
940  GenericValue n(StringRef(name));
941  return FindMember(n);
942  }
943 
944  ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
945 
947 
959  template <typename SourceAllocator>
960  MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
961  RAPIDJSON_ASSERT(IsObject());
962  RAPIDJSON_ASSERT(name.IsString());
963  MemberIterator member = MemberBegin();
964  for ( ; member != MemberEnd(); ++member)
965  if (name.StringEqual(member->name))
966  break;
967  return member;
968  }
969  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
970 
971 #if RAPIDJSON_HAS_STDSTRING
972 
979  MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(StringRef(name)); }
980  ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(StringRef(name)); }
981 #endif
982 
984 
993  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
994  RAPIDJSON_ASSERT(IsObject());
995  RAPIDJSON_ASSERT(name.IsString());
996 
997  Object& o = data_.o;
998  if (o.size >= o.capacity) {
999  if (o.capacity == 0) {
1000  o.capacity = kDefaultObjectCapacity;
1001  o.members = reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member)));
1002  }
1003  else {
1004  SizeType oldCapacity = o.capacity;
1005  o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
1006  o.members = reinterpret_cast<Member*>(allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)));
1007  }
1008  }
1009  o.members[o.size].name.RawAssign(name);
1010  o.members[o.size].value.RawAssign(value);
1011  o.size++;
1012  return *this;
1013  }
1014 
1016 
1024  GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1025  GenericValue v(value);
1026  return AddMember(name, v, allocator);
1027  }
1028 
1029 #if RAPIDJSON_HAS_STDSTRING
1030 
1039  GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1040  GenericValue v(value, allocator);
1041  return AddMember(name, v, allocator);
1042  }
1043 #endif
1044 
1046 
1062  template <typename T>
1063  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1064  AddMember(GenericValue& name, T value, Allocator& allocator) {
1065  GenericValue v(value);
1066  return AddMember(name, v, allocator);
1067  }
1068 
1069 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1070  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1071  return AddMember(name, value, allocator);
1072  }
1073  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1074  return AddMember(name, value, allocator);
1075  }
1076  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1077  return AddMember(name, value, allocator);
1078  }
1079  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1080  GenericValue n(name);
1081  return AddMember(n, value, allocator);
1082  }
1083 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1084 
1085 
1087 
1096  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1097  GenericValue n(name);
1098  return AddMember(n, value, allocator);
1099  }
1100 
1102 
1110  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1111  GenericValue v(value);
1112  return AddMember(name, v, allocator);
1113  }
1114 
1116 
1132  template <typename T>
1133  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1134  AddMember(StringRefType name, T value, Allocator& allocator) {
1135  GenericValue n(name);
1136  return AddMember(n, value, allocator);
1137  }
1138 
1140 
1143  void RemoveAllMembers() {
1144  RAPIDJSON_ASSERT(IsObject());
1145  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1146  m->~Member();
1147  data_.o.size = 0;
1148  }
1149 
1151 
1158  bool RemoveMember(const Ch* name) {
1159  GenericValue n(StringRef(name));
1160  return RemoveMember(n);
1161  }
1162 
1163 #if RAPIDJSON_HAS_STDSTRING
1164  bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1165 #endif
1166 
1167  template <typename SourceAllocator>
1168  bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1169  MemberIterator m = FindMember(name);
1170  if (m != MemberEnd()) {
1171  RemoveMember(m);
1172  return true;
1173  }
1174  else
1175  return false;
1176  }
1177 
1179 
1186  MemberIterator RemoveMember(MemberIterator m) {
1187  RAPIDJSON_ASSERT(IsObject());
1188  RAPIDJSON_ASSERT(data_.o.size > 0);
1189  RAPIDJSON_ASSERT(data_.o.members != 0);
1190  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1191 
1192  MemberIterator last(data_.o.members + (data_.o.size - 1));
1193  if (data_.o.size > 1 && m != last) {
1194  // Move the last one to this place
1195  *m = *last;
1196  }
1197  else {
1198  // Only one left, just destroy
1199  m->~Member();
1200  }
1201  --data_.o.size;
1202  return m;
1203  }
1204 
1206 
1214  MemberIterator EraseMember(ConstMemberIterator pos) {
1215  return EraseMember(pos, pos +1);
1216  }
1217 
1219 
1227  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1228  RAPIDJSON_ASSERT(IsObject());
1229  RAPIDJSON_ASSERT(data_.o.size > 0);
1230  RAPIDJSON_ASSERT(data_.o.members != 0);
1231  RAPIDJSON_ASSERT(first >= MemberBegin());
1232  RAPIDJSON_ASSERT(first <= last);
1233  RAPIDJSON_ASSERT(last <= MemberEnd());
1234 
1235  MemberIterator pos = MemberBegin() + (first - MemberBegin());
1236  for (MemberIterator itr = pos; itr != last; ++itr)
1237  itr->~Member();
1238  std::memmove(&*pos, &*last, (MemberEnd() - last) * sizeof(Member));
1239  data_.o.size -= (last - first);
1240  return pos;
1241  }
1242 
1244 
1248  bool EraseMember(const Ch* name) {
1249  GenericValue n(StringRef(name));
1250  return EraseMember(n);
1251  }
1252 
1253 #if RAPIDJSON_HAS_STDSTRING
1254  bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1255 #endif
1256 
1257  template <typename SourceAllocator>
1258  bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1259  MemberIterator m = FindMember(name);
1260  if (m != MemberEnd()) {
1261  EraseMember(m);
1262  return true;
1263  }
1264  else
1265  return false;
1266  }
1267 
1269 
1271 
1272 
1274 
1275  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1276 
1278  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1279 
1281  SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1282 
1284  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1285 
1287 
1290  void Clear() {
1291  RAPIDJSON_ASSERT(IsArray());
1292  for (SizeType i = 0; i < data_.a.size; ++i)
1293  data_.a.elements[i].~GenericValue();
1294  data_.a.size = 0;
1295  }
1296 
1298 
1302  GenericValue& operator[](SizeType index) {
1303  RAPIDJSON_ASSERT(IsArray());
1304  RAPIDJSON_ASSERT(index < data_.a.size);
1305  return data_.a.elements[index];
1306  }
1307  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1308 
1310 
1311  ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; }
1313 
1314  ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; }
1316 
1317  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1319 
1320  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1321 
1323 
1328  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1329  RAPIDJSON_ASSERT(IsArray());
1330  if (newCapacity > data_.a.capacity) {
1331  data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue));
1332  data_.a.capacity = newCapacity;
1333  }
1334  return *this;
1335  }
1336 
1338 
1347  GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1348  RAPIDJSON_ASSERT(IsArray());
1349  if (data_.a.size >= data_.a.capacity)
1350  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1351  data_.a.elements[data_.a.size++].RawAssign(value);
1352  return *this;
1353  }
1354 
1355 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1356  GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1357  return PushBack(value, allocator);
1358  }
1359 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1360 
1362 
1370  GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1371  return (*this).template PushBack<StringRefType>(value, allocator);
1372  }
1373 
1375 
1391  template <typename T>
1392  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1393  PushBack(T value, Allocator& allocator) {
1394  GenericValue v(value);
1395  return PushBack(v, allocator);
1396  }
1397 
1399 
1402  GenericValue& PopBack() {
1403  RAPIDJSON_ASSERT(IsArray());
1404  RAPIDJSON_ASSERT(!Empty());
1405  data_.a.elements[--data_.a.size].~GenericValue();
1406  return *this;
1407  }
1408 
1410 
1416  ValueIterator Erase(ConstValueIterator pos) {
1417  return Erase(pos, pos + 1);
1418  }
1419 
1421 
1428  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1429  RAPIDJSON_ASSERT(IsArray());
1430  RAPIDJSON_ASSERT(data_.a.size > 0);
1431  RAPIDJSON_ASSERT(data_.a.elements != 0);
1432  RAPIDJSON_ASSERT(first >= Begin());
1433  RAPIDJSON_ASSERT(first <= last);
1434  RAPIDJSON_ASSERT(last <= End());
1435  ValueIterator pos = Begin() + (first - Begin());
1436  for (ValueIterator itr = pos; itr != last; ++itr)
1437  itr->~GenericValue();
1438  std::memmove(pos, last, (End() - last) * sizeof(GenericValue));
1439  data_.a.size -= (last - first);
1440  return pos;
1441  }
1442 
1444 
1446 
1447 
1448  int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; }
1449  unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; }
1450  int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; }
1451  uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; }
1452 
1453  double GetDouble() const {
1454  RAPIDJSON_ASSERT(IsNumber());
1455  if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1456  if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double
1457  if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1458  if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision)
1459  RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision)
1460  }
1461 
1462  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1463  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1464  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1465  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1466  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1467 
1469 
1471 
1472 
1473  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? data_.ss.str : data_.s.str); }
1474 
1476 
1478  SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1479 
1481 
1488  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1489 
1491 
1495  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1496 
1498 
1505  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }
1506 
1508 
1513  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }
1514 
1515 #if RAPIDJSON_HAS_STDSTRING
1516 
1523  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }
1524 #endif
1525 
1527 
1529 
1535  template <typename Handler>
1536  bool Accept(Handler& handler) const {
1537  switch(GetType()) {
1538  case kNullType: return handler.Null();
1539  case kFalseType: return handler.Bool(false);
1540  case kTrueType: return handler.Bool(true);
1541 
1542  case kObjectType:
1543  if (!handler.StartObject())
1544  return false;
1545  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1546  RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1547  if (!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.flags_ & kCopyFlag) != 0))
1548  return false;
1549  if (!m->value.Accept(handler))
1550  return false;
1551  }
1552  return handler.EndObject(data_.o.size);
1553 
1554  case kArrayType:
1555  if (!handler.StartArray())
1556  return false;
1557  for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
1558  if (!v->Accept(handler))
1559  return false;
1560  return handler.EndArray(data_.a.size);
1561 
1562  case kStringType:
1563  return handler.String(GetString(), GetStringLength(), (flags_ & kCopyFlag) != 0);
1564 
1565  default:
1566  RAPIDJSON_ASSERT(GetType() == kNumberType);
1567  if (IsInt()) return handler.Int(data_.n.i.i);
1568  else if (IsUint()) return handler.Uint(data_.n.u.u);
1569  else if (IsInt64()) return handler.Int64(data_.n.i64);
1570  else if (IsUint64()) return handler.Uint64(data_.n.u64);
1571  else return handler.Double(data_.n.d);
1572  }
1573  }
1574 
1575 private:
1576  template <typename, typename> friend class GenericValue;
1577  template <typename, typename, typename> friend class GenericDocument;
1578 
1579  enum {
1580  kBoolFlag = 0x100,
1581  kNumberFlag = 0x200,
1582  kIntFlag = 0x400,
1583  kUintFlag = 0x800,
1584  kInt64Flag = 0x1000,
1585  kUint64Flag = 0x2000,
1586  kDoubleFlag = 0x4000,
1587  kStringFlag = 0x100000,
1588  kCopyFlag = 0x200000,
1589  kInlineStrFlag = 0x400000,
1590 
1591  // Initial flags of different types.
1606 
1607  kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler
1608  };
1609 
1610  static const SizeType kDefaultArrayCapacity = 16;
1612 
1613  struct String {
1614  const Ch* str;
1616  unsigned hashcode;
1617  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1618 
1619  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1620  // (excluding the terminating zero) and store a value to determine the length of the contained
1621  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1622  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1623  // the string terminator as well. For getting the string length back from that value just use
1624  // "MaxSize - str[LenPos]".
1625  // This allows to store 11-chars strings in 32-bit mode and 15-chars strings in 64-bit mode
1626  // inline (for `UTF8`-encoded strings).
1627  struct ShortString {
1628  enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
1629  Ch str[MaxChars];
1630 
1631  inline static bool Usable(SizeType len) { return (MaxSize >= len); }
1632  inline void SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize - len); }
1633  inline SizeType GetLength() const { return (SizeType)(MaxSize - str[LenPos]); }
1634  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1635 
1636  // By using proper binary layout, retrieval of different integer types do not need conversions.
1637  union Number {
1638 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
1639  struct I {
1640  int i;
1641  char padding[4];
1642  }i;
1643  struct U {
1644  unsigned u;
1645  char padding2[4];
1646  }u;
1647 #else
1648  struct I {
1649  char padding[4];
1650  int i;
1651  }i;
1652  struct U {
1653  char padding2[4];
1654  unsigned u;
1655  }u;
1656 #endif
1659  double d;
1660  }; // 8 bytes
1661 
1662  struct Object {
1663  Member* members;
1666  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1667 
1668  struct Array {
1672  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1673 
1674  union Data {
1680  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1681 
1682  // Initialize this value as array with initial data, without calling destructor.
1683  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
1684  flags_ = kArrayFlag;
1685  if (count) {
1686  data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue));
1687  std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
1688  }
1689  else
1690  data_.a.elements = NULL;
1691  data_.a.size = data_.a.capacity = count;
1692  }
1693 
1695  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
1696  flags_ = kObjectFlag;
1697  if (count) {
1698  data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member));
1699  std::memcpy(data_.o.members, members, count * sizeof(Member));
1700  }
1701  else
1702  data_.o.members = NULL;
1703  data_.o.size = data_.o.capacity = count;
1704  }
1705 
1707  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
1708  flags_ = kConstStringFlag;
1709  data_.s.str = s;
1710  data_.s.length = s.length;
1711  }
1712 
1714  void SetStringRaw(StringRefType s, Allocator& allocator) {
1715  Ch* str = NULL;
1716  if(ShortString::Usable(s.length)) {
1717  flags_ = kShortStringFlag;
1718  data_.ss.SetLength(s.length);
1719  str = data_.ss.str;
1720  } else {
1721  flags_ = kCopyStringFlag;
1722  data_.s.length = s.length;
1723  str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch));
1724  data_.s.str = str;
1725  }
1726  std::memcpy(str, s, s.length * sizeof(Ch));
1727  str[s.length] = '\0';
1728  }
1729 
1731  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
1732  data_ = rhs.data_;
1733  flags_ = rhs.flags_;
1734  rhs.flags_ = kNullFlag;
1735  }
1736 
1737  template <typename SourceAllocator>
1739  RAPIDJSON_ASSERT(IsString());
1740  RAPIDJSON_ASSERT(rhs.IsString());
1741 
1742  const SizeType len1 = GetStringLength();
1743  const SizeType len2 = rhs.GetStringLength();
1744  if(len1 != len2) { return false; }
1745 
1746  const Ch* const str1 = GetString();
1747  const Ch* const str2 = rhs.GetString();
1748  if(str1 == str2) { return true; } // fast path for constant string
1749 
1750  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
1751  }
1752 
1754  unsigned flags_;
1755 };
1756 
1759 
1761 // GenericDocument
1762 
1764 
1771 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
1772 class GenericDocument : public GenericValue<Encoding, Allocator> {
1773 public:
1774  typedef typename Encoding::Ch Ch;
1776  typedef Allocator AllocatorType;
1777 
1779 
1785  explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
1786  GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
1787  {
1788  if (!allocator_)
1789  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
1790  }
1791 
1793 
1798  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
1799  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
1800  {
1801  if (!allocator_)
1802  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
1803  }
1804 
1805 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1806  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
1808  : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
1809  allocator_(rhs.allocator_),
1810  ownAllocator_(rhs.ownAllocator_),
1811  stack_(std::move(rhs.stack_)),
1812  parseResult_(rhs.parseResult_)
1813  {
1814  rhs.allocator_ = 0;
1815  rhs.ownAllocator_ = 0;
1816  rhs.parseResult_ = ParseResult();
1817  }
1818 #endif
1819 
1821  Destroy();
1822  }
1823 
1824 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1825  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
1827  {
1828  // The cast to ValueType is necessary here, because otherwise it would
1829  // attempt to call GenericValue's templated assignment operator.
1830  ValueType::operator=(std::forward<ValueType>(rhs));
1831 
1832  // Calling the destructor here would prematurely call stack_'s destructor
1833  Destroy();
1834 
1835  allocator_ = rhs.allocator_;
1836  ownAllocator_ = rhs.ownAllocator_;
1837  stack_ = std::move(rhs.stack_);
1838  parseResult_ = rhs.parseResult_;
1839 
1840  rhs.allocator_ = 0;
1841  rhs.ownAllocator_ = 0;
1842  rhs.parseResult_ = ParseResult();
1843 
1844  return *this;
1845  }
1846 #endif
1847 
1849 
1854  GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
1855  ValueType::Swap(rhs);
1856  stack_.Swap(rhs.stack_);
1857  internal::Swap(allocator_, rhs.allocator_);
1858  internal::Swap(ownAllocator_, rhs.ownAllocator_);
1859  internal::Swap(parseResult_, rhs.parseResult_);
1860  return *this;
1861  }
1862 
1864 
1875  friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1876 
1879 
1881 
1887  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
1888  GenericDocument& ParseStream(InputStream& is) {
1890  stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
1891  ClearStackOnExit scope(*this);
1892  parseResult_ = reader.template Parse<parseFlags>(is, *this);
1893  if (parseResult_) {
1894  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
1895  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
1896  }
1897  return *this;
1898  }
1899 
1901 
1906  template <unsigned parseFlags, typename InputStream>
1907  GenericDocument& ParseStream(InputStream& is) {
1908  return ParseStream<parseFlags, Encoding, InputStream>(is);
1909  }
1910 
1912 
1916  template <typename InputStream>
1917  GenericDocument& ParseStream(InputStream& is) {
1918  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
1919  }
1921 
1924 
1926 
1930  template <unsigned parseFlags>
1933  return ParseStream<parseFlags | kParseInsituFlag>(s);
1934  }
1935 
1937 
1941  return ParseInsitu<kParseDefaultFlags>(str);
1942  }
1944 
1947 
1949 
1953  template <unsigned parseFlags, typename SourceEncoding>
1954  GenericDocument& Parse(const Ch* str) {
1955  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
1957  return ParseStream<parseFlags, SourceEncoding>(s);
1958  }
1959 
1961 
1964  template <unsigned parseFlags>
1965  GenericDocument& Parse(const Ch* str) {
1966  return Parse<parseFlags, Encoding>(str);
1967  }
1968 
1970 
1972  GenericDocument& Parse(const Ch* str) {
1973  return Parse<kParseDefaultFlags>(str);
1974  }
1976 
1979 
1981  bool HasParseError() const { return parseResult_.IsError(); }
1982 
1984  ParseErrorCode GetParseError() const { return parseResult_.Code(); }
1985 
1987  size_t GetErrorOffset() const { return parseResult_.Offset(); }
1988 
1990 
1992  Allocator& GetAllocator() {
1993  RAPIDJSON_ASSERT(allocator_);
1994  return *allocator_;
1995  }
1996 
1998  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
1999 
2000 private:
2001  // clear stack on any exit from ParseStream, e.g. due to exception
2003  explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2004  ~ClearStackOnExit() { d_.ClearStack(); }
2005  private:
2007  ClearStackOnExit& operator=(const ClearStackOnExit&);
2009  };
2010 
2011  // callers of the following private Handler functions
2012  template <typename,typename,typename> friend class GenericReader; // for parsing
2013  template <typename, typename> friend class GenericValue; // for deep copying
2014 
2015  // Implementation of Handler
2016  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2017  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2018  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2019  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2020  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2021  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2022  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2023 
2024  bool String(const Ch* str, SizeType length, bool copy) {
2025  if (copy)
2026  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2027  else
2028  new (stack_.template Push<ValueType>()) ValueType(str, length);
2029  return true;
2030  }
2031 
2032  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2033 
2034  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2035 
2036  bool EndObject(SizeType memberCount) {
2037  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2038  stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
2039  return true;
2040  }
2041 
2042  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2043 
2044  bool EndArray(SizeType elementCount) {
2045  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2046  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2047  return true;
2048  }
2049 
2050 private:
2055 
2056  void ClearStack() {
2057  if (Allocator::kNeedFree)
2058  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2059  (stack_.template Pop<ValueType>(1))->~ValueType();
2060  else
2061  stack_.Clear();
2062  stack_.ShrinkToFit();
2063  }
2064 
2065  void Destroy() {
2066  RAPIDJSON_DELETE(ownAllocator_);
2067  }
2068 
2069  static const size_t kDefaultStackCapacity = 1024;
2070  Allocator* allocator_;
2071  Allocator* ownAllocator_;
2074 };
2075 
2078 
2079 // defined here due to the dependency on GenericDocument
2080 template <typename Encoding, typename Allocator>
2081 template <typename SourceAllocator>
2082 inline
2084 {
2085  switch (rhs.GetType()) {
2086  case kObjectType:
2087  case kArrayType: { // perform deep copy via SAX Handler
2089  rhs.Accept(d);
2090  RawAssign(*d.stack_.template Pop<GenericValue>(1));
2091  }
2092  break;
2093  case kStringType:
2094  if (rhs.flags_ == kConstStringFlag) {
2095  flags_ = rhs.flags_;
2096  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
2097  } else {
2098  SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
2099  }
2100  break;
2101  default: // kNumberType, kTrueType, kFalseType, kNullType
2102  flags_ = rhs.flags_;
2103  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
2104  }
2105 }
2106 
2108 
2109 #if defined(_MSC_VER) || defined(__GNUC__)
2110 RAPIDJSON_DIAG_POP
2111 #endif
2112 
2113 #endif // RAPIDJSON_DOCUMENT_H_
GenericMember< Encoding, Allocator > PlainType
Definition: document.h:119
bool operator==(const ngl::Mat3 &_m1, const ngl::Mat3 &_m2)
Definition: Mat3.h:297
GenericMemberIterator(Pointer p)
Internal constructor from plain pointer.
Definition: document.h:201
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:1854
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:1972
bool Int(int i)
Definition: document.h:2018
ParseResult parseResult_
Definition: document.h:2073
ClearStackOnExit(GenericDocument &d)
Definition: document.h:2003
Pointer operator->() const
Definition: document.h:192
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:84
GenericValue * elements
Definition: document.h:1669
Iterator operator--(int)
Definition: document.h:167
bool Int64(int64_t i)
Definition: document.h:2020
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: document.h:1981
bool String(const Ch *str, SizeType length, bool copy)
Definition: document.h:2024
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:1907
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
Iterator operator+(DifferenceType n) const
Definition: document.h:172
bool operator==(ConstIterator that) const
Definition: document.h:181
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:1776
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:261
object
Definition: rapidjson.h:646
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:1775
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:160
BaseType::reference Reference
Reference to (const) GenericMember.
Definition: document.h:134
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:142
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:431
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1256
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:432
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:549
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:558
array
Definition: rapidjson.h:647
Iterator & operator-=(DifferenceType n)
Definition: document.h:176
bool Bool(bool b)
Definition: document.h:2017
Name-value pair in a JSON object value.
Definition: document.h:82
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:1731
GLenum const void GLuint GLint reference
Definition: glew.h:13925
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:1931
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:428
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:70
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:375
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:1984
GLsizei const GLfloat * value
Definition: glew.h:1852
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:425
false
Definition: rapidjson.h:644
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:1998
unsigned flags_
Definition: document.h:1754
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:116
bool EndObject(SizeType memberCount)
Definition: document.h:2036
unsigned hashcode
reserved
Definition: document.h:1616
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:433
ParseErrorCode
Error code of parsing.
Definition: error.h:59
Pointer ptr_
raw pointer
Definition: document.h:203
Allocator * allocator_
Definition: document.h:2070
GLint GLsizei const GLuint64 * values
Definition: glew.h:3624
GLuint GLsizei GLsizei * length
Definition: glew.h:1828
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:1940
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:1798
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:625
Iterator operator++(int)
Definition: document.h:166
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:1992
GLdouble GLdouble GLdouble b
Definition: glew.h:9162
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:308
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:325
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< T, bool >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:500
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:197
Reference operator*() const
Definition: document.h:191
bool EndArray(SizeType elementCount)
Definition: document.h:2044
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:286
bool Key(const Ch *str, SizeType length, bool copy)
Definition: document.h:2034
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:1714
fmt::BufferedFile & move(fmt::BufferedFile &f)
Definition: posix.h:361
bool StringEqual(const GenericValue< Encoding, SourceAllocator > &rhs) const
Definition: document.h:1738
Reference to a constant string (not taking a copy)
Definition: document.h:259
string
Definition: rapidjson.h:648
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:1987
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:439
bool operator>=(ConstIterator that) const
Definition: document.h:184
const GLdouble * v
Definition: glew.h:1394
GLenum GLsizei len
Definition: glew.h:7780
Allocator * ownAllocator_
Definition: document.h:2071
BaseType::pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:132
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:1695
static const SizeType kDefaultArrayCapacity
Definition: document.h:1610
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:125
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:1758
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:538
internal::Stack< StackAllocator > stack_
Definition: document.h:2072
Read-only string stream.
Definition: rapidjson.h:571
const Ch *const s
plain CharType pointer
Definition: document.h:324
BaseType::difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:136
GLuint GLuint GLsizei count
Definition: glew.h:1256
void Destroy()
Definition: document.h:2065
unsigned __int64 uint64_t
Definition: stdint.h:136
GLfloat GLfloat p
Definition: glew.h:16654
SizeType GetLength() const
Definition: document.h:1633
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:318
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2077
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:1875
number
Definition: rapidjson.h:649
void SetLength(SizeType len)
Definition: document.h:1632
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:83
#define RAPIDJSON_NEW(x)
! customization point for global new
Definition: rapidjson.h:480
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition: document.h:120
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:561
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:119
Reference operator[](DifferenceType n) const
Definition: document.h:193
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorith> header.
Definition: swap.h:28
std::iterator< std::random_access_iterator_tag, ValueType > BaseType
Definition: document.h:121
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:127
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:484
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:552
bool operator<=(ConstIterator that) const
Definition: document.h:183
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:129
static bool Usable(SizeType len)
Definition: document.h:1631
void SetArrayRaw(GenericValue *values, SizeType count, Allocator &allocator)
Definition: document.h:1683
bool StartArray()
Definition: document.h:2042
static const SizeType kDefaultObjectCapacity
Definition: document.h:1611
bool Uint(unsigned i)
Definition: document.h:2019
GLuint index
Definition: glew.h:1817
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:1965
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:374
bool Double(double d)
Definition: document.h:2022
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:348
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:1917
ShortString ss
Definition: document.h:1676
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:429
GLuint const GLchar * name
Definition: glew.h:1817
signed __int64 int64_t
Definition: stdint.h:135
CharType Ch
character type of the string
Definition: document.h:260
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:430
GLsizei n
Definition: glew.h:4052
Result of parsing (wraps ParseErrorCode)
Definition: error.h:101
bool operator<(ConstIterator that) const
Definition: document.h:185
const GLdouble * m
Definition: glew.h:9164
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:606
bool operator!=(ConstIterator that) const
Definition: document.h:182
~GenericValue()
Destructor.
Definition: document.h:573
bool Uint64(uint64_t i)
Definition: document.h:2021
true
Definition: rapidjson.h:645
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:30
GLsizei const void * pointer
Definition: glew.h:1526
const GLint * first
Definition: glew.h:1531
Iterator & operator+=(DifferenceType n)
Definition: document.h:175
Iterator operator-(DifferenceType n) const
Definition: document.h:173
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:1888
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:469
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:1954
void ClearStack()
Definition: document.h:2056
A read-write string stream.
Definition: rapidjson.h:605
friend class GenericDocument
Definition: document.h:1577
(Constant) member iterator for a JSON object value
Definition: document.h:112
Type
Type of JSON value.
Definition: rapidjson.h:642
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:1785
GLdouble s
Definition: glew.h:1393
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:1707
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9517
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >),(typename T::ValueType &)) GetValueByPointerWithDefault(T &root
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:517
bool StartObject()
Definition: document.h:2032
bool operator>(ConstIterator that) const
Definition: document.h:186
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
Iterator & operator++()
Definition: document.h:164
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:1774
A document for parsing JSON text as DOM.
Definition: document.h:73
In-situ(destructive) parsing.
Definition: reader.h:138
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:510
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:426
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:524
Iterator & operator--()
Definition: document.h:165
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:555
null
Definition: rapidjson.h:643
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:424
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:427