document.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef RAPIDJSON_DOCUMENT_H_
16 #define RAPIDJSON_DOCUMENT_H_
17 
20 #include "reader.h"
21 #include "internal/meta.h"
22 #include "internal/strfunc.h"
23 #include "memorystream.h"
24 #include "encodedstream.h"
25 #include <new> // placement new
26 #include <limits>
27 
28 RAPIDJSON_DIAG_PUSH
29 #if __clang__
30 RAPIDJSON_DIAG_OFF(padded)
31 RAPIDJSON_DIAG_OFF(switch - enum)
32 RAPIDJSON_DIAG_OFF(c++ 98 - compat)
33 #elif defined(_MSC_VER)
34 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
35 RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
36 #endif
37 
38 #if __GNUC__
39 RAPIDJSON_DIAG_OFF(effc++)
40 #endif // __GNUC__
41 
42 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
43 #include <iterator> // std::random_access_iterator_tag
44 #endif
45 
46 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
47 #include <utility> // std::move
48 #endif
49 
51 
52 // Forward declaration.
53 template <typename Encoding, typename Allocator>
55 
56 template <typename Encoding, typename Allocator, typename StackAllocator>
58 
60 
66 template <typename Encoding, typename Allocator>
68 {
71 
72  // swap() for std::sort() and other potential use in STL.
73  friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT
74  {
75  a.name.Swap(b.name);
76  a.value.Swap(b.value);
77  }
78 };
79 
81 // GenericMemberIterator
82 
83 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
84 
86 
104 template <bool Const, typename Encoding, typename Allocator>
106 {
107  friend class GenericValue<Encoding, Allocator>;
108  template <bool, typename, typename>
109  friend class GenericMemberIterator;
110 
113 
114 public:
121 
124  typedef ValueType value_type;
125  typedef ValueType* pointer;
126  typedef ValueType& reference;
127  typedef std::ptrdiff_t difference_type;
128  typedef std::random_access_iterator_tag iterator_category;
130 
132  typedef pointer Pointer;
134  typedef reference Reference;
136  typedef difference_type DifferenceType;
137 
139 
143  {
144  }
145 
147 
162  GenericMemberIterator(const NonConstIterator& it) : ptr_(it.ptr_)
163  {
164  }
165  Iterator& operator=(const NonConstIterator& it)
166  {
167  ptr_ = it.ptr_;
168  return *this;
169  }
170 
172 
173  Iterator& operator++()
174  {
175  ++ptr_;
176  return *this;
177  }
178  Iterator& operator--()
179  {
180  --ptr_;
181  return *this;
182  }
183  Iterator operator++(int)
184  {
185  Iterator old(*this);
186  ++ptr_;
187  return old;
188  }
189  Iterator operator--(int)
190  {
191  Iterator old(*this);
192  --ptr_;
193  return old;
194  }
196 
198 
199  Iterator operator+(DifferenceType n) const
200  {
201  return Iterator(ptr_ + n);
202  }
203  Iterator operator-(DifferenceType n) const
204  {
205  return Iterator(ptr_ - n);
206  }
207 
208  Iterator& operator+=(DifferenceType n)
209  {
210  ptr_ += n;
211  return *this;
212  }
213  Iterator& operator-=(DifferenceType n)
214  {
215  ptr_ -= n;
216  return *this;
217  }
219 
221 
222  bool operator==(ConstIterator that) const
223  {
224  return ptr_ == that.ptr_;
225  }
226  bool operator!=(ConstIterator that) const
227  {
228  return ptr_ != that.ptr_;
229  }
230  bool operator<=(ConstIterator that) const
231  {
232  return ptr_ <= that.ptr_;
233  }
234  bool operator>=(ConstIterator that) const
235  {
236  return ptr_ >= that.ptr_;
237  }
238  bool operator<(ConstIterator that) const
239  {
240  return ptr_ < that.ptr_;
241  }
242  bool operator>(ConstIterator that) const
243  {
244  return ptr_ > that.ptr_;
245  }
247 
249 
250  Reference operator*() const
251  {
252  return *ptr_;
253  }
254  Pointer operator->() const
255  {
256  return ptr_;
257  }
258  Reference operator[](DifferenceType n) const
259  {
260  return ptr_[n];
261  }
263 
265  DifferenceType operator-(ConstIterator that) const
266  {
267  return ptr_ - that.ptr_;
268  }
269 
270 private:
272  explicit GenericMemberIterator(Pointer p) : ptr_(p)
273  {
274  }
275 
276  Pointer ptr_;
277 };
278 
279 #else // RAPIDJSON_NOMEMBERITERATORCLASS
280 
281 // class-based member iterator implementation disabled, use plain pointers
282 
283 template <bool Const, typename Encoding, typename Allocator>
285 
287 template <typename Encoding, typename Allocator>
288 class GenericMemberIterator<false, Encoding, Allocator>
289 {
292 };
294 template <typename Encoding, typename Allocator>
295 class GenericMemberIterator<true, Encoding, Allocator>
296 {
299 };
300 
301 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
302 
304 // GenericStringRef
305 
307 
333 template <typename CharType>
335 {
336  typedef CharType Ch;
337 
339 #ifndef __clang__ // -Wdocumentation
340 
362 #endif
363  template <SizeType N>
364  GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT : s(str), length(N - 1)
365  {
366  }
367 
369 #ifndef __clang__ // -Wdocumentation
370 
388 #endif
389  explicit GenericStringRef(const CharType* str) : s(str), length(NotNullStrLen(str))
390  {
391  }
392 
394 #ifndef __clang__ // -Wdocumentation
395 
401 #endif
402  GenericStringRef(const CharType* str, SizeType len) : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len)
403  {
404  RAPIDJSON_ASSERT(str != 0 || len == 0u);
405  }
406 
407  GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length)
408  {
409  }
410 
412  operator const Ch*() const
413  {
414  return s;
415  }
416 
417  const Ch* const s;
418  const SizeType length;
419 
420 private:
421  SizeType NotNullStrLen(const CharType* str)
422  {
423  RAPIDJSON_ASSERT(str != 0);
424  return internal::StrLen(str);
425  }
426 
428  static const Ch emptyString[];
429 
431  template <SizeType N>
432  GenericStringRef(CharType (&str)[N]) /* = delete */;
434  GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
435 };
436 
437 template <typename CharType>
438 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
439 
441 
453 template <typename CharType>
454 inline GenericStringRef<CharType> StringRef(const CharType* str)
455 {
456  return GenericStringRef<CharType>(str);
457 }
458 
460 
474 template <typename CharType>
475 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length)
476 {
477  return GenericStringRef<CharType>(str, SizeType(length));
478 }
479 
480 #if RAPIDJSON_HAS_STDSTRING
481 
493 template <typename CharType>
494 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str)
495 {
496  return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
497 }
498 #endif
499 
501 // GenericValue type traits
502 namespace internal
503 {
504 template <typename T, typename Encoding = void, typename Allocator = void>
505 struct IsGenericValueImpl : FalseType
506 {
507 };
508 
509 // select candidates according to nested encoding and allocator types
510 template <typename T>
511 struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type,
512  typename Void<typename T::AllocatorType>::Type>
513  : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type
514 {
515 };
516 
517 // helper to match arbitrary GenericValue instantiations, including derived classes
518 template <typename T>
520 {
521 };
522 
523 } // namespace internal
524 
526 // TypeHelper
527 
528 namespace internal
529 {
530 template <typename ValueType, typename T>
532 {
533 };
534 
535 template <typename ValueType>
536 struct TypeHelper<ValueType, bool>
537 {
538  static bool Is(const ValueType& v)
539  {
540  return v.IsBool();
541  }
542  static bool Get(const ValueType& v)
543  {
544  return v.GetBool();
545  }
546  static ValueType& Set(ValueType& v, bool data)
547  {
548  return v.SetBool(data);
549  }
550  static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&)
551  {
552  return v.SetBool(data);
553  }
554 };
555 
556 template <typename ValueType>
557 struct TypeHelper<ValueType, int>
558 {
559  static bool Is(const ValueType& v)
560  {
561  return v.IsInt();
562  }
563  static int Get(const ValueType& v)
564  {
565  return v.GetInt();
566  }
567  static ValueType& Set(ValueType& v, int data)
568  {
569  return v.SetInt(data);
570  }
571  static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&)
572  {
573  return v.SetInt(data);
574  }
575 };
576 
577 template <typename ValueType>
578 struct TypeHelper<ValueType, unsigned>
579 {
580  static bool Is(const ValueType& v)
581  {
582  return v.IsUint();
583  }
584  static unsigned Get(const ValueType& v)
585  {
586  return v.GetUint();
587  }
588  static ValueType& Set(ValueType& v, unsigned data)
589  {
590  return v.SetUint(data);
591  }
592  static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&)
593  {
594  return v.SetUint(data);
595  }
596 };
597 
598 #if _MSC_VER
599 RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
600 template <typename ValueType>
601 struct TypeHelper<ValueType, long>
602 {
603  static bool Is(const ValueType& v)
604  {
605  return v.IsInt();
606  }
607  static long Get(const ValueType& v)
608  {
609  return v.GetInt();
610  }
611  static ValueType& Set(ValueType& v, long data)
612  {
613  return v.SetInt(data);
614  }
615  static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&)
616  {
617  return v.SetInt(data);
618  }
619 };
620 
621 RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
622 template <typename ValueType>
623 struct TypeHelper<ValueType, unsigned long>
624 {
625  static bool Is(const ValueType& v)
626  {
627  return v.IsUint();
628  }
629  static unsigned long Get(const ValueType& v)
630  {
631  return v.GetUint();
632  }
633  static ValueType& Set(ValueType& v, unsigned long data)
634  {
635  return v.SetUint(data);
636  }
637  static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&)
638  {
639  return v.SetUint(data);
640  }
641 };
642 #endif
643 
644 template <typename ValueType>
645 struct TypeHelper<ValueType, int64_t>
646 {
647  static bool Is(const ValueType& v)
648  {
649  return v.IsInt64();
650  }
651  static int64_t Get(const ValueType& v)
652  {
653  return v.GetInt64();
654  }
655  static ValueType& Set(ValueType& v, int64_t data)
656  {
657  return v.SetInt64(data);
658  }
659  static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&)
660  {
661  return v.SetInt64(data);
662  }
663 };
664 
665 template <typename ValueType>
666 struct TypeHelper<ValueType, uint64_t>
667 {
668  static bool Is(const ValueType& v)
669  {
670  return v.IsUint64();
671  }
672  static uint64_t Get(const ValueType& v)
673  {
674  return v.GetUint64();
675  }
676  static ValueType& Set(ValueType& v, uint64_t data)
677  {
678  return v.SetUint64(data);
679  }
680  static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&)
681  {
682  return v.SetUint64(data);
683  }
684 };
685 
686 template <typename ValueType>
687 struct TypeHelper<ValueType, double>
688 {
689  static bool Is(const ValueType& v)
690  {
691  return v.IsDouble();
692  }
693  static double Get(const ValueType& v)
694  {
695  return v.GetDouble();
696  }
697  static ValueType& Set(ValueType& v, double data)
698  {
699  return v.SetDouble(data);
700  }
701  static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&)
702  {
703  return v.SetDouble(data);
704  }
705 };
706 
707 template <typename ValueType>
708 struct TypeHelper<ValueType, float>
709 {
710  static bool Is(const ValueType& v)
711  {
712  return v.IsFloat();
713  }
714  static float Get(const ValueType& v)
715  {
716  return v.GetFloat();
717  }
718  static ValueType& Set(ValueType& v, float data)
719  {
720  return v.SetFloat(data);
721  }
722  static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&)
723  {
724  return v.SetFloat(data);
725  }
726 };
727 
728 template <typename ValueType>
729 struct TypeHelper<ValueType, const typename ValueType::Ch*>
730 {
731  typedef const typename ValueType::Ch* StringType;
732  static bool Is(const ValueType& v)
733  {
734  return v.IsString();
735  }
736  static StringType Get(const ValueType& v)
737  {
738  return v.GetString();
739  }
740  static ValueType& Set(ValueType& v, const StringType data)
741  {
742  return v.SetString(typename ValueType::StringRefType(data));
743  }
744  static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a)
745  {
746  return v.SetString(data, a);
747  }
748 };
749 
750 #if RAPIDJSON_HAS_STDSTRING
751 template <typename ValueType>
752 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> >
753 {
754  typedef std::basic_string<typename ValueType::Ch> StringType;
755  static bool Is(const ValueType& v)
756  {
757  return v.IsString();
758  }
759  static StringType Get(const ValueType& v)
760  {
761  return StringType(v.GetString(), v.GetStringLength());
762  }
763  static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a)
764  {
765  return v.SetString(data, a);
766  }
767 };
768 #endif
769 
770 template <typename ValueType>
771 struct TypeHelper<ValueType, typename ValueType::Array>
772 {
773  typedef typename ValueType::Array ArrayType;
774  static bool Is(const ValueType& v)
775  {
776  return v.IsArray();
777  }
778  static ArrayType Get(ValueType& v)
779  {
780  return v.GetArray();
781  }
782  static ValueType& Set(ValueType& v, ArrayType data)
783  {
784  return v = data;
785  }
786  static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&)
787  {
788  return v = data;
789  }
790 };
791 
792 template <typename ValueType>
793 struct TypeHelper<ValueType, typename ValueType::ConstArray>
794 {
795  typedef typename ValueType::ConstArray ArrayType;
796  static bool Is(const ValueType& v)
797  {
798  return v.IsArray();
799  }
800  static ArrayType Get(const ValueType& v)
801  {
802  return v.GetArray();
803  }
804 };
805 
806 template <typename ValueType>
807 struct TypeHelper<ValueType, typename ValueType::Object>
808 {
809  typedef typename ValueType::Object ObjectType;
810  static bool Is(const ValueType& v)
811  {
812  return v.IsObject();
813  }
814  static ObjectType Get(ValueType& v)
815  {
816  return v.GetObject();
817  }
818  static ValueType& Set(ValueType& v, ObjectType data)
819  {
820  return v = data;
821  }
822  static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&)
823  {
824  return v = data;
825  }
826 };
827 
828 template <typename ValueType>
829 struct TypeHelper<ValueType, typename ValueType::ConstObject>
830 {
831  typedef typename ValueType::ConstObject ObjectType;
832  static bool Is(const ValueType& v)
833  {
834  return v.IsObject();
835  }
836  static ObjectType Get(const ValueType& v)
837  {
838  return v.GetObject();
839  }
840 };
841 
842 } // namespace internal
843 
844 // Forward declarations
845 template <bool, typename>
847 template <bool, typename>
849 
851 // GenericValue
852 
854 
863 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
864 class GenericValue
865 {
866 public:
869  typedef Encoding EncodingType;
870  typedef Allocator AllocatorType;
871  typedef typename Encoding::Ch Ch;
876  typedef GenericValue* ValueIterator;
886 
888 
889 
891  GenericValue() RAPIDJSON_NOEXCEPT : data_()
892  {
893  data_.f.flags = kNullFlag;
894  }
895 
896 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
897  GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_)
899  {
900  rhs.data_.f.flags = kNullFlag; // give up contents
901  }
902 #endif
903 
904 private:
906  GenericValue(const GenericValue& rhs);
907 
908 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
909  template <typename StackAllocator>
912 
914  template <typename StackAllocator>
916 #endif
917 
918 public:
920 
924  explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_()
925  {
926  static const uint16_t defaultFlags[] = { kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag,
927  kArrayFlag, kShortStringFlag, kNumberAnyFlag };
928  RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
929  data_.f.flags = defaultFlags[type];
930 
931  // Use ShortString to store empty string.
932  if (type == kStringType)
933  data_.ss.SetLength(0);
934  }
935 
937 
945  template <typename SourceAllocator>
946  GenericValue(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false)
947  {
948  switch (rhs.GetType())
949  {
950  case kObjectType:
951  {
952  SizeType count = rhs.data_.o.size;
953  Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
955  for (SizeType i = 0; i < count; i++)
956  {
957  new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
958  new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
959  }
960  data_.f.flags = kObjectFlag;
961  data_.o.size = data_.o.capacity = count;
962  SetMembersPointer(lm);
963  }
964  break;
965  case kArrayType:
966  {
967  SizeType count = rhs.data_.a.size;
968  GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
970  for (SizeType i = 0; i < count; i++)
971  new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
972  data_.f.flags = kArrayFlag;
973  data_.a.size = data_.a.capacity = count;
974  SetElementsPointer(le);
975  }
976  break;
977  case kStringType:
978  if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings)
979  {
980  data_.f.flags = rhs.data_.f.flags;
981  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
982  }
983  else
984  SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
985  break;
986  default:
987  data_.f.flags = rhs.data_.f.flags;
988  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
989  break;
990  }
991  }
992 
994 
999 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
1000  template <typename T>
1001  explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
1002 #else
1003  explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
1004 #endif
1005  : data_()
1006  {
1007  // safe-guard against failing SFINAE
1009  data_.f.flags = b ? kTrueFlag : kFalseFlag;
1010  }
1011 
1013  explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_()
1014  {
1015  data_.n.i64 = i;
1016  data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
1017  }
1018 
1020  explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_()
1021  {
1022  data_.n.u64 = u;
1023  data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
1024  }
1025 
1027  explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_()
1028  {
1029  data_.n.i64 = i64;
1030  data_.f.flags = kNumberInt64Flag;
1031  if (i64 >= 0)
1032  {
1033  data_.f.flags |= kNumberUint64Flag;
1034  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
1035  data_.f.flags |= kUintFlag;
1036  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
1037  data_.f.flags |= kIntFlag;
1038  }
1039  else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
1040  data_.f.flags |= kIntFlag;
1041  }
1042 
1044  explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_()
1045  {
1046  data_.n.u64 = u64;
1047  data_.f.flags = kNumberUint64Flag;
1048  if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
1049  data_.f.flags |= kInt64Flag;
1050  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
1051  data_.f.flags |= kUintFlag;
1052  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
1053  data_.f.flags |= kIntFlag;
1054  }
1055 
1057  explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_()
1058  {
1059  data_.n.d = d;
1060  data_.f.flags = kNumberDoubleFlag;
1061  }
1062 
1064  explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_()
1065  {
1066  data_.n.d = static_cast<double>(f);
1067  data_.f.flags = kNumberDoubleFlag;
1068  }
1069 
1071  GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_()
1072  {
1073  SetStringRaw(StringRef(s, length));
1074  }
1075 
1077  explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_()
1078  {
1079  SetStringRaw(s);
1080  }
1081 
1083  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_()
1084  {
1085  SetStringRaw(StringRef(s, length), allocator);
1086  }
1087 
1089  GenericValue(const Ch* s, Allocator& allocator) : data_()
1090  {
1091  SetStringRaw(StringRef(s), allocator);
1092  }
1093 
1094 #if RAPIDJSON_HAS_STDSTRING
1095 
1098  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_()
1099  {
1100  SetStringRaw(StringRef(s), allocator);
1101  }
1102 #endif
1103 
1105 
1110  GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_)
1111  {
1112  a.value_.data_ = Data();
1113  a.value_.data_.f.flags = kArrayFlag;
1114  }
1115 
1117 
1122  GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_)
1123  {
1124  o.value_.data_ = Data();
1125  o.value_.data_.f.flags = kObjectFlag;
1126  }
1127 
1129 
1132  {
1133  if (Allocator::kNeedFree)
1134  { // Shortcut by Allocator's trait
1135  switch (data_.f.flags)
1136  {
1137  case kArrayFlag:
1138  {
1139  GenericValue* e = GetElementsPointer();
1140  for (GenericValue* v = e; v != e + data_.a.size; ++v)
1141  v->~GenericValue();
1142  Allocator::Free(e);
1143  }
1144  break;
1145 
1146  case kObjectFlag:
1147  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1148  m->~Member();
1149  Allocator::Free(GetMembersPointer());
1150  break;
1151 
1152  case kCopyStringFlag:
1153  Allocator::Free(const_cast<Ch*>(GetStringPointer()));
1154  break;
1155 
1156  default:
1157  break; // Do nothing for other types.
1158  }
1159  }
1160  }
1161 
1163 
1165 
1166 
1168 
1170  GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT
1171  {
1172  if (RAPIDJSON_LIKELY(this != &rhs))
1173  {
1174  this->~GenericValue();
1175  RawAssign(rhs);
1176  }
1177  return *this;
1178  }
1179 
1180 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1181  GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT
1183  {
1184  return *this = rhs.Move();
1185  }
1186 #endif
1187 
1189 
1193  GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT
1194  {
1195  GenericValue s(str);
1196  return *this = s;
1197  }
1198 
1200 
1211  template <typename T>
1212  RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
1213  operator=(T value)
1214  {
1215  GenericValue v(value);
1216  return *this = v;
1217  }
1218 
1220 
1226  template <typename SourceAllocator>
1227  GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator,
1228  bool copyConstStrings = false)
1229  {
1230  RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
1231  this->~GenericValue();
1232  new (this) GenericValue(rhs, allocator, copyConstStrings);
1233  return *this;
1234  }
1235 
1237 
1241  GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT
1242  {
1243  GenericValue temp;
1244  temp.RawAssign(*this);
1245  RawAssign(other);
1246  other.RawAssign(temp);
1247  return *this;
1248  }
1249 
1251 
1262  friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT
1263  {
1264  a.Swap(b);
1265  }
1266 
1268 
1269  GenericValue& Move() RAPIDJSON_NOEXCEPT
1270  {
1271  return *this;
1272  }
1274 
1276 
1277 
1283  template <typename SourceAllocator>
1284  bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const
1285  {
1287  if (GetType() != rhs.GetType())
1288  return false;
1289 
1290  switch (GetType())
1291  {
1292  case kObjectType: // Warning: O(n^2) inner-loop
1293  if (data_.o.size != rhs.data_.o.size)
1294  return false;
1295  for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr)
1296  {
1297  typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1298  if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
1299  return false;
1300  }
1301  return true;
1302 
1303  case kArrayType:
1304  if (data_.a.size != rhs.data_.a.size)
1305  return false;
1306  for (SizeType i = 0; i < data_.a.size; i++)
1307  if ((*this)[i] != rhs[i])
1308  return false;
1309  return true;
1310 
1311  case kStringType:
1312  return StringEqual(rhs);
1313 
1314  case kNumberType:
1315  if (IsDouble() || rhs.IsDouble())
1316  {
1317  double a = GetDouble(); // May convert from integer to double.
1318  double b = rhs.GetDouble(); // Ditto
1319  return a >= b && a <= b; // Prevent -Wfloat-equal
1320  }
1321  else
1322  return data_.n.u64 == rhs.data_.n.u64;
1323 
1324  default:
1325  return true;
1326  }
1327  }
1328 
1330  bool operator==(const Ch* rhs) const
1331  {
1332  return *this == GenericValue(StringRef(rhs));
1333  }
1334 
1335 #if RAPIDJSON_HAS_STDSTRING
1336 
1339  bool operator==(const std::basic_string<Ch>& rhs) const
1340  {
1341  return *this == GenericValue(StringRef(rhs));
1342  }
1343 #endif
1344 
1346 
1348  template <typename T>
1349  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (bool))
1350  operator==(const T& rhs) const
1351  {
1352  return *this == GenericValue(rhs);
1353  }
1354 
1356 
1358  template <typename SourceAllocator>
1359  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const
1360  {
1361  return !(*this == rhs);
1362  }
1363 
1365  bool operator!=(const Ch* rhs) const
1366  {
1367  return !(*this == rhs);
1368  }
1369 
1371 
1373  template <typename T>
1375  operator!=(const T& rhs) const
1376  {
1377  return !(*this == rhs);
1378  }
1379 
1381 
1383  template <typename T>
1384  friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs,
1385  const GenericValue& rhs)
1386  {
1387  return rhs == lhs;
1388  }
1389 
1391 
1393  template <typename T>
1394  friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs,
1395  const GenericValue& rhs)
1396  {
1397  return !(rhs == lhs);
1398  }
1400 
1402 
1403 
1404  Type GetType() const
1405  {
1406  return static_cast<Type>(data_.f.flags & kTypeMask);
1407  }
1408  bool IsNull() const
1409  {
1410  return data_.f.flags == kNullFlag;
1411  }
1412  bool IsFalse() const
1413  {
1414  return data_.f.flags == kFalseFlag;
1415  }
1416  bool IsTrue() const
1417  {
1418  return data_.f.flags == kTrueFlag;
1419  }
1420  bool IsBool() const
1421  {
1422  return (data_.f.flags & kBoolFlag) != 0;
1423  }
1424  bool IsObject() const
1425  {
1426  return data_.f.flags == kObjectFlag;
1427  }
1428  bool IsArray() const
1429  {
1430  return data_.f.flags == kArrayFlag;
1431  }
1432  bool IsNumber() const
1433  {
1434  return (data_.f.flags & kNumberFlag) != 0;
1435  }
1436  bool IsInt() const
1437  {
1438  return (data_.f.flags & kIntFlag) != 0;
1439  }
1440  bool IsUint() const
1441  {
1442  return (data_.f.flags & kUintFlag) != 0;
1443  }
1444  bool IsInt64() const
1445  {
1446  return (data_.f.flags & kInt64Flag) != 0;
1447  }
1448  bool IsUint64() const
1449  {
1450  return (data_.f.flags & kUint64Flag) != 0;
1451  }
1452  bool IsDouble() const
1453  {
1454  return (data_.f.flags & kDoubleFlag) != 0;
1455  }
1456  bool IsString() const
1457  {
1458  return (data_.f.flags & kStringFlag) != 0;
1459  }
1460 
1461  // Checks whether a number can be losslessly converted to a double.
1462  bool IsLosslessDouble() const
1463  {
1464  if (!IsNumber())
1465  return false;
1466  if (IsUint64())
1467  {
1468  uint64_t u = GetUint64();
1469  volatile double d = static_cast<double>(u);
1470  return (d >= 0.0) && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)())) &&
1471  (u == static_cast<uint64_t>(d));
1472  }
1473  if (IsInt64())
1474  {
1475  int64_t i = GetInt64();
1476  volatile double d = static_cast<double>(i);
1477  return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)())) &&
1478  (d < static_cast<double>((std::numeric_limits<int64_t>::max)())) && (i == static_cast<int64_t>(d));
1479  }
1480  return true; // double, int, uint are always lossless
1481  }
1482 
1483  // Checks whether a number is a float (possible lossy).
1484  bool IsFloat() const
1485  {
1486  if ((data_.f.flags & kDoubleFlag) == 0)
1487  return false;
1488  double d = GetDouble();
1489  return d >= -3.4028234e38 && d <= 3.4028234e38;
1490  }
1491  // Checks whether a number can be losslessly converted to a float.
1492  bool IsLosslessFloat() const
1493  {
1494  if (!IsNumber())
1495  return false;
1496  double a = GetDouble();
1497  if (a < static_cast<double>(-(std::numeric_limits<float>::max)()) ||
1498  a > static_cast<double>((std::numeric_limits<float>::max)()))
1499  return false;
1500  double b = static_cast<double>(static_cast<float>(a));
1501  return a >= b && a <= b; // Prevent -Wfloat-equal
1502  }
1503 
1505 
1507 
1508 
1509  GenericValue& SetNull()
1510  {
1511  this->~GenericValue();
1512  new (this) GenericValue();
1513  return *this;
1514  }
1515 
1517 
1519 
1520 
1521  bool GetBool() const
1522  {
1523  RAPIDJSON_ASSERT(IsBool());
1524  return data_.f.flags == kTrueFlag;
1525  }
1527 
1528  GenericValue& SetBool(bool b)
1529  {
1530  this->~GenericValue();
1531  new (this) GenericValue(b);
1532  return *this;
1533  }
1534 
1536 
1538 
1539 
1541 
1542  GenericValue& SetObject()
1543  {
1544  this->~GenericValue();
1545  new (this) GenericValue(kObjectType);
1546  return *this;
1547  }
1548 
1550  SizeType MemberCount() const
1551  {
1552  RAPIDJSON_ASSERT(IsObject());
1553  return data_.o.size;
1554  }
1555 
1557  SizeType MemberCapacity() const
1558  {
1559  RAPIDJSON_ASSERT(IsObject());
1560  return data_.o.capacity;
1561  }
1562 
1564  bool ObjectEmpty() const
1565  {
1566  RAPIDJSON_ASSERT(IsObject());
1567  return data_.o.size == 0;
1568  }
1569 
1571 
1579  template <typename T>
1580  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),
1581  (GenericValue&))
1582  operator[](T* name)
1583  {
1584  GenericValue n(StringRef(name));
1585  return (*this)[n];
1586  }
1587  template <typename T>
1588  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),
1589  (const GenericValue&))
1590  operator[](T* name) const
1591  {
1592  return const_cast<GenericValue&>(*this)[name];
1593  }
1594 
1596 
1604  template <typename SourceAllocator>
1605  GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name)
1606  {
1607  MemberIterator member = FindMember(name);
1608  if (member != MemberEnd())
1609  return member->value;
1610  else
1611  {
1612  RAPIDJSON_ASSERT(false); // see above note
1613 
1614  // This will generate -Wexit-time-destructors in clang
1615  // static GenericValue NullValue;
1616  // return NullValue;
1617 
1618  // Use static buffer and placement-new to prevent destruction
1619  static char buffer[sizeof(GenericValue)];
1620  return *new (buffer) GenericValue();
1621  }
1622  }
1623  template <typename SourceAllocator>
1624  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const
1625  {
1626  return const_cast<GenericValue&>(*this)[name];
1627  }
1628 
1629 #if RAPIDJSON_HAS_STDSTRING
1630  GenericValue& operator[](const std::basic_string<Ch>& name)
1632  {
1633  return (*this)[GenericValue(StringRef(name))];
1634  }
1635  const GenericValue& operator[](const std::basic_string<Ch>& name) const
1636  {
1637  return (*this)[GenericValue(StringRef(name))];
1638  }
1639 #endif
1640 
1642 
1643  ConstMemberIterator MemberBegin() const
1644  {
1645  RAPIDJSON_ASSERT(IsObject());
1646  return ConstMemberIterator(GetMembersPointer());
1647  }
1649 
1650  ConstMemberIterator MemberEnd() const
1651  {
1652  RAPIDJSON_ASSERT(IsObject());
1653  return ConstMemberIterator(GetMembersPointer() + data_.o.size);
1654  }
1656 
1657  MemberIterator MemberBegin()
1658  {
1659  RAPIDJSON_ASSERT(IsObject());
1660  return MemberIterator(GetMembersPointer());
1661  }
1663 
1664  MemberIterator MemberEnd()
1665  {
1666  RAPIDJSON_ASSERT(IsObject());
1667  return MemberIterator(GetMembersPointer() + data_.o.size);
1668  }
1669 
1671 
1677  GenericValue& MemberReserve(SizeType newCapacity, Allocator& allocator)
1678  {
1679  RAPIDJSON_ASSERT(IsObject());
1680  if (newCapacity > data_.o.capacity)
1681  {
1682  SetMembersPointer(reinterpret_cast<Member*>(
1683  allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
1684  data_.o.capacity = newCapacity;
1685  }
1686  return *this;
1687  }
1688 
1690 
1697  bool HasMember(const Ch* name) const
1698  {
1699  return FindMember(name) != MemberEnd();
1700  }
1701 
1702 #if RAPIDJSON_HAS_STDSTRING
1703 
1711  bool HasMember(const std::basic_string<Ch>& name) const
1712  {
1713  return FindMember(name) != MemberEnd();
1714  }
1715 #endif
1716 
1718 
1726  template <typename SourceAllocator>
1727  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const
1728  {
1729  return FindMember(name) != MemberEnd();
1730  }
1731 
1733 
1744  MemberIterator FindMember(const Ch* name)
1745  {
1746  GenericValue n(StringRef(name));
1747  return FindMember(n);
1748  }
1749 
1750  ConstMemberIterator FindMember(const Ch* name) const
1751  {
1752  return const_cast<GenericValue&>(*this).FindMember(name);
1753  }
1754 
1756 
1768  template <typename SourceAllocator>
1769  MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name)
1770  {
1771  RAPIDJSON_ASSERT(IsObject());
1772  RAPIDJSON_ASSERT(name.IsString());
1773  MemberIterator member = MemberBegin();
1774  for (; member != MemberEnd(); ++member)
1775  if (name.StringEqual(member->name))
1776  break;
1777  return member;
1778  }
1779  template <typename SourceAllocator>
1780  ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const
1781  {
1782  return const_cast<GenericValue&>(*this).FindMember(name);
1783  }
1784 
1785 #if RAPIDJSON_HAS_STDSTRING
1786 
1793  MemberIterator FindMember(const std::basic_string<Ch>& name)
1794  {
1795  return FindMember(GenericValue(StringRef(name)));
1796  }
1797  ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const
1798  {
1799  return FindMember(GenericValue(StringRef(name)));
1800  }
1801 #endif
1802 
1804 
1814  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator)
1815  {
1816  RAPIDJSON_ASSERT(IsObject());
1817  RAPIDJSON_ASSERT(name.IsString());
1818 
1819  ObjectData& o = data_.o;
1820  if (o.size >= o.capacity)
1821  MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1822  Member* members = GetMembersPointer();
1823  members[o.size].name.RawAssign(name);
1824  members[o.size].value.RawAssign(value);
1825  o.size++;
1826  return *this;
1827  }
1828 
1830 
1840  GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator)
1841  {
1842  GenericValue v(value);
1843  return AddMember(name, v, allocator);
1844  }
1845 
1846 #if RAPIDJSON_HAS_STDSTRING
1847 
1858  GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator)
1859  {
1860  GenericValue v(value, allocator);
1861  return AddMember(name, v, allocator);
1862  }
1863 #endif
1864 
1866 
1882  template <typename T>
1883  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1884  AddMember(GenericValue& name, T value, Allocator& allocator)
1885  {
1886  GenericValue v(value);
1887  return AddMember(name, v, allocator);
1888  }
1889 
1890 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1891  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator)
1892  {
1893  return AddMember(name, value, allocator);
1894  }
1895  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator)
1896  {
1897  return AddMember(name, value, allocator);
1898  }
1899  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator)
1900  {
1901  return AddMember(name, value, allocator);
1902  }
1903  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator)
1904  {
1905  GenericValue n(name);
1906  return AddMember(n, value, allocator);
1907  }
1908 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1909 
1911 
1921  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator)
1922  {
1923  GenericValue n(name);
1924  return AddMember(n, value, allocator);
1925  }
1926 
1928 
1938  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator)
1939  {
1940  GenericValue v(value);
1941  return AddMember(name, v, allocator);
1942  }
1943 
1945 
1961  template <typename T>
1962  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1963  AddMember(StringRefType name, T value, Allocator& allocator)
1964  {
1965  GenericValue n(name);
1966  return AddMember(n, value, allocator);
1967  }
1968 
1970 
1973  void RemoveAllMembers()
1974  {
1975  RAPIDJSON_ASSERT(IsObject());
1976  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1977  m->~Member();
1978  data_.o.size = 0;
1979  }
1980 
1982 
1989  bool RemoveMember(const Ch* name)
1990  {
1991  GenericValue n(StringRef(name));
1992  return RemoveMember(n);
1993  }
1994 
1995 #if RAPIDJSON_HAS_STDSTRING
1996  bool RemoveMember(const std::basic_string<Ch>& name)
1997  {
1998  return RemoveMember(GenericValue(StringRef(name)));
1999  }
2000 #endif
2001 
2002  template <typename SourceAllocator>
2003  bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name)
2004  {
2005  MemberIterator m = FindMember(name);
2006  if (m != MemberEnd())
2007  {
2008  RemoveMember(m);
2009  return true;
2010  }
2011  else
2012  return false;
2013  }
2014 
2016 
2023  MemberIterator RemoveMember(MemberIterator m)
2024  {
2025  RAPIDJSON_ASSERT(IsObject());
2026  RAPIDJSON_ASSERT(data_.o.size > 0);
2027  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
2028  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
2029 
2030  MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
2031  if (data_.o.size > 1 && m != last)
2032  *m = *last; // Move the last one to this place
2033  else
2034  m->~Member(); // Only one left, just destroy
2035  --data_.o.size;
2036  return m;
2037  }
2038 
2040 
2048  MemberIterator EraseMember(ConstMemberIterator pos)
2049  {
2050  return EraseMember(pos, pos + 1);
2051  }
2052 
2054 
2062  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last)
2063  {
2064  RAPIDJSON_ASSERT(IsObject());
2065  RAPIDJSON_ASSERT(data_.o.size > 0);
2066  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
2067  RAPIDJSON_ASSERT(first >= MemberBegin());
2068  RAPIDJSON_ASSERT(first <= last);
2069  RAPIDJSON_ASSERT(last <= MemberEnd());
2070 
2071  MemberIterator pos = MemberBegin() + (first - MemberBegin());
2072  for (MemberIterator itr = pos; itr != last; ++itr)
2073  itr->~Member();
2074  std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
2075  data_.o.size -= static_cast<SizeType>(last - first);
2076  return pos;
2077  }
2078 
2080 
2084  bool EraseMember(const Ch* name)
2085  {
2086  GenericValue n(StringRef(name));
2087  return EraseMember(n);
2088  }
2089 
2090 #if RAPIDJSON_HAS_STDSTRING
2091  bool EraseMember(const std::basic_string<Ch>& name)
2092  {
2093  return EraseMember(GenericValue(StringRef(name)));
2094  }
2095 #endif
2096 
2097  template <typename SourceAllocator>
2098  bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name)
2099  {
2100  MemberIterator m = FindMember(name);
2101  if (m != MemberEnd())
2102  {
2103  EraseMember(m);
2104  return true;
2105  }
2106  else
2107  return false;
2108  }
2109 
2110  Object GetObject()
2111  {
2112  RAPIDJSON_ASSERT(IsObject());
2113  return Object(*this);
2114  }
2115  ConstObject GetObject() const
2116  {
2117  RAPIDJSON_ASSERT(IsObject());
2118  return ConstObject(*this);
2119  }
2120 
2122 
2124 
2125 
2127 
2128  GenericValue& SetArray()
2129  {
2130  this->~GenericValue();
2131  new (this) GenericValue(kArrayType);
2132  return *this;
2133  }
2134 
2136  SizeType Size() const
2137  {
2138  RAPIDJSON_ASSERT(IsArray());
2139  return data_.a.size;
2140  }
2141 
2143  SizeType Capacity() const
2144  {
2145  RAPIDJSON_ASSERT(IsArray());
2146  return data_.a.capacity;
2147  }
2148 
2150  bool Empty() const
2151  {
2152  RAPIDJSON_ASSERT(IsArray());
2153  return data_.a.size == 0;
2154  }
2155 
2157 
2160  void Clear()
2161  {
2162  RAPIDJSON_ASSERT(IsArray());
2163  GenericValue* e = GetElementsPointer();
2164  for (GenericValue* v = e; v != e + data_.a.size; ++v)
2165  v->~GenericValue();
2166  data_.a.size = 0;
2167  }
2168 
2170 
2174  GenericValue& operator[](SizeType index)
2175  {
2176  RAPIDJSON_ASSERT(IsArray());
2177  RAPIDJSON_ASSERT(index < data_.a.size);
2178  return GetElementsPointer()[index];
2179  }
2180  const GenericValue& operator[](SizeType index) const
2181  {
2182  return const_cast<GenericValue&>(*this)[index];
2183  }
2184 
2186 
2187  ValueIterator Begin()
2188  {
2189  RAPIDJSON_ASSERT(IsArray());
2190  return GetElementsPointer();
2191  }
2193 
2194  ValueIterator End()
2195  {
2196  RAPIDJSON_ASSERT(IsArray());
2197  return GetElementsPointer() + data_.a.size;
2198  }
2200 
2201  ConstValueIterator Begin() const
2202  {
2203  return const_cast<GenericValue&>(*this).Begin();
2204  }
2206 
2207  ConstValueIterator End() const
2208  {
2209  return const_cast<GenericValue&>(*this).End();
2210  }
2211 
2213 
2219  GenericValue& Reserve(SizeType newCapacity, Allocator& allocator)
2220  {
2221  RAPIDJSON_ASSERT(IsArray());
2222  if (newCapacity > data_.a.capacity)
2223  {
2224  SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(
2225  GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
2226  data_.a.capacity = newCapacity;
2227  }
2228  return *this;
2229  }
2230 
2232 
2242  GenericValue& PushBack(GenericValue& value, Allocator& allocator)
2243  {
2244  RAPIDJSON_ASSERT(IsArray());
2245  if (data_.a.size >= data_.a.capacity)
2246  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2),
2247  allocator);
2248  GetElementsPointer()[data_.a.size++].RawAssign(value);
2249  return *this;
2250  }
2251 
2252 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2253  GenericValue& PushBack(GenericValue&& value, Allocator& allocator)
2254  {
2255  return PushBack(value, allocator);
2256  }
2257 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2258 
2260 
2269  GenericValue& PushBack(StringRefType value, Allocator& allocator)
2270  {
2271  return (*this).template PushBack<StringRefType>(value, allocator);
2272  }
2273 
2275 
2292  template <typename T>
2293  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
2294  PushBack(T value, Allocator& allocator)
2295  {
2296  GenericValue v(value);
2297  return PushBack(v, allocator);
2298  }
2299 
2301 
2304  GenericValue& PopBack()
2305  {
2306  RAPIDJSON_ASSERT(IsArray());
2307  RAPIDJSON_ASSERT(!Empty());
2308  GetElementsPointer()[--data_.a.size].~GenericValue();
2309  return *this;
2310  }
2311 
2313 
2320  ValueIterator Erase(ConstValueIterator pos)
2321  {
2322  return Erase(pos, pos + 1);
2323  }
2324 
2326 
2333  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)
2334  {
2335  RAPIDJSON_ASSERT(IsArray());
2336  RAPIDJSON_ASSERT(data_.a.size > 0);
2337  RAPIDJSON_ASSERT(GetElementsPointer() != 0);
2338  RAPIDJSON_ASSERT(first >= Begin());
2339  RAPIDJSON_ASSERT(first <= last);
2340  RAPIDJSON_ASSERT(last <= End());
2341  ValueIterator pos = Begin() + (first - Begin());
2342  for (ValueIterator itr = pos; itr != last; ++itr)
2343  itr->~GenericValue();
2344  std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
2345  data_.a.size -= static_cast<SizeType>(last - first);
2346  return pos;
2347  }
2348 
2349  Array GetArray()
2350  {
2351  RAPIDJSON_ASSERT(IsArray());
2352  return Array(*this);
2353  }
2354  ConstArray GetArray() const
2355  {
2356  RAPIDJSON_ASSERT(IsArray());
2357  return ConstArray(*this);
2358  }
2359 
2361 
2363 
2364 
2365  int GetInt() const
2366  {
2367  RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);
2368  return data_.n.i.i;
2369  }
2370  unsigned GetUint() const
2371  {
2372  RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);
2373  return data_.n.u.u;
2374  }
2375  int64_t GetInt64() const
2376  {
2377  RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag);
2378  return data_.n.i64;
2379  }
2380  uint64_t GetUint64() const
2381  {
2382  RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag);
2383  return data_.n.u64;
2384  }
2385 
2387 
2390  double GetDouble() const
2391  {
2392  RAPIDJSON_ASSERT(IsNumber());
2393  if ((data_.f.flags & kDoubleFlag) != 0)
2394  return data_.n.d; // exact type, no conversion.
2395  if ((data_.f.flags & kIntFlag) != 0)
2396  return data_.n.i.i; // int -> double
2397  if ((data_.f.flags & kUintFlag) != 0)
2398  return data_.n.u.u; // unsigned -> double
2399  if ((data_.f.flags & kInt64Flag) != 0)
2400  return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
2401  RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);
2402  return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
2403  }
2404 
2406 
2409  float GetFloat() const
2410  {
2411  return static_cast<float>(GetDouble());
2412  }
2413 
2414  GenericValue& SetInt(int i)
2415  {
2416  this->~GenericValue();
2417  new (this) GenericValue(i);
2418  return *this;
2419  }
2420  GenericValue& SetUint(unsigned u)
2421  {
2422  this->~GenericValue();
2423  new (this) GenericValue(u);
2424  return *this;
2425  }
2426  GenericValue& SetInt64(int64_t i64)
2427  {
2428  this->~GenericValue();
2429  new (this) GenericValue(i64);
2430  return *this;
2431  }
2432  GenericValue& SetUint64(uint64_t u64)
2433  {
2434  this->~GenericValue();
2435  new (this) GenericValue(u64);
2436  return *this;
2437  }
2438  GenericValue& SetDouble(double d)
2439  {
2440  this->~GenericValue();
2441  new (this) GenericValue(d);
2442  return *this;
2443  }
2444  GenericValue& SetFloat(float f)
2445  {
2446  this->~GenericValue();
2447  new (this) GenericValue(static_cast<double>(f));
2448  return *this;
2449  }
2450 
2452 
2454 
2455 
2456  const Ch* GetString() const
2457  {
2458  RAPIDJSON_ASSERT(IsString());
2459  return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer();
2460  }
2461 
2463 
2465  SizeType GetStringLength() const
2466  {
2467  RAPIDJSON_ASSERT(IsString());
2468  return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length);
2469  }
2470 
2472 
2479  GenericValue& SetString(const Ch* s, SizeType length)
2480  {
2481  return SetString(StringRef(s, length));
2482  }
2483 
2485 
2489  GenericValue& SetString(StringRefType s)
2490  {
2491  this->~GenericValue();
2492  SetStringRaw(s);
2493  return *this;
2494  }
2495 
2497 
2504  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator)
2505  {
2506  return SetString(StringRef(s, length), allocator);
2507  }
2508 
2510 
2515  GenericValue& SetString(const Ch* s, Allocator& allocator)
2516  {
2517  return SetString(StringRef(s), allocator);
2518  }
2519 
2521 
2526  GenericValue& SetString(StringRefType s, Allocator& allocator)
2527  {
2528  this->~GenericValue();
2529  SetStringRaw(s, allocator);
2530  return *this;
2531  }
2532 
2533 #if RAPIDJSON_HAS_STDSTRING
2534 
2542  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator)
2543  {
2544  return SetString(StringRef(s), allocator);
2545  }
2546 #endif
2547 
2549 
2551 
2552 
2554 
2558  template <typename T>
2559  bool Is() const
2560  {
2562  }
2563 
2564  template <typename T>
2565  T Get() const
2566  {
2568  }
2569 
2570  template <typename T>
2571  T Get()
2572  {
2574  }
2575 
2576  template <typename T>
2577  ValueType& Set(const T& data)
2578  {
2579  return internal::TypeHelper<ValueType, T>::Set(*this, data);
2580  }
2581 
2582  template <typename T>
2583  ValueType& Set(const T& data, AllocatorType& allocator)
2584  {
2585  return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator);
2586  }
2587 
2589 
2591 
2597  template <typename Handler>
2598  bool Accept(Handler& handler) const
2599  {
2600  switch (GetType())
2601  {
2602  case kNullType:
2603  return handler.Null();
2604  case kFalseType:
2605  return handler.Bool(false);
2606  case kTrueType:
2607  return handler.Bool(true);
2608 
2609  case kObjectType:
2610  if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
2611  return false;
2612  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2613  {
2614  RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
2615  if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(),
2616  (m->name.data_.f.flags & kCopyFlag) != 0)))
2617  return false;
2618  if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
2619  return false;
2620  }
2621  return handler.EndObject(data_.o.size);
2622 
2623  case kArrayType:
2624  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
2625  return false;
2626  for (const GenericValue* v = Begin(); v != End(); ++v)
2627  if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
2628  return false;
2629  return handler.EndArray(data_.a.size);
2630 
2631  case kStringType:
2632  return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
2633 
2634  default:
2635  RAPIDJSON_ASSERT(GetType() == kNumberType);
2636  if (IsDouble())
2637  return handler.Double(data_.n.d);
2638  else if (IsInt())
2639  return handler.Int(data_.n.i.i);
2640  else if (IsUint())
2641  return handler.Uint(data_.n.u.u);
2642  else if (IsInt64())
2643  return handler.Int64(data_.n.i64);
2644  else
2645  return handler.Uint64(data_.n.u64);
2646  }
2647  }
2648 
2649 private:
2650  template <typename, typename>
2651  friend class GenericValue;
2652  template <typename, typename, typename>
2653  friend class GenericDocument;
2654 
2655  enum
2656  {
2657  kBoolFlag = 0x0008,
2658  kNumberFlag = 0x0010,
2659  kIntFlag = 0x0020,
2660  kUintFlag = 0x0040,
2661  kInt64Flag = 0x0080,
2662  kUint64Flag = 0x0100,
2663  kDoubleFlag = 0x0200,
2664  kStringFlag = 0x0400,
2665  kCopyFlag = 0x0800,
2666  kInlineStrFlag = 0x1000,
2667 
2668  // Initial flags of different types.
2683 
2684  kTypeMask = 0x07
2685  };
2686 
2687  static const SizeType kDefaultArrayCapacity = 16;
2689 
2690  struct Flag
2691  {
2692 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2693  char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
2694 #elif RAPIDJSON_64BIT
2695  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
2696 #else
2697  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
2698 #endif
2700  };
2701 
2702  struct String
2703  {
2706  const Ch* str;
2707  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2708 
2709  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
2710  // (excluding the terminating zero) and store a value to determine the length of the contained
2711  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
2712  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
2713  // the string terminator as well. For getting the string length back from that value just use
2714  // "MaxSize - str[LenPos]".
2715  // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2716  // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
2718  {
2719  enum
2720  {
2721  MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch),
2722  MaxSize = MaxChars - 1,
2723  LenPos = MaxSize
2724  };
2725  Ch str[MaxChars];
2726 
2727  inline static bool Usable(SizeType len)
2728  {
2729  return (MaxSize >= len);
2730  }
2731  inline void SetLength(SizeType len)
2732  {
2733  str[LenPos] = static_cast<Ch>(MaxSize - len);
2734  }
2735  inline SizeType GetLength() const
2736  {
2737  return static_cast<SizeType>(MaxSize - str[LenPos]);
2738  }
2739  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2740 
2741  // By using proper binary layout, retrieval of different integer types do not need conversions.
2742  union Number
2743  {
2744 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2745  struct I
2746  {
2747  int i;
2748  char padding[4];
2749  } i;
2750  struct U
2751  {
2752  unsigned u;
2753  char padding2[4];
2754  } u;
2755 #else
2756  struct I
2757  {
2758  char padding[4];
2759  int i;
2760  } i;
2761  struct U
2762  {
2763  char padding2[4];
2764  unsigned u;
2765  } u;
2766 #endif
2769  double d;
2770  }; // 8 bytes
2771 
2772  struct ObjectData
2773  {
2776  Member* members;
2777  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2778 
2779  struct ArrayData
2780  {
2784  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2785 
2786  union Data
2787  {
2794  }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2795 
2796  RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const
2797  {
2798  return RAPIDJSON_GETPOINTER(Ch, data_.s.str);
2799  }
2800  RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str)
2801  {
2802  return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str);
2803  }
2804  RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const
2805  {
2806  return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements);
2807  }
2808  RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements)
2809  {
2810  return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements);
2811  }
2812  RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const
2813  {
2814  return RAPIDJSON_GETPOINTER(Member, data_.o.members);
2815  }
2816  RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members)
2817  {
2818  return RAPIDJSON_SETPOINTER(Member, data_.o.members, members);
2819  }
2820 
2821  // Initialize this value as array with initial data, without calling destructor.
2822  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator)
2823  {
2824  data_.f.flags = kArrayFlag;
2825  if (count)
2826  {
2827  GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2828  SetElementsPointer(e);
2829  std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2830  }
2831  else
2832  SetElementsPointer(0);
2833  data_.a.size = data_.a.capacity = count;
2834  }
2835 
2837  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator)
2838  {
2839  data_.f.flags = kObjectFlag;
2840  if (count)
2841  {
2842  Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2843  SetMembersPointer(m);
2844  std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2845  }
2846  else
2847  SetMembersPointer(0);
2848  data_.o.size = data_.o.capacity = count;
2849  }
2850 
2852  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
2853  {
2854  data_.f.flags = kConstStringFlag;
2855  SetStringPointer(s);
2856  data_.s.length = s.length;
2857  }
2858 
2860  void SetStringRaw(StringRefType s, Allocator& allocator)
2861  {
2862  Ch* str = 0;
2863  if (ShortString::Usable(s.length))
2864  {
2865  data_.f.flags = kShortStringFlag;
2866  data_.ss.SetLength(s.length);
2867  str = data_.ss.str;
2868  }
2869  else
2870  {
2871  data_.f.flags = kCopyStringFlag;
2872  data_.s.length = s.length;
2873  str = static_cast<Ch*>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2874  SetStringPointer(str);
2875  }
2876  std::memcpy(str, s, s.length * sizeof(Ch));
2877  str[s.length] = '\0';
2878  }
2879 
2881  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT
2882  {
2883  data_ = rhs.data_;
2884  // data_.f.flags = rhs.data_.f.flags;
2885  rhs.data_.f.flags = kNullFlag;
2886  }
2887 
2888  template <typename SourceAllocator>
2890  {
2891  RAPIDJSON_ASSERT(IsString());
2892  RAPIDJSON_ASSERT(rhs.IsString());
2893 
2894  const SizeType len1 = GetStringLength();
2895  const SizeType len2 = rhs.GetStringLength();
2896  if (len1 != len2)
2897  {
2898  return false;
2899  }
2900 
2901  const Ch* const str1 = GetString();
2902  const Ch* const str2 = rhs.GetString();
2903  if (str1 == str2)
2904  {
2905  return true;
2906  } // fast path for constant string
2907 
2908  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2909  }
2910 
2911  Data data_;
2912 };
2913 
2916 
2918 // GenericDocument
2919 
2921 
2930 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
2931 class GenericDocument : public GenericValue<Encoding, Allocator>
2932 {
2933 public:
2934  typedef typename Encoding::Ch Ch;
2936  typedef Allocator AllocatorType;
2937 
2939 
2945  explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity,
2946  StackAllocator* stackAllocator = 0)
2947  : GenericValue<Encoding, Allocator>(type)
2948  , allocator_(allocator)
2949  , ownAllocator_(0)
2950  , stack_(stackAllocator, stackCapacity)
2951  , parseResult_()
2952  {
2953  if (!allocator_)
2954  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2955  }
2956 
2958 
2963  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity,
2964  StackAllocator* stackAllocator = 0)
2965  : allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2966  {
2967  if (!allocator_)
2968  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2969  }
2970 
2971 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2972  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2974  : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2975  allocator_(rhs.allocator_),
2976  ownAllocator_(rhs.ownAllocator_),
2977  stack_(std::move(rhs.stack_)),
2978  parseResult_(rhs.parseResult_)
2979  {
2980  rhs.allocator_ = 0;
2981  rhs.ownAllocator_ = 0;
2982  rhs.parseResult_ = ParseResult();
2983  }
2984 #endif
2985 
2987  {
2988  Destroy();
2989  }
2990 
2991 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2992  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2994  {
2995  // The cast to ValueType is necessary here, because otherwise it would
2996  // attempt to call GenericValue's templated assignment operator.
2997  ValueType::operator=(std::forward<ValueType>(rhs));
2998 
2999  // Calling the destructor here would prematurely call stack_'s destructor
3000  Destroy();
3001 
3002  allocator_ = rhs.allocator_;
3003  ownAllocator_ = rhs.ownAllocator_;
3004  stack_ = std::move(rhs.stack_);
3005  parseResult_ = rhs.parseResult_;
3006 
3007  rhs.allocator_ = 0;
3008  rhs.ownAllocator_ = 0;
3009  rhs.parseResult_ = ParseResult();
3010 
3011  return *this;
3012  }
3013 #endif
3014 
3016 
3021  GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT
3022  {
3023  ValueType::Swap(rhs);
3024  stack_.Swap(rhs.stack_);
3025  internal::Swap(allocator_, rhs.allocator_);
3026  internal::Swap(ownAllocator_, rhs.ownAllocator_);
3027  internal::Swap(parseResult_, rhs.parseResult_);
3028  return *this;
3029  }
3030 
3031  // Allow Swap with ValueType.
3032  // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
3033  using ValueType::Swap;
3034 
3036 
3047  friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT
3048  {
3049  a.Swap(b);
3050  }
3051 
3053 
3057  template <typename Generator>
3058  GenericDocument& Populate(Generator& g)
3059  {
3060  ClearStackOnExit scope(*this);
3061  if (g(*this))
3062  {
3063  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
3064  ValueType::operator=(*stack_.template Pop<ValueType>(1)); // Move value from stack to document
3065  }
3066  return *this;
3067  }
3068 
3071 
3073 
3079  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
3080  GenericDocument& ParseStream(InputStream& is)
3081  {
3082  GenericReader<SourceEncoding, Encoding, StackAllocator> reader(stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
3083  ClearStackOnExit scope(*this);
3084  parseResult_ = reader.template Parse<parseFlags>(is, *this);
3085  if (parseResult_)
3086  {
3087  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
3088  ValueType::operator=(*stack_.template Pop<ValueType>(1)); // Move value from stack to document
3089  }
3090  return *this;
3091  }
3092 
3094 
3099  template <unsigned parseFlags, typename InputStream>
3100  GenericDocument& ParseStream(InputStream& is)
3101  {
3102  return ParseStream<parseFlags, Encoding, InputStream>(is);
3103  }
3104 
3106 
3110  template <typename InputStream>
3111  GenericDocument& ParseStream(InputStream& is)
3112  {
3113  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
3114  }
3116 
3119 
3121 
3125  template <unsigned parseFlags>
3127  {
3129  return ParseStream<parseFlags | kParseInsituFlag>(s);
3130  }
3131 
3133 
3137  {
3138  return ParseInsitu<kParseDefaultFlags>(str);
3139  }
3141 
3144 
3146 
3150  template <unsigned parseFlags, typename SourceEncoding>
3151  GenericDocument& Parse(const typename SourceEncoding::Ch* str)
3152  {
3153  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
3155  return ParseStream<parseFlags, SourceEncoding>(s);
3156  }
3157 
3159 
3162  template <unsigned parseFlags>
3163  GenericDocument& Parse(const Ch* str)
3164  {
3165  return Parse<parseFlags, Encoding>(str);
3166  }
3167 
3169 
3171  GenericDocument& Parse(const Ch* str)
3172  {
3173  return Parse<kParseDefaultFlags>(str);
3174  }
3175 
3176  template <unsigned parseFlags, typename SourceEncoding>
3177  GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length)
3178  {
3179  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
3180  MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
3182  ParseStream<parseFlags, SourceEncoding>(is);
3183  return *this;
3184  }
3185 
3186  template <unsigned parseFlags>
3187  GenericDocument& Parse(const Ch* str, size_t length)
3188  {
3189  return Parse<parseFlags, Encoding>(str, length);
3190  }
3191 
3192  GenericDocument& Parse(const Ch* str, size_t length)
3193  {
3194  return Parse<kParseDefaultFlags>(str, length);
3195  }
3196 
3197 #if RAPIDJSON_HAS_STDSTRING
3198  template <unsigned parseFlags, typename SourceEncoding>
3199  GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str)
3200  {
3201  // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
3202  return Parse<parseFlags, SourceEncoding>(str.c_str());
3203  }
3204 
3205  template <unsigned parseFlags>
3206  GenericDocument& Parse(const std::basic_string<Ch>& str)
3207  {
3208  return Parse<parseFlags, Encoding>(str.c_str());
3209  }
3210 
3211  GenericDocument& Parse(const std::basic_string<Ch>& str)
3212  {
3213  return Parse<kParseDefaultFlags>(str);
3214  }
3215 #endif // RAPIDJSON_HAS_STDSTRING
3216 
3218 
3221 
3223  bool HasParseError() const
3224  {
3225  return parseResult_.IsError();
3226  }
3227 
3230  {
3231  return parseResult_.Code();
3232  }
3233 
3235  size_t GetErrorOffset() const
3236  {
3237  return parseResult_.Offset();
3238  }
3239 
3241 #ifndef __clang // -Wdocumentation
3242 
3251 #endif
3252  operator ParseResult() const
3253  {
3254  return parseResult_;
3255  }
3257 
3259  Allocator& GetAllocator()
3260  {
3261  RAPIDJSON_ASSERT(allocator_);
3262  return *allocator_;
3263  }
3264 
3266  size_t GetStackCapacity() const
3267  {
3268  return stack_.GetCapacity();
3269  }
3270 
3271 private:
3272  // clear stack on any exit from ParseStream, e.g. due to exception
3274  {
3275  explicit ClearStackOnExit(GenericDocument& d) : d_(d)
3276  {
3277  }
3279  {
3280  d_.ClearStack();
3281  }
3282 
3283  private:
3285  ClearStackOnExit& operator=(const ClearStackOnExit&);
3287  };
3288 
3289  // callers of the following private Handler functions
3290  // template <typename,typename,typename> friend class GenericReader; // for parsing
3291  template <typename, typename>
3292  friend class GenericValue; // for deep copying
3293 
3294 public:
3295  // Implementation of Handler
3296  bool Null()
3297  {
3298  new (stack_.template Push<ValueType>()) ValueType();
3299  return true;
3300  }
3301  bool Bool(bool b)
3302  {
3303  new (stack_.template Push<ValueType>()) ValueType(b);
3304  return true;
3305  }
3306  bool Int(int i)
3307  {
3308  new (stack_.template Push<ValueType>()) ValueType(i);
3309  return true;
3310  }
3311  bool Uint(unsigned i)
3312  {
3313  new (stack_.template Push<ValueType>()) ValueType(i);
3314  return true;
3315  }
3316  bool Int64(int64_t i)
3317  {
3318  new (stack_.template Push<ValueType>()) ValueType(i);
3319  return true;
3320  }
3322  {
3323  new (stack_.template Push<ValueType>()) ValueType(i);
3324  return true;
3325  }
3326  bool Double(double d)
3327  {
3328  new (stack_.template Push<ValueType>()) ValueType(d);
3329  return true;
3330  }
3331 
3332  bool RawNumber(const Ch* str, SizeType length, bool copy)
3333  {
3334  if (copy)
3335  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
3336  else
3337  new (stack_.template Push<ValueType>()) ValueType(str, length);
3338  return true;
3339  }
3340 
3341  bool String(const Ch* str, SizeType length, bool copy)
3342  {
3343  if (copy)
3344  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
3345  else
3346  new (stack_.template Push<ValueType>()) ValueType(str, length);
3347  return true;
3348  }
3349 
3351  {
3352  new (stack_.template Push<ValueType>()) ValueType(kObjectType);
3353  return true;
3354  }
3355 
3356  bool Key(const Ch* str, SizeType length, bool copy)
3357  {
3358  return String(str, length, copy);
3359  }
3360 
3361  bool EndObject(SizeType memberCount)
3362  {
3363  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
3364  stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
3365  return true;
3366  }
3367 
3368  bool StartArray()
3369  {
3370  new (stack_.template Push<ValueType>()) ValueType(kArrayType);
3371  return true;
3372  }
3373 
3374  bool EndArray(SizeType elementCount)
3375  {
3376  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
3377  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
3378  return true;
3379  }
3380 
3381 private:
3386 
3387  void ClearStack()
3388  {
3389  if (Allocator::kNeedFree)
3390  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2
3391  // GenericValue objects)
3392  (stack_.template Pop<ValueType>(1))->~ValueType();
3393  else
3394  stack_.Clear();
3395  stack_.ShrinkToFit();
3396  }
3397 
3398  void Destroy()
3399  {
3400  RAPIDJSON_DELETE(ownAllocator_);
3401  }
3402 
3403  static const size_t kDefaultStackCapacity = 1024;
3404  Allocator* allocator_;
3405  Allocator* ownAllocator_;
3408 };
3409 
3412 
3414 
3418 template <bool Const, typename ValueT>
3419 class GenericArray
3420 {
3421 public:
3424  typedef ValueT PlainType;
3426  typedef ValueType* ValueIterator; // This may be const or non-const iterator
3427  typedef const ValueT* ConstValueIterator;
3428  typedef typename ValueType::AllocatorType AllocatorType;
3429  typedef typename ValueType::StringRefType StringRefType;
3430 
3431  template <typename, typename>
3432  friend class GenericValue;
3433 
3434  GenericArray(const GenericArray& rhs) : value_(rhs.value_)
3435  {
3436  }
3438  {
3439  value_ = rhs.value_;
3440  return *this;
3441  }
3443  {
3444  }
3445 
3446  SizeType Size() const
3447  {
3448  return value_.Size();
3449  }
3451  {
3452  return value_.Capacity();
3453  }
3454  bool Empty() const
3455  {
3456  return value_.Empty();
3457  }
3458  void Clear() const
3459  {
3460  value_.Clear();
3461  }
3462  ValueType& operator[](SizeType index) const
3463  {
3464  return value_[index];
3465  }
3466  ValueIterator Begin() const
3467  {
3468  return value_.Begin();
3469  }
3470  ValueIterator End() const
3471  {
3472  return value_.End();
3473  }
3474  GenericArray Reserve(SizeType newCapacity, AllocatorType& allocator) const
3475  {
3476  value_.Reserve(newCapacity, allocator);
3477  return *this;
3478  }
3479  GenericArray PushBack(ValueType& value, AllocatorType& allocator) const
3480  {
3481  value_.PushBack(value, allocator);
3482  return *this;
3483  }
3484 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3485  GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const
3486  {
3487  value_.PushBack(value, allocator);
3488  return *this;
3489  }
3490 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
3491  GenericArray PushBack(StringRefType value, AllocatorType& allocator) const
3492  {
3493  value_.PushBack(value, allocator);
3494  return *this;
3495  }
3496  template <typename T>
3497  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >),
3498  (const GenericArray&))
3499  PushBack(T value, AllocatorType& allocator) const
3500  {
3501  value_.PushBack(value, allocator);
3502  return *this;
3503  }
3505  {
3506  value_.PopBack();
3507  return *this;
3508  }
3509  ValueIterator Erase(ConstValueIterator pos) const
3510  {
3511  return value_.Erase(pos);
3512  }
3513  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const
3514  {
3515  return value_.Erase(first, last);
3516  }
3517 
3518 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
3519  ValueIterator begin() const
3520  {
3521  return value_.Begin();
3522  }
3523  ValueIterator end() const
3524  {
3525  return value_.End();
3526  }
3527 #endif
3528 
3529 private:
3530  GenericArray();
3531  GenericArray(ValueType& value) : value_(value)
3532  {
3533  }
3534  ValueType& value_;
3535 };
3536 
3538 
3542 template <bool Const, typename ValueT>
3543 class GenericObject
3544 {
3545 public:
3548  typedef ValueT PlainType;
3551  MemberIterator; // This may be const or non-const iterator
3554  typedef typename ValueType::AllocatorType AllocatorType;
3555  typedef typename ValueType::StringRefType StringRefType;
3556  typedef typename ValueType::EncodingType EncodingType;
3557  typedef typename ValueType::Ch Ch;
3558 
3559  template <typename, typename>
3560  friend class GenericValue;
3561 
3562  GenericObject(const GenericObject& rhs) : value_(rhs.value_)
3563  {
3564  }
3566  {
3567  value_ = rhs.value_;
3568  return *this;
3569  }
3571  {
3572  }
3573 
3575  {
3576  return value_.MemberCount();
3577  }
3579  {
3580  return value_.MemberCapacity();
3581  }
3582  bool ObjectEmpty() const
3583  {
3584  return value_.ObjectEmpty();
3585  }
3586  template <typename T>
3587  ValueType& operator[](T* name) const
3588  {
3589  return value_[name];
3590  }
3591  template <typename SourceAllocator>
3593  {
3594  return value_[name];
3595  }
3596 #if RAPIDJSON_HAS_STDSTRING
3597  ValueType& operator[](const std::basic_string<Ch>& name) const
3598  {
3599  return value_[name];
3600  }
3601 #endif
3602  MemberIterator MemberBegin() const
3603  {
3604  return value_.MemberBegin();
3605  }
3606  MemberIterator MemberEnd() const
3607  {
3608  return value_.MemberEnd();
3609  }
3610  GenericObject MemberReserve(SizeType newCapacity, AllocatorType& allocator) const
3611  {
3612  value_.MemberReserve(newCapacity, allocator);
3613  return *this;
3614  }
3615  bool HasMember(const Ch* name) const
3616  {
3617  return value_.HasMember(name);
3618  }
3619 #if RAPIDJSON_HAS_STDSTRING
3620  bool HasMember(const std::basic_string<Ch>& name) const
3621  {
3622  return value_.HasMember(name);
3623  }
3624 #endif
3625  template <typename SourceAllocator>
3627  {
3628  return value_.HasMember(name);
3629  }
3630  MemberIterator FindMember(const Ch* name) const
3631  {
3632  return value_.FindMember(name);
3633  }
3634  template <typename SourceAllocator>
3636  {
3637  return value_.FindMember(name);
3638  }
3639 #if RAPIDJSON_HAS_STDSTRING
3640  MemberIterator FindMember(const std::basic_string<Ch>& name) const
3641  {
3642  return value_.FindMember(name);
3643  }
3644 #endif
3645  GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const
3646  {
3647  value_.AddMember(name, value, allocator);
3648  return *this;
3649  }
3650  GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const
3651  {
3652  value_.AddMember(name, value, allocator);
3653  return *this;
3654  }
3655 #if RAPIDJSON_HAS_STDSTRING
3656  GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const
3657  {
3658  value_.AddMember(name, value, allocator);
3659  return *this;
3660  }
3661 #endif
3662  template <typename T>
3663  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
3664  AddMember(ValueType& name, T value, AllocatorType& allocator) const
3665  {
3666  value_.AddMember(name, value, allocator);
3667  return *this;
3668  }
3669 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3670  GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const
3671  {
3672  value_.AddMember(name, value, allocator);
3673  return *this;
3674  }
3675  GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const
3676  {
3677  value_.AddMember(name, value, allocator);
3678  return *this;
3679  }
3680  GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const
3681  {
3682  value_.AddMember(name, value, allocator);
3683  return *this;
3684  }
3685  GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const
3686  {
3687  value_.AddMember(name, value, allocator);
3688  return *this;
3689  }
3690 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
3691  GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const
3692  {
3693  value_.AddMember(name, value, allocator);
3694  return *this;
3695  }
3696  GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const
3697  {
3698  value_.AddMember(name, value, allocator);
3699  return *this;
3700  }
3701  template <typename T>
3702  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject))
3703  AddMember(StringRefType name, T value, AllocatorType& allocator) const
3704  {
3705  value_.AddMember(name, value, allocator);
3706  return *this;
3707  }
3709  {
3710  value_.RemoveAllMembers();
3711  }
3712  bool RemoveMember(const Ch* name) const
3713  {
3714  return value_.RemoveMember(name);
3715  }
3716 #if RAPIDJSON_HAS_STDSTRING
3717  bool RemoveMember(const std::basic_string<Ch>& name) const
3718  {
3719  return value_.RemoveMember(name);
3720  }
3721 #endif
3722  template <typename SourceAllocator>
3724  {
3725  return value_.RemoveMember(name);
3726  }
3727  MemberIterator RemoveMember(MemberIterator m) const
3728  {
3729  return value_.RemoveMember(m);
3730  }
3731  MemberIterator EraseMember(ConstMemberIterator pos) const
3732  {
3733  return value_.EraseMember(pos);
3734  }
3735  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const
3736  {
3737  return value_.EraseMember(first, last);
3738  }
3739  bool EraseMember(const Ch* name) const
3740  {
3741  return value_.EraseMember(name);
3742  }
3743 #if RAPIDJSON_HAS_STDSTRING
3744  bool EraseMember(const std::basic_string<Ch>& name) const
3745  {
3746  return EraseMember(ValueType(StringRef(name)));
3747  }
3748 #endif
3749  template <typename SourceAllocator>
3751  {
3752  return value_.EraseMember(name);
3753  }
3754 
3755 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
3756  MemberIterator begin() const
3757  {
3758  return value_.MemberBegin();
3759  }
3760  MemberIterator end() const
3761  {
3762  return value_.MemberEnd();
3763  }
3764 #endif
3765 
3766 private:
3767  GenericObject();
3768  GenericObject(ValueType& value) : value_(value)
3769  {
3770  }
3771  ValueType& value_;
3772 };
3773 
3775 RAPIDJSON_DIAG_POP
3776 
3777 #endif // RAPIDJSON_DOCUMENT_H_
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:1013
bool RemoveMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:3723
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:142
void SetLength(SizeType len)
Definition: document.h:2731
ValueT PlainType
Definition: document.h:3548
d
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:1083
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:69
bool Empty() const
Definition: document.h:3454
void Clear() const
Definition: document.h:3458
RAPIDJSON_FORCEINLINE const Ch * GetStringPointer() const
Definition: document.h:2796
Iterator operator--(int)
Definition: document.h:189
SizeType NotNullStrLen(const CharType *str)
Definition: document.h:421
GenericObject(ValueType &value)
Definition: document.h:3768
bool EndArray(SizeType elementCount)
Definition: document.h:3374
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition: document.h:3425
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2936
SizeType GetLength() const
Definition: document.h:2735
GenericStringRef(const GenericStringRef &rhs)
Definition: document.h:407
GenericArray PushBack(StringRefType value, AllocatorType &allocator) const
Definition: document.h:3491
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2935
GenericObject AddMember(StringRefType name, ValueType &value, AllocatorType &allocator) const
Definition: document.h:3691
static ValueType & Set(ValueType &v, uint64_t data)
Definition: document.h:676
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:394
Represents an in-memory input byte stream.
Definition: memorystream.h:42
GenericObject AddMember(ValueType &name, ValueType &value, AllocatorType &allocator) const
Definition: document.h:3645
bool String(const Ch *str, SizeType length, bool copy)
Definition: document.h:3341
ValueType * pointer
Definition: document.h:125
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition: document.h:1122
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:416
reference Reference
Reference to (const) GenericMember.
Definition: document.h:134
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition: document.h:112
ValueType::EncodingType EncodingType
Definition: document.h:3556
static bool Is(const ValueType &v)
Definition: document.h:689
ClearStackOnExit(GenericDocument &d)
Definition: document.h:3275
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:294
GenericArray< true, ValueT > ConstArray
Definition: document.h:3422
object
Definition: rapidjson.h:671
static bool Get(const ValueType &v)
Definition: document.h:542
Pointer ptr_
raw pointer
Definition: document.h:276
f
Helper class for accessing Value of array type.
Definition: document.h:846
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:924
bool StringEqual(const GenericValue< Encoding, SourceAllocator > &rhs) const
Definition: document.h:2889
Read-only string stream.
Definition: fwd.h:56
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:3047
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition: document.h:1064
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:126
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:70
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:3058
(Constant) member iterator for a JSON object value
Definition: document.h:105
const Ch *const s
plain CharType pointer
Definition: document.h:417
array
Definition: rapidjson.h:672
static ValueType & Set(ValueType &v, ObjectType data)
Definition: document.h:818
GenericArray PopBack() const
Definition: document.h:3504
static ValueType & Set(ValueType &v, ArrayType data)
Definition: document.h:782
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:116
GenericMemberIterator(Pointer p)
Internal constructor from plain pointer.
Definition: document.h:272
ValueType & operator[](SizeType index) const
Definition: document.h:3462
RAPIDJSON_FORCEINLINE GenericValue * SetElementsPointer(GenericValue *elements)
Definition: document.h:2808
XmlRpcServer s
GenericDocument & Parse(const Ch *str, size_t length)
Definition: document.h:3192
GenericDocument & Parse(const Ch *str, size_t length)
Definition: document.h:3187
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2934
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:3100
ValueType::StringRefType StringRefType
Definition: document.h:3429
internal::Stack< StackAllocator > stack_
Definition: document.h:3406
MemberIterator MemberEnd() const
Definition: document.h:3606
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:54
bool Bool(bool b)
Definition: document.h:3301
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:465
GenericMember< Encoding, Allocator > PlainType
Definition: document.h:111
std::ptrdiff_t difference_type
Definition: document.h:127
static bool Is(const ValueType &v)
Definition: document.h:668
ValueIterator Erase(ConstValueIterator pos) const
Definition: document.h:3509
bool operator!=(ConstIterator that) const
Definition: document.h:226
bool ObjectEmpty() const
Definition: document.h:3582
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:3229
pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:132
unsigned short uint16_t
Definition: stdint.h:125
static ValueType & Set(ValueType &v, double data, typename ValueType::AllocatorType &)
Definition: document.h:701
GenericArray PushBack(ValueType &value, AllocatorType &allocator) const
Definition: document.h:3479
false
Definition: rapidjson.h:669
static bool Is(const ValueType &v)
Definition: document.h:538
static ValueType & Set(ValueType &v, bool data)
Definition: document.h:546
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:1089
bool EraseMember(const Ch *name) const
Definition: document.h:3739
difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:136
ValueType & operator[](T *name) const
Definition: document.h:3587
SizeType Capacity() const
Definition: document.h:3450
MemberIterator FindMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:3635
void SetArrayRaw(GenericValue *values, SizeType count, Allocator &allocator)
Definition: document.h:2822
MemberIterator MemberBegin() const
Definition: document.h:3602
static ValueType & Set(ValueType &v, ArrayType data, typename ValueType::AllocatorType &)
Definition: document.h:786
Result of parsing (wraps ParseErrorCode)
Definition: error.h:107
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:880
friend class GenericDocument
Definition: document.h:2653
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:869
bool operator<(ConstIterator that) const
Definition: document.h:238
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:3111
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition: rapidjson.h:640
Pointer operator->() const
Definition: document.h:254
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
static unsigned Get(const ValueType &v)
Definition: document.h:584
GenericArray(const GenericArray &rhs)
Definition: document.h:3434
bool StartObject()
Definition: document.h:3350
SizeType MemberCapacity() const
Definition: document.h:3578
ValueType::StringRefType StringRefType
Definition: document.h:3555
bool StartArray()
Definition: document.h:3368
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:868
A document for parsing JSON text as DOM.
Definition: document.h:57
bool HasMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:3626
void RemoveAllMembers()
Definition: document.h:3708
static bool Is(const ValueType &v)
Definition: document.h:559
ShortString ss
Definition: document.h:2789
A read-write string stream.
Definition: fwd.h:61
GenericArray & operator=(const GenericArray &rhs)
Definition: document.h:3437
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:1027
bool operator==(ConstIterator that) const
Definition: document.h:222
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:118
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Definition: document.h:873
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:1071
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2945
static ValueType & Set(ValueType &v, double data)
Definition: document.h:697
Iterator & operator--()
Definition: document.h:178
bool HasMember(const Ch *name) const
Definition: document.h:3615
GenericMemberIterator< true, typename ValueT::EncodingType, typename ValueT::AllocatorType > ConstMemberIterator
Definition: document.h:3553
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:870
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:649
ValueT PlainType
Definition: document.h:3424
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2963
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:1001
Reference operator[](DifferenceType n) const
Definition: document.h:258
bool EndObject(SizeType memberCount)
Definition: document.h:3361
ObjectData o
Definition: document.h:2791
string
Definition: rapidjson.h:673
Allocator * ownAllocator_
Definition: document.h:3405
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:97
GenericArray(ValueType &value)
Definition: document.h:3531
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:871
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:389
ParseResult parseResult_
Definition: document.h:3407
static ValueType & Set(ValueType &v, ObjectType data, typename ValueType::AllocatorType &)
Definition: document.h:822
static bool Is(const ValueType &v)
Definition: document.h:647
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2915
bool Double(double d)
Definition: document.h:3326
static ValueType & Set(ValueType &v, float data, typename ValueType::AllocatorType &)
Definition: document.h:722
ParseErrorCode
Error code of parsing.
Definition: error.h:64
bool RawNumber(const Ch *str, SizeType length, bool copy)
Definition: document.h:3332
GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const
Definition: document.h:3610
RAPIDJSON_FORCEINLINE GenericValue * GetElementsPointer() const
Definition: document.h:2804
Helper class for accessing Value of object type.
Definition: document.h:848
GenericObject< true, ValueT > ConstObject
Definition: document.h:3546
static ValueType & Set(ValueType &v, float data)
Definition: document.h:718
Iterator & operator++()
Definition: document.h:173
RAPIDJSON_FORCEINLINE const Ch * SetStringPointer(const Ch *str)
Definition: document.h:2800
bool operator<=(ConstIterator that) const
Definition: document.h:230
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:3126
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:364
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:872
bool Int(int i)
Definition: document.h:3306
GenericObject(const GenericObject &rhs)
Definition: document.h:3562
unsigned __int64 uint64_t
Definition: stdint.h:136
ValueType::AllocatorType AllocatorType
Definition: document.h:3554
bool operator>(ConstIterator that) const
Definition: document.h:242
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:3259
static bool Usable(SizeType len)
Definition: document.h:2727
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:3411
Iterator operator++(int)
Definition: document.h:183
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
GenericArray< false, ValueType > Array
Definition: document.h:882
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:881
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:418
number
Definition: rapidjson.h:674
friend void swap(GenericMember &a, GenericMember &b) RAPIDJSON_NOEXCEPT
Definition: document.h:73
const ValueT * ConstValueIterator
Definition: document.h:3427
ValueIterator Begin() const
Definition: document.h:3466
Name-value pair in a JSON object value.
Definition: document.h:67
bool Int64(int64_t i)
Definition: document.h:3316
ValueType * ValueIterator
Definition: document.h:3426
SizeType hashcode
reserved
Definition: document.h:2705
Iterator & operator+=(DifferenceType n)
Definition: document.h:208
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
GenericArray< true, ValueType > ConstArray
Definition: document.h:883
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:653
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:3151
ValueIterator End() const
Definition: document.h:3470
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition: document.h:3549
static ValueType & Set(ValueType &v, unsigned data)
Definition: document.h:588
~GenericValue()
Destructor.
Definition: document.h:1131
static int Get(const ValueType &v)
Definition: document.h:563
GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType &allocator) const
Definition: document.h:3696
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:3136
GenericObject< false, ValueT > Object
Definition: document.h:3547
SizeType MemberCount() const
Definition: document.h:3574
#define RAPIDJSON_SETPOINTER(type, p, x)
Definition: rapidjson.h:329
static ValueType & Set(ValueType &v, unsigned data, typename ValueType::AllocatorType &)
Definition: document.h:592
MemberIterator FindMember(const Ch *name) const
Definition: document.h:3630
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:2837
CharType Ch
character type of the string
Definition: document.h:336
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:482
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:265
static bool Is(const ValueType &v)
Definition: document.h:710
RAPIDJSON_FORCEINLINE Member * SetMembersPointer(Member *members)
Definition: document.h:2816
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1422
MemberIterator RemoveMember(MemberIterator m) const
Definition: document.h:3727
std::random_access_iterator_tag iterator_category
Definition: document.h:128
RAPIDJSON_FORCEINLINE Member * GetMembersPointer() const
Definition: document.h:2812
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:454
Reference operator*() const
Definition: document.h:250
Iterator & operator=(const NonConstIterator &it)
Definition: document.h:165
MemberIterator EraseMember(ConstMemberIterator pos) const
Definition: document.h:3731
ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const
Definition: document.h:3513
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:2860
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:3235
bool operator>=(ConstIterator that) const
Definition: document.h:234
GenericDocument & Parse(const typename SourceEncoding::Ch *str, size_t length)
Definition: document.h:3177
static int64_t Get(const ValueType &v)
Definition: document.h:651
ValueType::AllocatorType AllocatorType
Definition: document.h:3428
GenericObject< true, ValueType > ConstObject
Definition: document.h:885
signed __int64 int64_t
Definition: stdint.h:135
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:2852
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:1020
static ValueType & Set(ValueType &v, int64_t data)
Definition: document.h:655
#define RAPIDJSON_GETPOINTER(type, p)
Definition: rapidjson.h:330
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:1044
Iterator operator-(DifferenceType n) const
Definition: document.h:203
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:1077
static const SizeType kDefaultObjectCapacity
Definition: document.h:2688
GenericObject< false, ValueType > Object
Definition: document.h:884
bool Uint64(uint64_t i)
Definition: document.h:3321
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:3163
true
Definition: rapidjson.h:670
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:120
static const SizeType kDefaultArrayCapacity
Definition: document.h:2687
GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const
Definition: document.h:3474
ValueType::Ch Ch
Definition: document.h:3557
static float Get(const ValueType &v)
Definition: document.h:714
bool Uint(unsigned i)
Definition: document.h:3311
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:31
static ValueType & Set(ValueType &v, const StringType data)
Definition: document.h:740
Reference to a constant string (not taking a copy)
Definition: document.h:334
void ClearStack()
Definition: document.h:3387
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:162
static ValueType & Set(ValueType &v, int data)
Definition: document.h:567
bool EraseMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:3750
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:891
static double Get(const ValueType &v)
Definition: document.h:693
Iterator operator+(DifferenceType n) const
Definition: document.h:199
ValueType & operator[](const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:3592
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:1057
ValueType & reference
Definition: document.h:126
SizeType Size() const
Definition: document.h:3446
Allocator * allocator_
Definition: document.h:3404
GenericArray< false, ValueT > Array
Definition: document.h:3423
bool RemoveMember(const Ch *name) const
Definition: document.h:3712
Type
Type of JSON value.
Definition: rapidjson.h:666
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:1193
ValueType & value_
Definition: document.h:3771
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:3171
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:402
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:2881
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:495
GenericObject & operator=(const GenericObject &rhs)
Definition: document.h:3565
MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const
Definition: document.h:3735
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:3021
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T2 >, internal::IsGenericValue< T2 > >),(typename T::ValueType &)) GetValueByPointerWithDefault(T &root
static ValueType & Set(ValueType &v, uint64_t data, typename ValueType::AllocatorType &)
Definition: document.h:680
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:3266
ValueType & value_
Definition: document.h:3534
GenericObject AddMember(ValueType &name, StringRefType value, AllocatorType &allocator) const
Definition: document.h:3650
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator)
Definition: document.h:946
GenericValue * elements
Definition: document.h:2783
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:1170
static ValueType & Set(ValueType &v, int data, typename ValueType::AllocatorType &)
Definition: document.h:571
static ValueType & Set(ValueType &v, int64_t data, typename ValueType::AllocatorType &)
Definition: document.h:659
In-situ(destructive) parsing.
Definition: reader.h:150
static bool Is(const ValueType &v)
Definition: document.h:580
void Destroy()
Definition: document.h:3398
Iterator & operator-=(DifferenceType n)
Definition: document.h:213
static uint64_t Get(const ValueType &v)
Definition: document.h:672
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: document.h:3223
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:3080
static ValueType & Set(ValueType &v, const StringType data, typename ValueType::AllocatorType &a)
Definition: document.h:744
null
Definition: rapidjson.h:668
ValueType value_type
Definition: document.h:124
GenericMemberIterator< Const, typename ValueT::EncodingType, typename ValueT::AllocatorType > MemberIterator
Definition: document.h:3551
static ValueType & Set(ValueType &v, bool data, typename ValueType::AllocatorType &)
Definition: document.h:550
bool Key(const Ch *str, SizeType length, bool copy)
Definition: document.h:3356
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition: document.h:1110


xbot_talker
Author(s): wangxiaoyun
autogenerated on Sat Oct 10 2020 03:27:53