Wizard
Software Engineering Project - Wizard
Loading...
Searching...
No Matches
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.
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
18
21#include "reader.h"
22#include "internal/meta.h"
23#include "internal/strfunc.h"
24#include "memorystream.h"
25#include "encodedstream.h"
26#include <new> // placement new
27#include <limits>
28#ifdef __cpp_lib_three_way_comparison
29#include <compare>
30#endif
31
32RAPIDJSON_DIAG_PUSH
33#ifdef __clang__
34RAPIDJSON_DIAG_OFF(padded)
35RAPIDJSON_DIAG_OFF(switch-enum)
36RAPIDJSON_DIAG_OFF(c++98-compat)
37#elif defined(_MSC_VER)
38RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
39RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
40#endif
41
42#ifdef __GNUC__
43RAPIDJSON_DIAG_OFF(effc++)
44#endif // __GNUC__
45
46#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
47#include <iterator> // std::random_access_iterator_tag
48#endif
49
50#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
51#include <utility> // std::move
52#endif
53
55
56// Forward declaration.
57template <typename Encoding, typename Allocator>
58class GenericValue;
59
60template <typename Encoding, typename Allocator, typename StackAllocator>
61class GenericDocument;
62
69#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
70#define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
71#endif
72
79#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
80#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
81#endif
82
89#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
90// number of objects that rapidjson::Value allocates memory for by default
91#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
92#endif
93
100#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
101// number of array elements that rapidjson::Value allocates memory for by default
102#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
103#endif
104
106
111template <typename Encoding, typename Allocator>
113public:
116
117#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
119 GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
120 : name(std::move(rhs.name)),
121 value(std::move(rhs.value))
122 {
123 }
124
126 GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
127 return *this = static_cast<GenericMember&>(rhs);
128 }
129#endif
130
132
134 GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
135 if (RAPIDJSON_LIKELY(this != &rhs)) {
136 name = rhs.name;
137 value = rhs.value;
138 }
139 return *this;
140 }
141
142 // swap() for std::sort() and other potential use in STL.
143 friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
144 a.name.Swap(b.name);
145 a.value.Swap(b.value);
146 }
147
148private:
150 GenericMember(const GenericMember& rhs);
151};
152
154// GenericMemberIterator
155
156#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
157
159
177template <bool Const, typename Encoding, typename Allocator>
179
180 friend class GenericValue<Encoding,Allocator>;
181 template <bool, typename, typename> friend class GenericMemberIterator;
182
184 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
185
186public:
193
196 typedef ValueType value_type;
197 typedef ValueType * pointer;
198 typedef ValueType & reference;
199 typedef std::ptrdiff_t difference_type;
200 typedef std::random_access_iterator_tag iterator_category;
202
204 typedef pointer Pointer;
206 typedef reference Reference;
208 typedef difference_type DifferenceType;
209
211
215
217
232 GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
233 Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
234
236
237 Iterator& operator++(){ ++ptr_; return *this; }
238 Iterator& operator--(){ --ptr_; return *this; }
239 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
240 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
242
244
245 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
246 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
247
248 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
249 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
251
253
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 template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
260
261#ifdef __cpp_lib_three_way_comparison
262 template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
263#endif
265
267
268 Reference operator*() const { return *ptr_; }
269 Pointer operator->() const { return ptr_; }
270 Reference operator[](DifferenceType n) const { return ptr_[n]; }
272
274 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
275
276private:
278 explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
279
280 Pointer ptr_;
281};
282
283#else // RAPIDJSON_NOMEMBERITERATORCLASS
284
285// class-based member iterator implementation disabled, use plain pointers
286
287template <bool Const, typename Encoding, typename Allocator>
289
291template <typename Encoding, typename Allocator>
293public:
296};
298template <typename Encoding, typename Allocator>
300public:
303};
304
305#endif // RAPIDJSON_NOMEMBERITERATORCLASS
306
308// GenericStringRef
309
311
337template<typename CharType>
339 typedef CharType Ch;
340
342#ifndef __clang__ // -Wdocumentation
365#endif
366 template<SizeType N>
367 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
368 : s(str), length(N-1) {}
369
371#ifndef __clang__ // -Wdocumentation
390#endif
391 explicit GenericStringRef(const CharType* str)
392 : s(str), length(NotNullStrLen(str)) {}
393
395#ifndef __clang__ // -Wdocumentation
402#endif
403 GenericStringRef(const CharType* str, SizeType len)
404 : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
405
406 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
407
409 operator const Ch *() const { return s; }
410
411 const Ch* const s;
413
414private:
415 SizeType NotNullStrLen(const CharType* str) {
416 RAPIDJSON_ASSERT(str != 0);
417 return internal::StrLen(str);
418 }
419
421 static const Ch emptyString[];
422
424 template<SizeType N>
425 GenericStringRef(CharType (&str)[N]) /* = delete */;
427 GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
428};
429
430template<typename CharType>
431const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
432
434
445template<typename CharType>
446inline GenericStringRef<CharType> StringRef(const CharType* str) {
447 return GenericStringRef<CharType>(str);
448}
449
451
465template<typename CharType>
466inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
467 return GenericStringRef<CharType>(str, SizeType(length));
468}
469
470#if RAPIDJSON_HAS_STDSTRING
472
483template<typename CharType>
484inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
485 return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
486}
487#endif
488
490// GenericValue type traits
491namespace internal {
492
493template <typename T, typename Encoding = void, typename Allocator = void>
494struct IsGenericValueImpl : FalseType {};
495
496// select candidates according to nested encoding and allocator types
497template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
498 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
499
500// helper to match arbitrary GenericValue instantiations, including derived classes
501template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
502
503} // namespace internal
504
506// TypeHelper
507
508namespace internal {
509
510template <typename ValueType, typename T>
511struct TypeHelper {};
512
513template<typename ValueType>
514struct TypeHelper<ValueType, bool> {
515 static bool Is(const ValueType& v) { return v.IsBool(); }
516 static bool Get(const ValueType& v) { return v.GetBool(); }
517 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
518 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
519};
520
521template<typename ValueType>
522struct TypeHelper<ValueType, int> {
523 static bool Is(const ValueType& v) { return v.IsInt(); }
524 static int Get(const ValueType& v) { return v.GetInt(); }
525 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
526 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
527};
528
529template<typename ValueType>
530struct TypeHelper<ValueType, unsigned> {
531 static bool Is(const ValueType& v) { return v.IsUint(); }
532 static unsigned Get(const ValueType& v) { return v.GetUint(); }
533 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
534 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
535};
536
537#ifdef _MSC_VER
538RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
539template<typename ValueType>
540struct TypeHelper<ValueType, long> {
541 static bool Is(const ValueType& v) { return v.IsInt(); }
542 static long Get(const ValueType& v) { return v.GetInt(); }
543 static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
544 static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
545};
546
547RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
548template<typename ValueType>
549struct TypeHelper<ValueType, unsigned long> {
550 static bool Is(const ValueType& v) { return v.IsUint(); }
551 static unsigned long Get(const ValueType& v) { return v.GetUint(); }
552 static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
553 static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
554};
555#endif
556
557template<typename ValueType>
558struct TypeHelper<ValueType, int64_t> {
559 static bool Is(const ValueType& v) { return v.IsInt64(); }
560 static int64_t Get(const ValueType& v) { return v.GetInt64(); }
561 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
562 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
563};
564
565template<typename ValueType>
566struct TypeHelper<ValueType, uint64_t> {
567 static bool Is(const ValueType& v) { return v.IsUint64(); }
568 static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
569 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
570 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
571};
572
573template<typename ValueType>
574struct TypeHelper<ValueType, double> {
575 static bool Is(const ValueType& v) { return v.IsDouble(); }
576 static double Get(const ValueType& v) { return v.GetDouble(); }
577 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
578 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
579};
580
581template<typename ValueType>
582struct TypeHelper<ValueType, float> {
583 static bool Is(const ValueType& v) { return v.IsFloat(); }
584 static float Get(const ValueType& v) { return v.GetFloat(); }
585 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
586 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
587};
588
589template<typename ValueType>
590struct TypeHelper<ValueType, const typename ValueType::Ch*> {
591 typedef const typename ValueType::Ch* StringType;
592 static bool Is(const ValueType& v) { return v.IsString(); }
593 static StringType Get(const ValueType& v) { return v.GetString(); }
594 static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
595 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
596};
597
598#if RAPIDJSON_HAS_STDSTRING
599template<typename ValueType>
600struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
601 typedef std::basic_string<typename ValueType::Ch> StringType;
602 static bool Is(const ValueType& v) { return v.IsString(); }
603 static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
604 static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
605};
606#endif
607
608template<typename ValueType>
609struct TypeHelper<ValueType, typename ValueType::Array> {
610 typedef typename ValueType::Array ArrayType;
611 static bool Is(const ValueType& v) { return v.IsArray(); }
612 static ArrayType Get(ValueType& v) { return v.GetArray(); }
613 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
614 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
615};
616
617template<typename ValueType>
618struct TypeHelper<ValueType, typename ValueType::ConstArray> {
619 typedef typename ValueType::ConstArray ArrayType;
620 static bool Is(const ValueType& v) { return v.IsArray(); }
621 static ArrayType Get(const ValueType& v) { return v.GetArray(); }
622};
623
624template<typename ValueType>
625struct TypeHelper<ValueType, typename ValueType::Object> {
626 typedef typename ValueType::Object ObjectType;
627 static bool Is(const ValueType& v) { return v.IsObject(); }
628 static ObjectType Get(ValueType& v) { return v.GetObject(); }
629 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
630 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
631};
632
633template<typename ValueType>
634struct TypeHelper<ValueType, typename ValueType::ConstObject> {
635 typedef typename ValueType::ConstObject ObjectType;
636 static bool Is(const ValueType& v) { return v.IsObject(); }
637 static ObjectType Get(const ValueType& v) { return v.GetObject(); }
638};
639
640} // namespace internal
641
642// Forward declarations
643template <bool, typename> class GenericArray;
644template <bool, typename> class GenericObject;
645
647// GenericValue
648
650
659template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
661public:
666 typedef typename Encoding::Ch Ch;
677
679
680
682 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
683
684#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
686 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
687 rhs.data_.f.flags = kNullFlag; // give up contents
688 }
689#endif
690
691private:
693 GenericValue(const GenericValue& rhs);
694
695#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
697 template <typename StackAllocator>
699
701 template <typename StackAllocator>
703#endif
704
705public:
706
708
712 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
713 static const uint16_t defaultFlags[] = {
714 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
715 kNumberAnyFlag
716 };
718 data_.f.flags = defaultFlags[type];
719
720 // Use ShortString to store empty string.
721 if (type == kStringType)
722 data_.ss.SetLength(0);
723 }
724
726
733 template <typename SourceAllocator>
734 GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
735 switch (rhs.GetType()) {
736 case kObjectType: {
737 SizeType count = rhs.data_.o.size;
738 Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
739 const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
740 for (SizeType i = 0; i < count; i++) {
741 new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
742 new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
743 }
744 data_.f.flags = kObjectFlag;
745 data_.o.size = data_.o.capacity = count;
746 SetMembersPointer(lm);
747 }
748 break;
749 case kArrayType: {
750 SizeType count = rhs.data_.a.size;
751 GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
752 const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
753 for (SizeType i = 0; i < count; i++)
754 new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
755 data_.f.flags = kArrayFlag;
756 data_.a.size = data_.a.capacity = count;
757 SetElementsPointer(le);
758 }
759 break;
760 case kStringType:
761 if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
762 data_.f.flags = rhs.data_.f.flags;
763 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
764 }
765 else
766 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
767 break;
768 default:
769 data_.f.flags = rhs.data_.f.flags;
770 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
771 break;
772 }
773 }
774
776
781#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
782 template <typename T>
783 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
784#else
785 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
786#endif
787 : data_() {
788 // safe-guard against failing SFINAE
789 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
790 data_.f.flags = b ? kTrueFlag : kFalseFlag;
791 }
792
794 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
795 data_.n.i64 = i;
796 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
797 }
798
800 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
801 data_.n.u64 = u;
802 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
803 }
804
806 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
807 data_.n.i64 = i64;
808 data_.f.flags = kNumberInt64Flag;
809 if (i64 >= 0) {
810 data_.f.flags |= kNumberUint64Flag;
811 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
812 data_.f.flags |= kUintFlag;
813 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
814 data_.f.flags |= kIntFlag;
815 }
816 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
817 data_.f.flags |= kIntFlag;
818 }
819
821 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
822 data_.n.u64 = u64;
823 data_.f.flags = kNumberUint64Flag;
824 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
825 data_.f.flags |= kInt64Flag;
826 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
827 data_.f.flags |= kUintFlag;
828 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
829 data_.f.flags |= kIntFlag;
830 }
831
833 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
834
836 explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
837
839 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
840
842 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
843
845 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
846
848 GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
849
850#if RAPIDJSON_HAS_STDSTRING
852
854 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
855#endif
856
858
863 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
864 a.value_.data_ = Data();
865 a.value_.data_.f.flags = kArrayFlag;
866 }
867
869
874 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
875 o.value_.data_ = Data();
876 o.value_.data_.f.flags = kObjectFlag;
877 }
878
880
883 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
884 switch(data_.f.flags) {
885 case kArrayFlag:
886 {
887 GenericValue* e = GetElementsPointer();
888 for (GenericValue* v = e; v != e + data_.a.size; ++v)
889 v->~GenericValue();
890 Allocator::Free(e);
891 }
892 break;
893
894 case kObjectFlag:
895 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
896 m->~Member();
897 Allocator::Free(GetMembersPointer());
898 break;
899
900 case kCopyStringFlag:
901 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
902 break;
903
904 default:
905 break; // Do nothing for other types.
906 }
907 }
908 }
909
911
913
914
916
918 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
919 if (RAPIDJSON_LIKELY(this != &rhs)) {
920 this->~GenericValue();
921 RawAssign(rhs);
922 }
923 return *this;
924 }
925
926#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
928 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
929 return *this = rhs.Move();
930 }
931#endif
932
934
938 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
939 GenericValue s(str);
940 return *this = s;
941 }
942
944
955 template <typename T>
956 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
957 operator=(T value) {
958 GenericValue v(value);
959 return *this = v;
960 }
961
963
969 template <typename SourceAllocator>
970 GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
971 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
972 this->~GenericValue();
973 new (this) GenericValue(rhs, allocator, copyConstStrings);
974 return *this;
975 }
976
978
982 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
983 GenericValue temp;
984 temp.RawAssign(*this);
985 RawAssign(other);
986 other.RawAssign(temp);
987 return *this;
988 }
989
991
1002 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1003
1005
1006 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
1008
1010
1011
1016 template <typename SourceAllocator>
1017 bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
1019 if (GetType() != rhs.GetType())
1020 return false;
1021
1022 switch (GetType()) {
1023 case kObjectType: // Warning: O(n^2) inner-loop
1024 if (data_.o.size != rhs.data_.o.size)
1025 return false;
1026 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1027 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1028 if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
1029 return false;
1030 }
1031 return true;
1032
1033 case kArrayType:
1034 if (data_.a.size != rhs.data_.a.size)
1035 return false;
1036 for (SizeType i = 0; i < data_.a.size; i++)
1037 if ((*this)[i] != rhs[i])
1038 return false;
1039 return true;
1040
1041 case kStringType:
1042 return StringEqual(rhs);
1043
1044 case kNumberType:
1045 if (IsDouble() || rhs.IsDouble()) {
1046 double a = GetDouble(); // May convert from integer to double.
1047 double b = rhs.GetDouble(); // Ditto
1048 return a >= b && a <= b; // Prevent -Wfloat-equal
1049 }
1050 else
1051 return data_.n.u64 == rhs.data_.n.u64;
1052
1053 default:
1054 return true;
1055 }
1056 }
1057
1059 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1060
1061#if RAPIDJSON_HAS_STDSTRING
1063
1065 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
1066#endif
1067
1069
1071 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
1072
1074
1076 template <typename SourceAllocator>
1077 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1078
1080 bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1081
1083
1085 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1086
1088
1090 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1091
1093
1095 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1097
1099
1100
1101 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1102 bool IsNull() const { return data_.f.flags == kNullFlag; }
1103 bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1104 bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1105 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1106 bool IsObject() const { return data_.f.flags == kObjectFlag; }
1107 bool IsArray() const { return data_.f.flags == kArrayFlag; }
1108 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1109 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1110 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1111 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1112 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1113 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1114 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1115
1116 // Checks whether a number can be losslessly converted to a double.
1117 bool IsLosslessDouble() const {
1118 if (!IsNumber()) return false;
1119 if (IsUint64()) {
1120 uint64_t u = GetUint64();
1121 volatile double d = static_cast<double>(u);
1122 return (d >= 0.0)
1123 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1124 && (u == static_cast<uint64_t>(d));
1125 }
1126 if (IsInt64()) {
1127 int64_t i = GetInt64();
1128 volatile double d = static_cast<double>(i);
1129 return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1130 && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1131 && (i == static_cast<int64_t>(d));
1132 }
1133 return true; // double, int, uint are always lossless
1134 }
1135
1136 // Checks whether a number is a float (possible lossy).
1137 bool IsFloat() const {
1138 if ((data_.f.flags & kDoubleFlag) == 0)
1139 return false;
1140 double d = GetDouble();
1141 return d >= -3.4028234e38 && d <= 3.4028234e38;
1142 }
1143 // Checks whether a number can be losslessly converted to a float.
1144 bool IsLosslessFloat() const {
1145 if (!IsNumber()) return false;
1146 double a = GetDouble();
1147 if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1148 || a > static_cast<double>((std::numeric_limits<float>::max)()))
1149 return false;
1150 double b = static_cast<double>(static_cast<float>(a));
1151 return a >= b && a <= b; // Prevent -Wfloat-equal
1152 }
1153
1155
1157
1158
1159 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1160
1162
1164
1165
1166 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1168
1169 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1170
1172
1174
1175
1177
1178 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1179
1181 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1182
1184 SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1185
1187 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1188
1190
1198 template <typename T>
1199 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1200 GenericValue n(StringRef(name));
1201 return (*this)[n];
1202 }
1203 template <typename T>
1204 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]; }
1205
1207
1215 template <typename SourceAllocator>
1216 GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1217 MemberIterator member = FindMember(name);
1218 if (member != MemberEnd())
1219 return member->value;
1220 else {
1221 RAPIDJSON_ASSERT(false); // see above note
1222
1223 // This will generate -Wexit-time-destructors in clang
1224 // static GenericValue NullValue;
1225 // return NullValue;
1226
1227 // Use static buffer and placement-new to prevent destruction
1228 static char buffer[sizeof(GenericValue)];
1229 return *new (buffer) GenericValue();
1230 }
1231 }
1232 template <typename SourceAllocator>
1233 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1234
1235#if RAPIDJSON_HAS_STDSTRING
1237 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1238 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1239#endif
1240
1242
1243 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1245
1246 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1248
1249 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1251
1252 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1253
1255
1260 GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1261 RAPIDJSON_ASSERT(IsObject());
1262 if (newCapacity > data_.o.capacity) {
1263 SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
1264 data_.o.capacity = newCapacity;
1265 }
1266 return *this;
1267 }
1268
1270
1277 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1278
1279#if RAPIDJSON_HAS_STDSTRING
1281
1288 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1289#endif
1290
1292
1300 template <typename SourceAllocator>
1301 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1302
1304
1315 MemberIterator FindMember(const Ch* name) {
1316 GenericValue n(StringRef(name));
1317 return FindMember(n);
1318 }
1319
1320 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1321
1323
1335 template <typename SourceAllocator>
1337 RAPIDJSON_ASSERT(IsObject());
1338 RAPIDJSON_ASSERT(name.IsString());
1339 MemberIterator member = MemberBegin();
1340 for ( ; member != MemberEnd(); ++member)
1341 if (name.StringEqual(member->name))
1342 break;
1343 return member;
1344 }
1345 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1346
1347#if RAPIDJSON_HAS_STDSTRING
1349
1355 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1356 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1357#endif
1358
1360
1369 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1370 RAPIDJSON_ASSERT(IsObject());
1371 RAPIDJSON_ASSERT(name.IsString());
1372
1373 ObjectData& o = data_.o;
1374 if (o.size >= o.capacity)
1375 MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1376 Member* members = GetMembersPointer();
1377 members[o.size].name.RawAssign(name);
1378 members[o.size].value.RawAssign(value);
1379 o.size++;
1380 return *this;
1381 }
1382
1384
1392 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1393 GenericValue v(value);
1394 return AddMember(name, v, allocator);
1395 }
1396
1397#if RAPIDJSON_HAS_STDSTRING
1399
1407 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1408 GenericValue v(value, allocator);
1409 return AddMember(name, v, allocator);
1410 }
1411#endif
1412
1414
1430 template <typename T>
1431 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1432 AddMember(GenericValue& name, T value, Allocator& allocator) {
1433 GenericValue v(value);
1434 return AddMember(name, v, allocator);
1435 }
1436
1437#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
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(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1445 return AddMember(name, value, allocator);
1446 }
1447 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1448 GenericValue n(name);
1449 return AddMember(n, value, allocator);
1450 }
1451#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1452
1453
1455
1464 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1465 GenericValue n(name);
1466 return AddMember(n, value, allocator);
1467 }
1468
1470
1478 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1479 GenericValue v(value);
1480 return AddMember(name, v, allocator);
1481 }
1482
1484
1500 template <typename T>
1501 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1502 AddMember(StringRefType name, T value, Allocator& allocator) {
1503 GenericValue n(name);
1504 return AddMember(n, value, allocator);
1505 }
1506
1508
1511 void RemoveAllMembers() {
1512 RAPIDJSON_ASSERT(IsObject());
1513 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1514 m->~Member();
1515 data_.o.size = 0;
1516 }
1517
1519
1526 bool RemoveMember(const Ch* name) {
1527 GenericValue n(StringRef(name));
1528 return RemoveMember(n);
1529 }
1530
1531#if RAPIDJSON_HAS_STDSTRING
1532 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1533#endif
1534
1535 template <typename SourceAllocator>
1536 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1537 MemberIterator m = FindMember(name);
1538 if (m != MemberEnd()) {
1539 RemoveMember(m);
1540 return true;
1541 }
1542 else
1543 return false;
1544 }
1545
1547
1554 MemberIterator RemoveMember(MemberIterator m) {
1555 RAPIDJSON_ASSERT(IsObject());
1556 RAPIDJSON_ASSERT(data_.o.size > 0);
1557 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1558 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1559
1560 MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1561 if (data_.o.size > 1 && m != last)
1562 *m = *last; // Move the last one to this place
1563 else
1564 m->~Member(); // Only one left, just destroy
1565 --data_.o.size;
1566 return m;
1567 }
1568
1570
1578 MemberIterator EraseMember(ConstMemberIterator pos) {
1579 return EraseMember(pos, pos +1);
1580 }
1581
1583
1591 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1592 RAPIDJSON_ASSERT(IsObject());
1593 RAPIDJSON_ASSERT(data_.o.size > 0);
1594 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1595 RAPIDJSON_ASSERT(first >= MemberBegin());
1596 RAPIDJSON_ASSERT(first <= last);
1597 RAPIDJSON_ASSERT(last <= MemberEnd());
1598
1599 MemberIterator pos = MemberBegin() + (first - MemberBegin());
1600 for (MemberIterator itr = pos; itr != last; ++itr)
1601 itr->~Member();
1602 std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1603 data_.o.size -= static_cast<SizeType>(last - first);
1604 return pos;
1605 }
1606
1608
1612 bool EraseMember(const Ch* name) {
1613 GenericValue n(StringRef(name));
1614 return EraseMember(n);
1615 }
1616
1617#if RAPIDJSON_HAS_STDSTRING
1618 bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1619#endif
1620
1621 template <typename SourceAllocator>
1622 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1623 MemberIterator m = FindMember(name);
1624 if (m != MemberEnd()) {
1625 EraseMember(m);
1626 return true;
1627 }
1628 else
1629 return false;
1630 }
1631
1632 Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1633 ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1634
1636
1638
1639
1641
1642 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1643
1645 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1646
1648 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1649
1651 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1652
1654
1657 void Clear() {
1658 RAPIDJSON_ASSERT(IsArray());
1659 GenericValue* e = GetElementsPointer();
1660 for (GenericValue* v = e; v != e + data_.a.size; ++v)
1661 v->~GenericValue();
1662 data_.a.size = 0;
1663 }
1664
1666
1670 GenericValue& operator[](SizeType index) {
1671 RAPIDJSON_ASSERT(IsArray());
1672 RAPIDJSON_ASSERT(index < data_.a.size);
1673 return GetElementsPointer()[index];
1674 }
1675 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1676
1678
1679 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1681
1682 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1684
1685 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1687
1688 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1689
1691
1696 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1697 RAPIDJSON_ASSERT(IsArray());
1698 if (newCapacity > data_.a.capacity) {
1699 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1700 data_.a.capacity = newCapacity;
1701 }
1702 return *this;
1703 }
1704
1706
1715 GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1716 RAPIDJSON_ASSERT(IsArray());
1717 if (data_.a.size >= data_.a.capacity)
1718 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1719 GetElementsPointer()[data_.a.size++].RawAssign(value);
1720 return *this;
1721 }
1722
1723#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1724 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1725 return PushBack(value, allocator);
1726 }
1727#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1728
1730
1738 GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1739 return (*this).template PushBack<StringRefType>(value, allocator);
1740 }
1741
1743
1759 template <typename T>
1760 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1761 PushBack(T value, Allocator& allocator) {
1762 GenericValue v(value);
1763 return PushBack(v, allocator);
1764 }
1765
1767
1770 GenericValue& PopBack() {
1771 RAPIDJSON_ASSERT(IsArray());
1772 RAPIDJSON_ASSERT(!Empty());
1773 GetElementsPointer()[--data_.a.size].~GenericValue();
1774 return *this;
1775 }
1776
1778
1785 return Erase(pos, pos + 1);
1786 }
1787
1789
1797 RAPIDJSON_ASSERT(IsArray());
1798 RAPIDJSON_ASSERT(data_.a.size > 0);
1799 RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1800 RAPIDJSON_ASSERT(first >= Begin());
1801 RAPIDJSON_ASSERT(first <= last);
1802 RAPIDJSON_ASSERT(last <= End());
1803 ValueIterator pos = Begin() + (first - Begin());
1804 for (ValueIterator itr = pos; itr != last; ++itr)
1805 itr->~GenericValue();
1806 std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1807 data_.a.size -= static_cast<SizeType>(last - first);
1808 return pos;
1809 }
1810
1811 Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1812 ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1813
1815
1817
1818
1819 int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1820 unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1821 int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1822 uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1823
1825
1827 double GetDouble() const {
1828 RAPIDJSON_ASSERT(IsNumber());
1829 if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1830 if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1831 if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1832 if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1833 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1834 }
1835
1837
1839 float GetFloat() const {
1840 return static_cast<float>(GetDouble());
1841 }
1842
1843 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1844 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1845 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1846 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1847 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1848 GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1849
1851
1853
1854
1855 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1856
1858
1860 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1861
1863
1870 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1871
1873
1877 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1878
1880
1887 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1888
1890
1895 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1896
1898
1903 GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1904
1905#if RAPIDJSON_HAS_STDSTRING
1907
1913 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1914#endif
1915
1917
1919
1920
1922
1925 template <typename T>
1926 bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1927
1928 template <typename T>
1929 T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1930
1931 template <typename T>
1932 T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1933
1934 template<typename T>
1935 ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1936
1937 template<typename T>
1938 ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1939
1941
1943
1949 template <typename Handler>
1950 bool Accept(Handler& handler) const {
1951 switch(GetType()) {
1952 case kNullType: return handler.Null();
1953 case kFalseType: return handler.Bool(false);
1954 case kTrueType: return handler.Bool(true);
1955
1956 case kObjectType:
1957 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1958 return false;
1959 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1960 RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1961 if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1962 return false;
1963 if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1964 return false;
1965 }
1966 return handler.EndObject(data_.o.size);
1967
1968 case kArrayType:
1969 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1970 return false;
1971 for (const GenericValue* v = Begin(); v != End(); ++v)
1972 if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1973 return false;
1974 return handler.EndArray(data_.a.size);
1975
1976 case kStringType:
1977 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1978
1979 default:
1980 RAPIDJSON_ASSERT(GetType() == kNumberType);
1981 if (IsDouble()) return handler.Double(data_.n.d);
1982 else if (IsInt()) return handler.Int(data_.n.i.i);
1983 else if (IsUint()) return handler.Uint(data_.n.u.u);
1984 else if (IsInt64()) return handler.Int64(data_.n.i64);
1985 else return handler.Uint64(data_.n.u64);
1986 }
1987 }
1988
1989private:
1990 template <typename, typename> friend class GenericValue;
1991 template <typename, typename, typename> friend class GenericDocument;
1992
1993 enum {
1994 kBoolFlag = 0x0008,
1995 kNumberFlag = 0x0010,
1996 kIntFlag = 0x0020,
1997 kUintFlag = 0x0040,
1998 kInt64Flag = 0x0080,
1999 kUint64Flag = 0x0100,
2000 kDoubleFlag = 0x0200,
2001 kStringFlag = 0x0400,
2002 kCopyFlag = 0x0800,
2003 kInlineStrFlag = 0x1000,
2004
2005 // Initial flags of different types.
2006 kNullFlag = kNullType,
2007 // These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types.
2008 kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
2009 kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
2010 kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
2011 kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
2012 kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
2013 kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
2014 kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
2015 kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
2016 kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
2017 kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
2018 kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2019 kObjectFlag = kObjectType,
2020 kArrayFlag = kArrayType,
2021
2022 kTypeMask = 0x07
2023 };
2024
2025 static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
2026 static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
2027
2028 struct Flag {
2029#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2030 char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + _lower 48-bit pointer
2031#elif RAPIDJSON_64BIT
2032 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
2033#else
2034 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
2035#endif
2036 uint16_t flags;
2037 };
2038
2039 struct String {
2040 SizeType length;
2042 const Ch* str;
2043 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2044
2045 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
2046 // (excluding the terminating zero) and store a value to determine the length of the contained
2047 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
2048 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
2049 // the string terminator as well. For getting the string length back from that value just use
2050 // "MaxSize - str[LenPos]".
2051 // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2052 // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
2054 enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2055 Ch str[MaxChars];
2056
2057 inline static bool Usable(SizeType len) { return (MaxSize >= len); }
2058 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2059 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
2060 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2061
2062 // By using proper binary layout, retrieval of different integer types do not need conversions.
2063 union Number {
2064#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2065 struct I {
2066 int i;
2067 char padding[4];
2068 }i;
2069 struct U {
2070 unsigned u;
2071 char padding2[4];
2072 }u;
2073#else
2074 struct I {
2075 char padding[4];
2076 int i;
2077 }i;
2078 struct U {
2079 char padding2[4];
2080 unsigned u;
2081 }u;
2082#endif
2083 int64_t i64;
2084 uint64_t u64;
2085 double d;
2086 }; // 8 bytes
2087
2088 struct ObjectData {
2089 SizeType size;
2090 SizeType capacity;
2091 Member* members;
2092 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2093
2094 struct ArrayData {
2095 SizeType size;
2096 SizeType capacity;
2097 GenericValue* elements;
2098 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2099
2100 union Data {
2101 String s;
2102 ShortString ss;
2103 Number n;
2104 ObjectData o;
2105 ArrayData a;
2106 Flag f;
2107 }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2108
2109 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2110 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2111 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2112 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2113 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2114 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2115
2116 // Initialize this value as array with initial data, without calling destructor.
2117 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2118 data_.f.flags = kArrayFlag;
2119 if (count) {
2120 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2121 SetElementsPointer(e);
2122 std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2123 }
2124 else
2125 SetElementsPointer(0);
2126 data_.a.size = data_.a.capacity = count;
2127 }
2128
2130 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2131 data_.f.flags = kObjectFlag;
2132 if (count) {
2133 Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2134 SetMembersPointer(m);
2135 std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2136 }
2137 else
2138 SetMembersPointer(0);
2139 data_.o.size = data_.o.capacity = count;
2140 }
2141
2143 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2144 data_.f.flags = kConstStringFlag;
2145 SetStringPointer(s);
2146 data_.s.length = s.length;
2147 }
2148
2151 Ch* str = 0;
2152 if (ShortString::Usable(s.length)) {
2153 data_.f.flags = kShortStringFlag;
2154 data_.ss.SetLength(s.length);
2155 str = data_.ss.str;
2156 } else {
2157 data_.f.flags = kCopyStringFlag;
2158 data_.s.length = s.length;
2159 str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2160 SetStringPointer(str);
2161 }
2162 std::memcpy(str, s, s.length * sizeof(Ch));
2163 str[s.length] = '\0';
2164 }
2165
2167 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2168 data_ = rhs.data_;
2169 // data_.f.flags = rhs.data_.f.flags;
2170 rhs.data_.f.flags = kNullFlag;
2171 }
2172
2173 template <typename SourceAllocator>
2174 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2175 RAPIDJSON_ASSERT(IsString());
2176 RAPIDJSON_ASSERT(rhs.IsString());
2177
2178 const SizeType len1 = GetStringLength();
2179 const SizeType len2 = rhs.GetStringLength();
2180 if(len1 != len2) { return false; }
2181
2182 const Ch* const str1 = GetString();
2183 const Ch* const str2 = rhs.GetString();
2184 if(str1 == str2) { return true; } // fast path for constant string
2185
2186 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2187 }
2188
2189 Data data_;
2190};
2191
2194
2196// GenericDocument
2197
2199
2206template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2207class GenericDocument : public GenericValue<Encoding, Allocator> {
2208public:
2209 typedef typename Encoding::Ch Ch;
2212
2214
2220 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2221 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2222 {
2223 if (!allocator_)
2224 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2225 }
2226
2228
2233 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2234 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2235 {
2236 if (!allocator_)
2237 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2238 }
2239
2240#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2242 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2243 : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2244 allocator_(rhs.allocator_),
2245 ownAllocator_(rhs.ownAllocator_),
2246 stack_(std::move(rhs.stack_)),
2247 parseResult_(rhs.parseResult_)
2248 {
2249 rhs.allocator_ = 0;
2250 rhs.ownAllocator_ = 0;
2251 rhs.parseResult_ = ParseResult();
2252 }
2253#endif
2254
2256 Destroy();
2257 }
2258
2259#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2261 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2262 {
2263 // The cast to ValueType is necessary here, because otherwise it would
2264 // attempt to call GenericValue's templated assignment operator.
2265 ValueType::operator=(std::forward<ValueType>(rhs));
2266
2267 // Calling the destructor here would prematurely call stack_'s destructor
2268 Destroy();
2269
2270 allocator_ = rhs.allocator_;
2271 ownAllocator_ = rhs.ownAllocator_;
2272 stack_ = std::move(rhs.stack_);
2273 parseResult_ = rhs.parseResult_;
2274
2275 rhs.allocator_ = 0;
2276 rhs.ownAllocator_ = 0;
2277 rhs.parseResult_ = ParseResult();
2278
2279 return *this;
2280 }
2281#endif
2282
2284
2289 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2290 ValueType::Swap(rhs);
2291 stack_.Swap(rhs.stack_);
2292 internal::Swap(allocator_, rhs.allocator_);
2293 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2294 internal::Swap(parseResult_, rhs.parseResult_);
2295 return *this;
2296 }
2297
2298 // Allow Swap with ValueType.
2299 // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2300 using ValueType::Swap;
2301
2303
2314 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2315
2317
2321 template <typename Generator>
2322 GenericDocument& Populate(Generator& g) {
2323 ClearStackOnExit scope(*this);
2324 if (g(*this)) {
2325 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2326 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2327 }
2328 return *this;
2329 }
2330
2333
2335
2341 template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2342 GenericDocument& ParseStream(InputStream& is) {
2344 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2345 ClearStackOnExit scope(*this);
2346 parseResult_ = reader.template Parse<parseFlags>(is, *this);
2347 if (parseResult_) {
2348 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2349 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2350 }
2351 return *this;
2352 }
2353
2355
2360 template <unsigned parseFlags, typename InputStream>
2364
2366
2370 template <typename InputStream>
2375
2378
2380
2384 template <unsigned parseFlags>
2389
2391
2398
2401
2403
2407 template <unsigned parseFlags, typename SourceEncoding>
2408 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2409 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2412 }
2413
2415
2418 template <unsigned parseFlags>
2419 GenericDocument& Parse(const Ch* str) {
2420 return Parse<parseFlags, Encoding>(str);
2421 }
2422
2424
2426 GenericDocument& Parse(const Ch* str) {
2427 return Parse<kParseDefaultFlags>(str);
2428 }
2429
2430 template <unsigned parseFlags, typename SourceEncoding>
2431 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2432 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2433 MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2436 return *this;
2437 }
2438
2439 template <unsigned parseFlags>
2440 GenericDocument& Parse(const Ch* str, size_t length) {
2441 return Parse<parseFlags, Encoding>(str, length);
2442 }
2443
2444 GenericDocument& Parse(const Ch* str, size_t length) {
2445 return Parse<kParseDefaultFlags>(str, length);
2446 }
2447
2448#if RAPIDJSON_HAS_STDSTRING
2449 template <unsigned parseFlags, typename SourceEncoding>
2450 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2451 // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2452 return Parse<parseFlags, SourceEncoding>(str.c_str());
2453 }
2454
2455 template <unsigned parseFlags>
2456 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2457 return Parse<parseFlags, Encoding>(str.c_str());
2458 }
2459
2460 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2461 return Parse<kParseDefaultFlags>(str);
2462 }
2463#endif // RAPIDJSON_HAS_STDSTRING
2464
2466
2469
2471 bool HasParseError() const { return parseResult_.IsError(); }
2472
2474 ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2475
2477 size_t GetErrorOffset() const { return parseResult_.Offset(); }
2478
2480#ifndef __clang // -Wdocumentation
2490#endif
2491 operator ParseResult() const { return parseResult_; }
2493
2496 RAPIDJSON_ASSERT(allocator_);
2497 return *allocator_;
2498 }
2499
2501 size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2502
2503private:
2504 // clear stack on any exit from ParseStream, e.g. due to exception
2505 struct ClearStackOnExit {
2506 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2507 ~ClearStackOnExit() { d_.ClearStack(); }
2508 private:
2509 ClearStackOnExit(const ClearStackOnExit&);
2510 ClearStackOnExit& operator=(const ClearStackOnExit&);
2511 GenericDocument& d_;
2512 };
2513
2514 // callers of the following private Handler functions
2515 // template <typename,typename,typename> friend class GenericReader; // for parsing
2516 template <typename, typename> friend class GenericValue; // for deep copying
2517
2518public:
2519 // Implementation of Handler
2520 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2521 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2522 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2523 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2524 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2525 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2526 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2527
2528 bool RawNumber(const Ch* str, SizeType length, bool copy) {
2529 if (copy)
2530 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2531 else
2532 new (stack_.template Push<ValueType>()) ValueType(str, length);
2533 return true;
2534 }
2535
2536 bool String(const Ch* str, SizeType length, bool copy) {
2537 if (copy)
2538 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2539 else
2540 new (stack_.template Push<ValueType>()) ValueType(str, length);
2541 return true;
2542 }
2543
2544 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2545
2546 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2547
2548 bool EndObject(SizeType memberCount) {
2549 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2550 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2551 return true;
2552 }
2553
2554 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2555
2556 bool EndArray(SizeType elementCount) {
2557 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2558 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2559 return true;
2560 }
2561
2562private:
2566 GenericDocument& operator=(const GenericDocument&);
2567
2568 void ClearStack() {
2569 if (Allocator::kNeedFree)
2570 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2571 (stack_.template Pop<ValueType>(1))->~ValueType();
2572 else
2573 stack_.Clear();
2574 stack_.ShrinkToFit();
2575 }
2576
2577 void Destroy() {
2578 RAPIDJSON_DELETE(ownAllocator_);
2579 }
2580
2581 static const size_t kDefaultStackCapacity = 1024;
2582 Allocator* allocator_;
2583 Allocator* ownAllocator_;
2585 ParseResult parseResult_;
2586};
2587
2590
2591
2593
2597template <bool Const, typename ValueT>
2599public:
2602 typedef ValueT PlainType;
2603 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2604 typedef ValueType* ValueIterator; // This may be const or non-const iterator
2605 typedef const ValueT* ConstValueIterator;
2606 typedef typename ValueType::AllocatorType AllocatorType;
2607 typedef typename ValueType::StringRefType StringRefType;
2608
2609 template <typename, typename>
2610 friend class GenericValue;
2611
2612 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2613 GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2614 ~GenericArray() {}
2615
2616 operator ValueType&() const { return value_; }
2617 SizeType Size() const { return value_.Size(); }
2618 SizeType Capacity() const { return value_.Capacity(); }
2619 bool Empty() const { return value_.Empty(); }
2620 void Clear() const { value_.Clear(); }
2621 ValueType& operator[](SizeType index) const { return value_[index]; }
2622 ValueIterator Begin() const { return value_.Begin(); }
2623 ValueIterator End() const { return value_.End(); }
2624 GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2625 GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2626#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2627 GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2628#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2629 GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2630 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; }
2631 GenericArray PopBack() const { value_.PopBack(); return *this; }
2632 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2633 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2634
2635#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2636 ValueIterator begin() const { return value_.Begin(); }
2637 ValueIterator end() const { return value_.End(); }
2638#endif
2639
2640private:
2641 GenericArray();
2642 GenericArray(ValueType& value) : value_(value) {}
2643 ValueType& value_;
2644};
2645
2647
2651template <bool Const, typename ValueT>
2653public:
2656 typedef ValueT PlainType;
2657 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2660 typedef typename ValueType::AllocatorType AllocatorType;
2661 typedef typename ValueType::StringRefType StringRefType;
2662 typedef typename ValueType::EncodingType EncodingType;
2663 typedef typename ValueType::Ch Ch;
2664
2665 template <typename, typename>
2666 friend class GenericValue;
2667
2668 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2669 GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2670 ~GenericObject() {}
2671
2672 operator ValueType&() const { return value_; }
2673 SizeType MemberCount() const { return value_.MemberCount(); }
2674 SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2675 bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2676 template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2677 template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2678#if RAPIDJSON_HAS_STDSTRING
2679 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2680#endif
2681 MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2682 MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2683 GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2684 bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2685#if RAPIDJSON_HAS_STDSTRING
2686 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2687#endif
2688 template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2689 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2690 template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2691#if RAPIDJSON_HAS_STDSTRING
2692 MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2693#endif
2694 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2695 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2696#if RAPIDJSON_HAS_STDSTRING
2697 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2698#endif
2699 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; }
2700#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2701 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2702 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2703 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2704 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2705#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2706 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2707 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2708 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; }
2709 void RemoveAllMembers() { value_.RemoveAllMembers(); }
2710 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2711#if RAPIDJSON_HAS_STDSTRING
2712 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2713#endif
2714 template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2715 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2716 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
2717 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2718 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2719#if RAPIDJSON_HAS_STDSTRING
2720 bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2721#endif
2722 template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2723
2724#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2725 MemberIterator begin() const { return value_.MemberBegin(); }
2726 MemberIterator end() const { return value_.MemberEnd(); }
2727#endif
2728
2729private:
2730 GenericObject();
2731 GenericObject(ValueType& value) : value_(value) {}
2732 ValueType& value_;
2733};
2734
2736RAPIDJSON_DIAG_POP
2737
2738#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:2598
A document for parsing JSON text as DOM.
Definition document.h:2207
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition document.h:2314
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:2495
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition document.h:2385
Encoding::Ch Ch
Character type derived from Encoding.
Definition document.h:2209
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition document.h:2289
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition document.h:2419
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition document.h:2220
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition document.h:2471
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition document.h:2361
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition document.h:2233
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition document.h:2371
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition document.h:2342
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition document.h:2408
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition document.h:2474
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition document.h:2394
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition document.h:2501
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition document.h:2322
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition document.h:2477
Allocator AllocatorType
Allocator type from template parameter.
Definition document.h:2211
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition document.h:2210
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition document.h:2426
Name-value pair in a JSON object value.
Definition document.h:112
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition document.h:114
GenericValue< Encoding, Allocator > value
value of member.
Definition document.h:115
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition document.h:134
(Constant) member iterator for a JSON object value
Definition document.h:178
difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition document.h:208
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition document.h:190
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition document.h:232
GenericMemberIterator()
Default constructor (singular value)
Definition document.h:214
GenericMemberIterator Iterator
Iterator type itself.
Definition document.h:188
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition document.h:192
reference Reference
Reference to (const) GenericMember.
Definition document.h:206
DifferenceType operator-(ConstIterator that) const
Distance.
Definition document.h:274
pointer Pointer
Pointer to (const) GenericMember.
Definition document.h:204
Helper class for accessing Value of object type.
Definition document.h:2652
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:660
Encoding EncodingType
Encoding type from template parameter.
Definition document.h:664
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition document.h:783
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition document.h:2143
~GenericValue()
Destructor.
Definition document.h:882
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition document.h:833
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition document.h:2130
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition document.h:938
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition document.h:663
Encoding::Ch Ch
Character type derived from Encoding.
Definition document.h:666
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:839
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition document.h:670
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition document.h:667
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator)
Definition document.h:734
Allocator AllocatorType
Allocator type from template parameter.
Definition document.h:665
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition document.h:712
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition document.h:863
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition document.h:806
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition document.h:800
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition document.h:848
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition document.h:874
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition document.h:845
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition document.h:668
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition document.h:794
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition document.h:682
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition document.h:842
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition document.h:2167
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition document.h:836
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition document.h:821
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition document.h:2150
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition document.h:918
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition document.h:672
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition document.h:669
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition document.h:671
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:2193
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:446
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition document.h:2589
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
User defined kDefaultArrayCapacity value.
Definition document.h:102
#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:91
#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:680
@ kFalseType
false
Definition rapidjson.h:682
@ kObjectType
object
Definition rapidjson.h:684
@ kTrueType
true
Definition rapidjson.h:683
@ kStringType
string
Definition rapidjson.h:686
@ kNullType
null
Definition rapidjson.h:681
@ kArrayType
array
Definition rapidjson.h:685
@ kNumberType
number
Definition rapidjson.h:687
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:667
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:663
#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
Definition gtest_pred_impl_unittest.cc:56
A read-write string stream.
Definition stream.h:188
Reference to a constant string (not taking a copy)
Definition document.h:338
CharType Ch
character type of the string
Definition document.h:339
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition document.h:412
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
Definition document.h:466
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition document.h:403
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition document.h:391
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:446
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition document.h:367
const Ch *const s
plain CharType pointer
Definition document.h:411
Read-only string stream.
Definition stream.h:154
Definition document.h:2094
Definition document.h:2028
Definition document.h:2065
Definition document.h:2069
Definition document.h:2088
Definition document.h:2053
Definition document.h:2039
SizeType hashcode
reserved
Definition document.h:2041
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
Definition document.h:501
Definition document.h:494
Definition document.h:511
Definition document.h:2100
Definition document.h:2063