Arcane  v3.16.8.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
document.h
Aller à la documentation de ce fichier.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2// Tencent is pleased to support the open source community by making RapidJSON available.
3//
4// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
5//
6// Licensed under the MIT License (the "License"); you may not use this file except
7// in compliance with the License. You may obtain a copy of the License at
8//
9// http://opensource.org/licenses/MIT
10//
11// Unless required by applicable law or agreed to in writing, software distributed
12// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13// CONDITIONS OF ANY KIND, either express or implied. See the License for the
14// specific language governing permissions and limitations under the License.
15
16#ifndef RAPIDJSON_DOCUMENT_H_
17#define RAPIDJSON_DOCUMENT_H_
18
20
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#ifdef GetObject
47// see https://github.com/Tencent/rapidjson/issues/1448
48// a former included windows.h might have defined a macro called GetObject, which affects
49// GetObject defined here. This ensures the macro does not get applied
50#pragma push_macro("GetObject")
51#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
52#undef GetObject
53#endif
54
55#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
56#include <iterator> // std::random_access_iterator_tag
57#endif
58
59#if RAPIDJSON_USE_MEMBERSMAP
60#include <map> // std::multimap
61#endif
62
64
65// Forward declaration.
66template <typename Encoding, typename Allocator>
67class GenericValue;
68
69template <typename Encoding, typename Allocator, typename StackAllocator>
70class GenericDocument;
71
78#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
79#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
80#endif
81
88#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
89#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
90#endif
91
98#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
99// number of objects that rapidjson::Value allocates memory for by default
100#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
101#endif
102
109#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
110// number of array elements that rapidjson::Value allocates memory for by default
111#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
112#endif
113
115
120template <typename Encoding, typename Allocator>
122public:
125
126#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
128 GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
129 : name(std::move(rhs.name)),
130 value(std::move(rhs.value))
131 {
132 }
133
135 GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
136 return *this = static_cast<GenericMember&>(rhs);
137 }
138#endif
139
141
143 GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
144 if (RAPIDJSON_LIKELY(this != &rhs)) {
145 name = rhs.name;
146 value = rhs.value;
147 }
148 return *this;
149 }
150
151 // swap() for std::sort() and other potential use in STL.
152 friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
153 a.name.Swap(b.name);
154 a.value.Swap(b.value);
155 }
156
157private:
160};
161
163// GenericMemberIterator
164
165#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
166
168
186template <bool Const, typename Encoding, typename Allocator>
187class GenericMemberIterator {
188
189 friend class GenericValue<Encoding,Allocator>;
190 template <bool, typename, typename> friend class GenericMemberIterator;
191
192 typedef GenericMember<Encoding,Allocator> PlainType;
193 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
194
195public:
197 typedef GenericMemberIterator Iterator;
199 typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator;
201 typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
202
205 typedef ValueType value_type;
206 typedef ValueType * pointer;
207 typedef ValueType & reference;
208 typedef std::ptrdiff_t difference_type;
209 typedef std::random_access_iterator_tag iterator_category;
211
213 typedef pointer Pointer;
215 typedef reference Reference;
217 typedef difference_type DifferenceType;
218
220
224
226
242 Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
243
245
246 Iterator& operator++(){ ++ptr_; return *this; }
247 Iterator& operator--(){ --ptr_; return *this; }
248 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
249 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
251
253
254 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
255 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
256
257 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
258 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
260
262
263 template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
264 template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
265 template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
266 template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
267 template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
268 template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
269
270#ifdef __cpp_lib_three_way_comparison
271 template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
272#endif
274
276
277 Reference operator*() const { return *ptr_; }
278 Pointer operator->() const { return ptr_; }
279 Reference operator[](DifferenceType n) const { return ptr_[n]; }
281
283 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
284
285private:
288
290};
291
292#else // RAPIDJSON_NOMEMBERITERATORCLASS
293
294// class-based member iterator implementation disabled, use plain pointers
295
296template <bool Const, typename Encoding, typename Allocator>
298
300template <typename Encoding, typename Allocator>
302public:
305};
307template <typename Encoding, typename Allocator>
309public:
311 typedef const GenericMember<Encoding,Allocator>* Iterator;
312};
313
314#endif // RAPIDJSON_NOMEMBERITERATORCLASS
315
317// GenericStringRef
318
320
346template<typename CharType>
348 typedef CharType Ch;
349
351#ifndef __clang__ // -Wdocumentation
374#endif
375 template<SizeType N>
376 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
377 : s(str), length(N-1) {}
378
380#ifndef __clang__ // -Wdocumentation
399#endif
400 explicit GenericStringRef(const CharType* str)
401 : s(str), length(NotNullStrLen(str)) {}
402
404#ifndef __clang__ // -Wdocumentation
411#endif
412 GenericStringRef(const CharType* str, SizeType len)
413 : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
414
415 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
416
418 operator const Ch *() const { return s; }
419
420 const Ch* const s;
422
423private:
424 SizeType NotNullStrLen(const CharType* str) {
425 RAPIDJSON_ASSERT(str != 0);
426 return internal::StrLen(str);
427 }
428
430 static const Ch emptyString[];
431
433 template<SizeType N>
434 GenericStringRef(CharType (&str)[N]) /* = delete */;
436 GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
437};
438
439template<typename CharType>
440const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
441
443
454template<typename CharType>
455inline GenericStringRef<CharType> StringRef(const CharType* str) {
456 return GenericStringRef<CharType>(str);
457}
458
460
474template<typename CharType>
475inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
477}
478
479#if RAPIDJSON_HAS_STDSTRING
481
492template<typename CharType>
493inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
494 return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
495}
496#endif
497
499// GenericValue type traits
500namespace internal {
501
502template <typename T, typename Encoding = void, typename Allocator = void>
503struct IsGenericValueImpl : FalseType {};
504
505// select candidates according to nested encoding and allocator types
506template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
507 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
508
509// helper to match arbitrary GenericValue instantiations, including derived classes
510template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
511
512} // namespace internal
513
515// TypeHelper
516
517namespace internal {
518
519template <typename ValueType, typename T>
520struct TypeHelper {};
521
522template<typename ValueType>
523struct TypeHelper<ValueType, bool> {
524 static bool Is(const ValueType& v) { return v.IsBool(); }
525 static bool Get(const ValueType& v) { return v.GetBool(); }
526 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
527 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
528};
529
530template<typename ValueType>
531struct TypeHelper<ValueType, int> {
532 static bool Is(const ValueType& v) { return v.IsInt(); }
533 static int Get(const ValueType& v) { return v.GetInt(); }
534 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
535 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
536};
537
538template<typename ValueType>
539struct TypeHelper<ValueType, unsigned> {
540 static bool Is(const ValueType& v) { return v.IsUint(); }
541 static unsigned Get(const ValueType& v) { return v.GetUint(); }
542 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
543 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
544};
545
546#ifdef _MSC_VER
547RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
548template<typename ValueType>
549struct TypeHelper<ValueType, long> {
550 static bool Is(const ValueType& v) { return v.IsInt(); }
551 static long Get(const ValueType& v) { return v.GetInt(); }
552 static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
553 static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
554};
555
556RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
557template<typename ValueType>
558struct TypeHelper<ValueType, unsigned long> {
559 static bool Is(const ValueType& v) { return v.IsUint(); }
560 static unsigned long Get(const ValueType& v) { return v.GetUint(); }
561 static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
562 static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
563};
564#endif
565
566template<typename ValueType>
567struct TypeHelper<ValueType, int64_t> {
568 static bool Is(const ValueType& v) { return v.IsInt64(); }
569 static int64_t Get(const ValueType& v) { return v.GetInt64(); }
570 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
571 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
572};
573
574template<typename ValueType>
575struct TypeHelper<ValueType, uint64_t> {
576 static bool Is(const ValueType& v) { return v.IsUint64(); }
577 static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
578 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
579 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
580};
581
582template<typename ValueType>
583struct TypeHelper<ValueType, double> {
584 static bool Is(const ValueType& v) { return v.IsDouble(); }
585 static double Get(const ValueType& v) { return v.GetDouble(); }
586 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
587 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
588};
589
590template<typename ValueType>
591struct TypeHelper<ValueType, float> {
592 static bool Is(const ValueType& v) { return v.IsFloat(); }
593 static float Get(const ValueType& v) { return v.GetFloat(); }
594 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
595 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
596};
597
598template<typename ValueType>
599struct TypeHelper<ValueType, const typename ValueType::Ch*> {
600 typedef const typename ValueType::Ch* StringType;
601 static bool Is(const ValueType& v) { return v.IsString(); }
602 static StringType Get(const ValueType& v) { return v.GetString(); }
603 static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
604 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
605};
606
607#if RAPIDJSON_HAS_STDSTRING
608template<typename ValueType>
609struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
610 typedef std::basic_string<typename ValueType::Ch> StringType;
611 static bool Is(const ValueType& v) { return v.IsString(); }
612 static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
613 static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
614};
615#endif
616
617template<typename ValueType>
618struct TypeHelper<ValueType, typename ValueType::Array> {
619 typedef typename ValueType::Array ArrayType;
620 static bool Is(const ValueType& v) { return v.IsArray(); }
621 static ArrayType Get(ValueType& v) { return v.GetArray(); }
622 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
623 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
624};
625
626template<typename ValueType>
627struct TypeHelper<ValueType, typename ValueType::ConstArray> {
628 typedef typename ValueType::ConstArray ArrayType;
629 static bool Is(const ValueType& v) { return v.IsArray(); }
630 static ArrayType Get(const ValueType& v) { return v.GetArray(); }
631};
632
633template<typename ValueType>
634struct TypeHelper<ValueType, typename ValueType::Object> {
635 typedef typename ValueType::Object ObjectType;
636 static bool Is(const ValueType& v) { return v.IsObject(); }
637 static ObjectType Get(ValueType& v) { return v.GetObject(); }
638 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
639 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
640};
641
642template<typename ValueType>
643struct TypeHelper<ValueType, typename ValueType::ConstObject> {
644 typedef typename ValueType::ConstObject ObjectType;
645 static bool Is(const ValueType& v) { return v.IsObject(); }
646 static ObjectType Get(const ValueType& v) { return v.GetObject(); }
647};
648
649} // namespace internal
650
651// Forward declarations
652template <bool, typename> class GenericArray;
653template <bool, typename> class GenericObject;
654
656// GenericValue
657
659
668template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
670public:
675 typedef typename Encoding::Ch Ch;
682 typedef GenericArray<false, ValueType> Array;
683 typedef GenericArray<true, ValueType> ConstArray;
684 typedef GenericObject<false, ValueType> Object;
685 typedef GenericObject<true, ValueType> ConstObject;
686
688
689
691 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
692
693#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
695 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
696 rhs.data_.f.flags = kNullFlag; // give up contents
697 }
698#endif
699
700private:
703
704#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
706 template <typename StackAllocator>
707 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
708
710 template <typename StackAllocator>
711 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
712#endif
713
714public:
715
717
721 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
722 static const uint16_t defaultFlags[] = {
723 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
724 kNumberAnyFlag
725 };
727 data_.f.flags = defaultFlags[type];
728
729 // Use ShortString to store empty string.
730 if (type == kStringType)
731 data_.ss.SetLength(0);
732 }
733
735
742 template <typename SourceAllocator>
743 GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
744 switch (rhs.GetType()) {
745 case kObjectType:
746 DoCopyMembers(rhs, allocator, copyConstStrings);
747 break;
748 case kArrayType: {
749 SizeType count = rhs.data_.a.size;
750 GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
751 const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
752 for (SizeType i = 0; i < count; i++)
753 new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
754 data_.f.flags = kArrayFlag;
755 data_.a.size = data_.a.capacity = count;
756 SetElementsPointer(le);
757 }
758 break;
759 case kStringType:
760 if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
761 data_.f.flags = rhs.data_.f.flags;
762 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
763 }
764 else
765 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
766 break;
767 default:
768 data_.f.flags = rhs.data_.f.flags;
769 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
770 break;
771 }
772 }
773
775
780#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
781 template <typename T>
782 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
783#else
784 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
785#endif
786 : data_() {
787 // safe-guard against failing SFINAE
788 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
789 data_.f.flags = b ? kTrueFlag : kFalseFlag;
790 }
791
793 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
794 data_.n.i64 = i;
795 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
796 }
797
799 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
800 data_.n.u64 = u;
801 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
802 }
803
805 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
806 data_.n.i64 = i64;
807 data_.f.flags = kNumberInt64Flag;
808 if (i64 >= 0) {
809 data_.f.flags |= kNumberUint64Flag;
810 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
811 data_.f.flags |= kUintFlag;
812 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
813 data_.f.flags |= kIntFlag;
814 }
815 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
816 data_.f.flags |= kIntFlag;
817 }
818
820 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
821 data_.n.u64 = u64;
822 data_.f.flags = kNumberUint64Flag;
823 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
824 data_.f.flags |= kInt64Flag;
825 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
826 data_.f.flags |= kUintFlag;
827 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
828 data_.f.flags |= kIntFlag;
829 }
830
832 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
833
835 explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
836
838 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
839
841 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
842
844 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
845
847 GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
848
849#if RAPIDJSON_HAS_STDSTRING
851
853 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
854#endif
855
857
862 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
863 a.value_.data_ = Data();
864 a.value_.data_.f.flags = kArrayFlag;
865 }
866
868
873 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
874 o.value_.data_ = Data();
875 o.value_.data_.f.flags = kObjectFlag;
876 }
877
879
882 // With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release
883 // their Allocator if it's refcounted (e.g. MemoryPoolAllocator).
884 if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
886 switch(data_.f.flags) {
887 case kArrayFlag:
888 {
889 GenericValue* e = GetElementsPointer();
890 for (GenericValue* v = e; v != e + data_.a.size; ++v)
891 v->~GenericValue();
892 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
893 Allocator::Free(e);
894 }
895 }
896 break;
897
898 case kObjectFlag:
899 DoFreeMembers();
900 break;
901
902 case kCopyStringFlag:
903 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
904 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
905 }
906 break;
907
908 default:
909 break; // Do nothing for other types.
910 }
911 }
912 }
913
915
917
918
920
922 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
923 if (RAPIDJSON_LIKELY(this != &rhs)) {
924 // Can't destroy "this" before assigning "rhs", otherwise "rhs"
925 // could be used after free if it's an sub-Value of "this",
926 // hence the temporary danse.
927 GenericValue temp;
928 temp.RawAssign(rhs);
929 this->~GenericValue();
930 RawAssign(temp);
931 }
932 return *this;
933 }
934
935#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
937 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
938 return *this = rhs.Move();
939 }
940#endif
941
943
947 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
948 GenericValue s(str);
949 return *this = s;
950 }
951
953
964 template <typename T>
965 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
966 operator=(T value) {
967 GenericValue v(value);
968 return *this = v;
969 }
970
972
978 template <typename SourceAllocator>
979 GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
980 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
981 this->~GenericValue();
982 new (this) GenericValue(rhs, allocator, copyConstStrings);
983 return *this;
984 }
985
987
991 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
992 GenericValue temp;
993 temp.RawAssign(*this);
994 RawAssign(other);
995 other.RawAssign(temp);
996 return *this;
997 }
998
1000
1011 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1012
1014
1015 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
1017
1019
1020
1025 template <typename SourceAllocator>
1026 bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
1028 if (GetType() != rhs.GetType())
1029 return false;
1030
1031 switch (GetType()) {
1032 case kObjectType: // Warning: O(n^2) inner-loop
1033 if (data_.o.size != rhs.data_.o.size)
1034 return false;
1035 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1036 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1037 if (rhsMemberItr == rhs.MemberEnd() || (!(lhsMemberItr->value == rhsMemberItr->value)))
1038 return false;
1039 }
1040 return true;
1041
1042 case kArrayType:
1043 if (data_.a.size != rhs.data_.a.size)
1044 return false;
1045 for (SizeType i = 0; i < data_.a.size; i++)
1046 if (!((*this)[i] == rhs[i]))
1047 return false;
1048 return true;
1049
1050 case kStringType:
1051 return StringEqual(rhs);
1052
1053 case kNumberType:
1054 if (IsDouble() || rhs.IsDouble()) {
1055 double a = GetDouble(); // May convert from integer to double.
1056 double b = rhs.GetDouble(); // Ditto
1057 return a >= b && a <= b; // Prevent -Wfloat-equal
1058 }
1059 else
1060 return data_.n.u64 == rhs.data_.n.u64;
1061
1062 default:
1063 return true;
1064 }
1065 }
1066
1068 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1069
1070#if RAPIDJSON_HAS_STDSTRING
1072
1074 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
1075#endif
1076
1078
1080 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
1081
1082#ifndef __cpp_impl_three_way_comparison
1084
1086 template <typename SourceAllocator>
1087 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1088
1090 bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1091
1093
1095 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1096
1098
1100 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1101
1103
1105 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1107#endif
1108
1110
1111
1112 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1113 bool IsNull() const { return data_.f.flags == kNullFlag; }
1114 bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1115 bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1116 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1117 bool IsObject() const { return data_.f.flags == kObjectFlag; }
1118 bool IsArray() const { return data_.f.flags == kArrayFlag; }
1119 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1120 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1121 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1122 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1123 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1124 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1125 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1126
1127 // Checks whether a number can be losslessly converted to a double.
1128 bool IsLosslessDouble() const {
1129 if (!IsNumber()) return false;
1130 if (IsUint64()) {
1131 uint64_t u = GetUint64();
1132 volatile double d = static_cast<double>(u);
1133 return (d >= 0.0)
1134 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1135 && (u == static_cast<uint64_t>(d));
1136 }
1137 if (IsInt64()) {
1138 int64_t i = GetInt64();
1139 volatile double d = static_cast<double>(i);
1140 return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1141 && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1142 && (i == static_cast<int64_t>(d));
1143 }
1144 return true; // double, int, uint are always lossless
1145 }
1146
1147 // Checks whether a number is a float (possible lossy).
1148 bool IsFloat() const {
1149 if ((data_.f.flags & kDoubleFlag) == 0)
1150 return false;
1151 double d = GetDouble();
1152 return d >= -3.4028234e38 && d <= 3.4028234e38;
1153 }
1154 // Checks whether a number can be losslessly converted to a float.
1155 bool IsLosslessFloat() const {
1156 if (!IsNumber()) return false;
1157 double a = GetDouble();
1158 if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1159 || a > static_cast<double>((std::numeric_limits<float>::max)()))
1160 return false;
1161 double b = static_cast<double>(static_cast<float>(a));
1162 return a >= b && a <= b; // Prevent -Wfloat-equal
1163 }
1164
1166
1168
1169
1170 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1171
1173
1175
1176
1177 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1179
1180 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1181
1183
1185
1186
1188
1189 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1190
1192 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1193
1195 SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1196
1198 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1199
1201
1209 template <typename T>
1210 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1211 GenericValue n(StringRef(name));
1212 return (*this)[n];
1213 }
1214 template <typename T>
1215 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]; }
1216
1218
1226 template <typename SourceAllocator>
1227 GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1228 MemberIterator member = FindMember(name);
1229 if (member != MemberEnd())
1230 return member->value;
1231 else {
1232 RAPIDJSON_ASSERT(false); // see above note
1233
1234#if RAPIDJSON_HAS_CXX11
1235 // Use thread-local storage to prevent races between threads.
1236 // Use static buffer and placement-new to prevent destruction, with
1237 // alignas() to ensure proper alignment.
1238 alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
1239 return *new (buffer) GenericValue();
1240#elif defined(_MSC_VER) && _MSC_VER < 1900
1241 // There's no way to solve both thread locality and proper alignment
1242 // simultaneously.
1243 __declspec(thread) static char buffer[sizeof(GenericValue)];
1244 return *new (buffer) GenericValue();
1245#elif defined(__GNUC__) || defined(__clang__)
1246 // This will generate -Wexit-time-destructors in clang, but that's
1247 // better than having under-alignment.
1248 __thread static GenericValue buffer;
1249 return buffer;
1250#else
1251 // Don't know what compiler this is, so don't know how to ensure
1252 // thread-locality.
1253 static GenericValue buffer;
1254 return buffer;
1255#endif
1256 }
1257 }
1258 template <typename SourceAllocator>
1259 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1260
1261#if RAPIDJSON_HAS_STDSTRING
1263 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1264 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1265#endif
1266
1268
1269 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1271
1272 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1274
1275 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1277
1278 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1279
1281
1286 GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1287 RAPIDJSON_ASSERT(IsObject());
1288 DoReserveMembers(newCapacity, allocator);
1289 return *this;
1290 }
1291
1293
1300 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1301
1302#if RAPIDJSON_HAS_STDSTRING
1304
1311 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1312#endif
1313
1315
1323 template <typename SourceAllocator>
1324 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1325
1327
1338 MemberIterator FindMember(const Ch* name) {
1339 GenericValue n(StringRef(name));
1340 return FindMember(n);
1341 }
1342
1343 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1344
1346
1358 template <typename SourceAllocator>
1360 RAPIDJSON_ASSERT(IsObject());
1361 RAPIDJSON_ASSERT(name.IsString());
1362 return DoFindMember(name);
1363 }
1364 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1365
1366#if RAPIDJSON_HAS_STDSTRING
1368
1374 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1375 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1376#endif
1377
1379
1388 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1389 RAPIDJSON_ASSERT(IsObject());
1390 RAPIDJSON_ASSERT(name.IsString());
1391 DoAddMember(name, value, allocator);
1392 return *this;
1393 }
1394
1396
1404 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1405 GenericValue v(value);
1406 return AddMember(name, v, allocator);
1407 }
1408
1409#if RAPIDJSON_HAS_STDSTRING
1411
1419 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1420 GenericValue v(value, allocator);
1421 return AddMember(name, v, allocator);
1422 }
1423#endif
1424
1426
1442 template <typename T>
1443 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1444 AddMember(GenericValue& name, T value, Allocator& allocator) {
1445 GenericValue v(value);
1446 return AddMember(name, v, allocator);
1447 }
1448
1449#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1450 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1451 return AddMember(name, value, allocator);
1452 }
1453 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1454 return AddMember(name, value, allocator);
1455 }
1456 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1457 return AddMember(name, value, allocator);
1458 }
1459 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1460 GenericValue n(name);
1461 return AddMember(n, value, allocator);
1462 }
1463#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1464
1465
1467
1476 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1477 GenericValue n(name);
1478 return AddMember(n, value, allocator);
1479 }
1480
1482
1490 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1491 GenericValue v(value);
1492 return AddMember(name, v, allocator);
1493 }
1494
1496
1512 template <typename T>
1513 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1514 AddMember(StringRefType name, T value, Allocator& allocator) {
1515 GenericValue n(name);
1516 return AddMember(n, value, allocator);
1517 }
1518
1520
1523 void RemoveAllMembers() {
1524 RAPIDJSON_ASSERT(IsObject());
1525 DoClearMembers();
1526 }
1527
1529
1536 bool RemoveMember(const Ch* name) {
1537 GenericValue n(StringRef(name));
1538 return RemoveMember(n);
1539 }
1540
1541#if RAPIDJSON_HAS_STDSTRING
1542 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1543#endif
1544
1545 template <typename SourceAllocator>
1546 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1547 MemberIterator m = FindMember(name);
1548 if (m != MemberEnd()) {
1549 RemoveMember(m);
1550 return true;
1551 }
1552 else
1553 return false;
1554 }
1555
1557
1564 MemberIterator RemoveMember(MemberIterator m) {
1565 RAPIDJSON_ASSERT(IsObject());
1566 RAPIDJSON_ASSERT(data_.o.size > 0);
1567 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1568 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1569 return DoRemoveMember(m);
1570 }
1571
1573
1581 MemberIterator EraseMember(ConstMemberIterator pos) {
1582 return EraseMember(pos, pos +1);
1583 }
1584
1586
1594 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1595 RAPIDJSON_ASSERT(IsObject());
1596 RAPIDJSON_ASSERT(data_.o.size > 0);
1597 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1598 RAPIDJSON_ASSERT(first >= MemberBegin());
1599 RAPIDJSON_ASSERT(first <= last);
1600 RAPIDJSON_ASSERT(last <= MemberEnd());
1601 return DoEraseMembers(first, last);
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 Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1631 ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1632 ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1633
1635
1637
1638
1640
1641 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1642
1644 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1645
1647 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1648
1650 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1651
1653
1656 void Clear() {
1657 RAPIDJSON_ASSERT(IsArray());
1658 GenericValue* e = GetElementsPointer();
1659 for (GenericValue* v = e; v != e + data_.a.size; ++v)
1660 v->~GenericValue();
1661 data_.a.size = 0;
1662 }
1663
1665
1669 GenericValue& operator[](SizeType index) {
1670 RAPIDJSON_ASSERT(IsArray());
1671 RAPIDJSON_ASSERT(index < data_.a.size);
1672 return GetElementsPointer()[index];
1673 }
1674 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1675
1677
1678 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1680
1681 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1683
1684 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1686
1687 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1688
1690
1695 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1696 RAPIDJSON_ASSERT(IsArray());
1697 if (newCapacity > data_.a.capacity) {
1698 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1699 data_.a.capacity = newCapacity;
1700 }
1701 return *this;
1702 }
1703
1705
1714 GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1715 RAPIDJSON_ASSERT(IsArray());
1716 if (data_.a.size >= data_.a.capacity)
1717 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1718 GetElementsPointer()[data_.a.size++].RawAssign(value);
1719 return *this;
1720 }
1721
1722#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1723 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1724 return PushBack(value, allocator);
1725 }
1726#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1727
1729
1737 GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1738 return (*this).template PushBack<StringRefType>(value, allocator);
1739 }
1740
1742
1758 template <typename T>
1759 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1760 PushBack(T value, Allocator& allocator) {
1761 GenericValue v(value);
1762 return PushBack(v, allocator);
1763 }
1764
1766
1769 GenericValue& PopBack() {
1770 RAPIDJSON_ASSERT(IsArray());
1771 RAPIDJSON_ASSERT(!Empty());
1772 GetElementsPointer()[--data_.a.size].~GenericValue();
1773 return *this;
1774 }
1775
1777
1784 return Erase(pos, pos + 1);
1785 }
1786
1788
1796 RAPIDJSON_ASSERT(IsArray());
1797 RAPIDJSON_ASSERT(data_.a.size > 0);
1798 RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1799 RAPIDJSON_ASSERT(first >= Begin());
1800 RAPIDJSON_ASSERT(first <= last);
1801 RAPIDJSON_ASSERT(last <= End());
1802 ValueIterator pos = Begin() + (first - Begin());
1803 for (ValueIterator itr = pos; itr != last; ++itr)
1804 itr->~GenericValue();
1805 std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1806 data_.a.size -= static_cast<SizeType>(last - first);
1807 return pos;
1808 }
1809
1810 Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1811 ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1812
1814
1816
1817
1818 int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1819 unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1820 int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1821 uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1822
1824
1826 double GetDouble() const {
1827 RAPIDJSON_ASSERT(IsNumber());
1828 if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1829 if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1830 if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1831 if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1832 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1833 }
1834
1836
1838 float GetFloat() const {
1839 return static_cast<float>(GetDouble());
1840 }
1841
1842 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1843 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1844 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1845 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1846 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1847 GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1848
1850
1852
1853
1854 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
1855
1857
1859 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
1860
1862
1869 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1870
1872
1876 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1877
1879
1886 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1887
1889
1894 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1895
1897
1902 GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1903
1904#if RAPIDJSON_HAS_STDSTRING
1906
1912 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1913#endif
1914
1916
1918
1919
1921
1924 template <typename T>
1925 bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1926
1927 template <typename T>
1928 T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1929
1930 template <typename T>
1931 T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1932
1933 template<typename T>
1934 ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1935
1936 template<typename T>
1937 ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1938
1940
1942
1948 template <typename Handler>
1949 bool Accept(Handler& handler) const {
1950 switch(GetType()) {
1951 case kNullType: return handler.Null();
1952 case kFalseType: return handler.Bool(false);
1953 case kTrueType: return handler.Bool(true);
1954
1955 case kObjectType:
1956 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1957 return false;
1958 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1959 RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1960 if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1961 return false;
1962 if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1963 return false;
1964 }
1965 return handler.EndObject(data_.o.size);
1966
1967 case kArrayType:
1968 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1969 return false;
1970 for (ConstValueIterator v = Begin(); v != End(); ++v)
1971 if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1972 return false;
1973 return handler.EndArray(data_.a.size);
1974
1975 case kStringType:
1976 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1977
1978 default:
1979 RAPIDJSON_ASSERT(GetType() == kNumberType);
1980 if (IsDouble()) return handler.Double(data_.n.d);
1981 else if (IsInt()) return handler.Int(data_.n.i.i);
1982 else if (IsUint()) return handler.Uint(data_.n.u.u);
1983 else if (IsInt64()) return handler.Int64(data_.n.i64);
1984 else return handler.Uint64(data_.n.u64);
1985 }
1986 }
1987
1988private:
1989 template <typename, typename> friend class GenericValue;
1990 template <typename, typename, typename> friend class GenericDocument;
1991
1992 enum {
1993 kBoolFlag = 0x0008,
1994 kNumberFlag = 0x0010,
1995 kIntFlag = 0x0020,
1996 kUintFlag = 0x0040,
1997 kInt64Flag = 0x0080,
1998 kUint64Flag = 0x0100,
1999 kDoubleFlag = 0x0200,
2000 kStringFlag = 0x0400,
2001 kCopyFlag = 0x0800,
2002 kInlineStrFlag = 0x1000,
2003
2004 // Initial flags of different types.
2005 kNullFlag = kNullType,
2006 // These casts are added to suppress the warning on MSVC about bitwise operations between enums of different types.
2007 kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
2008 kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
2009 kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
2010 kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
2011 kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
2012 kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
2013 kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
2014 kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
2015 kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
2016 kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
2017 kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2018 kObjectFlag = kObjectType,
2019 kArrayFlag = kArrayType,
2020
2021 kTypeMask = 0x07
2022 };
2023
2024 static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
2025 static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
2026
2027 struct Flag {
2028#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2029 char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
2030#elif RAPIDJSON_64BIT
2031 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
2032#else
2033 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
2034#endif
2035 uint16_t flags;
2036 };
2037
2038 struct String {
2039 SizeType length;
2041 const Ch* str;
2042 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2043
2044 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
2045 // (excluding the terminating zero) and store a value to determine the length of the contained
2046 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
2047 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
2048 // the string terminator as well. For getting the string length back from that value just use
2049 // "MaxSize - str[LenPos]".
2050 // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2051 // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
2053 enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2054 Ch str[MaxChars];
2055
2056 inline static bool Usable(SizeType len) { return (MaxSize >= len); }
2057 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2058 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
2059 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2060
2061 // By using proper binary layout, retrieval of different integer types do not need conversions.
2062 union Number {
2063#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2064 struct I {
2065 int i;
2066 char padding[4];
2067 }i;
2068 struct U {
2069 unsigned u;
2070 char padding2[4];
2071 }u;
2072#else
2073 struct I {
2074 char padding[4];
2075 int i;
2076 }i;
2077 struct U {
2078 char padding2[4];
2079 unsigned u;
2080 }u;
2081#endif
2082 int64_t i64;
2083 uint64_t u64;
2084 double d;
2085 }; // 8 bytes
2086
2087 struct ObjectData {
2088 SizeType size;
2089 SizeType capacity;
2090 Member* members;
2091 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2092
2093 struct ArrayData {
2094 SizeType size;
2095 SizeType capacity;
2096 GenericValue* elements;
2097 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2098
2099 union Data {
2100 String s;
2101 ShortString ss;
2102 Number n;
2103 ObjectData o;
2104 ArrayData a;
2105 Flag f;
2106 }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2107
2108 static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
2109 return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
2110 }
2111 static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
2112 return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2113 }
2114
2115 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2116 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2117 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2118 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2119 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2120 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2121
2122#if RAPIDJSON_USE_MEMBERSMAP
2123
2124 struct MapTraits {
2125 struct Less {
2126 bool operator()(const Data& s1, const Data& s2) const {
2127 SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
2128 int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2));
2129 return cmp < 0 || (cmp == 0 && n1 < n2);
2130 }
2131 };
2132 typedef std::pair<const Data, SizeType> Pair;
2133 typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
2134 typedef typename Map::iterator Iterator;
2135 };
2136 typedef typename MapTraits::Map Map;
2137 typedef typename MapTraits::Less MapLess;
2138 typedef typename MapTraits::Pair MapPair;
2139 typedef typename MapTraits::Iterator MapIterator;
2140
2141 //
2142 // Layout of the members' map/array, re(al)located according to the needed capacity:
2143 //
2144 // {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]}
2145 //
2146 // (where <> stands for the RAPIDJSON_ALIGN-ment, if needed)
2147 //
2148
2149 static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) {
2150 return RAPIDJSON_ALIGN(sizeof(Map*)) +
2151 RAPIDJSON_ALIGN(sizeof(SizeType)) +
2152 RAPIDJSON_ALIGN(capacity * sizeof(Member)) +
2153 capacity * sizeof(MapIterator);
2154 }
2155
2156 static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) {
2157 return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
2158 RAPIDJSON_ALIGN(sizeof(Map*)));
2159 }
2160
2161 static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) {
2162 return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
2163 RAPIDJSON_ALIGN(sizeof(Map*)) +
2164 RAPIDJSON_ALIGN(sizeof(SizeType)));
2165 }
2166
2167 static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
2168 return reinterpret_cast<MapIterator*>(reinterpret_cast<uintptr_t>(&map) +
2169 RAPIDJSON_ALIGN(sizeof(Map*)) +
2170 RAPIDJSON_ALIGN(sizeof(SizeType)) +
2171 RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member)));
2172 }
2173
2174 static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) {
2175 RAPIDJSON_ASSERT(members != 0);
2176 return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
2177 RAPIDJSON_ALIGN(sizeof(SizeType)) -
2178 RAPIDJSON_ALIGN(sizeof(Map*)));
2179 }
2180
2181 // Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting..
2182 RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
2183#if RAPIDJSON_HAS_CXX11
2184 MapIterator ret = std::move(rhs);
2185#else
2186 MapIterator ret = rhs;
2187#endif
2188 rhs.~MapIterator();
2189 return ret;
2190 }
2191
2192 Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) {
2193 Map **newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
2194 GetMapCapacity(*newMap) = newCapacity;
2195 if (!oldMap) {
2196 *newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator);
2197 }
2198 else {
2199 *newMap = *oldMap;
2200 size_t count = (*oldMap)->size();
2201 std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
2202 static_cast<void*>(GetMapMembers(*oldMap)),
2203 count * sizeof(Member));
2204 MapIterator *oldIt = GetMapIterators(*oldMap),
2205 *newIt = GetMapIterators(*newMap);
2206 while (count--) {
2207 new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
2208 }
2209 Allocator::Free(oldMap);
2210 }
2211 return *newMap;
2212 }
2213
2214 RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2215 return GetMapMembers(DoReallocMap(0, capacity, allocator));
2216 }
2217
2218 void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2219 ObjectData& o = data_.o;
2220 if (newCapacity > o.capacity) {
2221 Member* oldMembers = GetMembersPointer();
2222 Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
2223 *&newMap = DoReallocMap(oldMap, newCapacity, allocator);
2224 RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
2225 o.capacity = newCapacity;
2226 }
2227 }
2228
2229 template <typename SourceAllocator>
2231 if (Member* members = GetMembersPointer()) {
2232 Map* &map = GetMap(members);
2233 MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
2234 if (mit != map->end()) {
2235 return MemberIterator(&members[mit->second]);
2236 }
2237 }
2238 return MemberEnd();
2239 }
2240
2241 void DoClearMembers() {
2242 if (Member* members = GetMembersPointer()) {
2243 Map* &map = GetMap(members);
2244 MapIterator* mit = GetMapIterators(map);
2245 for (SizeType i = 0; i < data_.o.size; i++) {
2246 map->erase(DropMapIterator(mit[i]));
2247 members[i].~Member();
2248 }
2249 data_.o.size = 0;
2250 }
2251 }
2252
2253 void DoFreeMembers() {
2254 if (Member* members = GetMembersPointer()) {
2255 GetMap(members)->~Map();
2256 for (SizeType i = 0; i < data_.o.size; i++) {
2257 members[i].~Member();
2258 }
2259 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
2260 Map** map = &GetMap(members);
2261 Allocator::Free(*map);
2262 Allocator::Free(map);
2263 }
2264 }
2265 }
2266
2267#else // !RAPIDJSON_USE_MEMBERSMAP
2268
2269 RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2270 return Malloc<Member>(allocator, capacity);
2271 }
2272
2273 void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2274 ObjectData& o = data_.o;
2275 if (newCapacity > o.capacity) {
2276 Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2277 RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
2278 o.capacity = newCapacity;
2279 }
2280 }
2281
2282 template <typename SourceAllocator>
2284 MemberIterator member = MemberBegin();
2285 for ( ; member != MemberEnd(); ++member)
2286 if (name.StringEqual(member->name))
2287 break;
2288 return member;
2289 }
2290
2291 void DoClearMembers() {
2292 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2293 m->~Member();
2294 data_.o.size = 0;
2295 }
2296
2297 void DoFreeMembers() {
2298 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2299 m->~Member();
2300 Allocator::Free(GetMembersPointer());
2301 }
2302
2303#endif // !RAPIDJSON_USE_MEMBERSMAP
2304
2305 void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
2306 ObjectData& o = data_.o;
2307 if (o.size >= o.capacity)
2308 DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
2309 Member* members = GetMembersPointer();
2310 Member* m = members + o.size;
2311 m->name.RawAssign(name);
2312 m->value.RawAssign(value);
2313#if RAPIDJSON_USE_MEMBERSMAP
2314 Map* &map = GetMap(members);
2315 MapIterator* mit = GetMapIterators(map);
2316 new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
2317#endif
2318 ++o.size;
2319 }
2320
2321 MemberIterator DoRemoveMember(MemberIterator m) {
2322 ObjectData& o = data_.o;
2323 Member* members = GetMembersPointer();
2324#if RAPIDJSON_USE_MEMBERSMAP
2325 Map* &map = GetMap(members);
2326 MapIterator* mit = GetMapIterators(map);
2327 SizeType mpos = static_cast<SizeType>(&*m - members);
2328 map->erase(DropMapIterator(mit[mpos]));
2329#endif
2330 MemberIterator last(members + (o.size - 1));
2331 if (o.size > 1 && m != last) {
2332#if RAPIDJSON_USE_MEMBERSMAP
2333 new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
2334 mit[mpos]->second = mpos;
2335#endif
2336 *m = *last; // Move the last one to this place
2337 }
2338 else {
2339 m->~Member(); // Only one left, just destroy
2340 }
2341 --o.size;
2342 return m;
2343 }
2344
2345 MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) {
2346 ObjectData& o = data_.o;
2347 MemberIterator beg = MemberBegin(),
2348 pos = beg + (first - beg),
2349 end = MemberEnd();
2350#if RAPIDJSON_USE_MEMBERSMAP
2351 Map* &map = GetMap(GetMembersPointer());
2352 MapIterator* mit = GetMapIterators(map);
2353#endif
2354 for (MemberIterator itr = pos; itr != last; ++itr) {
2355#if RAPIDJSON_USE_MEMBERSMAP
2356 map->erase(DropMapIterator(mit[itr - beg]));
2357#endif
2358 itr->~Member();
2359 }
2360#if RAPIDJSON_USE_MEMBERSMAP
2361 if (first != last) {
2362 // Move remaining members/iterators
2363 MemberIterator next = pos + (last - first);
2364 for (MemberIterator itr = pos; next != end; ++itr, ++next) {
2365 std::memcpy(static_cast<void*>(&*itr), &*next, sizeof(Member));
2366 SizeType mpos = static_cast<SizeType>(itr - beg);
2367 new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
2368 mit[mpos]->second = mpos;
2369 }
2370 }
2371#else
2372 std::memmove(static_cast<void*>(&*pos), &*last,
2373 static_cast<size_t>(end - last) * sizeof(Member));
2374#endif
2375 o.size -= static_cast<SizeType>(last - first);
2376 return pos;
2377 }
2378
2379 template <typename SourceAllocator>
2380 void DoCopyMembers(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings) {
2381 RAPIDJSON_ASSERT(rhs.GetType() == kObjectType);
2382
2383 data_.f.flags = kObjectFlag;
2384 SizeType count = rhs.data_.o.size;
2385 Member* lm = DoAllocMembers(count, allocator);
2386 const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
2387#if RAPIDJSON_USE_MEMBERSMAP
2388 Map* &map = GetMap(lm);
2389 MapIterator* mit = GetMapIterators(map);
2390#endif
2391 for (SizeType i = 0; i < count; i++) {
2392 new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
2393 new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
2394#if RAPIDJSON_USE_MEMBERSMAP
2395 new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
2396#endif
2397 }
2398 data_.o.size = data_.o.capacity = count;
2399 SetMembersPointer(lm);
2400 }
2401
2402 // Initialize this value as array with initial data, without calling destructor.
2403 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2404 data_.f.flags = kArrayFlag;
2405 if (count) {
2406 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2407 SetElementsPointer(e);
2408 std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2409 }
2410 else
2411 SetElementsPointer(0);
2412 data_.a.size = data_.a.capacity = count;
2413 }
2414
2416 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2417 data_.f.flags = kObjectFlag;
2418 if (count) {
2419 Member* m = DoAllocMembers(count, allocator);
2420 SetMembersPointer(m);
2421 std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2422#if RAPIDJSON_USE_MEMBERSMAP
2423 Map* &map = GetMap(m);
2424 MapIterator* mit = GetMapIterators(map);
2425 for (SizeType i = 0; i < count; i++) {
2426 new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
2427 }
2428#endif
2429 }
2430 else
2431 SetMembersPointer(0);
2432 data_.o.size = data_.o.capacity = count;
2433 }
2434
2436 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2437 data_.f.flags = kConstStringFlag;
2438 SetStringPointer(s);
2439 data_.s.length = s.length;
2440 }
2441
2444 Ch* str = 0;
2445 if (ShortString::Usable(s.length)) {
2446 data_.f.flags = kShortStringFlag;
2447 data_.ss.SetLength(s.length);
2448 str = data_.ss.str;
2449 std::memmove(str, s, s.length * sizeof(Ch));
2450 } else {
2451 data_.f.flags = kCopyStringFlag;
2452 data_.s.length = s.length;
2453 str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2454 SetStringPointer(str);
2455 std::memcpy(str, s, s.length * sizeof(Ch));
2456 }
2457 str[s.length] = '\0';
2458 }
2459
2461 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2462 data_ = rhs.data_;
2463 // data_.f.flags = rhs.data_.f.flags;
2464 rhs.data_.f.flags = kNullFlag;
2465 }
2466
2467 template <typename SourceAllocator>
2468 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2469 RAPIDJSON_ASSERT(IsString());
2470 RAPIDJSON_ASSERT(rhs.IsString());
2471
2472 const SizeType len1 = GetStringLength();
2473 const SizeType len2 = rhs.GetStringLength();
2474 if(len1 != len2) { return false; }
2475
2476 const Ch* const str1 = GetString();
2477 const Ch* const str2 = rhs.GetString();
2478 if(str1 == str2) { return true; } // fast path for constant string
2479
2480 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2481 }
2482
2483 Data data_;
2484};
2485
2488
2490// GenericDocument
2491
2493
2500template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2501class GenericDocument : public GenericValue<Encoding, Allocator> {
2502public:
2503 typedef typename Encoding::Ch Ch;
2504 typedef GenericValue<Encoding, Allocator> ValueType;
2506 typedef StackAllocator StackAllocatorType;
2507
2509
2515 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2516 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2517 {
2518 if (!allocator_)
2519 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2520 }
2521
2523
2528 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2529 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2530 {
2531 if (!allocator_)
2532 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2533 }
2534
2535#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2537 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2538 : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2539 allocator_(rhs.allocator_),
2540 ownAllocator_(rhs.ownAllocator_),
2541 stack_(std::move(rhs.stack_)),
2542 parseResult_(rhs.parseResult_)
2543 {
2544 rhs.allocator_ = 0;
2545 rhs.ownAllocator_ = 0;
2546 rhs.parseResult_ = ParseResult();
2547 }
2548#endif
2549
2551 // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
2552 // runs last and may access its elements or members which would be freed
2553 // with an allocator like MemoryPoolAllocator (CrtAllocator does not
2554 // free its data when destroyed, but MemoryPoolAllocator does).
2555 if (ownAllocator_) {
2556 ValueType::SetNull();
2557 }
2558 Destroy();
2559 }
2560
2561#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2563 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2564 {
2565 // The cast to ValueType is necessary here, because otherwise it would
2566 // attempt to call GenericValue's templated assignment operator.
2567 ValueType::operator=(std::forward<ValueType>(rhs));
2568
2569 // Calling the destructor here would prematurely call stack_'s destructor
2570 Destroy();
2571
2572 allocator_ = rhs.allocator_;
2573 ownAllocator_ = rhs.ownAllocator_;
2574 stack_ = std::move(rhs.stack_);
2575 parseResult_ = rhs.parseResult_;
2576
2577 rhs.allocator_ = 0;
2578 rhs.ownAllocator_ = 0;
2579 rhs.parseResult_ = ParseResult();
2580
2581 return *this;
2582 }
2583#endif
2584
2586
2591 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2592 ValueType::Swap(rhs);
2593 stack_.Swap(rhs.stack_);
2594 internal::Swap(allocator_, rhs.allocator_);
2595 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2596 internal::Swap(parseResult_, rhs.parseResult_);
2597 return *this;
2598 }
2599
2600 // Allow Swap with ValueType.
2601 // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2602 using ValueType::Swap;
2603
2605
2616 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2617
2619
2623 template <typename Generator>
2624 GenericDocument& Populate(Generator& g) {
2625 ClearStackOnExit scope(*this);
2626 if (g(*this)) {
2627 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2628 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2629 }
2630 return *this;
2631 }
2632
2635
2637
2643 template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2644 GenericDocument& ParseStream(InputStream& is) {
2646 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2647 ClearStackOnExit scope(*this);
2648 parseResult_ = reader.template Parse<parseFlags>(is, *this);
2649 if (parseResult_) {
2650 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2651 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2652 }
2653 return *this;
2654 }
2655
2657
2662 template <unsigned parseFlags, typename InputStream>
2666
2668
2672 template <typename InputStream>
2676
2677
2680
2682
2686 template <unsigned parseFlags>
2691
2693
2699
2700
2703
2705
2709 template <unsigned parseFlags, typename SourceEncoding>
2710 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2711 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2714 }
2715
2717
2720 template <unsigned parseFlags>
2721 GenericDocument& Parse(const Ch* str) {
2722 return Parse<parseFlags, Encoding>(str);
2723 }
2724
2726
2728 GenericDocument& Parse(const Ch* str) {
2729 return Parse<kParseDefaultFlags>(str);
2730 }
2731
2732 template <unsigned parseFlags, typename SourceEncoding>
2733 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2734 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2735 MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2738 return *this;
2739 }
2740
2741 template <unsigned parseFlags>
2742 GenericDocument& Parse(const Ch* str, size_t length) {
2743 return Parse<parseFlags, Encoding>(str, length);
2744 }
2745
2746 GenericDocument& Parse(const Ch* str, size_t length) {
2747 return Parse<kParseDefaultFlags>(str, length);
2748 }
2749
2750#if RAPIDJSON_HAS_STDSTRING
2751 template <unsigned parseFlags, typename SourceEncoding>
2752 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2753 // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2754 return Parse<parseFlags, SourceEncoding>(str.c_str());
2755 }
2756
2757 template <unsigned parseFlags>
2758 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2759 return Parse<parseFlags, Encoding>(str.c_str());
2760 }
2761
2762 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2763 return Parse<kParseDefaultFlags>(str);
2764 }
2765#endif // RAPIDJSON_HAS_STDSTRING
2766
2768
2771
2773 bool HasParseError() const { return parseResult_.IsError(); }
2774
2776 ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2777
2779 size_t GetErrorOffset() const { return parseResult_.Offset(); }
2780
2782#ifndef __clang // -Wdocumentation
2792#endif
2793 operator ParseResult() const { return parseResult_; }
2795
2798 RAPIDJSON_ASSERT(allocator_);
2799 return *allocator_;
2800 }
2801
2803 size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2804
2805private:
2806 // clear stack on any exit from ParseStream, e.g. due to exception
2807 struct ClearStackOnExit {
2808 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2809 ~ClearStackOnExit() { d_.ClearStack(); }
2810 private:
2811 ClearStackOnExit(const ClearStackOnExit&);
2812 ClearStackOnExit& operator=(const ClearStackOnExit&);
2813 GenericDocument& d_;
2814 };
2815
2816 // callers of the following private Handler functions
2817 // template <typename,typename,typename> friend class GenericReader; // for parsing
2818 template <typename, typename> friend class GenericValue; // for deep copying
2819
2820public:
2821 // Implementation of Handler
2822 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2823 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2824 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2825 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2826 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2827 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2828 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2829
2830 bool RawNumber(const Ch* str, SizeType length, bool copy) {
2831 if (copy)
2832 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2833 else
2834 new (stack_.template Push<ValueType>()) ValueType(str, length);
2835 return true;
2836 }
2837
2838 bool String(const Ch* str, SizeType length, bool copy) {
2839 if (copy)
2840 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2841 else
2842 new (stack_.template Push<ValueType>()) ValueType(str, length);
2843 return true;
2844 }
2845
2846 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2847
2848 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2849
2850 bool EndObject(SizeType memberCount) {
2851 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2852 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2853 return true;
2854 }
2855
2856 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2857
2858 bool EndArray(SizeType elementCount) {
2859 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2860 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2861 return true;
2862 }
2863
2864private:
2869
2870 void ClearStack() {
2871 if (Allocator::kNeedFree)
2872 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2873 (stack_.template Pop<ValueType>(1))->~ValueType();
2874 else
2875 stack_.Clear();
2876 stack_.ShrinkToFit();
2877 }
2878
2879 void Destroy() {
2880 RAPIDJSON_DELETE(ownAllocator_);
2881 }
2882
2883 static const size_t kDefaultStackCapacity = 1024;
2884 Allocator* allocator_;
2885 Allocator* ownAllocator_;
2886 internal::Stack<StackAllocator> stack_;
2887 ParseResult parseResult_;
2888};
2889
2892
2893
2895
2899template <bool Const, typename ValueT>
2900class GenericArray {
2901public:
2902 typedef GenericArray<true, ValueT> ConstArray;
2903 typedef GenericArray<false, ValueT> Array;
2904 typedef ValueT PlainType;
2905 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2906 typedef ValueType* ValueIterator; // This may be const or non-const iterator
2907 typedef const ValueT* ConstValueIterator;
2908 typedef typename ValueType::AllocatorType AllocatorType;
2909 typedef typename ValueType::StringRefType StringRefType;
2910
2911 template <typename, typename>
2912 friend class GenericValue;
2913
2914 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2915 GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2916 ~GenericArray() {}
2917
2918 operator ValueType&() const { return value_; }
2919 SizeType Size() const { return value_.Size(); }
2920 SizeType Capacity() const { return value_.Capacity(); }
2921 bool Empty() const { return value_.Empty(); }
2922 void Clear() const { value_.Clear(); }
2923 ValueType& operator[](SizeType index) const { return value_[index]; }
2924 ValueIterator Begin() const { return value_.Begin(); }
2925 ValueIterator End() const { return value_.End(); }
2926 GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2927 GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2928#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2929 GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2930#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2931 GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2932 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; }
2933 GenericArray PopBack() const { value_.PopBack(); return *this; }
2934 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2935 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2936
2937#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2938 ValueIterator begin() const { return value_.Begin(); }
2939 ValueIterator end() const { return value_.End(); }
2940#endif
2941
2942private:
2943 GenericArray();
2944 GenericArray(ValueType& value) : value_(value) {}
2945 ValueType& value_;
2946};
2947
2949
2953template <bool Const, typename ValueT>
2954class GenericObject {
2955public:
2956 typedef GenericObject<true, ValueT> ConstObject;
2957 typedef GenericObject<false, ValueT> Object;
2958 typedef ValueT PlainType;
2959 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2960 typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
2962 typedef typename ValueType::AllocatorType AllocatorType;
2963 typedef typename ValueType::StringRefType StringRefType;
2964 typedef typename ValueType::EncodingType EncodingType;
2965 typedef typename ValueType::Ch Ch;
2966
2967 template <typename, typename>
2968 friend class GenericValue;
2969
2970 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2971 GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2972 ~GenericObject() {}
2973
2974 operator ValueType&() const { return value_; }
2975 SizeType MemberCount() const { return value_.MemberCount(); }
2976 SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2977 bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2978 template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2979 template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2980#if RAPIDJSON_HAS_STDSTRING
2981 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2982#endif
2983 MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2984 MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2985 GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2986 bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2987#if RAPIDJSON_HAS_STDSTRING
2988 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2989#endif
2990 template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2991 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2992 template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2993#if RAPIDJSON_HAS_STDSTRING
2994 MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2995#endif
2996 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2997 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2998#if RAPIDJSON_HAS_STDSTRING
2999 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3000#endif
3001 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; }
3002#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3003 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3004 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3005 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3006 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3007#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
3008 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3009 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3010 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; }
3011 void RemoveAllMembers() { value_.RemoveAllMembers(); }
3012 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
3013#if RAPIDJSON_HAS_STDSTRING
3014 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
3015#endif
3016 template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
3017 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
3018 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
3019 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
3020 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
3021#if RAPIDJSON_HAS_STDSTRING
3022 bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
3023#endif
3024 template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
3025
3026#if RAPIDJSON_HAS_CXX11_RANGE_FOR
3027 MemberIterator begin() const { return value_.MemberBegin(); }
3028 MemberIterator end() const { return value_.MemberEnd(); }
3029#endif
3030
3031private:
3032 GenericObject();
3033 GenericObject(ValueType& value) : value_(value) {}
3034 ValueType& value_;
3035};
3036
3038RAPIDJSON_DIAG_POP
3039
3040#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3041#pragma pop_macro("GetObject")
3042#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3043#endif
3044
3045#endif // RAPIDJSON_DOCUMENT_H_
Input byte stream wrapper with a statically bound encoding.
Helper class for accessing Value of array type.
Definition document.h:2900
A document for parsing JSON text as DOM.
Definition document.h:2501
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition document.h:2616
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:2797
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition document.h:2687
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition document.h:2591
Allocator AllocatorType
Allocator type from template parameter.
Definition document.h:2505
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition document.h:2721
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition document.h:2515
StackAllocator StackAllocatorType
StackAllocator type from template parameter.
Definition document.h:2506
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition document.h:2773
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition document.h:2663
GenericDocument(const GenericDocument &)
Prohibit copying.
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition document.h:2528
Encoding::Ch Ch
Character type derived from Encoding.
Definition document.h:2503
GenericDocument & operator=(const GenericDocument &)
Prohibit assignment.
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition document.h:2673
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition document.h:2644
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition document.h:2504
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition document.h:2710
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition document.h:2776
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition document.h:2696
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition document.h:2803
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition document.h:2624
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition document.h:2779
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition document.h:2728
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition document.h:241
GenericMemberIterator()
Default constructor (singular value)
Definition document.h:223
GenericMemberIterator(Pointer p)
Internal constructor from plain pointer.
Definition document.h:287
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Definition document.h:201
GenericMemberIterator Iterator
Iterator type itself.
Definition document.h:197
DifferenceType operator-(ConstIterator that) const
Distance.
Definition document.h:283
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition document.h:199
Name-value pair in a JSON object value.
Definition document.h:121
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition document.h:123
GenericValue< Encoding, Allocator > value
value of member.
Definition document.h:124
GenericMember(const GenericMember &rhs)
Copy constructor is not permitted.
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition document.h:143
Helper class for accessing Value of object type.
Definition document.h:2954
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition reader.h:540
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition document.h:669
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition document.h:782
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition document.h:2436
~GenericValue()
Destructor.
Definition document.h:881
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition document.h:832
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition document.h:2416
Encoding EncodingType
Encoding type from template parameter.
Definition document.h:673
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition document.h:947
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition document.h:676
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition document.h:677
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition document.h:681
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition document.h:680
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:838
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator)
Definition document.h:743
Allocator AllocatorType
Allocator type from template parameter.
Definition document.h:674
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition document.h:672
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition document.h:721
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition document.h:862
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition document.h:805
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition document.h:799
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition document.h:847
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition document.h:873
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition document.h:844
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition document.h:678
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition document.h:793
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition document.h:691
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition document.h:841
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition document.h:2461
GenericValue(const GenericValue &rhs)
Copy constructor is not permitted.
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition document.h:835
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition document.h:820
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition document.h:2443
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition document.h:922
Encoding::Ch Ch
Character type derived from Encoding.
Definition document.h:675
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition document.h:679
Concept for allocating, resizing and freeing memory block.
Concept for encoding of Unicode characters.
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition document.h:2487
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:455
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition document.h:2891
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
User defined kDefaultArrayCapacity value.
Definition document.h:111
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition rapidjson.h:688
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition rapidjson.h:308
#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
User defined kDefaultObjectCapacity value.
Definition document.h:100
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition rapidjson.h:495
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition rapidjson.h:508
#define RAPIDJSON_USE_MEMBERSMAP
Enable RapidJSON support for object members handling in a std::multimap.
Definition rapidjson.h:181
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:438
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:122
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:125
ParseErrorCode
Error code of parsing.
Definition error.h:65
void swap(UniqueArray< T > &v1, UniqueArray< T > &v2)
Échange les valeurs de v1 et v2.
Type
Type of JSON value.
Definition rapidjson.h:730
@ kFalseType
false
Definition rapidjson.h:732
@ kObjectType
object
Definition rapidjson.h:734
@ kTrueType
true
Definition rapidjson.h:733
@ kStringType
string
Definition rapidjson.h:736
@ kNullType
null
Definition rapidjson.h:731
@ kArrayType
array
Definition rapidjson.h:735
@ kNumberType
number
Definition rapidjson.h:737
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:717
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition rapidjson.h:416
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition rapidjson.h:321
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:713
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition rapidjson.h:477
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition reader.h:149
A read-write string stream.
Definition stream.h:189
Reference to a constant string (not taking a copy)
Definition document.h:347
GenericStringRef & operator=(const GenericStringRef &rhs)
Copy assignment operator not permitted - immutable type.
CharType Ch
character type of the string
Definition document.h:348
static const Ch emptyString[]
Definition document.h:430
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition document.h:421
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
Definition document.h:475
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition document.h:412
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition document.h:400
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:455
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition document.h:376
GenericStringRef(CharType(&str)[N])
Disallow construction from non-const array.
const Ch *const s
plain CharType pointer
Definition document.h:420
Read-only string stream.
Definition stream.h:155
SizeType hashcode
reserved
Definition document.h:2040
Represents an in-memory input byte stream.
Result of parsing (wraps ParseErrorCode)
Definition error.h:107