identt
document.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef RAPIDJSON_DOCUMENT_H_
16 #define RAPIDJSON_DOCUMENT_H_
17 
20 #include "reader.h"
21 #include "internal/meta.h"
22 #include "internal/strfunc.h"
23 #include "memorystream.h"
24 #include "encodedstream.h"
25 #include <new> // placement new
26 #include <limits>
27 
28 RAPIDJSON_DIAG_PUSH
29 #ifdef _MSC_VER
30 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
31 RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
32 #ifdef _MINWINDEF_ // see: http://stackoverflow.com/questions/22744262/cant-call-stdmax-because-minwindef-h-defines-max
33 #ifndef NOMINMAX
34 #pragma push_macro("min")
35 #pragma push_macro("max")
36 #undef min
37 #undef max
38 #endif
39 #endif
40 #endif
41 
42 #ifdef __clang__
43 RAPIDJSON_DIAG_OFF(padded)
44 RAPIDJSON_DIAG_OFF(switch-enum)
45 RAPIDJSON_DIAG_OFF(c++98-compat)
46 #endif
47 
48 #ifdef __GNUC__
49 RAPIDJSON_DIAG_OFF(effc++)
50 #if __GNUC__ >= 6
51 RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions
52 #endif
53 #endif // __GNUC__
54 
55 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
56 #include <iterator> // std::iterator, std::random_access_iterator_tag
57 #endif
58 
59 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
60 #include <utility> // std::move
61 #endif
62 
64 
65 // Forward declaration.
66 template <typename Encoding, typename Allocator>
68 
69 template <typename Encoding, typename Allocator, typename StackAllocator>
71 
73 
78 template <typename Encoding, typename Allocator>
79 struct GenericMember {
82 };
83 
85 // GenericMemberIterator
86 
87 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
88 
90 
108 template <bool Const, typename Encoding, typename Allocator>
110  : public std::iterator<std::random_access_iterator_tag
111  , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
112 
113  friend class GenericValue<Encoding,Allocator>;
114  template <bool, typename, typename> friend class GenericMemberIterator;
115 
117  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
118  typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
119 
120 public:
127 
129  typedef typename BaseType::pointer Pointer;
131  typedef typename BaseType::reference Reference;
133  typedef typename BaseType::difference_type DifferenceType;
134 
136 
139  GenericMemberIterator() : ptr_() {}
140 
142 
157  GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
158  Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
159 
161 
162  Iterator& operator++(){ ++ptr_; return *this; }
163  Iterator& operator--(){ --ptr_; return *this; }
164  Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
165  Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
167 
169 
170  Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
171  Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
172 
173  Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
174  Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
176 
178 
179  bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
180  bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
181  bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
182  bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
183  bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
184  bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
186 
188 
189  Reference operator*() const { return *ptr_; }
190  Pointer operator->() const { return ptr_; }
191  Reference operator[](DifferenceType n) const { return ptr_[n]; }
193 
195  DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
196 
197 private:
199  explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
200 
201  Pointer ptr_;
202 };
203 
204 #else // RAPIDJSON_NOMEMBERITERATORCLASS
205 
206 // class-based member iterator implementation disabled, use plain pointers
207 
208 template <bool Const, typename Encoding, typename Allocator>
209 struct GenericMemberIterator;
210 
212 template <typename Encoding, typename Allocator>
213 struct GenericMemberIterator<false,Encoding,Allocator> {
216 };
218 template <typename Encoding, typename Allocator>
219 struct GenericMemberIterator<true,Encoding,Allocator> {
222 };
223 
224 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
225 
227 // GenericStringRef
228 
230 
256 template<typename CharType>
258  typedef CharType Ch;
259 
261 #ifndef __clang__ // -Wdocumentation
262 
284 #endif
285  template<SizeType N>
286  GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
287  : s(str), length(N-1) {}
288 
290 #ifndef __clang__ // -Wdocumentation
291 
309 #endif
310  explicit GenericStringRef(const CharType* str)
311  : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); }
312 
314 #ifndef __clang__ // -Wdocumentation
315 
321 #endif
322  GenericStringRef(const CharType* str, SizeType len)
323  : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); }
324 
325  GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
326 
328  operator const Ch *() const { return s; }
329 
330  const Ch* const s;
331  const SizeType length;
332 
333 private:
335  template<SizeType N>
336  GenericStringRef(CharType (&str)[N]) /* = delete */;
338  GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
339 };
340 
342 
353 template<typename CharType>
354 inline GenericStringRef<CharType> StringRef(const CharType* str) {
355  return GenericStringRef<CharType>(str, internal::StrLen(str));
356 }
357 
359 
373 template<typename CharType>
374 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
375  return GenericStringRef<CharType>(str, SizeType(length));
376 }
377 
378 #if RAPIDJSON_HAS_STDSTRING
379 
391 template<typename CharType>
392 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
393  return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
394 }
395 #endif
396 
398 // GenericValue type traits
399 namespace internal {
400 
401 template <typename T, typename Encoding = void, typename Allocator = void>
402 struct IsGenericValueImpl : FalseType {};
403 
404 // select candidates according to nested encoding and allocator types
405 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
406  : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
407 
408 // helper to match arbitrary GenericValue instantiations, including derived classes
409 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
410 
411 } // namespace internal
412 
414 // TypeHelper
415 
416 namespace internal {
417 
418 template <typename ValueType, typename T>
419 struct TypeHelper {};
420 
421 template<typename ValueType>
422 struct TypeHelper<ValueType, bool> {
423  static bool Is(const ValueType& v) { return v.IsBool(); }
424  static bool Get(const ValueType& v) { return v.GetBool(); }
425  static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
426  static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
427 };
428 
429 template<typename ValueType>
430 struct TypeHelper<ValueType, int> {
431  static bool Is(const ValueType& v) { return v.IsInt(); }
432  static int Get(const ValueType& v) { return v.GetInt(); }
433  static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
434  static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
435 };
436 
437 template<typename ValueType>
438 struct TypeHelper<ValueType, unsigned> {
439  static bool Is(const ValueType& v) { return v.IsUint(); }
440  static unsigned Get(const ValueType& v) { return v.GetUint(); }
441  static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
442  static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
443 };
444 
445 template<typename ValueType>
446 struct TypeHelper<ValueType, int64_t> {
447  static bool Is(const ValueType& v) { return v.IsInt64(); }
448  static int64_t Get(const ValueType& v) { return v.GetInt64(); }
449  static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
450  static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
451 };
452 
453 template<typename ValueType>
454 struct TypeHelper<ValueType, uint64_t> {
455  static bool Is(const ValueType& v) { return v.IsUint64(); }
456  static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
457  static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
458  static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
459 };
460 
461 template<typename ValueType>
462 struct TypeHelper<ValueType, double> {
463  static bool Is(const ValueType& v) { return v.IsDouble(); }
464  static double Get(const ValueType& v) { return v.GetDouble(); }
465  static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
466  static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
467 };
468 
469 template<typename ValueType>
470 struct TypeHelper<ValueType, float> {
471  static bool Is(const ValueType& v) { return v.IsFloat(); }
472  static float Get(const ValueType& v) { return v.GetFloat(); }
473  static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
474  static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
475 };
476 
477 template<typename ValueType>
478 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
479  typedef const typename ValueType::Ch* StringType;
480  static bool Is(const ValueType& v) { return v.IsString(); }
481  static StringType Get(const ValueType& v) { return v.GetString(); }
482  static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
483  static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
484 };
485 
486 #if RAPIDJSON_HAS_STDSTRING
487 template<typename ValueType>
488 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
489  typedef std::basic_string<typename ValueType::Ch> StringType;
490  static bool Is(const ValueType& v) { return v.IsString(); }
491  static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
492  static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
493 };
494 #endif
495 
496 template<typename ValueType>
497 struct TypeHelper<ValueType, typename ValueType::Array> {
498  typedef typename ValueType::Array ArrayType;
499  static bool Is(const ValueType& v) { return v.IsArray(); }
500  static ArrayType Get(ValueType& v) { return v.GetArray(); }
501  static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
502  static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
503 };
504 
505 template<typename ValueType>
506 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
507  typedef typename ValueType::ConstArray ArrayType;
508  static bool Is(const ValueType& v) { return v.IsArray(); }
509  static ArrayType Get(const ValueType& v) { return v.GetArray(); }
510 };
511 
512 template<typename ValueType>
513 struct TypeHelper<ValueType, typename ValueType::Object> {
514  typedef typename ValueType::Object ObjectType;
515  static bool Is(const ValueType& v) { return v.IsObject(); }
516  static ObjectType Get(ValueType& v) { return v.GetObject(); }
517  static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
518  static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; }
519 };
520 
521 template<typename ValueType>
522 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
523  typedef typename ValueType::ConstObject ObjectType;
524  static bool Is(const ValueType& v) { return v.IsObject(); }
525  static ObjectType Get(const ValueType& v) { return v.GetObject(); }
526 };
527 
528 } // namespace internal
529 
530 // Forward declarations
531 template <bool, typename> class GenericArray;
532 template <bool, typename> class GenericObject;
533 
535 // GenericValue
536 
538 
547 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
548 class GenericValue {
549 public:
552  typedef Encoding EncodingType;
553  typedef Allocator AllocatorType;
554  typedef typename Encoding::Ch Ch;
565 
567 
568 
570  GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
571 
572 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
573  GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
575  rhs.data_.f.flags = kNullFlag; // give up contents
576  }
577 #endif
578 
579 private:
581  GenericValue(const GenericValue& rhs);
582 
583 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
584  template <typename StackAllocator>
587 
589  template <typename StackAllocator>
591 #endif
592 
593 public:
594 
596 
600  explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
601  static const uint16_t defaultFlags[7] = {
602  kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
603  kNumberAnyFlag
604  };
605  RAPIDJSON_ASSERT(type <= kNumberType);
606  data_.f.flags = defaultFlags[type];
607 
608  // Use ShortString to store empty string.
609  if (type == kStringType)
610  data_.ss.SetLength(0);
611  }
612 
614 
620  template <typename SourceAllocator>
621  GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) {
622  switch (rhs.GetType()) {
623  case kObjectType: {
624  SizeType count = rhs.data_.o.size;
625  Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
626  const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
627  for (SizeType i = 0; i < count; i++) {
628  new (&lm[i].name) GenericValue(rm[i].name, allocator);
629  new (&lm[i].value) GenericValue(rm[i].value, allocator);
630  }
631  data_.f.flags = kObjectFlag;
632  data_.o.size = data_.o.capacity = count;
633  SetMembersPointer(lm);
634  }
635  break;
636  case kArrayType: {
637  SizeType count = rhs.data_.a.size;
638  GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
639  const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
640  for (SizeType i = 0; i < count; i++)
641  new (&le[i]) GenericValue(re[i], allocator);
642  data_.f.flags = kArrayFlag;
643  data_.a.size = data_.a.capacity = count;
644  SetElementsPointer(le);
645  }
646  break;
647  case kStringType:
648  if (rhs.data_.f.flags == kConstStringFlag) {
649  data_.f.flags = rhs.data_.f.flags;
650  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
651  }
652  else
653  SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
654  break;
655  default:
656  data_.f.flags = rhs.data_.f.flags;
657  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
658  break;
659  }
660  }
661 
663 
668 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
669  template <typename T>
670  explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
671 #else
672  explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
673 #endif
674  : data_() {
675  // safe-guard against failing SFINAE
677  data_.f.flags = b ? kTrueFlag : kFalseFlag;
678  }
679 
681  explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
682  data_.n.i64 = i;
683  data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
684  }
685 
687  explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
688  data_.n.u64 = u;
689  data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
690  }
691 
693  explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
694  data_.n.i64 = i64;
695  data_.f.flags = kNumberInt64Flag;
696  if (i64 >= 0) {
697  data_.f.flags |= kNumberUint64Flag;
698  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
699  data_.f.flags |= kUintFlag;
700  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
701  data_.f.flags |= kIntFlag;
702  }
703  else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
704  data_.f.flags |= kIntFlag;
705  }
706 
708  explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
709  data_.n.u64 = u64;
710  data_.f.flags = kNumberUint64Flag;
711  if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
712  data_.f.flags |= kInt64Flag;
713  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
714  data_.f.flags |= kUintFlag;
715  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
716  data_.f.flags |= kIntFlag;
717  }
718 
720  explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
721 
723  explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
724 
726  GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
727 
729  explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
730 
732  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
733 
735  GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
736 
737 #if RAPIDJSON_HAS_STDSTRING
738 
741  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
742 #endif
743 
745 
750  GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
751  a.value_.data_ = Data();
752  a.value_.data_.f.flags = kArrayFlag;
753  }
754 
756 
761  GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
762  o.value_.data_ = Data();
763  o.value_.data_.f.flags = kObjectFlag;
764  }
765 
767 
770  if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
771  switch(data_.f.flags) {
772  case kArrayFlag:
773  {
774  GenericValue* e = GetElementsPointer();
775  for (GenericValue* v = e; v != e + data_.a.size; ++v)
776  v->~GenericValue();
777  Allocator::Free(e);
778  }
779  break;
780 
781  case kObjectFlag:
782  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
783  m->~Member();
784  Allocator::Free(GetMembersPointer());
785  break;
786 
787  case kCopyStringFlag:
788  Allocator::Free(const_cast<Ch*>(GetStringPointer()));
789  break;
790 
791  default:
792  break; // Do nothing for other types.
793  }
794  }
795  }
796 
798 
800 
801 
803 
805  GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
806  RAPIDJSON_ASSERT(this != &rhs);
807  this->~GenericValue();
808  RawAssign(rhs);
809  return *this;
810  }
811 
812 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
813  GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
815  return *this = rhs.Move();
816  }
817 #endif
818 
820 
824  GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
825  GenericValue s(str);
826  return *this = s;
827  }
828 
830 
841  template <typename T>
842  RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
843  operator=(T value) {
844  GenericValue v(value);
845  return *this = v;
846  }
847 
849 
854  template <typename SourceAllocator>
855  GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) {
856  RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
857  this->~GenericValue();
858  new (this) GenericValue(rhs, allocator);
859  return *this;
860  }
861 
863 
867  GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
868  GenericValue temp;
869  temp.RawAssign(*this);
870  RawAssign(other);
871  other.RawAssign(temp);
872  return *this;
873  }
874 
876 
887  friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
888 
890 
891  GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
893 
895 
896 
901  template <typename SourceAllocator>
902  bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
904  if (GetType() != rhs.GetType())
905  return false;
906 
907  switch (GetType()) {
908  case kObjectType: // Warning: O(n^2) inner-loop
909  if (data_.o.size != rhs.data_.o.size)
910  return false;
911  for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
912  typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
913  if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
914  return false;
915  }
916  return true;
917 
918  case kArrayType:
919  if (data_.a.size != rhs.data_.a.size)
920  return false;
921  for (SizeType i = 0; i < data_.a.size; i++)
922  if ((*this)[i] != rhs[i])
923  return false;
924  return true;
925 
926  case kStringType:
927  return StringEqual(rhs);
928 
929  case kNumberType:
930  if (IsDouble() || rhs.IsDouble()) {
931  double a = GetDouble(); // May convert from integer to double.
932  double b = rhs.GetDouble(); // Ditto
933  return a >= b && a <= b; // Prevent -Wfloat-equal
934  }
935  else
936  return data_.n.u64 == rhs.data_.n.u64;
937 
938  default:
939  return true;
940  }
941  }
942 
944  bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
945 
946 #if RAPIDJSON_HAS_STDSTRING
947 
950  bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
951 #endif
952 
954 
956  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
957 
959 
961  template <typename SourceAllocator>
962  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
963 
965  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
966 
968 
970  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
971 
973 
975  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
976 
978 
980  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
982 
984 
985 
986  Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
987  bool IsNull() const { return data_.f.flags == kNullFlag; }
988  bool IsFalse() const { return data_.f.flags == kFalseFlag; }
989  bool IsTrue() const { return data_.f.flags == kTrueFlag; }
990  bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
991  bool IsObject() const { return data_.f.flags == kObjectFlag; }
992  bool IsArray() const { return data_.f.flags == kArrayFlag; }
993  bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
994  bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
995  bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
996  bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
997  bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
998  bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
999  bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1000 
1001  // Checks whether a number can be losslessly converted to a double.
1002  bool IsLosslessDouble() const {
1003  if (!IsNumber()) return false;
1004  if (IsUint64()) {
1005  uint64_t u = GetUint64();
1006  volatile double d = static_cast<double>(u);
1007  return (d >= 0.0)
1008  && (d < static_cast<double>(std::numeric_limits<uint64_t>::max()))
1009  && (u == static_cast<uint64_t>(d));
1010  }
1011  if (IsInt64()) {
1012  int64_t i = GetInt64();
1013  volatile double d = static_cast<double>(i);
1014  return (d >= static_cast<double>(std::numeric_limits<int64_t>::min()))
1015  && (d < static_cast<double>(std::numeric_limits<int64_t>::max()))
1016  && (i == static_cast<int64_t>(d));
1017  }
1018  return true; // double, int, uint are always lossless
1019  }
1020 
1021  // Checks whether a number is a float (possible lossy).
1022  bool IsFloat() const {
1023  if ((data_.f.flags & kDoubleFlag) == 0)
1024  return false;
1025  double d = GetDouble();
1026  return d >= -3.4028234e38 && d <= 3.4028234e38;
1027  }
1028  // Checks whether a number can be losslessly converted to a float.
1029  bool IsLosslessFloat() const {
1030  if (!IsNumber()) return false;
1031  double a = GetDouble();
1032  if (a < static_cast<double>(-std::numeric_limits<float>::max())
1033  || a > static_cast<double>(std::numeric_limits<float>::max()))
1034  return false;
1035  double b = static_cast<double>(static_cast<float>(a));
1036  return a >= b && a <= b; // Prevent -Wfloat-equal
1037  }
1038 
1040 
1042 
1043 
1044  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1045 
1047 
1049 
1050 
1051  bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1053 
1054  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1055 
1057 
1059 
1060 
1062 
1063  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1064 
1066  SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1067 
1069  bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1070 
1072 
1080  template <typename T>
1081  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1082  GenericValue n(StringRef(name));
1083  return (*this)[n];
1084  }
1085  template <typename T>
1086  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }
1087 
1089 
1097  template <typename SourceAllocator>
1098  GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1099  MemberIterator member = FindMember(name);
1100  if (member != MemberEnd())
1101  return member->value;
1102  else {
1103  RAPIDJSON_ASSERT(false); // see above note
1104 
1105  // This will generate -Wexit-time-destructors in clang
1106  // static GenericValue NullValue;
1107  // return NullValue;
1108 
1109  // Use static buffer and placement-new to prevent destruction
1110  static char buffer[sizeof(GenericValue)];
1111  return *new (buffer) GenericValue();
1112  }
1113  }
1114  template <typename SourceAllocator>
1115  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1116 
1117 #if RAPIDJSON_HAS_STDSTRING
1118  GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1120  const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1121 #endif
1122 
1124 
1125  ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1127 
1128  ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1130 
1131  MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1133 
1134  MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1135 
1137 
1144  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1145 
1146 #if RAPIDJSON_HAS_STDSTRING
1147 
1155  bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1156 #endif
1157 
1159 
1167  template <typename SourceAllocator>
1168  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1169 
1171 
1182  MemberIterator FindMember(const Ch* name) {
1183  GenericValue n(StringRef(name));
1184  return FindMember(n);
1185  }
1186 
1187  ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1188 
1190 
1202  template <typename SourceAllocator>
1203  MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
1204  RAPIDJSON_ASSERT(IsObject());
1205  RAPIDJSON_ASSERT(name.IsString());
1206  MemberIterator member = MemberBegin();
1207  for ( ; member != MemberEnd(); ++member)
1208  if (name.StringEqual(member->name))
1209  break;
1210  return member;
1211  }
1212  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1213 
1214 #if RAPIDJSON_HAS_STDSTRING
1215 
1222  MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1223  ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1224 #endif
1225 
1227 
1236  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1237  RAPIDJSON_ASSERT(IsObject());
1238  RAPIDJSON_ASSERT(name.IsString());
1239 
1240  ObjectData& o = data_.o;
1241  if (o.size >= o.capacity) {
1242  if (o.capacity == 0) {
1243  o.capacity = kDefaultObjectCapacity;
1244  SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))));
1245  }
1246  else {
1247  SizeType oldCapacity = o.capacity;
1248  o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
1249  SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member))));
1250  }
1251  }
1252  Member* members = GetMembersPointer();
1253  members[o.size].name.RawAssign(name);
1254  members[o.size].value.RawAssign(value);
1255  o.size++;
1256  return *this;
1257  }
1258 
1260 
1268  GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1269  GenericValue v(value);
1270  return AddMember(name, v, allocator);
1271  }
1272 
1273 #if RAPIDJSON_HAS_STDSTRING
1274 
1283  GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1284  GenericValue v(value, allocator);
1285  return AddMember(name, v, allocator);
1286  }
1287 #endif
1288 
1290 
1306  template <typename T>
1307  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1308  AddMember(GenericValue& name, T value, Allocator& allocator) {
1309  GenericValue v(value);
1310  return AddMember(name, v, allocator);
1311  }
1312 
1313 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1314  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1315  return AddMember(name, value, allocator);
1316  }
1317  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1318  return AddMember(name, value, allocator);
1319  }
1320  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1321  return AddMember(name, value, allocator);
1322  }
1323  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1324  GenericValue n(name);
1325  return AddMember(n, value, allocator);
1326  }
1327 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1328 
1329 
1331 
1340  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1341  GenericValue n(name);
1342  return AddMember(n, value, allocator);
1343  }
1344 
1346 
1354  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1355  GenericValue v(value);
1356  return AddMember(name, v, allocator);
1357  }
1358 
1360 
1376  template <typename T>
1377  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1378  AddMember(StringRefType name, T value, Allocator& allocator) {
1379  GenericValue n(name);
1380  return AddMember(n, value, allocator);
1381  }
1382 
1384 
1387  void RemoveAllMembers() {
1388  RAPIDJSON_ASSERT(IsObject());
1389  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1390  m->~Member();
1391  data_.o.size = 0;
1392  }
1393 
1395 
1402  bool RemoveMember(const Ch* name) {
1403  GenericValue n(StringRef(name));
1404  return RemoveMember(n);
1405  }
1406 
1407 #if RAPIDJSON_HAS_STDSTRING
1408  bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1409 #endif
1410 
1411  template <typename SourceAllocator>
1412  bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1413  MemberIterator m = FindMember(name);
1414  if (m != MemberEnd()) {
1415  RemoveMember(m);
1416  return true;
1417  }
1418  else
1419  return false;
1420  }
1421 
1423 
1430  MemberIterator RemoveMember(MemberIterator m) {
1431  RAPIDJSON_ASSERT(IsObject());
1432  RAPIDJSON_ASSERT(data_.o.size > 0);
1433  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1434  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1435 
1436  MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1437  if (data_.o.size > 1 && m != last)
1438  *m = *last; // Move the last one to this place
1439  else
1440  m->~Member(); // Only one left, just destroy
1441  --data_.o.size;
1442  return m;
1443  }
1444 
1446 
1454  MemberIterator EraseMember(ConstMemberIterator pos) {
1455  return EraseMember(pos, pos +1);
1456  }
1457 
1459 
1467  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1468  RAPIDJSON_ASSERT(IsObject());
1469  RAPIDJSON_ASSERT(data_.o.size > 0);
1470  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1471  RAPIDJSON_ASSERT(first >= MemberBegin());
1472  RAPIDJSON_ASSERT(first <= last);
1473  RAPIDJSON_ASSERT(last <= MemberEnd());
1474 
1475  MemberIterator pos = MemberBegin() + (first - MemberBegin());
1476  for (MemberIterator itr = pos; itr != last; ++itr)
1477  itr->~Member();
1478  std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1479  data_.o.size -= static_cast<SizeType>(last - first);
1480  return pos;
1481  }
1482 
1484 
1488  bool EraseMember(const Ch* name) {
1489  GenericValue n(StringRef(name));
1490  return EraseMember(n);
1491  }
1492 
1493 #if RAPIDJSON_HAS_STDSTRING
1494  bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1495 #endif
1496 
1497  template <typename SourceAllocator>
1498  bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1499  MemberIterator m = FindMember(name);
1500  if (m != MemberEnd()) {
1501  EraseMember(m);
1502  return true;
1503  }
1504  else
1505  return false;
1506  }
1507 
1508  Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1509  ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1510 
1512 
1514 
1515 
1517 
1518  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1519 
1521  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1522 
1524  SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1525 
1527  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1528 
1530 
1533  void Clear() {
1534  RAPIDJSON_ASSERT(IsArray());
1535  GenericValue* e = GetElementsPointer();
1536  for (GenericValue* v = e; v != e + data_.a.size; ++v)
1537  v->~GenericValue();
1538  data_.a.size = 0;
1539  }
1540 
1542 
1546  GenericValue& operator[](SizeType index) {
1547  RAPIDJSON_ASSERT(IsArray());
1548  RAPIDJSON_ASSERT(index < data_.a.size);
1549  return GetElementsPointer()[index];
1550  }
1551  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1552 
1554 
1555  ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1557 
1558  ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1560 
1561  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1563 
1564  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1565 
1567 
1572  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1573  RAPIDJSON_ASSERT(IsArray());
1574  if (newCapacity > data_.a.capacity) {
1575  SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1576  data_.a.capacity = newCapacity;
1577  }
1578  return *this;
1579  }
1580 
1582 
1591  GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1592  RAPIDJSON_ASSERT(IsArray());
1593  if (data_.a.size >= data_.a.capacity)
1594  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1595  GetElementsPointer()[data_.a.size++].RawAssign(value);
1596  return *this;
1597  }
1598 
1599 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1600  GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1601  return PushBack(value, allocator);
1602  }
1603 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1604 
1606 
1614  GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1615  return (*this).template PushBack<StringRefType>(value, allocator);
1616  }
1617 
1619 
1635  template <typename T>
1636  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1637  PushBack(T value, Allocator& allocator) {
1638  GenericValue v(value);
1639  return PushBack(v, allocator);
1640  }
1641 
1643 
1646  GenericValue& PopBack() {
1647  RAPIDJSON_ASSERT(IsArray());
1648  RAPIDJSON_ASSERT(!Empty());
1649  GetElementsPointer()[--data_.a.size].~GenericValue();
1650  return *this;
1651  }
1652 
1654 
1660  ValueIterator Erase(ConstValueIterator pos) {
1661  return Erase(pos, pos + 1);
1662  }
1663 
1665 
1672  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1673  RAPIDJSON_ASSERT(IsArray());
1674  RAPIDJSON_ASSERT(data_.a.size > 0);
1675  RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1676  RAPIDJSON_ASSERT(first >= Begin());
1677  RAPIDJSON_ASSERT(first <= last);
1678  RAPIDJSON_ASSERT(last <= End());
1679  ValueIterator pos = Begin() + (first - Begin());
1680  for (ValueIterator itr = pos; itr != last; ++itr)
1681  itr->~GenericValue();
1682  std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1683  data_.a.size -= static_cast<SizeType>(last - first);
1684  return pos;
1685  }
1686 
1687  Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1688  ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1689 
1691 
1693 
1694 
1695  int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1696  unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1697  int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1698  uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1699 
1701 
1703  double GetDouble() const {
1704  RAPIDJSON_ASSERT(IsNumber());
1705  if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1706  if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1707  if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1708  if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1709  RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1710  }
1711 
1713 
1715  float GetFloat() const {
1716  return static_cast<float>(GetDouble());
1717  }
1718 
1719  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1720  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1721  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1722  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1723  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1724  GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1725 
1727 
1729 
1730 
1731  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1732 
1734 
1736  SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1737 
1739 
1746  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1747 
1749 
1753  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1754 
1756 
1763  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }
1764 
1766 
1771  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }
1772 
1773 #if RAPIDJSON_HAS_STDSTRING
1774 
1781  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }
1782 #endif
1783 
1785 
1787 
1788 
1790 
1793  template <typename T>
1794  bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1795 
1796  template <typename T>
1797  T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1798 
1799  template <typename T>
1800  T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1801 
1802  template<typename T>
1803  ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1804 
1805  template<typename T>
1806  ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1807 
1809 
1811 
1817  template <typename Handler>
1818  bool Accept(Handler& handler) const {
1819  switch(GetType()) {
1820  case kNullType: return handler.Null();
1821  case kFalseType: return handler.Bool(false);
1822  case kTrueType: return handler.Bool(true);
1823 
1824  case kObjectType:
1825  if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1826  return false;
1827  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1828  RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1829  if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1830  return false;
1831  if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1832  return false;
1833  }
1834  return handler.EndObject(data_.o.size);
1835 
1836  case kArrayType:
1837  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1838  return false;
1839  for (const GenericValue* v = Begin(); v != End(); ++v)
1840  if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1841  return false;
1842  return handler.EndArray(data_.a.size);
1843 
1844  case kStringType:
1845  return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1846 
1847  default:
1848  RAPIDJSON_ASSERT(GetType() == kNumberType);
1849  if (IsDouble()) return handler.Double(data_.n.d);
1850  else if (IsInt()) return handler.Int(data_.n.i.i);
1851  else if (IsUint()) return handler.Uint(data_.n.u.u);
1852  else if (IsInt64()) return handler.Int64(data_.n.i64);
1853  else return handler.Uint64(data_.n.u64);
1854  }
1855  }
1856 
1857 private:
1858  template <typename, typename> friend class GenericValue;
1859  template <typename, typename, typename> friend class GenericDocument;
1860 
1861  enum {
1862  kBoolFlag = 0x0008,
1863  kNumberFlag = 0x0010,
1864  kIntFlag = 0x0020,
1865  kUintFlag = 0x0040,
1866  kInt64Flag = 0x0080,
1867  kUint64Flag = 0x0100,
1868  kDoubleFlag = 0x0200,
1869  kStringFlag = 0x0400,
1870  kCopyFlag = 0x0800,
1871  kInlineStrFlag = 0x1000,
1872 
1873  // Initial flags of different types.
1874  kNullFlag = kNullType,
1875  kTrueFlag = kTrueType | kBoolFlag,
1876  kFalseFlag = kFalseType | kBoolFlag,
1877  kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
1878  kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
1879  kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
1880  kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
1881  kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
1882  kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
1883  kConstStringFlag = kStringType | kStringFlag,
1884  kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
1885  kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
1886  kObjectFlag = kObjectType,
1887  kArrayFlag = kArrayType,
1888 
1889  kTypeMask = 0x07
1890  };
1891 
1892  static const SizeType kDefaultArrayCapacity = 16;
1893  static const SizeType kDefaultObjectCapacity = 16;
1894 
1895  struct Flag {
1896 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
1897  char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
1898 #elif RAPIDJSON_64BIT
1899  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
1900 #else
1901  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
1902 #endif
1903  uint16_t flags;
1904  };
1905 
1906  struct String {
1907  SizeType length;
1909  const Ch* str;
1910  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1911 
1912  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1913  // (excluding the terminating zero) and store a value to determine the length of the contained
1914  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1915  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1916  // the string terminator as well. For getting the string length back from that value just use
1917  // "MaxSize - str[LenPos]".
1918  // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
1919  // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
1920  struct ShortString {
1921  enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
1922  Ch str[MaxChars];
1923 
1924  inline static bool Usable(SizeType len) { return (MaxSize >= len); }
1925  inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
1926  inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
1927  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1928 
1929  // By using proper binary layout, retrieval of different integer types do not need conversions.
1930  union Number {
1931 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
1932  struct I {
1933  int i;
1934  char padding[4];
1935  }i;
1936  struct U {
1937  unsigned u;
1938  char padding2[4];
1939  }u;
1940 #else
1941  struct I {
1942  char padding[4];
1943  int i;
1944  }i;
1945  struct U {
1946  char padding2[4];
1947  unsigned u;
1948  }u;
1949 #endif
1950  int64_t i64;
1951  uint64_t u64;
1952  double d;
1953  }; // 8 bytes
1954 
1955  struct ObjectData {
1956  SizeType size;
1957  SizeType capacity;
1958  Member* members;
1959  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1960 
1961  struct ArrayData {
1962  SizeType size;
1963  SizeType capacity;
1964  GenericValue* elements;
1965  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1966 
1967  union Data {
1968  String s;
1969  ShortString ss;
1970  Number n;
1971  ObjectData o;
1972  ArrayData a;
1973  Flag f;
1974  }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
1975 
1976  RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
1977  RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
1978  RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
1979  RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
1980  RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
1981  RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
1982 
1983  // Initialize this value as array with initial data, without calling destructor.
1984  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
1985  data_.f.flags = kArrayFlag;
1986  if (count) {
1987  GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
1988  SetElementsPointer(e);
1989  std::memcpy(e, values, count * sizeof(GenericValue));
1990  }
1991  else
1992  SetElementsPointer(0);
1993  data_.a.size = data_.a.capacity = count;
1994  }
1995 
1997  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
1998  data_.f.flags = kObjectFlag;
1999  if (count) {
2000  Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2001  SetMembersPointer(m);
2002  std::memcpy(m, members, count * sizeof(Member));
2003  }
2004  else
2005  SetMembersPointer(0);
2006  data_.o.size = data_.o.capacity = count;
2007  }
2008 
2010  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2011  data_.f.flags = kConstStringFlag;
2012  SetStringPointer(s);
2013  data_.s.length = s.length;
2014  }
2015 
2017  void SetStringRaw(StringRefType s, Allocator& allocator) {
2018  Ch* str = 0;
2019  if (ShortString::Usable(s.length)) {
2020  data_.f.flags = kShortStringFlag;
2021  data_.ss.SetLength(s.length);
2022  str = data_.ss.str;
2023  } else {
2024  data_.f.flags = kCopyStringFlag;
2025  data_.s.length = s.length;
2026  str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2027  SetStringPointer(str);
2028  }
2029  std::memcpy(str, s, s.length * sizeof(Ch));
2030  str[s.length] = '\0';
2031  }
2032 
2034  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2035  data_ = rhs.data_;
2036  // data_.f.flags = rhs.data_.f.flags;
2037  rhs.data_.f.flags = kNullFlag;
2038  }
2039 
2040  template <typename SourceAllocator>
2041  bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2042  RAPIDJSON_ASSERT(IsString());
2043  RAPIDJSON_ASSERT(rhs.IsString());
2044 
2045  const SizeType len1 = GetStringLength();
2046  const SizeType len2 = rhs.GetStringLength();
2047  if(len1 != len2) { return false; }
2048 
2049  const Ch* const str1 = GetString();
2050  const Ch* const str2 = rhs.GetString();
2051  if(str1 == str2) { return true; } // fast path for constant string
2052 
2053  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2054  }
2055 
2056  Data data_;
2057 };
2058 
2061 
2063 // GenericDocument
2064 
2066 
2073 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
2074 class GenericDocument : public GenericValue<Encoding, Allocator> {
2075 public:
2076  typedef typename Encoding::Ch Ch;
2078  typedef Allocator AllocatorType;
2079 
2081 
2087  explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2088  GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2089  {
2090  if (!allocator_)
2091  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
2092  }
2093 
2095 
2100  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2101  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2102  {
2103  if (!allocator_)
2104  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
2105  }
2106 
2107 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2108  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2110  : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2111  allocator_(rhs.allocator_),
2112  ownAllocator_(rhs.ownAllocator_),
2113  stack_(std::move(rhs.stack_)),
2114  parseResult_(rhs.parseResult_)
2115  {
2116  rhs.allocator_ = 0;
2117  rhs.ownAllocator_ = 0;
2118  rhs.parseResult_ = ParseResult();
2119  }
2120 #endif
2121 
2122  ~GenericDocument() {
2123  Destroy();
2124  }
2125 
2126 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2127  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2129  {
2130  // The cast to ValueType is necessary here, because otherwise it would
2131  // attempt to call GenericValue's templated assignment operator.
2132  ValueType::operator=(std::forward<ValueType>(rhs));
2133 
2134  // Calling the destructor here would prematurely call stack_'s destructor
2135  Destroy();
2136 
2137  allocator_ = rhs.allocator_;
2138  ownAllocator_ = rhs.ownAllocator_;
2139  stack_ = std::move(rhs.stack_);
2140  parseResult_ = rhs.parseResult_;
2141 
2142  rhs.allocator_ = 0;
2143  rhs.ownAllocator_ = 0;
2144  rhs.parseResult_ = ParseResult();
2145 
2146  return *this;
2147  }
2148 #endif
2149 
2151 
2156  GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2157  ValueType::Swap(rhs);
2158  stack_.Swap(rhs.stack_);
2159  internal::Swap(allocator_, rhs.allocator_);
2160  internal::Swap(ownAllocator_, rhs.ownAllocator_);
2161  internal::Swap(parseResult_, rhs.parseResult_);
2162  return *this;
2163  }
2164 
2166 
2177  friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2178 
2180 
2184  template <typename Generator>
2185  GenericDocument& Populate(Generator& g) {
2186  ClearStackOnExit scope(*this);
2187  if (g(*this)) {
2188  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2189  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2190  }
2191  return *this;
2192  }
2193 
2196 
2198 
2204  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2205  GenericDocument& ParseStream(InputStream& is) {
2207  stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2208  ClearStackOnExit scope(*this);
2209  parseResult_ = reader.template Parse<parseFlags>(is, *this);
2210  if (parseResult_) {
2211  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2212  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2213  }
2214  return *this;
2215  }
2216 
2218 
2223  template <unsigned parseFlags, typename InputStream>
2224  GenericDocument& ParseStream(InputStream& is) {
2225  return ParseStream<parseFlags, Encoding, InputStream>(is);
2226  }
2227 
2229 
2233  template <typename InputStream>
2234  GenericDocument& ParseStream(InputStream& is) {
2235  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2236  }
2238 
2241 
2243 
2247  template <unsigned parseFlags>
2250  return ParseStream<parseFlags | kParseInsituFlag>(s);
2251  }
2252 
2254 
2258  return ParseInsitu<kParseDefaultFlags>(str);
2259  }
2261 
2264 
2266 
2270  template <unsigned parseFlags, typename SourceEncoding>
2271  GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2272  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2274  return ParseStream<parseFlags, SourceEncoding>(s);
2275  }
2276 
2278 
2281  template <unsigned parseFlags>
2282  GenericDocument& Parse(const Ch* str) {
2283  return Parse<parseFlags, Encoding>(str);
2284  }
2285 
2287 
2289  GenericDocument& Parse(const Ch* str) {
2290  return Parse<kParseDefaultFlags>(str);
2291  }
2292 
2293  template <unsigned parseFlags, typename SourceEncoding>
2294  GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2295  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2296  MemoryStream ms(static_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2298  ParseStream<parseFlags, SourceEncoding>(is);
2299  return *this;
2300  }
2301 
2302  template <unsigned parseFlags>
2303  GenericDocument& Parse(const Ch* str, size_t length) {
2304  return Parse<parseFlags, Encoding>(str, length);
2305  }
2306 
2307  GenericDocument& Parse(const Ch* str, size_t length) {
2308  return Parse<kParseDefaultFlags>(str, length);
2309  }
2310 
2311 #if RAPIDJSON_HAS_STDSTRING
2312  template <unsigned parseFlags, typename SourceEncoding>
2313  GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2314  // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2315  return Parse<parseFlags, SourceEncoding>(str.c_str());
2316  }
2317 
2318  template <unsigned parseFlags>
2319  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2320  return Parse<parseFlags, Encoding>(str.c_str());
2321  }
2322 
2323  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2324  return Parse<kParseDefaultFlags>(str);
2325  }
2326 #endif // RAPIDJSON_HAS_STDSTRING
2327 
2329 
2332 
2334  bool HasParseError() const { return parseResult_.IsError(); }
2335 
2337  ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2338 
2340  size_t GetErrorOffset() const { return parseResult_.Offset(); }
2341 
2343 #ifndef __clang // -Wdocumentation
2344 
2353 #endif
2354  operator ParseResult() const { return parseResult_; }
2356 
2358  Allocator& GetAllocator() {
2359  RAPIDJSON_ASSERT(allocator_);
2360  return *allocator_;
2361  }
2362 
2364  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2365 
2366 private:
2367  // clear stack on any exit from ParseStream, e.g. due to exception
2368  struct ClearStackOnExit {
2369  explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2370  ~ClearStackOnExit() { d_.ClearStack(); }
2371  private:
2372  ClearStackOnExit(const ClearStackOnExit&);
2373  ClearStackOnExit& operator=(const ClearStackOnExit&);
2374  GenericDocument& d_;
2375  };
2376 
2377  // callers of the following private Handler functions
2378  // template <typename,typename,typename> friend class GenericReader; // for parsing
2379  template <typename, typename> friend class GenericValue; // for deep copying
2380 
2381 public:
2382  // Implementation of Handler
2383  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2384  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2385  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2386  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2387  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2388  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2389  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2390 
2391  bool RawNumber(const Ch* str, SizeType length, bool copy) {
2392  if (copy)
2393  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2394  else
2395  new (stack_.template Push<ValueType>()) ValueType(str, length);
2396  return true;
2397  }
2398 
2399  bool String(const Ch* str, SizeType length, bool copy) {
2400  if (copy)
2401  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2402  else
2403  new (stack_.template Push<ValueType>()) ValueType(str, length);
2404  return true;
2405  }
2406 
2407  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2408 
2409  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2410 
2411  bool EndObject(SizeType memberCount) {
2412  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2413  stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2414  return true;
2415  }
2416 
2417  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2418 
2419  bool EndArray(SizeType elementCount) {
2420  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2421  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2422  return true;
2423  }
2424 
2425 private:
2430 
2431  void ClearStack() {
2432  if (Allocator::kNeedFree)
2433  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2434  (stack_.template Pop<ValueType>(1))->~ValueType();
2435  else
2436  stack_.Clear();
2437  stack_.ShrinkToFit();
2438  }
2439 
2440  void Destroy() {
2441  RAPIDJSON_DELETE(ownAllocator_);
2442  }
2443 
2444  static const size_t kDefaultStackCapacity = 1024;
2445  Allocator* allocator_;
2446  Allocator* ownAllocator_;
2448  ParseResult parseResult_;
2449 };
2450 
2453 
2455 
2459 template <bool Const, typename ValueT>
2460 class GenericArray {
2461 public:
2462  typedef GenericArray<true, ValueT> ConstArray;
2463  typedef GenericArray<false, ValueT> Array;
2464  typedef ValueT PlainType;
2465  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2466  typedef ValueType* ValueIterator; // This may be const or non-const iterator
2467  typedef const ValueT* ConstValueIterator;
2468  typedef typename ValueType::AllocatorType AllocatorType;
2469  typedef typename ValueType::StringRefType StringRefType;
2470 
2471  template <typename, typename>
2472  friend class GenericValue;
2473 
2474  GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2475  GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2476  ~GenericArray() {}
2477 
2478  SizeType Size() const { return value_.Size(); }
2479  SizeType Capacity() const { return value_.Capacity(); }
2480  bool Empty() const { return value_.Empty(); }
2481  void Clear() const { value_.Clear(); }
2482  ValueType& operator[](SizeType index) const { return value_[index]; }
2483  ValueIterator Begin() const { return value_.Begin(); }
2484  ValueIterator End() const { return value_.End(); }
2485  GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2486  GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2487 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2488  GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2489 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2490  GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2491  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2492  GenericArray PopBack() const { value_.PopBack(); return *this; }
2493  ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2494  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2495 
2496 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2497  ValueIterator begin() const { return value_.Begin(); }
2498  ValueIterator end() const { return value_.End(); }
2499 #endif
2500 
2501 private:
2502  GenericArray();
2503  GenericArray(ValueType& value) : value_(value) {}
2504  ValueType& value_;
2505 };
2506 
2508 
2512 template <bool Const, typename ValueT>
2513 class GenericObject {
2514 public:
2515  typedef GenericObject<true, ValueT> ConstObject;
2516  typedef GenericObject<false, ValueT> Object;
2517  typedef ValueT PlainType;
2518  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2519  typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
2521  typedef typename ValueType::AllocatorType AllocatorType;
2522  typedef typename ValueType::StringRefType StringRefType;
2523  typedef typename ValueType::EncodingType EncodingType;
2524  typedef typename ValueType::Ch Ch;
2525 
2526  template <typename, typename>
2527  friend class GenericValue;
2528 
2529  GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2530  GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2531  ~GenericObject() {}
2532 
2533  SizeType MemberCount() const { return value_.MemberCount(); }
2534  bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2535  template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2536  template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2537 #if RAPIDJSON_HAS_STDSTRING
2538  ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2539 #endif
2540  MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2541  MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2542  bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2543 #if RAPIDJSON_HAS_STDSTRING
2544  bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2545 #endif
2546  template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2547  MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2548  template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2549 #if RAPIDJSON_HAS_STDSTRING
2550  MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2551 #endif
2552  GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2553  GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2554 #if RAPIDJSON_HAS_STDSTRING
2555  GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2556 #endif
2557  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2558 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2559  GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2560  GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2561  GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2562  GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2563 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2564  GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2565  GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2566  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2567  void RemoveAllMembers() { return value_.RemoveAllMembers(); }
2568  bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2569 #if RAPIDJSON_HAS_STDSTRING
2570  bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2571 #endif
2572  template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2573  MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2574  MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
2575  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2576  bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2577 #if RAPIDJSON_HAS_STDSTRING
2578  bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2579 #endif
2580  template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2581 
2582 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2583  MemberIterator begin() const { return value_.MemberBegin(); }
2584  MemberIterator end() const { return value_.MemberEnd(); }
2585 #endif
2586 
2587 private:
2588  GenericObject();
2589  GenericObject(ValueType& value) : value_(value) {}
2590  ValueType& value_;
2591 };
2592 
2594 #ifdef _MINWINDEF_ // see: http://stackoverflow.com/questions/22744262/cant-call-stdmax-because-minwindef-h-defines-max
2595 #ifndef NOMINMAX
2596 #pragma pop_macro("min")
2597 #pragma pop_macro("max")
2598 #endif
2599 #endif
2600 RAPIDJSON_DIAG_POP
2601 
2602 #endif // RAPIDJSON_DOCUMENT_H_
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:681
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:139
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:732
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:80
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2078
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2077
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:380
Definition: document.h:402
Represents an in-memory input byte stream.
Definition: memorystream.h:40
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition: document.h:761
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:402
Definition: document.h:1955
BaseType::pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:129
Definition: document.h:1932
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
object
Definition: rapidjson.h:607
Helper class for accessing Value of array type.
Definition: document.h:531
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:600
Read-only string stream.
Definition: fwd.h:47
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:2177
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition: document.h:723
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:119
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:81
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2185
(Constant) member iterator for a JSON object value
Definition: document.h:109
const Ch *const s
plain CharType pointer
Definition: document.h:330
array
Definition: rapidjson.h:608
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:122
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2076
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:2224
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:67
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:437
false
Definition: rapidjson.h:605
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:195
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:735
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: document.h:2334
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:124
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:559
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:552
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:2234
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:116
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:2340
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:551
A document for parsing JSON text as DOM.
Definition: document.h:70
A read-write string stream.
Definition: fwd.h:52
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:693
Definition: document.h:1967
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:726
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2087
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:553
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2100
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:670
string
Definition: rapidjson.h:609
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: fwd.h:88
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:554
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:310
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2060
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:557
ParseErrorCode
Error code of parsing.
Definition: error.h:64
Helper class for accessing Value of object type.
Definition: document.h:532
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:2248
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:286
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:555
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2358
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2452
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:560
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:331
number
Definition: rapidjson.h:610
#define RAPIDJSON_NEW(x)
! customization point for global new
Definition: rapidjson.h:586
Name-value pair in a JSON object value.
Definition: document.h:79
SizeType hashcode
reserved
Definition: document.h:1908
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:590
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2271
~GenericValue()
Destructor.
Definition: document.h:769
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:2257
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:2364
Definition: document.h:1961
Definition: document.h:1930
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:1997
CharType Ch
character type of the string
Definition: document.h:258
Definition: document.h:1920
Definition: document.h:399
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:2337
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:354
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:556
Definition: document.h:1906
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:2017
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:2010
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:687
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:708
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:558
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator)
Explicit copy constructor (with allocator)
Definition: document.h:621
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:729
Definition: document.h:1936
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:2282
true
Definition: rapidjson.h:606
Definition: document.h:419
Reference to a constant string (not taking a copy)
Definition: document.h:257
Definition: document.h:409
BaseType::difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:133
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:126
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:157
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:570
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:720
Type
Type of JSON value.
Definition: rapidjson.h:603
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:824
BaseType::reference Reference
Reference to (const) GenericMember.
Definition: document.h:131
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:2289
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:322
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:2034
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:468
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:2156
Definition: document.h:1895
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:805
In-situ(destructive) parsing.
Definition: reader.h:147
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:2205
null
Definition: rapidjson.h:604
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition: document.h:750