bes  Updated for version 3.20.8
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 #ifdef __cpp_lib_three_way_comparison
28 #include <compare>
29 #endif
30 
31 RAPIDJSON_DIAG_PUSH
32 #ifdef __clang__
33 RAPIDJSON_DIAG_OFF(padded)
34 RAPIDJSON_DIAG_OFF(switch-enum)
35 RAPIDJSON_DIAG_OFF(c++98-compat)
36 #elif defined(_MSC_VER)
37 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
38 RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
39 #endif
40 
41 #ifdef __GNUC__
42 RAPIDJSON_DIAG_OFF(effc++)
43 #endif // __GNUC__
44 
45 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
46 #include <iterator> // std::random_access_iterator_tag
47 #endif
48 
49 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
50 #include <utility> // std::move
51 #endif
52 
54 
55 // Forward declaration.
56 template <typename Encoding, typename Allocator>
57 class GenericValue;
58 
59 template <typename Encoding, typename Allocator, typename StackAllocator>
60 class GenericDocument;
61 
68 #ifndef RAPIDJSON_DEFAULT_ALLOCATOR
69 #define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
70 #endif
71 
78 #ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
79 #define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
80 #endif
81 
88 #ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
89 // number of objects that rapidjson::Value allocates memory for by default
90 #define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
91 #endif
92 
99 #ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
100 // number of array elements that rapidjson::Value allocates memory for by default
101 #define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
102 #endif
103 
105 
110 template <typename Encoding, typename Allocator>
112 public:
115 
116 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
118  GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
119  : name(std::move(rhs.name)),
120  value(std::move(rhs.value))
121  {
122  }
123 
125  GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
126  return *this = static_cast<GenericMember&>(rhs);
127  }
128 #endif
129 
131 
133  GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
134  if (RAPIDJSON_LIKELY(this != &rhs)) {
135  name = rhs.name;
136  value = rhs.value;
137  }
138  return *this;
139  }
140 
141  // swap() for std::sort() and other potential use in STL.
142  friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
143  a.name.Swap(b.name);
144  a.value.Swap(b.value);
145  }
146 
147 private:
149  GenericMember(const GenericMember& rhs);
150 };
151 
153 // GenericMemberIterator
154 
155 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
156 
158 
176 template <bool Const, typename Encoding, typename Allocator>
178 
179  friend class GenericValue<Encoding,Allocator>;
180  template <bool, typename, typename> friend class GenericMemberIterator;
181 
183  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
184 
185 public:
192 
195  typedef ValueType value_type;
196  typedef ValueType * pointer;
197  typedef ValueType & reference;
198  typedef std::ptrdiff_t difference_type;
199  typedef std::random_access_iterator_tag iterator_category;
201 
203  typedef pointer Pointer;
205  typedef reference Reference;
207  typedef difference_type DifferenceType;
208 
210 
213  GenericMemberIterator() : ptr_() {}
214 
216 
231  GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
232  Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
233 
235 
236  Iterator& operator++(){ ++ptr_; return *this; }
237  Iterator& operator--(){ --ptr_; return *this; }
238  Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
239  Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
241 
243 
244  Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
245  Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
246 
247  Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
248  Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
250 
252 
253  template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
254  template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
255  template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
256  template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
257  template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
258  template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
259 
260 #ifdef __cpp_lib_three_way_comparison
261  template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
262 #endif
264 
266 
267  Reference operator*() const { return *ptr_; }
268  Pointer operator->() const { return ptr_; }
269  Reference operator[](DifferenceType n) const { return ptr_[n]; }
271 
273  DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
274 
275 private:
277  explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
278 
279  Pointer ptr_;
280 };
281 
282 #else // RAPIDJSON_NOMEMBERITERATORCLASS
283 
284 // class-based member iterator implementation disabled, use plain pointers
285 
286 template <bool Const, typename Encoding, typename Allocator>
288 
290 template <typename Encoding, typename Allocator>
294 };
296 template <typename Encoding, typename Allocator>
300 };
301 
302 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
303 
305 // GenericStringRef
306 
308 
334 template<typename CharType>
336  typedef CharType Ch;
337 
339 #ifndef __clang__ // -Wdocumentation
362 #endif
363  template<SizeType N>
364  GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
365  : s(str), length(N-1) {}
366 
368 #ifndef __clang__ // -Wdocumentation
387 #endif
388  explicit GenericStringRef(const CharType* str)
389  : s(str), length(NotNullStrLen(str)) {}
390 
392 #ifndef __clang__ // -Wdocumentation
399 #endif
400  GenericStringRef(const CharType* str, SizeType len)
401  : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
402 
403  GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
404 
406  operator const Ch *() const { return s; }
407 
408  const Ch* const s;
409  const SizeType length;
410 
411 private:
412  SizeType NotNullStrLen(const CharType* str) {
413  RAPIDJSON_ASSERT(str != 0);
414  return internal::StrLen(str);
415  }
416 
418  static const Ch emptyString[];
419 
421  template<SizeType N>
422  GenericStringRef(CharType (&str)[N]) /* = delete */;
424  GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
425 };
426 
427 template<typename CharType>
428 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
429 
431 
442 template<typename CharType>
443 inline GenericStringRef<CharType> StringRef(const CharType* str) {
444  return GenericStringRef<CharType>(str);
445 }
446 
448 
462 template<typename CharType>
463 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
464  return GenericStringRef<CharType>(str, SizeType(length));
465 }
466 
467 #if RAPIDJSON_HAS_STDSTRING
469 
480 template<typename CharType>
481 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
482  return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
483 }
484 #endif
485 
487 // GenericValue type traits
488 namespace internal {
489 
490 template <typename T, typename Encoding = void, typename Allocator = void>
492 
493 // select candidates according to nested encoding and allocator types
494 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
495  : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
496 
497 // helper to match arbitrary GenericValue instantiations, including derived classes
498 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
499 
500 } // namespace internal
501 
503 // TypeHelper
504 
505 namespace internal {
506 
507 template <typename ValueType, typename T>
508 struct TypeHelper {};
509 
510 template<typename ValueType>
511 struct TypeHelper<ValueType, bool> {
512  static bool Is(const ValueType& v) { return v.IsBool(); }
513  static bool Get(const ValueType& v) { return v.GetBool(); }
514  static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
515  static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
516 };
517 
518 template<typename ValueType>
519 struct TypeHelper<ValueType, int> {
520  static bool Is(const ValueType& v) { return v.IsInt(); }
521  static int Get(const ValueType& v) { return v.GetInt(); }
522  static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
523  static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
524 };
525 
526 template<typename ValueType>
527 struct TypeHelper<ValueType, unsigned> {
528  static bool Is(const ValueType& v) { return v.IsUint(); }
529  static unsigned Get(const ValueType& v) { return v.GetUint(); }
530  static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
531  static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
532 };
533 
534 #ifdef _MSC_VER
535 RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
536 template<typename ValueType>
537 struct TypeHelper<ValueType, long> {
538  static bool Is(const ValueType& v) { return v.IsInt(); }
539  static long Get(const ValueType& v) { return v.GetInt(); }
540  static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
541  static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
542 };
543 
544 RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
545 template<typename ValueType>
546 struct TypeHelper<ValueType, unsigned long> {
547  static bool Is(const ValueType& v) { return v.IsUint(); }
548  static unsigned long Get(const ValueType& v) { return v.GetUint(); }
549  static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
550  static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
551 };
552 #endif
553 
554 template<typename ValueType>
555 struct TypeHelper<ValueType, int64_t> {
556  static bool Is(const ValueType& v) { return v.IsInt64(); }
557  static int64_t Get(const ValueType& v) { return v.GetInt64(); }
558  static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
559  static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
560 };
561 
562 template<typename ValueType>
563 struct TypeHelper<ValueType, uint64_t> {
564  static bool Is(const ValueType& v) { return v.IsUint64(); }
565  static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
566  static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
567  static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
568 };
569 
570 template<typename ValueType>
571 struct TypeHelper<ValueType, double> {
572  static bool Is(const ValueType& v) { return v.IsDouble(); }
573  static double Get(const ValueType& v) { return v.GetDouble(); }
574  static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
575  static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
576 };
577 
578 template<typename ValueType>
579 struct TypeHelper<ValueType, float> {
580  static bool Is(const ValueType& v) { return v.IsFloat(); }
581  static float Get(const ValueType& v) { return v.GetFloat(); }
582  static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
583  static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
584 };
585 
586 template<typename ValueType>
587 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
588  typedef const typename ValueType::Ch* StringType;
589  static bool Is(const ValueType& v) { return v.IsString(); }
590  static StringType Get(const ValueType& v) { return v.GetString(); }
591  static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
592  static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
593 };
594 
595 #if RAPIDJSON_HAS_STDSTRING
596 template<typename ValueType>
597 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
598  typedef std::basic_string<typename ValueType::Ch> StringType;
599  static bool Is(const ValueType& v) { return v.IsString(); }
600  static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
601  static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
602 };
603 #endif
604 
605 template<typename ValueType>
606 struct TypeHelper<ValueType, typename ValueType::Array> {
607  typedef typename ValueType::Array ArrayType;
608  static bool Is(const ValueType& v) { return v.IsArray(); }
609  static ArrayType Get(ValueType& v) { return v.GetArray(); }
610  static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
611  static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
612 };
613 
614 template<typename ValueType>
615 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
616  typedef typename ValueType::ConstArray ArrayType;
617  static bool Is(const ValueType& v) { return v.IsArray(); }
618  static ArrayType Get(const ValueType& v) { return v.GetArray(); }
619 };
620 
621 template<typename ValueType>
622 struct TypeHelper<ValueType, typename ValueType::Object> {
623  typedef typename ValueType::Object ObjectType;
624  static bool Is(const ValueType& v) { return v.IsObject(); }
625  static ObjectType Get(ValueType& v) { return v.GetObject(); }
626  static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
627  static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
628 };
629 
630 template<typename ValueType>
631 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
632  typedef typename ValueType::ConstObject ObjectType;
633  static bool Is(const ValueType& v) { return v.IsObject(); }
634  static ObjectType Get(const ValueType& v) { return v.GetObject(); }
635 };
636 
637 } // namespace internal
638 
639 // Forward declarations
640 template <bool, typename> class GenericArray;
641 template <bool, typename> class GenericObject;
642 
644 // GenericValue
645 
647 
656 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
658 public:
663  typedef typename Encoding::Ch Ch;
674 
676 
677 
679  GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
680 
681 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
683  GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
684  rhs.data_.f.flags = kNullFlag; // give up contents
685  }
686 #endif
687 
688 private:
690  GenericValue(const GenericValue& rhs);
691 
692 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
694  template <typename StackAllocator>
696 
698  template <typename StackAllocator>
700 #endif
701 
702 public:
703 
705 
709  explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
710  static const uint16_t defaultFlags[] = {
711  kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
712  kNumberAnyFlag
713  };
714  RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
715  data_.f.flags = defaultFlags[type];
716 
717  // Use ShortString to store empty string.
718  if (type == kStringType)
719  data_.ss.SetLength(0);
720  }
721 
723 
730  template <typename SourceAllocator>
731  GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
732  switch (rhs.GetType()) {
733  case kObjectType: {
734  SizeType count = rhs.data_.o.size;
735  Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
736  const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
737  for (SizeType i = 0; i < count; i++) {
738  new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
739  new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
740  }
741  data_.f.flags = kObjectFlag;
742  data_.o.size = data_.o.capacity = count;
743  SetMembersPointer(lm);
744  }
745  break;
746  case kArrayType: {
747  SizeType count = rhs.data_.a.size;
748  GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
749  const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
750  for (SizeType i = 0; i < count; i++)
751  new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
752  data_.f.flags = kArrayFlag;
753  data_.a.size = data_.a.capacity = count;
754  SetElementsPointer(le);
755  }
756  break;
757  case kStringType:
758  if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
759  data_.f.flags = rhs.data_.f.flags;
760  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
761  }
762  else
763  SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
764  break;
765  default:
766  data_.f.flags = rhs.data_.f.flags;
767  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
768  break;
769  }
770  }
771 
773 
778 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
779  template <typename T>
780  explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
781 #else
782  explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
783 #endif
784  : data_() {
785  // safe-guard against failing SFINAE
787  data_.f.flags = b ? kTrueFlag : kFalseFlag;
788  }
789 
791  explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
792  data_.n.i64 = i;
793  data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
794  }
795 
797  explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
798  data_.n.u64 = u;
799  data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
800  }
801 
803  explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
804  data_.n.i64 = i64;
805  data_.f.flags = kNumberInt64Flag;
806  if (i64 >= 0) {
807  data_.f.flags |= kNumberUint64Flag;
808  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
809  data_.f.flags |= kUintFlag;
810  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
811  data_.f.flags |= kIntFlag;
812  }
813  else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
814  data_.f.flags |= kIntFlag;
815  }
816 
818  explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
819  data_.n.u64 = u64;
820  data_.f.flags = kNumberUint64Flag;
821  if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
822  data_.f.flags |= kInt64Flag;
823  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
824  data_.f.flags |= kUintFlag;
825  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
826  data_.f.flags |= kIntFlag;
827  }
828 
830  explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
831 
833  explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
834 
836  GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
837 
839  explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
840 
842  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
843 
845  GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
846 
847 #if RAPIDJSON_HAS_STDSTRING
849 
851  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
852 #endif
853 
855 
860  GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
861  a.value_.data_ = Data();
862  a.value_.data_.f.flags = kArrayFlag;
863  }
864 
866 
871  GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
872  o.value_.data_ = Data();
873  o.value_.data_.f.flags = kObjectFlag;
874  }
875 
877 
880  if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
881  switch(data_.f.flags) {
882  case kArrayFlag:
883  {
884  GenericValue* e = GetElementsPointer();
885  for (GenericValue* v = e; v != e + data_.a.size; ++v)
886  v->~GenericValue();
887  Allocator::Free(e);
888  }
889  break;
890 
891  case kObjectFlag:
892  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
893  m->~Member();
894  Allocator::Free(GetMembersPointer());
895  break;
896 
897  case kCopyStringFlag:
898  Allocator::Free(const_cast<Ch*>(GetStringPointer()));
899  break;
900 
901  default:
902  break; // Do nothing for other types.
903  }
904  }
905  }
906 
908 
910 
911 
913 
915  GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
916  if (RAPIDJSON_LIKELY(this != &rhs)) {
917  this->~GenericValue();
918  RawAssign(rhs);
919  }
920  return *this;
921  }
922 
923 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
925  GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
926  return *this = rhs.Move();
927  }
928 #endif
929 
931 
935  GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
936  GenericValue s(str);
937  return *this = s;
938  }
939 
941 
952  template <typename T>
953  RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
954  operator=(T value) {
955  GenericValue v(value);
956  return *this = v;
957  }
958 
960 
966  template <typename SourceAllocator>
967  GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
968  RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
969  this->~GenericValue();
970  new (this) GenericValue(rhs, allocator, copyConstStrings);
971  return *this;
972  }
973 
975 
979  GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
980  GenericValue temp;
981  temp.RawAssign(*this);
982  RawAssign(other);
983  other.RawAssign(temp);
984  return *this;
985  }
986 
988 
999  friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1000 
1002 
1003  GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
1005 
1007 
1008 
1013  template <typename SourceAllocator>
1014  bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
1016  if (GetType() != rhs.GetType())
1017  return false;
1018 
1019  switch (GetType()) {
1020  case kObjectType: // Warning: O(n^2) inner-loop
1021  if (data_.o.size != rhs.data_.o.size)
1022  return false;
1023  for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1024  typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1025  if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
1026  return false;
1027  }
1028  return true;
1029 
1030  case kArrayType:
1031  if (data_.a.size != rhs.data_.a.size)
1032  return false;
1033  for (SizeType i = 0; i < data_.a.size; i++)
1034  if ((*this)[i] != rhs[i])
1035  return false;
1036  return true;
1037 
1038  case kStringType:
1039  return StringEqual(rhs);
1040 
1041  case kNumberType:
1042  if (IsDouble() || rhs.IsDouble()) {
1043  double a = GetDouble(); // May convert from integer to double.
1044  double b = rhs.GetDouble(); // Ditto
1045  return a >= b && a <= b; // Prevent -Wfloat-equal
1046  }
1047  else
1048  return data_.n.u64 == rhs.data_.n.u64;
1049 
1050  default:
1051  return true;
1052  }
1053  }
1054 
1056  bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1057 
1058 #if RAPIDJSON_HAS_STDSTRING
1060 
1062  bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
1063 #endif
1064 
1066 
1068  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
1069 
1071 
1073  template <typename SourceAllocator>
1074  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1075 
1077  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1078 
1080 
1082  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1083 
1085 
1087  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1088 
1090 
1092  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1094 
1096 
1097 
1098  Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1099  bool IsNull() const { return data_.f.flags == kNullFlag; }
1100  bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1101  bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1102  bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1103  bool IsObject() const { return data_.f.flags == kObjectFlag; }
1104  bool IsArray() const { return data_.f.flags == kArrayFlag; }
1105  bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1106  bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1107  bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1108  bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1109  bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1110  bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1111  bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1112 
1113  // Checks whether a number can be losslessly converted to a double.
1114  bool IsLosslessDouble() const {
1115  if (!IsNumber()) return false;
1116  if (IsUint64()) {
1117  uint64_t u = GetUint64();
1118  volatile double d = static_cast<double>(u);
1119  return (d >= 0.0)
1120  && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1121  && (u == static_cast<uint64_t>(d));
1122  }
1123  if (IsInt64()) {
1124  int64_t i = GetInt64();
1125  volatile double d = static_cast<double>(i);
1126  return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1127  && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1128  && (i == static_cast<int64_t>(d));
1129  }
1130  return true; // double, int, uint are always lossless
1131  }
1132 
1133  // Checks whether a number is a float (possible lossy).
1134  bool IsFloat() const {
1135  if ((data_.f.flags & kDoubleFlag) == 0)
1136  return false;
1137  double d = GetDouble();
1138  return d >= -3.4028234e38 && d <= 3.4028234e38;
1139  }
1140  // Checks whether a number can be losslessly converted to a float.
1141  bool IsLosslessFloat() const {
1142  if (!IsNumber()) return false;
1143  double a = GetDouble();
1144  if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1145  || a > static_cast<double>((std::numeric_limits<float>::max)()))
1146  return false;
1147  double b = static_cast<double>(static_cast<float>(a));
1148  return a >= b && a <= b; // Prevent -Wfloat-equal
1149  }
1150 
1152 
1154 
1155 
1156  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1157 
1159 
1161 
1162 
1163  bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1165 
1166  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1167 
1169 
1171 
1172 
1174 
1175  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1176 
1178  SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1179 
1181  SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1182 
1184  bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1185 
1187 
1195  template <typename T>
1196  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1197  GenericValue n(StringRef(name));
1198  return (*this)[n];
1199  }
1200  template <typename T>
1201  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]; }
1202 
1204 
1212  template <typename SourceAllocator>
1213  GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1214  MemberIterator member = FindMember(name);
1215  if (member != MemberEnd())
1216  return member->value;
1217  else {
1218  RAPIDJSON_ASSERT(false); // see above note
1219 
1220  // This will generate -Wexit-time-destructors in clang
1221  // static GenericValue NullValue;
1222  // return NullValue;
1223 
1224  // Use static buffer and placement-new to prevent destruction
1225  static char buffer[sizeof(GenericValue)];
1226  return *new (buffer) GenericValue();
1227  }
1228  }
1229  template <typename SourceAllocator>
1230  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1231 
1232 #if RAPIDJSON_HAS_STDSTRING
1234  GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1235  const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1236 #endif
1237 
1239 
1240  ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1242 
1243  ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1245 
1246  MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1248 
1249  MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1250 
1252 
1257  GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1258  RAPIDJSON_ASSERT(IsObject());
1259  if (newCapacity > data_.o.capacity) {
1260  SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
1261  data_.o.capacity = newCapacity;
1262  }
1263  return *this;
1264  }
1265 
1267 
1274  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1275 
1276 #if RAPIDJSON_HAS_STDSTRING
1278 
1285  bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1286 #endif
1287 
1289 
1297  template <typename SourceAllocator>
1298  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1299 
1301 
1312  MemberIterator FindMember(const Ch* name) {
1313  GenericValue n(StringRef(name));
1314  return FindMember(n);
1315  }
1316 
1317  ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1318 
1320 
1332  template <typename SourceAllocator>
1334  RAPIDJSON_ASSERT(IsObject());
1335  RAPIDJSON_ASSERT(name.IsString());
1336  MemberIterator member = MemberBegin();
1337  for ( ; member != MemberEnd(); ++member)
1338  if (name.StringEqual(member->name))
1339  break;
1340  return member;
1341  }
1342  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1343 
1344 #if RAPIDJSON_HAS_STDSTRING
1346 
1352  MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1353  ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1354 #endif
1355 
1357 
1366  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1367  RAPIDJSON_ASSERT(IsObject());
1368  RAPIDJSON_ASSERT(name.IsString());
1369 
1370  ObjectData& o = data_.o;
1371  if (o.size >= o.capacity)
1372  MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1373  Member* members = GetMembersPointer();
1374  members[o.size].name.RawAssign(name);
1375  members[o.size].value.RawAssign(value);
1376  o.size++;
1377  return *this;
1378  }
1379 
1381 
1389  GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1390  GenericValue v(value);
1391  return AddMember(name, v, allocator);
1392  }
1393 
1394 #if RAPIDJSON_HAS_STDSTRING
1396 
1404  GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1405  GenericValue v(value, allocator);
1406  return AddMember(name, v, allocator);
1407  }
1408 #endif
1409 
1411 
1427  template <typename T>
1428  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1429  AddMember(GenericValue& name, T value, Allocator& allocator) {
1430  GenericValue v(value);
1431  return AddMember(name, v, allocator);
1432  }
1433 
1434 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1435  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1436  return AddMember(name, value, allocator);
1437  }
1438  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1439  return AddMember(name, value, allocator);
1440  }
1441  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1442  return AddMember(name, value, allocator);
1443  }
1444  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1445  GenericValue n(name);
1446  return AddMember(n, value, allocator);
1447  }
1448 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1449 
1450 
1452 
1461  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1462  GenericValue n(name);
1463  return AddMember(n, value, allocator);
1464  }
1465 
1467 
1475  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1476  GenericValue v(value);
1477  return AddMember(name, v, allocator);
1478  }
1479 
1481 
1497  template <typename T>
1498  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1499  AddMember(StringRefType name, T value, Allocator& allocator) {
1500  GenericValue n(name);
1501  return AddMember(n, value, allocator);
1502  }
1503 
1505 
1508  void RemoveAllMembers() {
1509  RAPIDJSON_ASSERT(IsObject());
1510  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1511  m->~Member();
1512  data_.o.size = 0;
1513  }
1514 
1516 
1523  bool RemoveMember(const Ch* name) {
1524  GenericValue n(StringRef(name));
1525  return RemoveMember(n);
1526  }
1527 
1528 #if RAPIDJSON_HAS_STDSTRING
1529  bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1530 #endif
1531 
1532  template <typename SourceAllocator>
1533  bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1534  MemberIterator m = FindMember(name);
1535  if (m != MemberEnd()) {
1536  RemoveMember(m);
1537  return true;
1538  }
1539  else
1540  return false;
1541  }
1542 
1544 
1551  MemberIterator RemoveMember(MemberIterator m) {
1552  RAPIDJSON_ASSERT(IsObject());
1553  RAPIDJSON_ASSERT(data_.o.size > 0);
1554  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1555  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1556 
1557  MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1558  if (data_.o.size > 1 && m != last)
1559  *m = *last; // Move the last one to this place
1560  else
1561  m->~Member(); // Only one left, just destroy
1562  --data_.o.size;
1563  return m;
1564  }
1565 
1567 
1575  MemberIterator EraseMember(ConstMemberIterator pos) {
1576  return EraseMember(pos, pos +1);
1577  }
1578 
1580 
1588  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1589  RAPIDJSON_ASSERT(IsObject());
1590  RAPIDJSON_ASSERT(data_.o.size > 0);
1591  RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1592  RAPIDJSON_ASSERT(first >= MemberBegin());
1593  RAPIDJSON_ASSERT(first <= last);
1594  RAPIDJSON_ASSERT(last <= MemberEnd());
1595 
1596  MemberIterator pos = MemberBegin() + (first - MemberBegin());
1597  for (MemberIterator itr = pos; itr != last; ++itr)
1598  itr->~Member();
1599  std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1600  data_.o.size -= static_cast<SizeType>(last - first);
1601  return pos;
1602  }
1603 
1605 
1609  bool EraseMember(const Ch* name) {
1610  GenericValue n(StringRef(name));
1611  return EraseMember(n);
1612  }
1613 
1614 #if RAPIDJSON_HAS_STDSTRING
1615  bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1616 #endif
1617 
1618  template <typename SourceAllocator>
1619  bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1620  MemberIterator m = FindMember(name);
1621  if (m != MemberEnd()) {
1622  EraseMember(m);
1623  return true;
1624  }
1625  else
1626  return false;
1627  }
1628 
1629  Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1630  ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1631 
1633 
1635 
1636 
1638 
1639  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1640 
1642  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1643 
1645  SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1646 
1648  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1649 
1651 
1654  void Clear() {
1655  RAPIDJSON_ASSERT(IsArray());
1656  GenericValue* e = GetElementsPointer();
1657  for (GenericValue* v = e; v != e + data_.a.size; ++v)
1658  v->~GenericValue();
1659  data_.a.size = 0;
1660  }
1661 
1663 
1667  GenericValue& operator[](SizeType index) {
1668  RAPIDJSON_ASSERT(IsArray());
1669  RAPIDJSON_ASSERT(index < data_.a.size);
1670  return GetElementsPointer()[index];
1671  }
1672  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1673 
1675 
1676  ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1678 
1679  ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1681 
1682  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1684 
1685  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1686 
1688 
1693  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1694  RAPIDJSON_ASSERT(IsArray());
1695  if (newCapacity > data_.a.capacity) {
1696  SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1697  data_.a.capacity = newCapacity;
1698  }
1699  return *this;
1700  }
1701 
1703 
1712  GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1713  RAPIDJSON_ASSERT(IsArray());
1714  if (data_.a.size >= data_.a.capacity)
1715  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1716  GetElementsPointer()[data_.a.size++].RawAssign(value);
1717  return *this;
1718  }
1719 
1720 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1721  GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1722  return PushBack(value, allocator);
1723  }
1724 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1725 
1727 
1735  GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1736  return (*this).template PushBack<StringRefType>(value, allocator);
1737  }
1738 
1740 
1756  template <typename T>
1757  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1758  PushBack(T value, Allocator& allocator) {
1759  GenericValue v(value);
1760  return PushBack(v, allocator);
1761  }
1762 
1764 
1767  GenericValue& PopBack() {
1768  RAPIDJSON_ASSERT(IsArray());
1769  RAPIDJSON_ASSERT(!Empty());
1770  GetElementsPointer()[--data_.a.size].~GenericValue();
1771  return *this;
1772  }
1773 
1775 
1781  ValueIterator Erase(ConstValueIterator pos) {
1782  return Erase(pos, pos + 1);
1783  }
1784 
1786 
1794  RAPIDJSON_ASSERT(IsArray());
1795  RAPIDJSON_ASSERT(data_.a.size > 0);
1796  RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1797  RAPIDJSON_ASSERT(first >= Begin());
1798  RAPIDJSON_ASSERT(first <= last);
1799  RAPIDJSON_ASSERT(last <= End());
1800  ValueIterator pos = Begin() + (first - Begin());
1801  for (ValueIterator itr = pos; itr != last; ++itr)
1802  itr->~GenericValue();
1803  std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1804  data_.a.size -= static_cast<SizeType>(last - first);
1805  return pos;
1806  }
1807 
1808  Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1809  ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1810 
1812 
1814 
1815 
1816  int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1817  unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1818  int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1819  uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1820 
1822 
1824  double GetDouble() const {
1825  RAPIDJSON_ASSERT(IsNumber());
1826  if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1827  if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1828  if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1829  if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1830  RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1831  }
1832 
1834 
1836  float GetFloat() const {
1837  return static_cast<float>(GetDouble());
1838  }
1839 
1840  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1841  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1842  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1843  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1844  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1845  GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1846 
1848 
1850 
1851 
1852  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1853 
1855 
1857  SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1858 
1860 
1867  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1868 
1870 
1874  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1875 
1877 
1884  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1885 
1887 
1892  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1893 
1895 
1900  GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1901 
1902 #if RAPIDJSON_HAS_STDSTRING
1904 
1910  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1911 #endif
1912 
1914 
1916 
1917 
1919 
1922  template <typename T>
1923  bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1924 
1925  template <typename T>
1926  T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1927 
1928  template <typename T>
1929  T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1930 
1931  template<typename T>
1932  ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1933 
1934  template<typename T>
1935  ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1936 
1938 
1940 
1946  template <typename Handler>
1947  bool Accept(Handler& handler) const {
1948  switch(GetType()) {
1949  case kNullType: return handler.Null();
1950  case kFalseType: return handler.Bool(false);
1951  case kTrueType: return handler.Bool(true);
1952 
1953  case kObjectType:
1954  if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1955  return false;
1956  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1957  RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1958  if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1959  return false;
1960  if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1961  return false;
1962  }
1963  return handler.EndObject(data_.o.size);
1964 
1965  case kArrayType:
1966  if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1967  return false;
1968  for (const GenericValue* v = Begin(); v != End(); ++v)
1969  if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1970  return false;
1971  return handler.EndArray(data_.a.size);
1972 
1973  case kStringType:
1974  return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1975 
1976  default:
1977  RAPIDJSON_ASSERT(GetType() == kNumberType);
1978  if (IsDouble()) return handler.Double(data_.n.d);
1979  else if (IsInt()) return handler.Int(data_.n.i.i);
1980  else if (IsUint()) return handler.Uint(data_.n.u.u);
1981  else if (IsInt64()) return handler.Int64(data_.n.i64);
1982  else return handler.Uint64(data_.n.u64);
1983  }
1984  }
1985 
1986 private:
1987  template <typename, typename> friend class GenericValue;
1988  template <typename, typename, typename> friend class GenericDocument;
1989 
1990  enum {
1991  kBoolFlag = 0x0008,
1992  kNumberFlag = 0x0010,
1993  kIntFlag = 0x0020,
1994  kUintFlag = 0x0040,
1995  kInt64Flag = 0x0080,
1996  kUint64Flag = 0x0100,
1997  kDoubleFlag = 0x0200,
1998  kStringFlag = 0x0400,
1999  kCopyFlag = 0x0800,
2000  kInlineStrFlag = 0x1000,
2001 
2002  // Initial flags of different types.
2003  kNullFlag = kNullType,
2004  kTrueFlag = kTrueType | kBoolFlag,
2005  kFalseFlag = kFalseType | kBoolFlag,
2006  kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
2007  kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
2008  kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
2009  kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
2010  kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
2011  kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
2012  kConstStringFlag = kStringType | kStringFlag,
2013  kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
2014  kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
2015  kObjectFlag = kObjectType,
2016  kArrayFlag = kArrayType,
2017 
2018  kTypeMask = 0x07
2019  };
2020 
2021  static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
2022  static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
2023 
2024  struct Flag {
2025 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2026  char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
2027 #elif RAPIDJSON_64BIT
2028  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
2029 #else
2030  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
2031 #endif
2032  uint16_t flags;
2033  };
2034 
2035  struct String {
2036  SizeType length;
2038  const Ch* str;
2039  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2040 
2041  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
2042  // (excluding the terminating zero) and store a value to determine the length of the contained
2043  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
2044  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
2045  // the string terminator as well. For getting the string length back from that value just use
2046  // "MaxSize - str[LenPos]".
2047  // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2048  // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
2049  struct ShortString {
2050  enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2051  Ch str[MaxChars];
2052 
2053  inline static bool Usable(SizeType len) { return (MaxSize >= len); }
2054  inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2055  inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
2056  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2057 
2058  // By using proper binary layout, retrieval of different integer types do not need conversions.
2059  union Number {
2060 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2061  struct I {
2062  int i;
2063  char padding[4];
2064  }i;
2065  struct U {
2066  unsigned u;
2067  char padding2[4];
2068  }u;
2069 #else
2070  struct I {
2071  char padding[4];
2072  int i;
2073  }i;
2074  struct U {
2075  char padding2[4];
2076  unsigned u;
2077  }u;
2078 #endif
2079  int64_t i64;
2080  uint64_t u64;
2081  double d;
2082  }; // 8 bytes
2083 
2084  struct ObjectData {
2085  SizeType size;
2086  SizeType capacity;
2087  Member* members;
2088  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2089 
2090  struct ArrayData {
2091  SizeType size;
2092  SizeType capacity;
2093  GenericValue* elements;
2094  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2095 
2096  union Data {
2097  String s;
2098  ShortString ss;
2099  Number n;
2100  ObjectData o;
2101  ArrayData a;
2102  Flag f;
2103  }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2104 
2105  RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2106  RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2107  RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2108  RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2109  RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2110  RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2111 
2112  // Initialize this value as array with initial data, without calling destructor.
2113  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2114  data_.f.flags = kArrayFlag;
2115  if (count) {
2116  GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2117  SetElementsPointer(e);
2118  std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2119  }
2120  else
2121  SetElementsPointer(0);
2122  data_.a.size = data_.a.capacity = count;
2123  }
2124 
2126  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2127  data_.f.flags = kObjectFlag;
2128  if (count) {
2129  Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2130  SetMembersPointer(m);
2131  std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2132  }
2133  else
2134  SetMembersPointer(0);
2135  data_.o.size = data_.o.capacity = count;
2136  }
2137 
2139  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2140  data_.f.flags = kConstStringFlag;
2141  SetStringPointer(s);
2142  data_.s.length = s.length;
2143  }
2144 
2146  void SetStringRaw(StringRefType s, Allocator& allocator) {
2147  Ch* str = 0;
2148  if (ShortString::Usable(s.length)) {
2149  data_.f.flags = kShortStringFlag;
2150  data_.ss.SetLength(s.length);
2151  str = data_.ss.str;
2152  } else {
2153  data_.f.flags = kCopyStringFlag;
2154  data_.s.length = s.length;
2155  str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2156  SetStringPointer(str);
2157  }
2158  std::memcpy(str, s, s.length * sizeof(Ch));
2159  str[s.length] = '\0';
2160  }
2161 
2163  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2164  data_ = rhs.data_;
2165  // data_.f.flags = rhs.data_.f.flags;
2166  rhs.data_.f.flags = kNullFlag;
2167  }
2168 
2169  template <typename SourceAllocator>
2170  bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2171  RAPIDJSON_ASSERT(IsString());
2172  RAPIDJSON_ASSERT(rhs.IsString());
2173 
2174  const SizeType len1 = GetStringLength();
2175  const SizeType len2 = rhs.GetStringLength();
2176  if(len1 != len2) { return false; }
2177 
2178  const Ch* const str1 = GetString();
2179  const Ch* const str2 = rhs.GetString();
2180  if(str1 == str2) { return true; } // fast path for constant string
2181 
2182  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2183  }
2184 
2185  Data data_;
2186 };
2187 
2190 
2192 // GenericDocument
2193 
2195 
2202 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2203 class GenericDocument : public GenericValue<Encoding, Allocator> {
2204 public:
2205  typedef typename Encoding::Ch Ch;
2208 
2210 
2216  explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2217  GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2218  {
2219  if (!allocator_)
2220  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2221  }
2222 
2224 
2229  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2230  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2231  {
2232  if (!allocator_)
2233  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2234  }
2235 
2236 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2238  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2239  : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2240  allocator_(rhs.allocator_),
2241  ownAllocator_(rhs.ownAllocator_),
2242  stack_(std::move(rhs.stack_)),
2243  parseResult_(rhs.parseResult_)
2244  {
2245  rhs.allocator_ = 0;
2246  rhs.ownAllocator_ = 0;
2247  rhs.parseResult_ = ParseResult();
2248  }
2249 #endif
2250 
2251  ~GenericDocument() {
2252  Destroy();
2253  }
2254 
2255 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2257  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2258  {
2259  // The cast to ValueType is necessary here, because otherwise it would
2260  // attempt to call GenericValue's templated assignment operator.
2261  ValueType::operator=(std::forward<ValueType>(rhs));
2262 
2263  // Calling the destructor here would prematurely call stack_'s destructor
2264  Destroy();
2265 
2266  allocator_ = rhs.allocator_;
2267  ownAllocator_ = rhs.ownAllocator_;
2268  stack_ = std::move(rhs.stack_);
2269  parseResult_ = rhs.parseResult_;
2270 
2271  rhs.allocator_ = 0;
2272  rhs.ownAllocator_ = 0;
2273  rhs.parseResult_ = ParseResult();
2274 
2275  return *this;
2276  }
2277 #endif
2278 
2280 
2285  GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2286  ValueType::Swap(rhs);
2287  stack_.Swap(rhs.stack_);
2288  internal::Swap(allocator_, rhs.allocator_);
2289  internal::Swap(ownAllocator_, rhs.ownAllocator_);
2290  internal::Swap(parseResult_, rhs.parseResult_);
2291  return *this;
2292  }
2293 
2294  // Allow Swap with ValueType.
2295  // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2296  using ValueType::Swap;
2297 
2299 
2310  friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2311 
2313 
2317  template <typename Generator>
2318  GenericDocument& Populate(Generator& g) {
2319  ClearStackOnExit scope(*this);
2320  if (g(*this)) {
2321  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2322  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2323  }
2324  return *this;
2325  }
2326 
2329 
2331 
2337  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2338  GenericDocument& ParseStream(InputStream& is) {
2340  stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2341  ClearStackOnExit scope(*this);
2342  parseResult_ = reader.template Parse<parseFlags>(is, *this);
2343  if (parseResult_) {
2344  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2345  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2346  }
2347  return *this;
2348  }
2349 
2351 
2356  template <unsigned parseFlags, typename InputStream>
2357  GenericDocument& ParseStream(InputStream& is) {
2358  return ParseStream<parseFlags, Encoding, InputStream>(is);
2359  }
2360 
2362 
2366  template <typename InputStream>
2367  GenericDocument& ParseStream(InputStream& is) {
2368  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2369  }
2371 
2374 
2376 
2380  template <unsigned parseFlags>
2383  return ParseStream<parseFlags | kParseInsituFlag>(s);
2384  }
2385 
2387 
2391  return ParseInsitu<kParseDefaultFlags>(str);
2392  }
2394 
2397 
2399 
2403  template <unsigned parseFlags, typename SourceEncoding>
2404  GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2405  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2407  return ParseStream<parseFlags, SourceEncoding>(s);
2408  }
2409 
2411 
2414  template <unsigned parseFlags>
2415  GenericDocument& Parse(const Ch* str) {
2416  return Parse<parseFlags, Encoding>(str);
2417  }
2418 
2420 
2422  GenericDocument& Parse(const Ch* str) {
2423  return Parse<kParseDefaultFlags>(str);
2424  }
2425 
2426  template <unsigned parseFlags, typename SourceEncoding>
2427  GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2428  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2429  MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2431  ParseStream<parseFlags, SourceEncoding>(is);
2432  return *this;
2433  }
2434 
2435  template <unsigned parseFlags>
2436  GenericDocument& Parse(const Ch* str, size_t length) {
2437  return Parse<parseFlags, Encoding>(str, length);
2438  }
2439 
2440  GenericDocument& Parse(const Ch* str, size_t length) {
2441  return Parse<kParseDefaultFlags>(str, length);
2442  }
2443 
2444 #if RAPIDJSON_HAS_STDSTRING
2445  template <unsigned parseFlags, typename SourceEncoding>
2446  GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2447  // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2448  return Parse<parseFlags, SourceEncoding>(str.c_str());
2449  }
2450 
2451  template <unsigned parseFlags>
2452  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2453  return Parse<parseFlags, Encoding>(str.c_str());
2454  }
2455 
2456  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2457  return Parse<kParseDefaultFlags>(str);
2458  }
2459 #endif // RAPIDJSON_HAS_STDSTRING
2460 
2462 
2465 
2467  bool HasParseError() const { return parseResult_.IsError(); }
2468 
2470  ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2471 
2473  size_t GetErrorOffset() const { return parseResult_.Offset(); }
2474 
2476 #ifndef __clang // -Wdocumentation
2486 #endif
2487  operator ParseResult() const { return parseResult_; }
2489 
2492  RAPIDJSON_ASSERT(allocator_);
2493  return *allocator_;
2494  }
2495 
2497  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2498 
2499 private:
2500  // clear stack on any exit from ParseStream, e.g. due to exception
2501  struct ClearStackOnExit {
2502  explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2503  ~ClearStackOnExit() { d_.ClearStack(); }
2504  private:
2505  ClearStackOnExit(const ClearStackOnExit&);
2506  ClearStackOnExit& operator=(const ClearStackOnExit&);
2507  GenericDocument& d_;
2508  };
2509 
2510  // callers of the following private Handler functions
2511  // template <typename,typename,typename> friend class GenericReader; // for parsing
2512  template <typename, typename> friend class GenericValue; // for deep copying
2513 
2514 public:
2515  // Implementation of Handler
2516  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2517  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2518  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2519  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2520  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2521  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2522  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2523 
2524  bool RawNumber(const Ch* str, SizeType length, bool copy) {
2525  if (copy)
2526  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2527  else
2528  new (stack_.template Push<ValueType>()) ValueType(str, length);
2529  return true;
2530  }
2531 
2532  bool String(const Ch* str, SizeType length, bool copy) {
2533  if (copy)
2534  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2535  else
2536  new (stack_.template Push<ValueType>()) ValueType(str, length);
2537  return true;
2538  }
2539 
2540  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2541 
2542  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2543 
2544  bool EndObject(SizeType memberCount) {
2545  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2546  stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2547  return true;
2548  }
2549 
2550  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2551 
2552  bool EndArray(SizeType elementCount) {
2553  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2554  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2555  return true;
2556  }
2557 
2558 private:
2563 
2564  void ClearStack() {
2565  if (Allocator::kNeedFree)
2566  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2567  (stack_.template Pop<ValueType>(1))->~ValueType();
2568  else
2569  stack_.Clear();
2570  stack_.ShrinkToFit();
2571  }
2572 
2573  void Destroy() {
2574  RAPIDJSON_DELETE(ownAllocator_);
2575  }
2576 
2577  static const size_t kDefaultStackCapacity = 1024;
2578  Allocator* allocator_;
2579  Allocator* ownAllocator_;
2581  ParseResult parseResult_;
2582 };
2583 
2586 
2587 
2589 
2593 template <bool Const, typename ValueT>
2595 public:
2598  typedef ValueT PlainType;
2599  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2600  typedef ValueType* ValueIterator; // This may be const or non-const iterator
2601  typedef const ValueT* ConstValueIterator;
2602  typedef typename ValueType::AllocatorType AllocatorType;
2603  typedef typename ValueType::StringRefType StringRefType;
2604 
2605  template <typename, typename>
2606  friend class GenericValue;
2607 
2608  GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2609  GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2610  ~GenericArray() {}
2611 
2612  SizeType Size() const { return value_.Size(); }
2613  SizeType Capacity() const { return value_.Capacity(); }
2614  bool Empty() const { return value_.Empty(); }
2615  void Clear() const { value_.Clear(); }
2616  ValueType& operator[](SizeType index) const { return value_[index]; }
2617  ValueIterator Begin() const { return value_.Begin(); }
2618  ValueIterator End() const { return value_.End(); }
2619  GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2620  GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2621 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2622  GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2623 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2624  GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2625  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; }
2626  GenericArray PopBack() const { value_.PopBack(); return *this; }
2627  ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2628  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2629 
2630 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2631  ValueIterator begin() const { return value_.Begin(); }
2632  ValueIterator end() const { return value_.End(); }
2633 #endif
2634 
2635 private:
2636  GenericArray();
2637  GenericArray(ValueType& value) : value_(value) {}
2638  ValueType& value_;
2639 };
2640 
2642 
2646 template <bool Const, typename ValueT>
2648 public:
2651  typedef ValueT PlainType;
2652  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2655  typedef typename ValueType::AllocatorType AllocatorType;
2656  typedef typename ValueType::StringRefType StringRefType;
2657  typedef typename ValueType::EncodingType EncodingType;
2658  typedef typename ValueType::Ch Ch;
2659 
2660  template <typename, typename>
2661  friend class GenericValue;
2662 
2663  GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2664  GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2665  ~GenericObject() {}
2666 
2667  SizeType MemberCount() const { return value_.MemberCount(); }
2668  SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2669  bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2670  template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2671  template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2672 #if RAPIDJSON_HAS_STDSTRING
2673  ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2674 #endif
2675  MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2676  MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2677  GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2678  bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2679 #if RAPIDJSON_HAS_STDSTRING
2680  bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2681 #endif
2682  template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2683  MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2684  template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2685 #if RAPIDJSON_HAS_STDSTRING
2686  MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2687 #endif
2688  GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2689  GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2690 #if RAPIDJSON_HAS_STDSTRING
2691  GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2692 #endif
2693  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; }
2694 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2695  GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2696  GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2697  GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2698  GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2699 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2700  GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2701  GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2702  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; }
2703  void RemoveAllMembers() { value_.RemoveAllMembers(); }
2704  bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2705 #if RAPIDJSON_HAS_STDSTRING
2706  bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2707 #endif
2708  template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2709  MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2710  MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
2711  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2712  bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2713 #if RAPIDJSON_HAS_STDSTRING
2714  bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2715 #endif
2716  template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2717 
2718 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2719  MemberIterator begin() const { return value_.MemberBegin(); }
2720  MemberIterator end() const { return value_.MemberEnd(); }
2721 #endif
2722 
2723 private:
2724  GenericObject();
2725  GenericObject(ValueType& value) : value_(value) {}
2726  ValueType& value_;
2727 };
2728 
2730 RAPIDJSON_DIAG_POP
2731 
2732 #endif // RAPIDJSON_DOCUMENT_H_
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
Helper class for accessing Value of array type.
Definition: document.h:2594
A document for parsing JSON text as DOM.
Definition: document.h:2203
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:2310
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:2381
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2207
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2318
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2216
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:2422
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: document.h:2467
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:2415
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:2285
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2229
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:2357
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2205
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:2390
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2206
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:2470
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:2497
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2491
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2404
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:2367
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:2473
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:2338
(Constant) member iterator for a JSON object value
Definition: document.h:177
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:231
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:213
reference Reference
Reference to (const) GenericMember.
Definition: document.h:205
difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:207
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:191
pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:203
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:187
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:273
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:189
Name-value pair in a JSON object value.
Definition: document.h:111
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:113
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:133
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:114
Helper class for accessing Value of object type.
Definition: document.h:2647
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: pointer.h:79
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:539
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:657
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:780
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:2139
~GenericValue()
Destructor.
Definition: document.h:879
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:830
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:2126
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:661
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:664
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:665
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:935
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:669
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:668
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:836
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator)
Definition: document.h:731
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:662
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:660
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:709
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:915
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition: document.h:860
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:803
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:797
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:845
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition: document.h:871
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:842
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:666
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:791
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:679
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:839
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:2163
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition: document.h:833
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:818
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:2146
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:663
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:667
Concept for allocating, resizing and freeing memory block.
Concept for encoding of Unicode characters.
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2189
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:443
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2585
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
User defined kDefaultArrayCapacity value.
Definition: document.h:101
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition: rapidjson.h:638
#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
User defined kDefaultObjectCapacity value.
Definition: document.h:90
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:463
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:476
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:406
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
ParseErrorCode
Error code of parsing.
Definition: error.h:64
Type
Type of JSON value.
Definition: rapidjson.h:664
@ kFalseType
false
Definition: rapidjson.h:666
@ kObjectType
object
Definition: rapidjson.h:668
@ kTrueType
true
Definition: rapidjson.h:667
@ kStringType
string
Definition: rapidjson.h:670
@ kNullType
null
Definition: rapidjson.h:665
@ kArrayType
array
Definition: rapidjson.h:669
@ kNumberType
number
Definition: rapidjson.h:671
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:651
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:384
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:647
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:445
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition: reader.h:148
A read-write string stream.
Definition: stream.h:188
Reference to a constant string (not taking a copy)
Definition: document.h:335
CharType Ch
character type of the string
Definition: document.h:336
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:409
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
Definition: document.h:463
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:400
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:388
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:443
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:364
const Ch *const s
plain CharType pointer
Definition: document.h:408
Read-only string stream.
Definition: stream.h:154
SizeType hashcode
reserved
Definition: document.h:2037
Represents an in-memory input byte stream.
Definition: memorystream.h:40
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
ParseErrorCode Code() const
Get the error code.
Definition: error.h:116
bool IsError() const
Whether the result is an error.
Definition: error.h:123
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:118