TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 
73 
78 template <typename Encoding, typename Allocator>
79 struct GenericMember {
82 };
83 
85 // GenericMemberIterator
86 
87 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
88 
90 
108 template <bool Const, typename Encoding, typename Allocator>
110  : public std::iterator<std::random_access_iterator_tag
111  , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
112 
113  friend class GenericValue<Encoding,Allocator>;
114  template <bool, typename, typename> friend class GenericMemberIterator;
115 
118  typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
119 
120 public:
127 
129  typedef typename BaseType::pointer Pointer;
131  typedef typename BaseType::reference Reference;
133  typedef typename BaseType::difference_type DifferenceType;
134 
136 
140 
142 
157  GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
158 
160 
161  Iterator& operator++(){ ++ptr_; return *this; }
162  Iterator& operator--(){ --ptr_; return *this; }
163  Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
164  Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
166 
168 
169  Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
170  Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
171 
172  Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
173  Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
175 
177 
178  bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
179  bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
180  bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
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_; }
185 
187 
188  Reference operator*() const { return *ptr_; }
189  Pointer operator->() const { return ptr_; }
190  Reference operator[](DifferenceType n) const { return ptr_[n]; }
192 
194  DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
195 
196 private:
198  explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
199 
200  Pointer ptr_;
201 };
202 
203 #else // RAPIDJSON_NOMEMBERITERATORCLASS
204 
205 // class-based member iterator implementation disabled, use plain pointers
206 
207 template <bool Const, typename Encoding, typename Allocator>
208 struct GenericMemberIterator;
209 
211 template <typename Encoding, typename Allocator>
212 struct GenericMemberIterator<false,Encoding,Allocator> {
215 };
217 template <typename Encoding, typename Allocator>
218 struct GenericMemberIterator<true,Encoding,Allocator> {
221 };
222 
223 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
224 
226 // GenericStringRef
227 
229 
255 template<typename CharType>
257  typedef CharType Ch;
258 
260 
282  template<SizeType N>
283  GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
284  : s(str), length(N-1) {}
285 
287 
305  explicit GenericStringRef(const CharType* str)
306  : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); }
307 
309 
315  GenericStringRef(const CharType* str, SizeType len)
316  : s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); }
317 
319  operator const Ch *() const { return s; }
320 
321  const Ch* const s;
322  const SizeType length;
323 
324 private:
328  template<SizeType N>
329  GenericStringRef(CharType (&str)[N]) /* = delete */;
330 };
331 
333 
344 template<typename CharType>
345 inline GenericStringRef<CharType> StringRef(const CharType* str) {
347 }
348 
350 
364 template<typename CharType>
365 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
366  return GenericStringRef<CharType>(str, SizeType(length));
367 }
368 
369 #if RAPIDJSON_HAS_STDSTRING
370 
382 template<typename CharType>
383 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
384  return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
385 }
386 #endif
387 
389 // GenericValue type traits
390 namespace internal {
391 
392 template <typename T, typename Encoding = void, typename Allocator = void>
393 struct IsGenericValueImpl : FalseType {};
394 
395 // select candidates according to nested encoding and allocator types
396 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
397  : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
398 
399 // helper to match arbitrary GenericValue instantiations, including derived classes
400 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
401 
402 } // namespace internal
403 
405 // GenericValue
406 
408 
417 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
418 class GenericValue {
419 public:
422  typedef Encoding EncodingType;
423  typedef Allocator AllocatorType;
424  typedef typename Encoding::Ch Ch;
431 
433 
434 
436  GenericValue() RAPIDJSON_NOEXCEPT : data_(), flags_(kNullFlag) {}
437 
438 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
439  GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_), flags_(rhs.flags_) {
441  rhs.flags_ = kNullFlag; // give up contents
442  }
443 #endif
444 
445 private:
447  GenericValue(const GenericValue& rhs);
448 
449 public:
450 
452 
456  explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() {
457  static const unsigned defaultFlags[7] = {
460  };
461  RAPIDJSON_ASSERT(type <= kNumberType);
462  flags_ = defaultFlags[type];
463 
464  // Use ShortString to store empty string.
465  if (type == kStringType)
466  data_.ss.SetLength(0);
467  }
468 
470 
476  template< typename SourceAllocator >
477  GenericValue(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator & allocator);
478 
480 
485 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
486  template <typename T>
487  explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<T,bool>))) RAPIDJSON_NOEXCEPT
488 #else
489  explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
490 #endif
491  : data_(), flags_(b ? kTrueFlag : kFalseFlag) {
492  // safe-guard against failing SFINAE
494  }
495 
497  explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberIntFlag) {
498  data_.n.i64 = i;
499  if (i >= 0)
501  }
502 
504  explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUintFlag) {
505  data_.n.u64 = u;
506  if (!(u & 0x80000000))
508  }
509 
511  explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberInt64Flag) {
512  data_.n.i64 = i64;
513  if (i64 >= 0) {
515  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
516  flags_ |= kUintFlag;
517  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
518  flags_ |= kIntFlag;
519  }
520  else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
521  flags_ |= kIntFlag;
522  }
523 
525  explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUint64Flag) {
526  data_.n.u64 = u64;
527  if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
528  flags_ |= kInt64Flag;
529  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
530  flags_ |= kUintFlag;
531  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
532  flags_ |= kIntFlag;
533  }
534 
536  explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberDoubleFlag) { data_.n.d = d; }
537 
539  GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(StringRef(s, length)); }
540 
542  explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(s); }
543 
545  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s, length), allocator); }
546 
548  GenericValue(const Ch*s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); }
549 
550 #if RAPIDJSON_HAS_STDSTRING
551 
554  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); }
555 #endif
556 
558 
561  if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
562  switch(flags_) {
563  case kArrayFlag:
564  for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
565  v->~GenericValue();
566  Allocator::Free(data_.a.elements);
567  break;
568 
569  case kObjectFlag:
570  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
571  m->~Member();
572  Allocator::Free(data_.o.members);
573  break;
574 
575  case kCopyStringFlag:
576  Allocator::Free(const_cast<Ch*>(data_.s.str));
577  break;
578 
579  default:
580  break; // Do nothing for other types.
581  }
582  }
583  }
584 
586 
588 
589 
591 
593  GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
594  RAPIDJSON_ASSERT(this != &rhs);
595  this->~GenericValue();
596  RawAssign(rhs);
597  return *this;
598  }
599 
600 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
601  GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
603  return *this = rhs.Move();
604  }
605 #endif
606 
608 
612  GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
613  GenericValue s(str);
614  return *this = s;
615  }
616 
618 
629  template <typename T>
630  RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
631  operator=(T value) {
632  GenericValue v(value);
633  return *this = v;
634  }
635 
637 
642  template <typename SourceAllocator>
643  GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {
644  RAPIDJSON_ASSERT((void*)this != (void const*)&rhs);
645  this->~GenericValue();
646  new (this) GenericValue(rhs, allocator);
647  return *this;
648  }
649 
651 
655  GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
656  GenericValue temp;
657  temp.RawAssign(*this);
658  RawAssign(other);
659  other.RawAssign(temp);
660  return *this;
661  }
662 
664 
665  GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
667 
669 
670 
675  template <typename SourceAllocator>
676  bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
678  if (GetType() != rhs.GetType())
679  return false;
680 
681  switch (GetType()) {
682  case kObjectType: // Warning: O(n^2) inner-loop
683  if (data_.o.size != rhs.data_.o.size)
684  return false;
685  for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
686  typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
687  if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
688  return false;
689  }
690  return true;
691 
692  case kArrayType:
693  if (data_.a.size != rhs.data_.a.size)
694  return false;
695  for (SizeType i = 0; i < data_.a.size; i++)
696  if ((*this)[i] != rhs[i])
697  return false;
698  return true;
699 
700  case kStringType:
701  return StringEqual(rhs);
702 
703  case kNumberType:
704  if (IsDouble() || rhs.IsDouble()) {
705  double a = GetDouble(); // May convert from integer to double.
706  double b = rhs.GetDouble(); // Ditto
707  return a >= b && a <= b; // Prevent -Wfloat-equal
708  }
709  else
710  return data_.n.u64 == rhs.data_.n.u64;
711 
712  default: // kTrueType, kFalseType, kNullType
713  return true;
714  }
715  }
716 
718  bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
719 
720 #if RAPIDJSON_HAS_STDSTRING
721 
724  bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
725 #endif
726 
728 
730  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
731 
733 
735  template <typename SourceAllocator>
736  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
737 
739  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
740 
742 
744  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
745 
747 
749  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
750 
752 
754  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
756 
758 
759 
760  Type GetType() const { return static_cast<Type>(flags_ & kTypeMask); }
761  bool IsNull() const { return flags_ == kNullFlag; }
762  bool IsFalse() const { return flags_ == kFalseFlag; }
763  bool IsTrue() const { return flags_ == kTrueFlag; }
764  bool IsBool() const { return (flags_ & kBoolFlag) != 0; }
765  bool IsObject() const { return flags_ == kObjectFlag; }
766  bool IsArray() const { return flags_ == kArrayFlag; }
767  bool IsNumber() const { return (flags_ & kNumberFlag) != 0; }
768  bool IsInt() const { return (flags_ & kIntFlag) != 0; }
769  bool IsUint() const { return (flags_ & kUintFlag) != 0; }
770  bool IsInt64() const { return (flags_ & kInt64Flag) != 0; }
771  bool IsUint64() const { return (flags_ & kUint64Flag) != 0; }
772  bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; }
773  bool IsString() const { return (flags_ & kStringFlag) != 0; }
774 
776 
778 
779 
780  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
781 
783 
785 
786 
787  bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; }
789 
790  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
791 
793 
795 
796 
798 
799  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
800 
802  SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
803 
805  bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
806 
808 
816  template <typename T>
817  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
818  GenericValue n(StringRef(name));
819  return (*this)[n];
820  }
821  template <typename T>
822  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]; }
823 
825 
833  template <typename SourceAllocator>
835  MemberIterator member = FindMember(name);
836  if (member != MemberEnd())
837  return member->value;
838  else {
839  RAPIDJSON_ASSERT(false); // see above note
840  static GenericValue NullValue;
841  return NullValue;
842  }
843  }
844  template <typename SourceAllocator>
845  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
846 
847 #if RAPIDJSON_HAS_STDSTRING
848  GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
850  const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
851 #endif
852 
854 
855  ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); }
857 
858  ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members + data_.o.size); }
860 
861  MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members); }
863 
864  MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members + data_.o.size); }
865 
867 
874  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
875 
876 #if RAPIDJSON_HAS_STDSTRING
877 
885  bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
886 #endif
887 
889 
897  template <typename SourceAllocator>
898  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
899 
901 
912  MemberIterator FindMember(const Ch* name) {
913  GenericValue n(StringRef(name));
914  return FindMember(n);
915  }
916 
917  ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
918 
920 
932  template <typename SourceAllocator>
933  MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
934  RAPIDJSON_ASSERT(IsObject());
935  RAPIDJSON_ASSERT(name.IsString());
936  MemberIterator member = MemberBegin();
937  for ( ; member != MemberEnd(); ++member)
938  if (name.StringEqual(member->name))
939  break;
940  return member;
941  }
942  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
943 
944 #if RAPIDJSON_HAS_STDSTRING
945 
952  MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(StringRef(name)); }
953  ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(StringRef(name)); }
954 #endif
955 
957 
966  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
967  RAPIDJSON_ASSERT(IsObject());
968  RAPIDJSON_ASSERT(name.IsString());
969 
970  Object& o = data_.o;
971  if (o.size >= o.capacity) {
972  if (o.capacity == 0) {
974  o.members = reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member)));
975  }
976  else {
977  SizeType oldCapacity = o.capacity;
978  o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
979  o.members = reinterpret_cast<Member*>(allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)));
980  }
981  }
982  o.members[o.size].name.RawAssign(name);
983  o.members[o.size].value.RawAssign(value);
984  o.size++;
985  return *this;
986  }
987 
989 
997  GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
998  GenericValue v(value);
999  return AddMember(name, v, allocator);
1000  }
1001 
1002 #if RAPIDJSON_HAS_STDSTRING
1003 
1012  GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1013  GenericValue v(value, allocator);
1014  return AddMember(name, v, allocator);
1015  }
1016 #endif
1017 
1019 
1035  template <typename T>
1036  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1037  AddMember(GenericValue& name, T value, Allocator& allocator) {
1038  GenericValue v(value);
1039  return AddMember(name, v, allocator);
1040  }
1041 
1042 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1043  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1044  return AddMember(name, value, allocator);
1045  }
1046  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1047  return AddMember(name, value, allocator);
1048  }
1049  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1050  return AddMember(name, value, allocator);
1051  }
1052  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1053  GenericValue n(name);
1054  return AddMember(n, value, allocator);
1055  }
1056 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1057 
1058 
1060 
1069  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1070  GenericValue n(name);
1071  return AddMember(n, value, allocator);
1072  }
1073 
1075 
1083  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1084  GenericValue v(value);
1085  return AddMember(name, v, allocator);
1086  }
1087 
1089 
1105  template <typename T>
1106  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1107  AddMember(StringRefType name, T value, Allocator& allocator) {
1108  GenericValue n(name);
1109  return AddMember(n, value, allocator);
1110  }
1111 
1113 
1116  void RemoveAllMembers() {
1117  RAPIDJSON_ASSERT(IsObject());
1118  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1119  m->~Member();
1120  data_.o.size = 0;
1121  }
1122 
1124 
1131  bool RemoveMember(const Ch* name) {
1132  GenericValue n(StringRef(name));
1133  return RemoveMember(n);
1134  }
1135 
1136 #if RAPIDJSON_HAS_STDSTRING
1137  bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1138 #endif
1139 
1140  template <typename SourceAllocator>
1141  bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1142  MemberIterator m = FindMember(name);
1143  if (m != MemberEnd()) {
1144  RemoveMember(m);
1145  return true;
1146  }
1147  else
1148  return false;
1149  }
1150 
1152 
1159  MemberIterator RemoveMember(MemberIterator m) {
1160  RAPIDJSON_ASSERT(IsObject());
1163  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1164 
1165  MemberIterator last(data_.o.members + (data_.o.size - 1));
1166  if (data_.o.size > 1 && m != last) {
1167  // Move the last one to this place
1168  *m = *last;
1169  }
1170  else {
1171  // Only one left, just destroy
1172  m->~Member();
1173  }
1174  --data_.o.size;
1175  return m;
1176  }
1177 
1179 
1187  MemberIterator EraseMember(ConstMemberIterator pos) {
1188  return EraseMember(pos, pos +1);
1189  }
1190 
1192 
1200  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1201  RAPIDJSON_ASSERT(IsObject());
1204  RAPIDJSON_ASSERT(first >= MemberBegin());
1205  RAPIDJSON_ASSERT(first <= last);
1206  RAPIDJSON_ASSERT(last <= MemberEnd());
1207 
1208  MemberIterator pos = MemberBegin() + (first - MemberBegin());
1209  for (MemberIterator itr = pos; itr != last; ++itr)
1210  itr->~Member();
1211  std::memmove(&*pos, &*last, (MemberEnd() - last) * sizeof(Member));
1212  data_.o.size -= (last - first);
1213  return pos;
1214  }
1215 
1217 
1219 
1220 
1222 
1223  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1224 
1226  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1227 
1229  SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1230 
1232  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1233 
1235 
1238  void Clear() {
1239  RAPIDJSON_ASSERT(IsArray());
1240  for (SizeType i = 0; i < data_.a.size; ++i)
1242  data_.a.size = 0;
1243  }
1244 
1246 
1250  GenericValue& operator[](SizeType index) {
1251  RAPIDJSON_ASSERT(IsArray());
1252  RAPIDJSON_ASSERT(index < data_.a.size);
1253  return data_.a.elements[index];
1254  }
1255  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1256 
1258 
1259  ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; }
1261 
1262  ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; }
1264 
1265  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1267 
1268  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1269 
1271 
1276  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1277  RAPIDJSON_ASSERT(IsArray());
1278  if (newCapacity > data_.a.capacity) {
1279  data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue));
1280  data_.a.capacity = newCapacity;
1281  }
1282  return *this;
1283  }
1284 
1286 
1295  GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1296  RAPIDJSON_ASSERT(IsArray());
1297  if (data_.a.size >= data_.a.capacity)
1298  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1299  data_.a.elements[data_.a.size++].RawAssign(value);
1300  return *this;
1301  }
1302 
1303 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1304  GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1305  return PushBack(value, allocator);
1306  }
1307 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1308 
1310 
1318  GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1319  return (*this).template PushBack<StringRefType>(value, allocator);
1320  }
1321 
1323 
1339  template <typename T>
1340  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1341  PushBack(T value, Allocator& allocator) {
1342  GenericValue v(value);
1343  return PushBack(v, allocator);
1344  }
1345 
1347 
1350  GenericValue& PopBack() {
1351  RAPIDJSON_ASSERT(IsArray());
1352  RAPIDJSON_ASSERT(!Empty());
1354  return *this;
1355  }
1356 
1358 
1364  ValueIterator Erase(ConstValueIterator pos) {
1365  return Erase(pos, pos + 1);
1366  }
1367 
1369 
1376  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1377  RAPIDJSON_ASSERT(IsArray());
1380  RAPIDJSON_ASSERT(first >= Begin());
1381  RAPIDJSON_ASSERT(first <= last);
1382  RAPIDJSON_ASSERT(last <= End());
1383  ValueIterator pos = Begin() + (first - Begin());
1384  for (ValueIterator itr = pos; itr != last; ++itr)
1385  itr->~GenericValue();
1386  std::memmove(pos, last, (End() - last) * sizeof(GenericValue));
1387  data_.a.size -= (last - first);
1388  return pos;
1389  }
1390 
1392 
1394 
1395 
1396  int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; }
1397  unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; }
1398  int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; }
1399  uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; }
1400 
1401  double GetDouble() const {
1402  RAPIDJSON_ASSERT(IsNumber());
1403  if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1404  if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double
1405  if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1406  if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision)
1407  RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision)
1408  }
1409 
1410  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1411  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1412  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1413  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1414  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1415 
1417 
1419 
1420 
1421  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? data_.ss.str : data_.s.str); }
1422 
1424 
1426  SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1427 
1429 
1436  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1437 
1439 
1443  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1444 
1446 
1453  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }
1454 
1456 
1461  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }
1462 
1463 #if RAPIDJSON_HAS_STDSTRING
1464 
1471  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }
1472 #endif
1473 
1475 
1477 
1483  template <typename Handler>
1484  bool Accept(Handler& handler) const {
1485  switch(GetType()) {
1486  case kNullType: return handler.Null();
1487  case kFalseType: return handler.Bool(false);
1488  case kTrueType: return handler.Bool(true);
1489 
1490  case kObjectType:
1491  if (!handler.StartObject())
1492  return false;
1493  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1494  RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1495  if (!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.flags_ & kCopyFlag) != 0))
1496  return false;
1497  if (!m->value.Accept(handler))
1498  return false;
1499  }
1500  return handler.EndObject(data_.o.size);
1501 
1502  case kArrayType:
1503  if (!handler.StartArray())
1504  return false;
1505  for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
1506  if (!v->Accept(handler))
1507  return false;
1508  return handler.EndArray(data_.a.size);
1509 
1510  case kStringType:
1511  return handler.String(GetString(), GetStringLength(), (flags_ & kCopyFlag) != 0);
1512 
1513  default:
1514  RAPIDJSON_ASSERT(GetType() == kNumberType);
1515  if (IsInt()) return handler.Int(data_.n.i.i);
1516  else if (IsUint()) return handler.Uint(data_.n.u.u);
1517  else if (IsInt64()) return handler.Int64(data_.n.i64);
1518  else if (IsUint64()) return handler.Uint64(data_.n.u64);
1519  else return handler.Double(data_.n.d);
1520  }
1521  }
1522 
1523 private:
1524  template <typename, typename> friend class GenericValue;
1525  template <typename, typename, typename> friend class GenericDocument;
1526 
1527  enum {
1528  kBoolFlag = 0x100,
1529  kNumberFlag = 0x200,
1530  kIntFlag = 0x400,
1531  kUintFlag = 0x800,
1532  kInt64Flag = 0x1000,
1533  kUint64Flag = 0x2000,
1534  kDoubleFlag = 0x4000,
1535  kStringFlag = 0x100000,
1536  kCopyFlag = 0x200000,
1537  kInlineStrFlag = 0x400000,
1538 
1539  // Initial flags of different types.
1548  kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
1554 
1555  kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler
1556  };
1557 
1558  static const SizeType kDefaultArrayCapacity = 16;
1560 
1561  struct String {
1562  const Ch* str;
1564  unsigned hashcode;
1565  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1566 
1567  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1568  // (excluding the terminating zero) and store a value to determine the length of the contained
1569  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1570  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1571  // the string terminator as well. For getting the string length back from that value just use
1572  // "MaxSize - str[LenPos]".
1573  // This allows to store 11-chars strings in 32-bit mode and 15-chars strings in 64-bit mode
1574  // inline (for `UTF8`-encoded strings).
1575  struct ShortString {
1576  enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
1577  Ch str[MaxChars];
1578 
1579  inline static bool Usable(SizeType len) { return (MaxSize >= len); }
1580  inline void SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize - len); }
1581  inline SizeType GetLength() const { return (SizeType)(MaxSize - str[LenPos]); }
1582  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1583 
1584  // By using proper binary layout, retrieval of different integer types do not need conversions.
1585  union Number {
1586 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
1587  struct I {
1588  int i;
1589  char padding[4];
1590  }i;
1591  struct U {
1592  unsigned u;
1593  char padding2[4];
1594  }u;
1595 #else
1596  struct I {
1597  char padding[4];
1598  int i;
1599  }i;
1600  struct U {
1601  char padding2[4];
1602  unsigned u;
1603  }u;
1604 #endif
1607  double d;
1608  }; // 8 bytes
1609 
1610  struct Object {
1611  Member* members;
1614  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1615 
1616  struct Array {
1620  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1621 
1622  union Data {
1628  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1629 
1630  // Initialize this value as array with initial data, without calling destructor.
1631  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
1632  flags_ = kArrayFlag;
1633  if (count) {
1634  data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue));
1635  std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
1636  }
1637  else
1638  data_.a.elements = NULL;
1639  data_.a.size = data_.a.capacity = count;
1640  }
1641 
1643  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
1644  flags_ = kObjectFlag;
1645  if (count) {
1646  data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member));
1647  std::memcpy(data_.o.members, members, count * sizeof(Member));
1648  }
1649  else
1650  data_.o.members = NULL;
1651  data_.o.size = data_.o.capacity = count;
1652  }
1653 
1655  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
1657  data_.s.str = s;
1658  data_.s.length = s.length;
1659  }
1660 
1662  void SetStringRaw(StringRefType s, Allocator& allocator) {
1663  Ch* str = NULL;
1664  if(ShortString::Usable(s.length)) {
1666  data_.ss.SetLength(s.length);
1667  str = data_.ss.str;
1668  } else {
1670  data_.s.length = s.length;
1671  str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch));
1672  data_.s.str = str;
1673  }
1674  std::memcpy(str, s, s.length * sizeof(Ch));
1675  str[s.length] = '\0';
1676  }
1677 
1679  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
1680  data_ = rhs.data_;
1681  flags_ = rhs.flags_;
1682  rhs.flags_ = kNullFlag;
1683  }
1684 
1685  template <typename SourceAllocator>
1687  RAPIDJSON_ASSERT(IsString());
1688  RAPIDJSON_ASSERT(rhs.IsString());
1689 
1690  const SizeType len1 = GetStringLength();
1691  const SizeType len2 = rhs.GetStringLength();
1692  if(len1 != len2) { return false; }
1693 
1694  const Ch* const str1 = GetString();
1695  const Ch* const str2 = rhs.GetString();
1696  if(str1 == str2) { return true; } // fast path for constant string
1697 
1698  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
1699  }
1700 
1702  unsigned flags_;
1703 };
1704 
1707 
1709 // GenericDocument
1710 
1712 
1719 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
1720 class GenericDocument : public GenericValue<Encoding, Allocator> {
1721 public:
1722  typedef typename Encoding::Ch Ch;
1724  typedef Allocator AllocatorType;
1725 
1727 
1731  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
1732  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
1733  {
1734  if (!allocator_)
1735  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
1736  }
1737 
1738 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1739  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
1741  : ValueType(std::move(rhs)),
1742  allocator_(rhs.allocator_),
1744  stack_(std::move(rhs.stack_)),
1746  {
1747  rhs.allocator_ = 0;
1748  rhs.ownAllocator_ = 0;
1749  rhs.parseResult_ = ParseResult();
1750  }
1751 #endif
1752 
1754  Destroy();
1755  }
1756 
1757 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1758  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
1760  {
1761  // The cast to ValueType is necessary here, because otherwise it would
1762  // attempt to call GenericValue's templated assignment operator.
1763  ValueType::operator=(std::forward<ValueType>(rhs));
1764 
1765  // Calling the destructor here would prematurely call stack_'s destructor
1766  Destroy();
1767 
1768  allocator_ = rhs.allocator_;
1769  ownAllocator_ = rhs.ownAllocator_;
1770  stack_ = std::move(rhs.stack_);
1771  parseResult_ = rhs.parseResult_;
1772 
1773  rhs.allocator_ = 0;
1774  rhs.ownAllocator_ = 0;
1775  rhs.parseResult_ = ParseResult();
1776 
1777  return *this;
1778  }
1779 #endif
1780 
1783 
1785 
1791  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
1792  GenericDocument& ParseStream(InputStream& is) {
1793  ValueType::SetNull(); // Remove existing root if exist
1795  ClearStackOnExit scope(*this);
1796  parseResult_ = reader.template Parse<parseFlags>(is, *this);
1797  if (parseResult_) {
1798  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
1799  this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13.
1800  }
1801  return *this;
1802  }
1803 
1805 
1810  template <unsigned parseFlags, typename InputStream>
1811  GenericDocument& ParseStream(InputStream& is) {
1812  return ParseStream<parseFlags, Encoding, InputStream>(is);
1813  }
1814 
1816 
1820  template <typename InputStream>
1821  GenericDocument& ParseStream(InputStream& is) {
1822  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
1823  }
1825 
1828 
1830 
1834  template <unsigned parseFlags>
1837  return ParseStream<parseFlags | kParseInsituFlag>(s);
1838  }
1839 
1841 
1845  return ParseInsitu<kParseDefaultFlags>(str);
1846  }
1848 
1851 
1853 
1857  template <unsigned parseFlags, typename SourceEncoding>
1858  GenericDocument& Parse(const Ch* str) {
1859  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
1861  return ParseStream<parseFlags, SourceEncoding>(s);
1862  }
1863 
1865 
1868  template <unsigned parseFlags>
1869  GenericDocument& Parse(const Ch* str) {
1870  return Parse<parseFlags, Encoding>(str);
1871  }
1872 
1874 
1876  GenericDocument& Parse(const Ch* str) {
1877  return Parse<kParseDefaultFlags>(str);
1878  }
1880 
1883 
1885  bool HasParseError() const { return parseResult_.IsError(); }
1886 
1889 
1891  size_t GetErrorOffset() const { return parseResult_.Offset(); }
1892 
1894 
1896  Allocator& GetAllocator() { return *allocator_; }
1897 
1899  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
1900 
1901 private:
1902  // clear stack on any exit from ParseStream, e.g. due to exception
1904  explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
1906  private:
1910  };
1911 
1912  // callers of the following private Handler functions
1913  template <typename,typename,typename> friend class GenericReader; // for parsing
1914  template <typename, typename> friend class GenericValue; // for deep copying
1915 
1916  // Implementation of Handler
1917  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
1918  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
1919  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
1920  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
1921  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
1922  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
1923  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
1924 
1925  bool String(const Ch* str, SizeType length, bool copy) {
1926  if (copy)
1927  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
1928  else
1929  new (stack_.template Push<ValueType>()) ValueType(str, length);
1930  return true;
1931  }
1932 
1933  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
1934 
1935  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
1936 
1937  bool EndObject(SizeType memberCount) {
1938  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
1939  stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
1940  return true;
1941  }
1942 
1943  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
1944 
1945  bool EndArray(SizeType elementCount) {
1946  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
1947  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
1948  return true;
1949  }
1950 
1951 private:
1956 
1957  void ClearStack() {
1958  if (Allocator::kNeedFree)
1959  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
1960  (stack_.template Pop<ValueType>(1))->~ValueType();
1961  else
1962  stack_.Clear();
1963  stack_.ShrinkToFit();
1964  }
1965 
1966  void Destroy() {
1968  }
1969 
1970  static const size_t kDefaultStackCapacity = 1024;
1971  Allocator* allocator_;
1972  Allocator* ownAllocator_;
1975 };
1976 
1979 
1980 // defined here due to the dependency on GenericDocument
1981 template <typename Encoding, typename Allocator>
1982 template <typename SourceAllocator>
1983 inline
1985 {
1986  switch (rhs.GetType()) {
1987  case kObjectType:
1988  case kArrayType: { // perform deep copy via SAX Handler
1990  rhs.Accept(d);
1991  RawAssign(*d.stack_.template Pop<GenericValue>(1));
1992  }
1993  break;
1994  case kStringType:
1995  if (rhs.flags_ == kConstStringFlag) {
1996  flags_ = rhs.flags_;
1997  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
1998  } else {
1999  SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
2000  }
2001  break;
2002  default: // kNumberType, kTrueType, kFalseType, kNullType
2003  flags_ = rhs.flags_;
2004  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
2005  }
2006 }
2007 
2009 
2010 #if defined(_MSC_VER) || defined(__GNUC__)
2011 RAPIDJSON_DIAG_POP
2012 #endif
2013 
2014 #endif // RAPIDJSON_DOCUMENT_H_
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:139
void SetLength(SizeType len)
Definition: document.h:1580
Definition: Object.h:95
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:80
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:345
struct GenericValue::Number::I i
Iterator operator--(int)
Definition: document.h:164
Definition: document.h:1536
Definition: document.h:1547
static const size_t kDefaultStackCapacity
Definition: document.h:1970
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:428
bool EndArray(SizeType elementCount)
Definition: document.h:1945
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:1724
SizeType GetLength() const
Definition: document.h:1581
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:612
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:429
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:1723
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:322
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:1643
Definition: document.h:393
Definition: document.h:1532
bool String(const Ch *str, SizeType length, bool copy)
Definition: document.h:1925
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:344
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:111
BaseType::pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:129
Definition: document.h:1555
ClearStackOnExit(GenericDocument &d)
Definition: document.h:1904
Definition: document.h:1587
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:261
Definition: document.h:1548
Member * members
Definition: document.h:1611
object
Definition: rapidjson.h:646
Definition: document.h:1903
Pointer ptr_
raw pointer
Definition: document.h:200
~ClearStackOnExit()
Definition: document.h:1905
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:456
void SetArrayRaw(GenericValue *values, SizeType count, Allocator &allocator)
Definition: document.h:1631
Read-only string stream.
Definition: rapidjson.h:571
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:1679
GenericDocument & operator=(const GenericDocument &)
Prohibit assignment.
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:119
static const SizeType kDefaultArrayCapacity
Definition: document.h:1558
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:81
const Ch * str
Definition: document.h:1562
(Constant) member iterator for a JSON object value
Definition: document.h:109
const Ch *const s
plain CharType pointer
Definition: document.h:321
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:1655
array
Definition: rapidjson.h:647
Definition: document.h:1552
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:122
int i
Definition: document.h:1588
GenericMemberIterator(Pointer p)
Internal constructor from plain pointer.
Definition: document.h:198
Data data_
Definition: document.h:1701
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:1722
SizeType capacity
Definition: document.h:1613
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:1811
internal::Stack< StackAllocator > stack_
Definition: document.h:1973
~GenericValue()
Destructor.
Definition: document.h:560
bool Bool(bool b)
Definition: document.h:1918
std::iterator< std::random_access_iterator_tag, ValueType > BaseType
Definition: document.h:118
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:375
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:525
bool operator!=(ConstIterator that) const
Definition: document.h:179
STL namespace.
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:1888
Definition: document.h:1549
false
Definition: rapidjson.h:644
arena_t NULL
Definition: jemalloc_internal.h:624
#define false
Definition: CascPort.h:18
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:545
Definition: document.h:1533
Definition: document.h:1541
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:124
bool StringEqual(const GenericValue< Encoding, SourceAllocator > &rhs) const
Definition: document.h:1686
Result of parsing (wraps ParseErrorCode)
Definition: error.h:101
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:539
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:430
void Clear()
Definition: stack.h:84
bool operator<(ConstIterator that) const
Definition: document.h:182
signed __int64 int64_t
Definition: stdint.h:89
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:1821
Pointer operator->() const
Definition: document.h:189
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:116
Definition: document.h:1530
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition: document.h:117
Definition: document.h:1551
bool StartObject()
Definition: document.h:1933
SizeType size
Definition: document.h:1618
bool StartArray()
Definition: document.h:1943
Definition: document.h:1553
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:536
A document for parsing JSON text as DOM.
Definition: document.h:1720
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:423
ShortString ss
Definition: document.h:1624
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:70
Definition: document.h:1576
Definition: document.h:1531
A read-write string stream.
Definition: rapidjson.h:605
~GenericDocument()
Definition: document.h:1753
Definition: document.h:1537
bool operator==(ConstIterator that) const
Definition: document.h:178
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:427
Definition: document.h:1622
Ch str[MaxChars]
Definition: document.h:1577
#define true
Definition: CascPort.h:17
ClearStackOnExit & operator=(const ClearStackOnExit &)
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:425
Iterator & operator--()
Definition: document.h:162
Definition: document.h:1534
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:1731
Definition: document.h:1543
Reference operator[](DifferenceType n) const
Definition: document.h:190
bool EndObject(SizeType memberCount)
Definition: document.h:1937
Array a
Definition: document.h:1627
SizeType capacity
Definition: document.h:1619
string
Definition: rapidjson.h:648
Allocator * ownAllocator_
Definition: document.h:1972
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:374
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:305
Number n
Definition: document.h:1625
char padding[4]
Definition: document.h:1589
ParseResult parseResult_
Definition: document.h:1974
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:1706
Definition: document.h:1550
bool Double(double d)
Definition: document.h:1923
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:426
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:422
bool Null()
Definition: document.h:1917
double d
Definition: document.h:1607
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
unsigned hashcode
reserved
Definition: document.h:1564
ParseErrorCode
Error code of parsing.
Definition: error.h:59
unsigned __int64 uint64_t
Definition: stdint.h:90
Iterator & operator++()
Definition: document.h:161
char padding2[4]
Definition: document.h:1593
bool operator<=(ConstIterator that) const
Definition: document.h:180
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:1835
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:283
bool Int(int i)
Definition: document.h:1919
ParseErrorCode Code() const
Get the error code.
Definition: error.h:109
bool operator>(ConstIterator that) const
Definition: document.h:183
bool operator!=(const CoordPair< LIMIT > &p1, const CoordPair< LIMIT > &p2)
Definition: GridDefines.h:166
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:1896
static bool Usable(SizeType len)
Definition: document.h:1579
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:1978
Iterator operator++(int)
Definition: document.h:163
bool operator==(const CoordPair< LIMIT > &p1, const CoordPair< LIMIT > &p2)
Definition: GridDefines.h:160
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:322
number
Definition: rapidjson.h:649
#define RAPIDJSON_NEW(x)
! customization point for global new
Definition: rapidjson.h:480
size_t GetSize() const
Definition: stack.h:129
Name-value pair in a JSON object value.
Definition: document.h:79
bool Int64(int64_t i)
Definition: document.h:1921
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:593
Iterator & operator+=(DifferenceType n)
Definition: document.h:172
Definition: document.h:1546
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:1662
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:484
Definition: document.h:1545
String s
Definition: document.h:1623
G3D::int16 & operator[](int i)
Definition: Vector2int16.h:51
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:1844
Definition: document.h:1616
Definition: document.h:1585
Allocator & GetAllocator()
Definition: stack.h:127
CharType Ch
character type of the string
Definition: document.h:257
Definition: document.h:1575
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:194
Definition: document.h:1540
GenericStringRef operator=(const GenericStringRef &)
Disallow copy-assignment.
Definition: document.h:1529
Definition: document.h:390
bool IsError() const
Whether the result is an error.
Definition: error.h:116
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:345
Definition: document.h:1610
GenericMember< Encoding, Allocator > PlainType
Definition: document.h:116
void ShrinkToFit()
Definition: stack.h:86
Reference operator*() const
Definition: document.h:188
Definition: document.h:1528
uint64_t u64
Definition: document.h:1606
SizeType size
Definition: document.h:1612
size_t GetCapacity() const
Definition: stack.h:130
Definition: document.h:1561
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:1891
bool operator>=(ConstIterator that) const
Definition: document.h:181
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:511
Definition: document.h:1542
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:424
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:548
Iterator operator-(DifferenceType n) const
Definition: document.h:170
Definition: document.h:1535
Definition: document.h:1544
Definition: document.h:1591
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:421
bool Uint64(uint64_t i)
Definition: document.h:1922
GenericDocument & d_
Definition: document.h:1909
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:1869
true
Definition: rapidjson.h:645
unsigned u
Definition: document.h:1592
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< T, bool >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:487
bool Uint(unsigned i)
Definition: document.h:1920
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:497
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:30
Reference to a constant string (not taking a copy)
Definition: document.h:256
Definition: document.h:400
const FieldDescriptor value
Definition: descriptor.h:1522
void ClearStack()
Definition: document.h:1957
BaseType::difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:133
#define const
Definition: zconf.h:217
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:126
Definition: document.h:1576
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:157
Iterator operator+(DifferenceType n) const
Definition: document.h:169
int64_t i64
Definition: document.h:1605
Allocator * allocator_
Definition: document.h:1971
Type
Type of JSON value.
Definition: rapidjson.h:642
static const SizeType kDefaultObjectCapacity
Definition: document.h:1559
unsigned flags_
Definition: document.h:1702
BaseType::reference Reference
Reference to (const) GenericMember.
Definition: document.h:131
SizeType length
Definition: document.h:1563
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:1876
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:315
GenericValue * elements
Definition: document.h:1617
Definition: document.h:1576
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:1899
struct GenericValue::Number::U u
Data
Definition: molten_core.h:69
In-situ(destructive) parsing.
Definition: reader.h:138
void Destroy()
Definition: document.h:1966
Iterator & operator-=(DifferenceType n)
Definition: document.h:173
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:1858
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:436
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: document.h:1885
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:1792
null
Definition: rapidjson.h:643
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:542
Object o
Definition: document.h:1626
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:504
bool Key(const Ch *str, SizeType length, bool copy)
Definition: document.h:1935