bes Updated for version 3.21.1
The Backend Server (BES) is the lower two tiers of the Hyrax data server
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
19
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>
111class GenericMember {
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>
177class GenericMemberIterator {
178
179 friend class GenericValue<Encoding,Allocator>;
180 template <bool, typename, typename> friend class GenericMemberIterator;
181
182 typedef GenericMember<Encoding,Allocator> PlainType;
183 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
184
185public:
187 typedef GenericMemberIterator Iterator;
189 typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator;
191 typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
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>
293 typedef GenericMember<Encoding,Allocator>* Iterator;
294};
296template <typename Encoding, typename Allocator>
299 typedef const GenericMember<Encoding,Allocator>* Iterator;
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) {
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>
491struct IsGenericValueImpl : FalseType {};
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;
670 typedef GenericArray<false, ValueType> Array;
671 typedef GenericArray<true, ValueType> ConstArray;
672 typedef GenericObject<false, ValueType> Object;
673 typedef GenericObject<true, ValueType> ConstObject;
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>
695 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
696
698 template <typename StackAllocator>
699 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
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;
2206 typedef GenericValue<Encoding, Allocator> ValueType;
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>
2360
2362
2366 template <typename InputStream>
2370
2371
2374
2376
2380 template <unsigned parseFlags>
2385
2387
2393
2394
2397
2399
2403 template <unsigned parseFlags, typename SourceEncoding>
2404 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2405 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
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));
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_;
2580 internal::Stack<StackAllocator> stack_;
2581 ParseResult parseResult_;
2582};
2583
2586
2587
2589
2593template <bool Const, typename ValueT>
2594class GenericArray {
2595public:
2596 typedef GenericArray<true, ValueT> ConstArray;
2597 typedef GenericArray<false, ValueT> Array;
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>
2647class GenericObject {
2648public:
2649 typedef GenericObject<true, ValueT> ConstObject;
2650 typedef GenericObject<false, ValueT> Object;
2651 typedef ValueT PlainType;
2652 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2653 typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
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.
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
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition document.h:231
GenericMemberIterator()
Default constructor (singular value)
Definition document.h:213
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Definition document.h:191
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
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
Concept for allocating, resizing and freeing memory block.
Concept for encoding of Unicode characters.
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.
Result of parsing (wraps ParseErrorCode)
Definition error.h:106