bes Updated for version 3.20.13
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
31RAPIDJSON_DIAG_PUSH
32#ifdef __clang__
33RAPIDJSON_DIAG_OFF(padded)
34RAPIDJSON_DIAG_OFF(switch-enum)
35RAPIDJSON_DIAG_OFF(c++98-compat)
36#elif defined(_MSC_VER)
37RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
38RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
39#endif
40
41#ifdef __GNUC__
42RAPIDJSON_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.
56template <typename Encoding, typename Allocator>
57class GenericValue;
58
59template <typename Encoding, typename Allocator, typename StackAllocator>
60class 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
110template <typename Encoding, typename Allocator>
112public:
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
147private:
149 GenericMember(const GenericMember& rhs);
150};
151
153// GenericMemberIterator
154
155#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
156
158
176template <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
185public:
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
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
275private:
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
286template <bool Const, typename Encoding, typename Allocator>
288
290template <typename Encoding, typename Allocator>
294};
296template <typename Encoding, typename Allocator>
300};
301
302#endif // RAPIDJSON_NOMEMBERITERATORCLASS
303
305// GenericStringRef
306
308
334template<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;
410
411private:
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
427template<typename CharType>
428const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
429
431
442template<typename CharType>
443inline GenericStringRef<CharType> StringRef(const CharType* str) {
444 return GenericStringRef<CharType>(str);
445}
446
448
462template<typename CharType>
463inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
464 return GenericStringRef<CharType>(str, SizeType(length));
465}
466
467#if RAPIDJSON_HAS_STDSTRING
469
480template<typename CharType>
481inline 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
488namespace internal {
489
490template <typename T, typename Encoding = void, typename Allocator = void>
492
493// select candidates according to nested encoding and allocator types
494template <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
498template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
499
500} // namespace internal
501
503// TypeHelper
504
505namespace internal {
506
507template <typename ValueType, typename T>
508struct TypeHelper {};
509
510template<typename ValueType>
511struct 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
518template<typename ValueType>
519struct 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
526template<typename ValueType>
527struct 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
535RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
536template<typename ValueType>
537struct 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
544RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
545template<typename ValueType>
546struct 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
554template<typename ValueType>
555struct 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
562template<typename ValueType>
563struct 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
570template<typename ValueType>
571struct 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
578template<typename ValueType>
579struct 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
586template<typename ValueType>
587struct 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
596template<typename ValueType>
597struct 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
605template<typename ValueType>
606struct 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
614template<typename ValueType>
615struct 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
621template<typename ValueType>
622struct 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
630template<typename ValueType>
631struct 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
640template <bool, typename> class GenericArray;
641template <bool, typename> class GenericObject;
642
644// GenericValue
645
647
656template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
658public:
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
688private:
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
702public:
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 };
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
786 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
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
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
1986private:
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).
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
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
2202template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2203class GenericDocument : public GenericValue<Encoding, Allocator> {
2204public:
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
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
2499private:
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
2514public:
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
2558private:
2562 GenericDocument& operator=(const GenericDocument&);
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
2593template <bool Const, typename ValueT>
2595public:
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
2635private:
2636 GenericArray();
2637 GenericArray(ValueType& value) : value_(value) {}
2638 ValueType& value_;
2639};
2640
2642
2646template <bool Const, typename ValueT>
2648public:
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
2723private:
2724 GenericObject();
2725 GenericObject(ValueType& value) : value_(value) {}
2726 ValueType& value_;
2727};
2728
2730RAPIDJSON_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
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2491
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:2381
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:2285
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2207
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:2415
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2216
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: document.h:2467
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:2357
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2229
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2205
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:2367
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:2338
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2206
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2404
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:2470
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:2390
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:2497
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2318
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:2473
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:2422
(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
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:114
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:133
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
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:935
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< 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(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
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:915
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:663
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:667
A type-unsafe stack for storing different types of data.
Definition: stack.h:37
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