document.h Source File

document.h Source File#

Composable Kernel: document.h Source File
document.h
Go to the documentation of this file.
1// Tencent is pleased to support the open source community by making RapidJSON available.
2//
3// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip.
4//
5// Licensed under the MIT License (the "License"); you may not use this file except
6// in compliance with the License. You may obtain a copy of the License at
7//
8// http://opensource.org/licenses/MIT
9//
10// Unless required by applicable law or agreed to in writing, software distributed
11// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13// specific language governing permissions and limitations under the License.
14
15#ifndef RAPIDJSON_DOCUMENT_H_
16#define RAPIDJSON_DOCUMENT_H_
17
19
20#include "reader.h"
21#include "internal/meta.h"
22#include "internal/strfunc.h"
23#include "memorystream.h"
24#include "encodedstream.h"
25#include <new> // placement new
26#include <limits>
27#ifdef __cpp_lib_three_way_comparison
28#include <compare>
29#endif
30
31RAPIDJSON_DIAG_PUSH
32#ifdef __clang__
33RAPIDJSON_DIAG_OFF(padded)
34RAPIDJSON_DIAG_OFF(switch - enum)
35RAPIDJSON_DIAG_OFF(c++ 98 - compat)
36#elif defined(_MSC_VER)
37RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
38RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
39#endif
40
41#ifdef __GNUC__
42RAPIDJSON_DIAG_OFF(effc++)
43#endif // __GNUC__
44
45#ifdef GetObject
46// see https://github.com/Tencent/rapidjson/issues/1448
47// a former included windows.h might have defined a macro called GetObject, which affects
48// GetObject defined here. This ensures the macro does not get applied
49#pragma push_macro("GetObject")
50#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
51#undef GetObject
52#endif
53
54#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
55#include <iterator> // std::random_access_iterator_tag
56#endif
57
58#if RAPIDJSON_USE_MEMBERSMAP
59#include <map> // std::multimap
60#endif
61
63
64// Forward declaration.
65template <typename Encoding, typename Allocator>
66class GenericValue;
67
68template <typename Encoding, typename Allocator, typename StackAllocator>
69class GenericDocument;
70
77#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
78#define RAPIDJSON_DEFAULT_ALLOCATOR \
79 ::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>
121class GenericMember
122{
123 public:
126
127#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
129 GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT : name(std::move(rhs.name)),
130 value(std::move(rhs.value))
131 {
132 }
133
135 GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
136 {
137 return *this = static_cast<GenericMember&>(rhs);
138 }
139#endif
140
142
145 GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT
146 {
147 if(RAPIDJSON_LIKELY(this != &rhs))
148 {
149 name = rhs.name;
150 value = rhs.value;
151 }
152 return *this;
153 }
154
155 // swap() for std::sort() and other potential use in STL.
156 friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT
157 {
158 a.name.Swap(b.name);
159 a.value.Swap(b.value);
160 }
161
162 private:
165};
166
168// GenericMemberIterator
169
170#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
171
173
192template <bool Const, typename Encoding, typename Allocator>
194{
195
196 friend class GenericValue<Encoding, Allocator>;
197 template <bool, typename, typename>
199
200 typedef GenericMember<Encoding, Allocator> PlainType;
201 typedef typename internal::MaybeAddConst<Const, PlainType>::Type ValueType;
202
203 public:
210
213 typedef ValueType value_type;
214 typedef ValueType* pointer;
215 typedef ValueType& reference;
216 typedef std::ptrdiff_t difference_type;
217 typedef std::random_access_iterator_tag iterator_category;
219
226
228
232
234
249 GenericMemberIterator(const NonConstIterator& it) : ptr_(it.ptr_) {}
251 {
252 ptr_ = it.ptr_;
253 return *this;
254 }
255
257
259 {
260 ++ptr_;
261 return *this;
262 }
264 {
265 --ptr_;
266 return *this;
267 }
269 {
270 Iterator old(*this);
271 ++ptr_;
272 return old;
273 }
275 {
276 Iterator old(*this);
277 --ptr_;
278 return old;
279 }
280
281
283
284 Iterator operator+(DifferenceType n) const { return Iterator(ptr_ + n); }
285 Iterator operator-(DifferenceType n) const { return Iterator(ptr_ - n); }
286
288 {
289 ptr_ += n;
290 return *this;
291 }
293 {
294 ptr_ -= n;
295 return *this;
296 }
297
298
300
301 template <bool Const_>
303 {
304 return ptr_ == that.ptr_;
305 }
306 template <bool Const_>
308 {
309 return ptr_ != that.ptr_;
310 }
311 template <bool Const_>
313 {
314 return ptr_ <= that.ptr_;
315 }
316 template <bool Const_>
318 {
319 return ptr_ >= that.ptr_;
320 }
321 template <bool Const_>
323 {
324 return ptr_ < that.ptr_;
325 }
326 template <bool Const_>
328 {
329 return ptr_ > that.ptr_;
330 }
331
332#ifdef __cpp_lib_three_way_comparison
333 template <bool Const_>
334 std::strong_ordering
335 operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const
336 {
337 return ptr_ <=> that.ptr_;
338 }
339#endif
341
343
344 Reference operator*() const { return *ptr_; }
345 Pointer operator->() const { return ptr_; }
346 Reference operator[](DifferenceType n) const { return ptr_[n]; }
348
350 DifferenceType operator-(ConstIterator that) const { return ptr_ - that.ptr_; }
351
352 private:
354 explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
355
356 Pointer ptr_;
357};
358
359#else // RAPIDJSON_NOMEMBERITERATORCLASS
360
361// class-based member iterator implementation disabled, use plain pointers
362
363template <bool Const, typename Encoding, typename Allocator>
365
367template <typename Encoding, typename Allocator>
369{
370 public:
372 typedef GenericMember<Encoding, Allocator>* Iterator;
373};
375template <typename Encoding, typename Allocator>
377{
378 public:
380 typedef const GenericMember<Encoding, Allocator>* Iterator;
381};
382
383#endif // RAPIDJSON_NOMEMBERITERATORCLASS
384
386// GenericStringRef
387
389
415template <typename CharType>
417{
418 typedef CharType Ch;
419
421#ifndef __clang__ // -Wdocumentation
444#endif
445 template <SizeType N>
446 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT : s(str), length(N - 1)
447 {
448 }
449
451#ifndef __clang__ // -Wdocumentation
470#endif
471 explicit GenericStringRef(const CharType* str) : s(str), length(NotNullStrLen(str)) {}
472
474#ifndef __clang__ // -Wdocumentation
481#endif
482 GenericStringRef(const CharType* str, SizeType len)
483 : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len)
484 {
485 RAPIDJSON_ASSERT(str != 0 || len == 0u);
486 }
487
488 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
489
491 operator const Ch*() const { return s; }
492
493 const Ch* const s;
495
496 private:
497 SizeType NotNullStrLen(const CharType* str)
498 {
499 RAPIDJSON_ASSERT(str != 0);
500 return internal::StrLen(str);
501 }
502
504 static const Ch emptyString[];
505
507 template <SizeType N>
508 GenericStringRef(CharType (&str)[N]) /* = delete */;
510 GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
511};
512
513template <typename CharType>
514const CharType GenericStringRef<CharType>::emptyString[] = {CharType()};
515
517
529template <typename CharType>
530inline GenericStringRef<CharType> StringRef(const CharType* str)
531{
532 return GenericStringRef<CharType>(str);
533}
534
536
549template <typename CharType>
550inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length)
551{
553}
554
555#if RAPIDJSON_HAS_STDSTRING
557
567template <typename CharType>
568inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str)
569{
570 return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
571}
572#endif
573
575// GenericValue type traits
576namespace internal {
577
578template <typename T, typename Encoding = void, typename Allocator = void>
579struct IsGenericValueImpl : FalseType
580{
581};
582
583// select candidates according to nested encoding and allocator types
584template <typename T>
586 typename Void<typename T::EncodingType>::Type,
587 typename Void<typename T::AllocatorType>::Type>
588 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type
589{
590};
591
592// helper to match arbitrary GenericValue instantiations, including derived classes
593template <typename T>
597
598} // namespace internal
599
601// TypeHelper
602
603namespace internal {
604
605template <typename ValueType, typename T>
607{
608};
609
610template <typename ValueType>
611struct TypeHelper<ValueType, bool>
612{
613 static bool Is(const ValueType& v) { return v.IsBool(); }
614 static bool Get(const ValueType& v) { return v.GetBool(); }
615 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
616 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&)
617 {
618 return v.SetBool(data);
619 }
620};
621
622template <typename ValueType>
623struct TypeHelper<ValueType, int>
624{
625 static bool Is(const ValueType& v) { return v.IsInt(); }
626 static int Get(const ValueType& v) { return v.GetInt(); }
627 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
628 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&)
629 {
630 return v.SetInt(data);
631 }
632};
633
634template <typename ValueType>
635struct TypeHelper<ValueType, unsigned>
636{
637 static bool Is(const ValueType& v) { return v.IsUint(); }
638 static unsigned Get(const ValueType& v) { return v.GetUint(); }
639 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
640 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&)
641 {
642 return v.SetUint(data);
643 }
644};
645
646#ifdef _MSC_VER
647RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
648template <typename ValueType>
649struct TypeHelper<ValueType, long>
650{
651 static bool Is(const ValueType& v) { return v.IsInt(); }
652 static long Get(const ValueType& v) { return v.GetInt(); }
653 static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
654 static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&)
655 {
656 return v.SetInt(data);
657 }
658};
659
660RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
661template <typename ValueType>
662struct TypeHelper<ValueType, unsigned long>
663{
664 static bool Is(const ValueType& v) { return v.IsUint(); }
665 static unsigned long Get(const ValueType& v) { return v.GetUint(); }
666 static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
667 static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&)
668 {
669 return v.SetUint(data);
670 }
671};
672#endif
673
674template <typename ValueType>
675struct TypeHelper<ValueType, int64_t>
676{
677 static bool Is(const ValueType& v) { return v.IsInt64(); }
678 static int64_t Get(const ValueType& v) { return v.GetInt64(); }
679 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
680 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&)
681 {
682 return v.SetInt64(data);
683 }
684};
685
686template <typename ValueType>
687struct TypeHelper<ValueType, uint64_t>
688{
689 static bool Is(const ValueType& v) { return v.IsUint64(); }
690 static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
691 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
692 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&)
693 {
694 return v.SetUint64(data);
695 }
696};
697
698template <typename ValueType>
699struct TypeHelper<ValueType, double>
700{
701 static bool Is(const ValueType& v) { return v.IsDouble(); }
702 static double Get(const ValueType& v) { return v.GetDouble(); }
703 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
704 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&)
705 {
706 return v.SetDouble(data);
707 }
708};
709
710template <typename ValueType>
711struct TypeHelper<ValueType, float>
712{
713 static bool Is(const ValueType& v) { return v.IsFloat(); }
714 static float Get(const ValueType& v) { return v.GetFloat(); }
715 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
716 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&)
717 {
718 return v.SetFloat(data);
719 }
720};
721
722template <typename ValueType>
723struct TypeHelper<ValueType, const typename ValueType::Ch*>
724{
725 typedef const typename ValueType::Ch* StringType;
726 static bool Is(const ValueType& v) { return v.IsString(); }
727 static StringType Get(const ValueType& v) { return v.GetString(); }
728 static ValueType& Set(ValueType& v, const StringType data)
729 {
730 return v.SetString(typename ValueType::StringRefType(data));
731 }
732 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a)
733 {
734 return v.SetString(data, a);
735 }
736};
737
738#if RAPIDJSON_HAS_STDSTRING
739template <typename ValueType>
740struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch>>
741{
742 typedef std::basic_string<typename ValueType::Ch> StringType;
743 static bool Is(const ValueType& v) { return v.IsString(); }
744 static StringType Get(const ValueType& v)
745 {
746 return StringType(v.GetString(), v.GetStringLength());
747 }
748 static ValueType&
749 Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a)
750 {
751 return v.SetString(data, a);
752 }
753};
754#endif
755
756template <typename ValueType>
757struct TypeHelper<ValueType, typename ValueType::Array>
758{
759 typedef typename ValueType::Array ArrayType;
760 static bool Is(const ValueType& v) { return v.IsArray(); }
761 static ArrayType Get(ValueType& v) { return v.GetArray(); }
762 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
763 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&)
764 {
765 return v = data;
766 }
767};
768
769template <typename ValueType>
770struct TypeHelper<ValueType, typename ValueType::ConstArray>
771{
772 typedef typename ValueType::ConstArray ArrayType;
773 static bool Is(const ValueType& v) { return v.IsArray(); }
774 static ArrayType Get(const ValueType& v) { return v.GetArray(); }
775};
776
777template <typename ValueType>
778struct TypeHelper<ValueType, typename ValueType::Object>
779{
780 typedef typename ValueType::Object ObjectType;
781 static bool Is(const ValueType& v) { return v.IsObject(); }
782 static ObjectType Get(ValueType& v) { return v.GetObject(); }
783 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
784 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&)
785 {
786 return v = data;
787 }
788};
789
790template <typename ValueType>
791struct TypeHelper<ValueType, typename ValueType::ConstObject>
792{
793 typedef typename ValueType::ConstObject ObjectType;
794 static bool Is(const ValueType& v) { return v.IsObject(); }
795 static ObjectType Get(const ValueType& v) { return v.GetObject(); }
796};
797
798} // namespace internal
799
800// Forward declarations
801template <bool, typename>
802class GenericArray;
803template <bool, typename>
804class GenericObject;
805
807// GenericValue
808
810
820template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR>
822{
823 public:
828 typedef typename Encoding::Ch Ch;
835 typedef const GenericValue*
842
844
845
847 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
848
849#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
851 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_)
852 {
853 rhs.data_.f.flags = kNullFlag; // give up contents
854 }
855#endif
856
857 private:
859 GenericValue(const GenericValue& rhs);
860
861#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
863 template <typename StackAllocator>
865
867 template <typename StackAllocator>
869#endif
870
871 public:
873
877 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_()
878 {
879 static const uint16_t defaultFlags[] = {kNullFlag,
881 kTrueFlag,
887 data_.f.flags = defaultFlags[type];
888
889 // Use ShortString to store empty string.
890 if(type == kStringType)
891 data_.ss.SetLength(0);
892 }
893
895
902 template <typename SourceAllocator>
904 Allocator& allocator,
905 bool copyConstStrings = false)
906 {
907 switch(rhs.GetType())
908 {
909 case kObjectType: DoCopyMembers(rhs, allocator, copyConstStrings); break;
910 case kArrayType: {
911 SizeType count = rhs.data_.a.size;
912 GenericValue* le =
913 reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
915 for(SizeType i = 0; i < count; i++)
916 new(&le[i]) GenericValue(re[i], allocator, copyConstStrings);
917 data_.f.flags = kArrayFlag;
918 data_.a.size = data_.a.capacity = count;
920 }
921 break;
922 case kStringType:
923 if(rhs.data_.f.flags == kConstStringFlag && !copyConstStrings)
924 {
925 data_.f.flags = rhs.data_.f.flags;
926 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
927 }
928 else
929 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
930 break;
931 default:
932 data_.f.flags = rhs.data_.f.flags;
933 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
934 break;
935 }
936 }
937
939
944#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
945 template <typename T>
946 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>)))
947 RAPIDJSON_NOEXCEPT // See #472
948#else
949 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
950#endif
951 : data_()
952 {
953 // safe-guard against failing SFINAE
954 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool, T>::Value));
955 data_.f.flags = b ? kTrueFlag : kFalseFlag;
956 }
957
959 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_()
960 {
961 data_.n.i64 = i;
962 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
963 }
964
966 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_()
967 {
968 data_.n.u64 = u;
969 data_.f.flags =
970 (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
971 }
972
974 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_()
975 {
976 data_.n.i64 = i64;
977 data_.f.flags = kNumberInt64Flag;
978 if(i64 >= 0)
979 {
980 data_.f.flags |= kNumberUint64Flag;
981 if(!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
982 data_.f.flags |= kUintFlag;
983 if(!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
984 data_.f.flags |= kIntFlag;
985 }
986 else if(i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
987 data_.f.flags |= kIntFlag;
988 }
989
991 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_()
992 {
993 data_.n.u64 = u64;
994 data_.f.flags = kNumberUint64Flag;
995 if(!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
996 data_.f.flags |= kInt64Flag;
997 if(!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
998 data_.f.flags |= kUintFlag;
999 if(!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
1000 data_.f.flags |= kIntFlag;
1001 }
1002
1004 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_()
1005 {
1006 data_.n.d = d;
1007 data_.f.flags = kNumberDoubleFlag;
1008 }
1009
1011 explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_()
1012 {
1013 data_.n.d = static_cast<double>(f);
1014 data_.f.flags = kNumberDoubleFlag;
1015 }
1016
1018 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_()
1019 {
1020 SetStringRaw(StringRef(s, length));
1021 }
1022
1024 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
1025
1027 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_()
1028 {
1029 SetStringRaw(StringRef(s, length), allocator);
1030 }
1031
1033 GenericValue(const Ch* s, Allocator& allocator) : data_()
1034 {
1035 SetStringRaw(StringRef(s), allocator);
1036 }
1037
1038#if RAPIDJSON_HAS_STDSTRING
1040
1042 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_()
1043 {
1044 SetStringRaw(StringRef(s), allocator);
1045 }
1046#endif
1047
1049
1054 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_)
1055 {
1056 a.value_.data_ = Data();
1057 a.value_.data_.f.flags = kArrayFlag;
1058 }
1059
1061
1066 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_)
1067 {
1068 o.value_.data_ = Data();
1069 o.value_.data_.f.flags = kObjectFlag;
1070 }
1071
1073
1076 {
1077 // With RAPIDJSON_USE_MEMBERSMAP, the maps need to be destroyed to release
1078 // their Allocator if it's refcounted (e.g. MemoryPoolAllocator).
1079 if(Allocator::kNeedFree ||
1081 {
1082 switch(data_.f.flags)
1083 {
1084 case kArrayFlag: {
1086 for(GenericValue* v = e; v != e + data_.a.size; ++v)
1087 v->~GenericValue();
1088 if(Allocator::kNeedFree)
1089 { // Shortcut by Allocator's trait
1090 Allocator::Free(e);
1091 }
1092 }
1093 break;
1094
1095 case kObjectFlag: DoFreeMembers(); break;
1096
1097 case kCopyStringFlag:
1098 if(Allocator::kNeedFree)
1099 { // Shortcut by Allocator's trait
1100 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
1101 }
1102 break;
1103
1104 default: break; // Do nothing for other types.
1105 }
1106 }
1107 }
1108
1110
1112
1113
1115
1117 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT
1118 {
1119 if(RAPIDJSON_LIKELY(this != &rhs))
1120 {
1121 // Can't destroy "this" before assigning "rhs", otherwise "rhs"
1122 // could be used after free if it's an sub-Value of "this",
1123 // hence the temporary danse.
1124 GenericValue temp;
1125 temp.RawAssign(rhs);
1126 this->~GenericValue();
1127 RawAssign(temp);
1128 }
1129 return *this;
1130 }
1131
1132#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1134 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { return *this = rhs.Move(); }
1135#endif
1136
1138
1142 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT
1143 {
1144 GenericValue s(str);
1145 return *this = s;
1146 }
1147
1149
1160 template <typename T>
1161 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
1162 operator=(T value)
1163 {
1165 return *this = v;
1166 }
1167
1169
1176 template <typename SourceAllocator>
1178 Allocator& allocator,
1179 bool copyConstStrings = false)
1180 {
1181 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
1182 this->~GenericValue();
1183 new(this) GenericValue(rhs, allocator, copyConstStrings);
1184 return *this;
1185 }
1186
1188
1192 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT
1193 {
1194 GenericValue temp;
1195 temp.RawAssign(*this);
1196 RawAssign(other);
1197 other.RawAssign(temp);
1198 return *this;
1199 }
1200
1202
1210 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1211
1213
1214 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
1216
1218
1219
1225 template <typename SourceAllocator>
1227 {
1229 if(GetType() != rhs.GetType())
1230 return false;
1231
1232 switch(GetType())
1233 {
1234 case kObjectType: // Warning: O(n^2) inner-loop
1235 if(data_.o.size != rhs.data_.o.size)
1236 return false;
1237 for(ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd();
1238 ++lhsMemberItr)
1239 {
1240 typename RhsType::ConstMemberIterator rhsMemberItr =
1241 rhs.FindMember(lhsMemberItr->name);
1242 if(rhsMemberItr == rhs.MemberEnd() ||
1243 (!(lhsMemberItr->value == rhsMemberItr->value)))
1244 return false;
1245 }
1246 return true;
1247
1248 case kArrayType:
1249 if(data_.a.size != rhs.data_.a.size)
1250 return false;
1251 for(SizeType i = 0; i < data_.a.size; i++)
1252 if(!((*this)[i] == rhs[i]))
1253 return false;
1254 return true;
1255
1256 case kStringType: return StringEqual(rhs);
1257
1258 case kNumberType:
1259 if(IsDouble() || rhs.IsDouble())
1260 {
1261 double a = GetDouble(); // May convert from integer to double.
1262 double b = rhs.GetDouble(); // Ditto
1263 return a >= b && a <= b; // Prevent -Wfloat-equal
1264 }
1265 else
1266 return data_.n.u64 == rhs.data_.n.u64;
1267
1268 default: return true;
1269 }
1270 }
1271
1273 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1274
1275#if RAPIDJSON_HAS_STDSTRING
1277
1279 bool operator==(const std::basic_string<Ch>& rhs) const
1280 {
1281 return *this == GenericValue(StringRef(rhs));
1282 }
1283#endif
1284
1286
1289 template <typename T>
1291 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (bool))
1292 operator==(const T & rhs) const
1293 {
1294 return *this == GenericValue(rhs);
1295 }
1296
1297#ifndef __cpp_impl_three_way_comparison
1299
1301 template <typename SourceAllocator>
1303 {
1304 return !(*this == rhs);
1305 }
1306
1308 bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1309
1311
1313 template <typename T>
1314 RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool))
1315 operator!=(const T & rhs) const
1316 {
1317 return !(*this == rhs);
1318 }
1319
1321
1323 template <typename T>
1324 friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>),
1325 (bool)) operator==(const T & lhs, const GenericValue & rhs)
1326 {
1327 return rhs == lhs;
1328 }
1329
1331
1333 template <typename T>
1334 friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>),
1335 (bool)) operator!=(const T & lhs, const GenericValue & rhs)
1336 {
1337 return !(rhs == lhs);
1338 }
1340#endif
1341
1343
1344
1345 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1346 bool IsNull() const { return data_.f.flags == kNullFlag; }
1347 bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1348 bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1349 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1350 bool IsObject() const { return data_.f.flags == kObjectFlag; }
1351 bool IsArray() const { return data_.f.flags == kArrayFlag; }
1352 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1353 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1354 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1355 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1356 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1357 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1358 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1359
1360 // Checks whether a number can be losslessly converted to a double.
1361 bool IsLosslessDouble() const
1362 {
1363 if(!IsNumber())
1364 return false;
1365 if(IsUint64())
1366 {
1367 uint64_t u = GetUint64();
1368 volatile double d = static_cast<double>(u);
1369 return (d >= 0.0) &&
1370 (d < static_cast<double>((std::numeric_limits<uint64_t>::max)())) &&
1371 (u == static_cast<uint64_t>(d));
1372 }
1373 if(IsInt64())
1374 {
1375 int64_t i = GetInt64();
1376 volatile double d = static_cast<double>(i);
1377 return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)())) &&
1378 (d < static_cast<double>((std::numeric_limits<int64_t>::max)())) &&
1379 (i == static_cast<int64_t>(d));
1380 }
1381 return true; // double, int, uint are always lossless
1382 }
1383
1384 // Checks whether a number is a float (possible lossy).
1385 bool IsFloat() const
1386 {
1387 if((data_.f.flags & kDoubleFlag) == 0)
1388 return false;
1389 double d = GetDouble();
1390 return d >= -3.4028234e38 && d <= 3.4028234e38;
1391 }
1392 // Checks whether a number can be losslessly converted to a float.
1393 bool IsLosslessFloat() const
1394 {
1395 if(!IsNumber())
1396 return false;
1397 double a = GetDouble();
1398 if(a < static_cast<double>(-(std::numeric_limits<float>::max)()) ||
1399 a > static_cast<double>((std::numeric_limits<float>::max)()))
1400 return false;
1401 double b = static_cast<double>(static_cast<float>(a));
1402 return a >= b && a <= b; // Prevent -Wfloat-equal
1403 }
1404
1406
1408
1409
1410 GenericValue& SetNull()
1411 {
1412 this->~GenericValue();
1413 new(this) GenericValue();
1414 return *this;
1415 }
1416
1418
1420
1421
1422 bool GetBool() const
1423 {
1424 RAPIDJSON_ASSERT(IsBool());
1425 return data_.f.flags == kTrueFlag;
1426 }
1428
1429 GenericValue& SetBool(bool b)
1430 {
1431 this->~GenericValue();
1432 new(this) GenericValue(b);
1433 return *this;
1434 }
1435
1437
1439
1440
1442
1443 GenericValue& SetObject()
1444 {
1445 this->~GenericValue();
1446 new(this) GenericValue(kObjectType);
1447 return *this;
1448 }
1449
1451 SizeType MemberCount() const
1452 {
1453 RAPIDJSON_ASSERT(IsObject());
1454 return data_.o.size;
1455 }
1456
1458 SizeType MemberCapacity() const
1459 {
1460 RAPIDJSON_ASSERT(IsObject());
1461 return data_.o.capacity;
1462 }
1463
1465 bool ObjectEmpty() const
1466 {
1467 RAPIDJSON_ASSERT(IsObject());
1468 return data_.o.size == 0;
1469 }
1470
1472
1479 template <typename T>
1481 (internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch>>),
1482 (GenericValue&))
1483 operator[](T * name)
1484 {
1485 GenericValue n(StringRef(name));
1486 return (*this)[n];
1487 }
1488 template <typename T>
1490 (internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch>>),
1491 (const GenericValue&))
1492 operator[](T * name) const
1493 {
1494 return const_cast<GenericValue&>(*this)[name];
1495 }
1496
1498
1506 template <typename SourceAllocator>
1508 {
1509 MemberIterator member = FindMember(name);
1510 if(member != MemberEnd())
1511 return member->value;
1512 else
1513 {
1514 RAPIDJSON_ASSERT(false); // see above note
1515
1516#if RAPIDJSON_HAS_CXX11
1517 // Use thread-local storage to prevent races between threads.
1518 // Use static buffer and placement-new to prevent destruction, with
1519 // alignas() to ensure proper alignment.
1520 alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
1521 return *new(buffer) GenericValue();
1522#elif defined(_MSC_VER) && _MSC_VER < 1900
1523 // There's no way to solve both thread locality and proper alignment
1524 // simultaneously.
1525 __declspec(thread) static char buffer[sizeof(GenericValue)];
1526 return *new(buffer) GenericValue();
1527#elif defined(__GNUC__) || defined(__clang__)
1528 // This will generate -Wexit-time-destructors in clang, but
1529 // that's
1530 // better than having under-alignment.
1531 __thread static GenericValue buffer;
1532 return buffer;
1533#else
1534 // Don't know what compiler this is, so don't know how to
1535 // ensure
1536 // thread-locality.
1537 static GenericValue buffer;
1538 return buffer;
1539#endif
1540 }
1541 }
1542 template <typename SourceAllocator>
1543 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const
1544 {
1545 return const_cast<GenericValue&>(*this)[name];
1546 }
1547
1548#if RAPIDJSON_HAS_STDSTRING
1550 GenericValue& operator[](const std::basic_string<Ch>& name)
1551 {
1552 return (*this)[GenericValue(StringRef(name))];
1553 }
1554 const GenericValue& operator[](const std::basic_string<Ch>& name) const
1555 {
1556 return (*this)[GenericValue(StringRef(name))];
1557 }
1558#endif
1559
1561
1562 ConstMemberIterator MemberBegin() const
1563 {
1564 RAPIDJSON_ASSERT(IsObject());
1566 }
1568
1569 ConstMemberIterator MemberEnd() const
1570 {
1571 RAPIDJSON_ASSERT(IsObject());
1572 return ConstMemberIterator(GetMembersPointer() + data_.o.size);
1573 }
1575
1576 MemberIterator MemberBegin()
1577 {
1578 RAPIDJSON_ASSERT(IsObject());
1580 }
1582
1583 MemberIterator MemberEnd()
1584 {
1585 RAPIDJSON_ASSERT(IsObject());
1586 return MemberIterator(GetMembersPointer() + data_.o.size);
1587 }
1588
1590
1595 GenericValue& MemberReserve(SizeType newCapacity, Allocator& allocator)
1596 {
1597 RAPIDJSON_ASSERT(IsObject());
1598 DoReserveMembers(newCapacity, allocator);
1599 return *this;
1600 }
1601
1603
1610 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1611
1612#if RAPIDJSON_HAS_STDSTRING
1614
1621 bool HasMember(const std::basic_string<Ch>& name) const
1622 {
1623 return FindMember(name) != MemberEnd();
1624 }
1625#endif
1626
1628
1634 template <typename SourceAllocator>
1635 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const
1636 {
1637 return FindMember(name) != MemberEnd();
1638 }
1639
1641
1652 MemberIterator FindMember(const Ch* name)
1653 {
1654 GenericValue n(StringRef(name));
1655 return FindMember(n);
1656 }
1657
1658 ConstMemberIterator FindMember(const Ch* name) const
1659 {
1660 return const_cast<GenericValue&>(*this).FindMember(name);
1661 }
1662
1664
1674 template <typename SourceAllocator>
1676 {
1677 RAPIDJSON_ASSERT(IsObject());
1678 RAPIDJSON_ASSERT(name.IsString());
1679 return DoFindMember(name);
1680 }
1681 template <typename SourceAllocator>
1683 {
1684 return const_cast<GenericValue&>(*this).FindMember(name);
1685 }
1686
1687#if RAPIDJSON_HAS_STDSTRING
1689
1695 MemberIterator FindMember(const std::basic_string<Ch>& name)
1696 {
1697 return FindMember(GenericValue(StringRef(name)));
1698 }
1699 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const
1700 {
1701 return FindMember(GenericValue(StringRef(name)));
1702 }
1703#endif
1704
1706
1714 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator)
1715 {
1716 RAPIDJSON_ASSERT(IsObject());
1717 RAPIDJSON_ASSERT(name.IsString());
1718 DoAddMember(name, value, allocator);
1719 return *this;
1720 }
1721
1723
1731 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator)
1732 {
1734 return AddMember(name, v, allocator);
1735 }
1736
1737#if RAPIDJSON_HAS_STDSTRING
1739
1747 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator)
1748 {
1749 GenericValue v(value, allocator);
1750 return AddMember(name, v, allocator);
1751 }
1752#endif
1753
1755
1770 template <typename T>
1772 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (GenericValue&))
1773 AddMember(GenericValue& name, T value, Allocator& allocator)
1774 {
1776 return AddMember(name, v, allocator);
1777 }
1778
1779#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1780 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator)
1781 {
1782 return AddMember(name, value, allocator);
1783 }
1784 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator)
1785 {
1786 return AddMember(name, value, allocator);
1787 }
1788 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator)
1789 {
1790 return AddMember(name, value, allocator);
1791 }
1792 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator)
1793 {
1794 GenericValue n(name);
1795 return AddMember(n, value, allocator);
1796 }
1797#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1798
1800
1807 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator)
1808 {
1809 GenericValue n(name);
1810 return AddMember(n, value, allocator);
1811 }
1812
1814
1822 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator)
1823 {
1825 return AddMember(name, v, allocator);
1826 }
1827
1829
1844 template <typename T>
1846 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (GenericValue&))
1847 AddMember(StringRefType name, T value, Allocator& allocator)
1848 {
1849 GenericValue n(name);
1850 return AddMember(n, value, allocator);
1851 }
1852
1854
1857 void RemoveAllMembers()
1858 {
1859 RAPIDJSON_ASSERT(IsObject());
1861 }
1862
1864
1871 bool RemoveMember(const Ch* name)
1872 {
1873 GenericValue n(StringRef(name));
1874 return RemoveMember(n);
1875 }
1876
1877#if RAPIDJSON_HAS_STDSTRING
1878 bool RemoveMember(const std::basic_string<Ch>& name)
1879 {
1880 return RemoveMember(GenericValue(StringRef(name)));
1881 }
1882#endif
1883
1884 template <typename SourceAllocator>
1885 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name)
1886 {
1887 MemberIterator m = FindMember(name);
1888 if(m != MemberEnd())
1889 {
1890 RemoveMember(m);
1891 return true;
1892 }
1893 else
1894 return false;
1895 }
1896
1898
1905 MemberIterator RemoveMember(MemberIterator m)
1906 {
1907 RAPIDJSON_ASSERT(IsObject());
1908 RAPIDJSON_ASSERT(data_.o.size > 0);
1910 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1911 return DoRemoveMember(m);
1912 }
1913
1915
1923 MemberIterator EraseMember(ConstMemberIterator pos) { return EraseMember(pos, pos + 1); }
1924
1926
1935 {
1936 RAPIDJSON_ASSERT(IsObject());
1937 RAPIDJSON_ASSERT(data_.o.size > 0);
1939 RAPIDJSON_ASSERT(first >= MemberBegin());
1940 RAPIDJSON_ASSERT(first <= last);
1941 RAPIDJSON_ASSERT(last <= MemberEnd());
1942 return DoEraseMembers(first, last);
1943 }
1944
1946
1950 bool EraseMember(const Ch* name)
1951 {
1952 GenericValue n(StringRef(name));
1953 return EraseMember(n);
1954 }
1955
1956#if RAPIDJSON_HAS_STDSTRING
1957 bool EraseMember(const std::basic_string<Ch>& name)
1958 {
1959 return EraseMember(GenericValue(StringRef(name)));
1960 }
1961#endif
1962
1963 template <typename SourceAllocator>
1964 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name)
1965 {
1966 MemberIterator m = FindMember(name);
1967 if(m != MemberEnd())
1968 {
1969 EraseMember(m);
1970 return true;
1971 }
1972 else
1973 return false;
1974 }
1975
1976 Object GetObject()
1977 {
1978 RAPIDJSON_ASSERT(IsObject());
1979 return Object(*this);
1980 }
1981 Object GetObj()
1982 {
1983 RAPIDJSON_ASSERT(IsObject());
1984 return Object(*this);
1985 }
1986 ConstObject GetObject() const
1987 {
1988 RAPIDJSON_ASSERT(IsObject());
1989 return ConstObject(*this);
1990 }
1991 ConstObject GetObj() const
1992 {
1993 RAPIDJSON_ASSERT(IsObject());
1994 return ConstObject(*this);
1995 }
1996
1998
2000
2001
2003
2004 GenericValue& SetArray()
2005 {
2006 this->~GenericValue();
2007 new(this) GenericValue(kArrayType);
2008 return *this;
2009 }
2010
2012 SizeType Size() const
2013 {
2014 RAPIDJSON_ASSERT(IsArray());
2015 return data_.a.size;
2016 }
2017
2019 SizeType Capacity() const
2020 {
2021 RAPIDJSON_ASSERT(IsArray());
2022 return data_.a.capacity;
2023 }
2024
2026 bool Empty() const
2027 {
2028 RAPIDJSON_ASSERT(IsArray());
2029 return data_.a.size == 0;
2030 }
2031
2033
2036 void Clear()
2037 {
2038 RAPIDJSON_ASSERT(IsArray());
2040 for(GenericValue* v = e; v != e + data_.a.size; ++v)
2041 v->~GenericValue();
2042 data_.a.size = 0;
2043 }
2044
2046
2050 GenericValue& operator[](SizeType index)
2051 {
2052 RAPIDJSON_ASSERT(IsArray());
2053 RAPIDJSON_ASSERT(index < data_.a.size);
2054 return GetElementsPointer()[index];
2055 }
2056 const GenericValue& operator[](SizeType index) const
2057 {
2058 return const_cast<GenericValue&>(*this)[index];
2059 }
2060
2062
2063 ValueIterator Begin()
2064 {
2065 RAPIDJSON_ASSERT(IsArray());
2066 return GetElementsPointer();
2067 }
2069
2070 ValueIterator End()
2071 {
2072 RAPIDJSON_ASSERT(IsArray());
2073 return GetElementsPointer() + data_.a.size;
2074 }
2076
2077 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
2079
2080 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
2081
2083
2088 GenericValue& Reserve(SizeType newCapacity, Allocator& allocator)
2089 {
2090 RAPIDJSON_ASSERT(IsArray());
2091 if(newCapacity > data_.a.capacity)
2092 {
2093 SetElementsPointer(reinterpret_cast<GenericValue*>(
2094 allocator.Realloc(GetElementsPointer(),
2095 data_.a.capacity * sizeof(GenericValue),
2096 newCapacity * sizeof(GenericValue))));
2097 data_.a.capacity = newCapacity;
2098 }
2099 return *this;
2100 }
2101
2103
2111 GenericValue& PushBack(GenericValue& value, Allocator& allocator)
2112 {
2113 RAPIDJSON_ASSERT(IsArray());
2114 if(data_.a.size >= data_.a.capacity)
2115 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity
2116 : (data_.a.capacity + (data_.a.capacity + 1) / 2),
2117 allocator);
2119 return *this;
2120 }
2121
2122#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2123 GenericValue& PushBack(GenericValue&& value, Allocator& allocator)
2124 {
2125 return PushBack(value, allocator);
2126 }
2127#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2128
2130
2137 GenericValue& PushBack(StringRefType value, Allocator& allocator)
2138 {
2139 return (*this).template PushBack<StringRefType>(value, allocator);
2140 }
2141
2143
2159 template <typename T>
2161 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (GenericValue&))
2162 PushBack(T value, Allocator& allocator)
2163 {
2165 return PushBack(v, allocator);
2166 }
2167
2169
2172 GenericValue& PopBack()
2173 {
2174 RAPIDJSON_ASSERT(IsArray());
2177 return *this;
2178 }
2179
2181
2187 ValueIterator Erase(ConstValueIterator pos) { return Erase(pos, pos + 1); }
2188
2190
2198 {
2199 RAPIDJSON_ASSERT(IsArray());
2200 RAPIDJSON_ASSERT(data_.a.size > 0);
2202 RAPIDJSON_ASSERT(first >= Begin());
2203 RAPIDJSON_ASSERT(first <= last);
2204 RAPIDJSON_ASSERT(last <= End());
2205 ValueIterator pos = Begin() + (first - Begin());
2206 for(ValueIterator itr = pos; itr != last; ++itr)
2207 itr->~GenericValue();
2208 std::memmove(static_cast<void*>(pos),
2209 last,
2210 static_cast<size_t>(End() - last) * sizeof(GenericValue));
2211 data_.a.size -= static_cast<SizeType>(last - first);
2212 return pos;
2213 }
2214
2215 Array GetArray()
2216 {
2217 RAPIDJSON_ASSERT(IsArray());
2218 return Array(*this);
2219 }
2220 ConstArray GetArray() const
2221 {
2222 RAPIDJSON_ASSERT(IsArray());
2223 return ConstArray(*this);
2224 }
2225
2227
2229
2230
2231 int GetInt() const
2232 {
2233 RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);
2234 return data_.n.i.i;
2235 }
2236 unsigned GetUint() const
2237 {
2238 RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);
2239 return data_.n.u.u;
2240 }
2241 int64_t GetInt64() const
2242 {
2244 return data_.n.i64;
2245 }
2246 uint64_t GetUint64() const
2247 {
2249 return data_.n.u64;
2250 }
2251
2253
2256 double GetDouble() const
2257 {
2258 RAPIDJSON_ASSERT(IsNumber());
2259 if((data_.f.flags & kDoubleFlag) != 0)
2260 return data_.n.d; // exact type, no conversion.
2261 if((data_.f.flags & kIntFlag) != 0)
2262 return data_.n.i.i; // int -> double
2263 if((data_.f.flags & kUintFlag) != 0)
2264 return data_.n.u.u; // unsigned -> double
2265 if((data_.f.flags & kInt64Flag) != 0)
2266 return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
2267 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);
2268 return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
2269 }
2270
2272
2275 float GetFloat() const { return static_cast<float>(GetDouble()); }
2276
2277 GenericValue& SetInt(int i)
2278 {
2279 this->~GenericValue();
2280 new(this) GenericValue(i);
2281 return *this;
2282 }
2283 GenericValue& SetUint(unsigned u)
2284 {
2285 this->~GenericValue();
2286 new(this) GenericValue(u);
2287 return *this;
2288 }
2289 GenericValue& SetInt64(int64_t i64)
2290 {
2291 this->~GenericValue();
2292 new(this) GenericValue(i64);
2293 return *this;
2294 }
2295 GenericValue& SetUint64(uint64_t u64)
2296 {
2297 this->~GenericValue();
2298 new(this) GenericValue(u64);
2299 return *this;
2300 }
2301 GenericValue& SetDouble(double d)
2302 {
2303 this->~GenericValue();
2304 new(this) GenericValue(d);
2305 return *this;
2306 }
2307 GenericValue& SetFloat(float f)
2308 {
2309 this->~GenericValue();
2310 new(this) GenericValue(static_cast<double>(f));
2311 return *this;
2312 }
2313
2315
2317
2318
2319 const Ch* GetString() const
2320 {
2321 RAPIDJSON_ASSERT(IsString());
2322 return DataString(data_);
2323 }
2324
2326
2329 SizeType GetStringLength() const
2330 {
2331 RAPIDJSON_ASSERT(IsString());
2332 return DataStringLength(data_);
2333 }
2334
2336
2342 GenericValue& SetString(const Ch* s, SizeType length)
2343 {
2344 return SetString(StringRef(s, length));
2345 }
2346
2348
2352 GenericValue& SetString(StringRefType s)
2353 {
2354 this->~GenericValue();
2355 SetStringRaw(s);
2356 return *this;
2357 }
2358
2360
2367 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator)
2368 {
2369 return SetString(StringRef(s, length), allocator);
2370 }
2371
2373
2378 GenericValue& SetString(const Ch* s, Allocator& allocator)
2379 {
2380 return SetString(StringRef(s), allocator);
2381 }
2382
2384
2389 GenericValue& SetString(StringRefType s, Allocator& allocator)
2390 {
2391 this->~GenericValue();
2392 SetStringRaw(s, allocator);
2393 return *this;
2394 }
2395
2396#if RAPIDJSON_HAS_STDSTRING
2398
2405 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator)
2406 {
2407 return SetString(StringRef(s), allocator);
2408 }
2409#endif
2410
2412
2414
2415
2417
2421 template <typename T>
2422 bool Is() const
2423 {
2424 return internal::TypeHelper<ValueType, T>::Is(*this);
2425 }
2426
2427 template <typename T>
2428 T Get() const
2429 {
2430 return internal::TypeHelper<ValueType, T>::Get(*this);
2431 }
2432
2433 template <typename T>
2434 T Get()
2435 {
2436 return internal::TypeHelper<ValueType, T>::Get(*this);
2437 }
2438
2439 template <typename T>
2440 ValueType& Set(const T& data)
2441 {
2442 return internal::TypeHelper<ValueType, T>::Set(*this, data);
2443 }
2444
2445 template <typename T>
2446 ValueType& Set(const T& data, AllocatorType& allocator)
2447 {
2448 return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator);
2449 }
2450
2452
2454
2460 template <typename Handler>
2461 bool Accept(Handler& handler) const
2462 {
2463 switch(GetType())
2464 {
2465 case kNullType: return handler.Null();
2466 case kFalseType: return handler.Bool(false);
2467 case kTrueType: return handler.Bool(true);
2468
2469 case kObjectType:
2470 if(RAPIDJSON_UNLIKELY(!handler.StartObject()))
2471 return false;
2472 for(ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2473 {
2475 m->name.IsString()); // User may change the type of name by MemberIterator.
2476 if(RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(),
2477 m->name.GetStringLength(),
2478 (m->name.data_.f.flags & kCopyFlag) != 0)))
2479 return false;
2480 if(RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
2481 return false;
2482 }
2483 return handler.EndObject(data_.o.size);
2484
2485 case kArrayType:
2486 if(RAPIDJSON_UNLIKELY(!handler.StartArray()))
2487 return false;
2488 for(ConstValueIterator v = Begin(); v != End(); ++v)
2489 if(RAPIDJSON_UNLIKELY(!v->Accept(handler)))
2490 return false;
2491 return handler.EndArray(data_.a.size);
2492
2493 case kStringType:
2494 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
2495
2496 default:
2497 RAPIDJSON_ASSERT(GetType() == kNumberType);
2498 if(IsDouble())
2499 return handler.Double(data_.n.d);
2500 else if(IsInt())
2501 return handler.Int(data_.n.i.i);
2502 else if(IsUint())
2503 return handler.Uint(data_.n.u.u);
2504 else if(IsInt64())
2505 return handler.Int64(data_.n.i64);
2506 else
2507 return handler.Uint64(data_.n.u64);
2508 }
2509 }
2510
2511 private:
2512 template <typename, typename>
2513 friend class GenericValue;
2514 template <typename, typename, typename>
2515 friend class GenericDocument;
2516
2517 enum
2518 {
2519 kBoolFlag = 0x0008,
2520 kNumberFlag = 0x0010,
2521 kIntFlag = 0x0020,
2522 kUintFlag = 0x0040,
2523 kInt64Flag = 0x0080,
2524 kUint64Flag = 0x0100,
2525 kDoubleFlag = 0x0200,
2526 kStringFlag = 0x0400,
2527 kCopyFlag = 0x0800,
2529
2530 // Initial flags of different types.
2532 // These casts are added to suppress the warning on MSVC about bitwise operations between
2533 // enums of different types.
2534 kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
2535 kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
2537 static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
2538 kNumberUintFlag = static_cast<int>(kNumberType) |
2539 static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
2541 static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
2543 static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
2545 static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
2547 static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag |
2549 kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
2550 kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
2551 kShortStringFlag = static_cast<int>(kStringType) |
2552 static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2555
2557 };
2558
2561
2562 struct Flag
2563 {
2564#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2565 char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
2566#elif RAPIDJSON_64BIT
2567 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
2568#else
2569 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
2570#endif
2572 };
2573
2574 struct String
2575 {
2578 const Ch* str;
2579 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2580
2581 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
2582 // (excluding the terminating zero) and store a value to determine the length of the contained
2583 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
2584 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
2585 // the string terminator as well. For getting the string length back from that value just use
2586 // "MaxSize - str[LenPos]".
2587 // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2588 // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded
2589 // strings).
2591 {
2592 enum
2593 {
2594 MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch),
2597 };
2599
2600 inline static bool Usable(SizeType len) { return (MaxSize >= len); }
2601 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2602 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
2603 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit
2604 // mode
2605
2606 // By using proper binary layout, retrieval of different integer types do not need conversions.
2608 {
2609#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2610 struct I
2611 {
2612 int i;
2613 char padding[4];
2614 } i;
2615 struct U
2616 {
2617 unsigned u;
2618 char padding2[4];
2619 } u;
2620#else
2621 struct I
2622 {
2623 char padding[4];
2624 int i;
2625 } i;
2626 struct U
2627 {
2628 char padding2[4];
2629 unsigned u;
2630 } u;
2631#endif
2634 double d;
2635 }; // 8 bytes
2636
2638 {
2642 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2643
2645 {
2649 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2650
2651 union Data
2652 {
2659 }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with
2660 // RAPIDJSON_48BITPOINTER_OPTIMIZATION
2661
2662 static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data)
2663 {
2664 return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
2665 }
2666 static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data)
2667 {
2668 return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2669 }
2670
2671 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const
2672 {
2673 return RAPIDJSON_GETPOINTER(Ch, data_.s.str);
2674 }
2675 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str)
2676 {
2677 return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str);
2678 }
2679 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const
2680 {
2681 return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements);
2682 }
2683 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements)
2684 {
2685 return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements);
2686 }
2687 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const
2688 {
2689 return RAPIDJSON_GETPOINTER(Member, data_.o.members);
2690 }
2691 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members)
2692 {
2693 return RAPIDJSON_SETPOINTER(Member, data_.o.members, members);
2694 }
2695
2696#if RAPIDJSON_USE_MEMBERSMAP
2697
2698 struct MapTraits
2699 {
2700 struct Less
2701 {
2702 bool operator()(const Data& s1, const Data& s2) const
2703 {
2704 SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
2705 int cmp =
2706 std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2));
2707 return cmp < 0 || (cmp == 0 && n1 < n2);
2708 }
2709 };
2710 typedef std::pair<const Data, SizeType> Pair;
2711 typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator>> Map;
2712 typedef typename Map::iterator Iterator;
2713 };
2714 typedef typename MapTraits::Map Map;
2715 typedef typename MapTraits::Less MapLess;
2716 typedef typename MapTraits::Pair MapPair;
2717 typedef typename MapTraits::Iterator MapIterator;
2718
2719 //
2720 // Layout of the members' map/array, re(al)located according to the needed capacity:
2721 //
2722 // {Map*}<>{capacity}<>{Member[capacity]}<>{MapIterator[capacity]}
2723 //
2724 // (where <> stands for the RAPIDJSON_ALIGN-ment, if needed)
2725 //
2726
2727 static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity)
2728 {
2729 return RAPIDJSON_ALIGN(sizeof(Map*)) + RAPIDJSON_ALIGN(sizeof(SizeType)) +
2730 RAPIDJSON_ALIGN(capacity * sizeof(Member)) + capacity * sizeof(MapIterator);
2731 }
2732
2733 static RAPIDJSON_FORCEINLINE SizeType& GetMapCapacity(Map*& map)
2734 {
2735 return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
2736 RAPIDJSON_ALIGN(sizeof(Map*)));
2737 }
2738
2739 static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map*& map)
2740 {
2741 return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
2742 RAPIDJSON_ALIGN(sizeof(Map*)) +
2743 RAPIDJSON_ALIGN(sizeof(SizeType)));
2744 }
2745
2746 static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map*& map)
2747 {
2748 return reinterpret_cast<MapIterator*>(
2749 reinterpret_cast<uintptr_t>(&map) + RAPIDJSON_ALIGN(sizeof(Map*)) +
2750 RAPIDJSON_ALIGN(sizeof(SizeType)) +
2751 RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member)));
2752 }
2753
2754 static RAPIDJSON_FORCEINLINE Map*& GetMap(Member* members)
2755 {
2756 RAPIDJSON_ASSERT(members != 0);
2757 return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
2758 RAPIDJSON_ALIGN(sizeof(SizeType)) -
2759 RAPIDJSON_ALIGN(sizeof(Map*)));
2760 }
2761
2762 // Some compilers' debug mechanisms want all iterators to be destroyed, for their accounting..
2763 RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs)
2764 {
2765#if RAPIDJSON_HAS_CXX11
2766 MapIterator ret = std::move(rhs);
2767#else
2768 MapIterator ret = rhs;
2769#endif
2770 rhs.~MapIterator();
2771 return ret;
2772 }
2773
2774 Map*& DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator)
2775 {
2776 Map** newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
2777 GetMapCapacity(*newMap) = newCapacity;
2778 if(!oldMap)
2779 {
2780 *newMap = new(allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator);
2781 }
2782 else
2783 {
2784 *newMap = *oldMap;
2785 size_t count = (*oldMap)->size();
2786 std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
2787 static_cast<void*>(GetMapMembers(*oldMap)),
2788 count * sizeof(Member));
2789 MapIterator *oldIt = GetMapIterators(*oldMap), *newIt = GetMapIterators(*newMap);
2790 while(count--)
2791 {
2792 new(&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
2793 }
2794 Allocator::Free(oldMap);
2795 }
2796 return *newMap;
2797 }
2798
2799 RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator)
2800 {
2801 return GetMapMembers(DoReallocMap(0, capacity, allocator));
2802 }
2803
2804 void DoReserveMembers(SizeType newCapacity, Allocator& allocator)
2805 {
2806 ObjectData& o = data_.o;
2807 if(newCapacity > o.capacity)
2808 {
2809 Member* oldMembers = GetMembersPointer();
2810 Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
2811 *&newMap = DoReallocMap(oldMap, newCapacity, allocator);
2812 RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
2813 o.capacity = newCapacity;
2814 }
2815 }
2816
2817 template <typename SourceAllocator>
2819 {
2820 if(Member* members = GetMembersPointer())
2821 {
2822 Map*& map = GetMap(members);
2823 MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
2824 if(mit != map->end())
2825 {
2826 return MemberIterator(&members[mit->second]);
2827 }
2828 }
2829 return MemberEnd();
2830 }
2831
2832 void DoClearMembers()
2833 {
2834 if(Member* members = GetMembersPointer())
2835 {
2836 Map*& map = GetMap(members);
2837 MapIterator* mit = GetMapIterators(map);
2838 for(SizeType i = 0; i < data_.o.size; i++)
2839 {
2840 map->erase(DropMapIterator(mit[i]));
2841 members[i].~Member();
2842 }
2843 data_.o.size = 0;
2844 }
2845 }
2846
2847 void DoFreeMembers()
2848 {
2849 if(Member* members = GetMembersPointer())
2850 {
2851 GetMap(members)->~Map();
2852 for(SizeType i = 0; i < data_.o.size; i++)
2853 {
2854 members[i].~Member();
2855 }
2856 if(Allocator::kNeedFree)
2857 { // Shortcut by Allocator's trait
2858 Map** map = &GetMap(members);
2859 Allocator::Free(*map);
2860 Allocator::Free(map);
2861 }
2862 }
2863 }
2864
2865#else // !RAPIDJSON_USE_MEMBERSMAP
2866
2867 RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator)
2868 {
2869 return Malloc<Member>(allocator, capacity);
2870 }
2871
2872 void DoReserveMembers(SizeType newCapacity, Allocator& allocator)
2873 {
2874 ObjectData& o = data_.o;
2875 if(newCapacity > o.capacity)
2876 {
2877 Member* newMembers =
2878 Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2879 RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
2880 o.capacity = newCapacity;
2881 }
2882 }
2883
2884 template <typename SourceAllocator>
2886 {
2887 MemberIterator member = MemberBegin();
2888 for(; member != MemberEnd(); ++member)
2889 if(name.StringEqual(member->name))
2890 break;
2891 return member;
2892 }
2893
2895 {
2896 for(MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2897 m->~Member();
2898 data_.o.size = 0;
2899 }
2900
2902 {
2903 for(MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2904 m->~Member();
2905 Allocator::Free(GetMembersPointer());
2906 }
2907
2908#endif // !RAPIDJSON_USE_MEMBERSMAP
2909
2911 {
2912 ObjectData& o = data_.o;
2913 if(o.size >= o.capacity)
2914 DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2)
2916 allocator);
2917 Member* members = GetMembersPointer();
2918 Member* m = members + o.size;
2919 m->name.RawAssign(name);
2920 m->value.RawAssign(value);
2921#if RAPIDJSON_USE_MEMBERSMAP
2922 Map*& map = GetMap(members);
2923 MapIterator* mit = GetMapIterators(map);
2924 new(&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
2925#endif
2926 ++o.size;
2927 }
2928
2930 {
2931 ObjectData& o = data_.o;
2932 Member* members = GetMembersPointer();
2933#if RAPIDJSON_USE_MEMBERSMAP
2934 Map*& map = GetMap(members);
2935 MapIterator* mit = GetMapIterators(map);
2936 SizeType mpos = static_cast<SizeType>(&*m - members);
2937 map->erase(DropMapIterator(mit[mpos]));
2938#endif
2939 MemberIterator last(members + (o.size - 1));
2940 if(o.size > 1 && m != last)
2941 {
2942#if RAPIDJSON_USE_MEMBERSMAP
2943 new(&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
2944 mit[mpos]->second = mpos;
2945#endif
2946 *m = *last; // Move the last one to this place
2947 }
2948 else
2949 {
2950 m->~Member(); // Only one left, just destroy
2951 }
2952 --o.size;
2953 return m;
2954 }
2955
2957 {
2958 ObjectData& o = data_.o;
2959 MemberIterator beg = MemberBegin(), pos = beg + (first - beg), end = MemberEnd();
2960#if RAPIDJSON_USE_MEMBERSMAP
2961 Map*& map = GetMap(GetMembersPointer());
2962 MapIterator* mit = GetMapIterators(map);
2963#endif
2964 for(MemberIterator itr = pos; itr != last; ++itr)
2965 {
2966#if RAPIDJSON_USE_MEMBERSMAP
2967 map->erase(DropMapIterator(mit[itr - beg]));
2968#endif
2969 itr->~Member();
2970 }
2971#if RAPIDJSON_USE_MEMBERSMAP
2972 if(first != last)
2973 {
2974 // Move remaining members/iterators
2975 MemberIterator next = pos + (last - first);
2976 for(MemberIterator itr = pos; next != end; ++itr, ++next)
2977 {
2978 std::memcpy(static_cast<void*>(&*itr), &*next, sizeof(Member));
2979 SizeType mpos = static_cast<SizeType>(itr - beg);
2980 new(&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
2981 mit[mpos]->second = mpos;
2982 }
2983 }
2984#else
2985 std::memmove(
2986 static_cast<void*>(&*pos), &*last, static_cast<size_t>(end - last) * sizeof(Member));
2987#endif
2988 o.size -= static_cast<SizeType>(last - first);
2989 return pos;
2990 }
2991
2992 template <typename SourceAllocator>
2994 Allocator& allocator,
2995 bool copyConstStrings)
2996 {
2997 RAPIDJSON_ASSERT(rhs.GetType() == kObjectType);
2998
2999 data_.f.flags = kObjectFlag;
3000 SizeType count = rhs.data_.o.size;
3001 Member* lm = DoAllocMembers(count, allocator);
3003 rhs.GetMembersPointer();
3004#if RAPIDJSON_USE_MEMBERSMAP
3005 Map*& map = GetMap(lm);
3006 MapIterator* mit = GetMapIterators(map);
3007#endif
3008 for(SizeType i = 0; i < count; i++)
3009 {
3010 new(&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
3011 new(&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
3012#if RAPIDJSON_USE_MEMBERSMAP
3013 new(&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
3014#endif
3015 }
3016 data_.o.size = data_.o.capacity = count;
3018 }
3019
3020 // Initialize this value as array with initial data, without calling destructor.
3021 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator)
3022 {
3023 data_.f.flags = kArrayFlag;
3024 if(count)
3025 {
3026 GenericValue* e =
3027 static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
3029 std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
3030 }
3031 else
3033 data_.a.size = data_.a.capacity = count;
3034 }
3035
3037 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator)
3038 {
3039 data_.f.flags = kObjectFlag;
3040 if(count)
3041 {
3042 Member* m = DoAllocMembers(count, allocator);
3044 std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
3045#if RAPIDJSON_USE_MEMBERSMAP
3046 Map*& map = GetMap(m);
3047 MapIterator* mit = GetMapIterators(map);
3048 for(SizeType i = 0; i < count; i++)
3049 {
3050 new(&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
3051 }
3052#endif
3053 }
3054 else
3056 data_.o.size = data_.o.capacity = count;
3057 }
3058
3060 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
3061 {
3062 data_.f.flags = kConstStringFlag;
3064 data_.s.length = s.length;
3065 }
3066
3069 {
3070 Ch* str = 0;
3072 {
3073 data_.f.flags = kShortStringFlag;
3074 data_.ss.SetLength(s.length);
3075 str = data_.ss.str;
3076 std::memmove(str, s, s.length * sizeof(Ch));
3077 }
3078 else
3079 {
3080 data_.f.flags = kCopyStringFlag;
3081 data_.s.length = s.length;
3082 str = static_cast<Ch*>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
3083 SetStringPointer(str);
3084 std::memcpy(str, s, s.length * sizeof(Ch));
3085 }
3086 str[s.length] = '\0';
3087 }
3088
3090 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT
3091 {
3092 data_ = rhs.data_;
3093 // data_.f.flags = rhs.data_.f.flags;
3094 rhs.data_.f.flags = kNullFlag;
3095 }
3096
3097 template <typename SourceAllocator>
3099 {
3100 RAPIDJSON_ASSERT(IsString());
3101 RAPIDJSON_ASSERT(rhs.IsString());
3102
3103 const SizeType len1 = GetStringLength();
3104 const SizeType len2 = rhs.GetStringLength();
3105 if(len1 != len2)
3106 {
3107 return false;
3108 }
3109
3110 const Ch* const str1 = GetString();
3111 const Ch* const str2 = rhs.GetString();
3112 if(str1 == str2)
3113 {
3114 return true;
3115 } // fast path for constant string
3116
3117 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
3118 }
3119
3120 Data data_;
3121};
3122
3125
3127// GenericDocument
3128
3130
3139template <typename Encoding,
3141 typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR>
3142class GenericDocument : public GenericValue<Encoding, Allocator>
3143{
3144 public:
3145 typedef typename Encoding::Ch Ch;
3148 typedef StackAllocator StackAllocatorType;
3149
3151
3157 explicit GenericDocument(Type type,
3158 Allocator* allocator = 0,
3159 size_t stackCapacity = kDefaultStackCapacity,
3160 StackAllocator* stackAllocator = 0)
3162 allocator_(allocator),
3163 ownAllocator_(0),
3164 stack_(stackAllocator, stackCapacity),
3165 parseResult_()
3166 {
3167 if(!allocator_)
3168 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
3169 }
3170
3172
3178 size_t stackCapacity = kDefaultStackCapacity,
3179 StackAllocator* stackAllocator = 0)
3180 : allocator_(allocator),
3181 ownAllocator_(0),
3182 stack_(stackAllocator, stackCapacity),
3183 parseResult_()
3184 {
3185 if(!allocator_)
3186 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
3187 }
3188
3189#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3191 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
3192 : ValueType(
3193 std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
3194 allocator_(rhs.allocator_),
3195 ownAllocator_(rhs.ownAllocator_),
3196 stack_(std::move(rhs.stack_)),
3197 parseResult_(rhs.parseResult_)
3198 {
3199 rhs.allocator_ = 0;
3200 rhs.ownAllocator_ = 0;
3201 rhs.parseResult_ = ParseResult();
3202 }
3203#endif
3204
3206 {
3207 // Clear the ::ValueType before ownAllocator is destroyed, ~ValueType()
3208 // runs last and may access its elements or members which would be freed
3209 // with an allocator like MemoryPoolAllocator (CrtAllocator does not
3210 // free its data when destroyed, but MemoryPoolAllocator does).
3211 if(ownAllocator_)
3212 {
3213 ValueType::SetNull();
3214 }
3215 Destroy();
3216 }
3217
3218#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3220 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
3221 {
3222 // The cast to ValueType is necessary here, because otherwise it would
3223 // attempt to call GenericValue's templated assignment operator.
3224 ValueType::operator=(std::forward<ValueType>(rhs));
3225
3226 // Calling the destructor here would prematurely call stack_'s destructor
3227 Destroy();
3228
3229 allocator_ = rhs.allocator_;
3230 ownAllocator_ = rhs.ownAllocator_;
3231 stack_ = std::move(rhs.stack_);
3232 parseResult_ = rhs.parseResult_;
3233
3234 rhs.allocator_ = 0;
3235 rhs.ownAllocator_ = 0;
3236 rhs.parseResult_ = ParseResult();
3237
3238 return *this;
3239 }
3240#endif
3241
3243
3248 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT
3249 {
3250 ValueType::Swap(rhs);
3251 stack_.Swap(rhs.stack_);
3252 internal::Swap(allocator_, rhs.allocator_);
3253 internal::Swap(ownAllocator_, rhs.ownAllocator_);
3254 internal::Swap(parseResult_, rhs.parseResult_);
3255 return *this;
3256 }
3257
3258 // Allow Swap with ValueType.
3259 // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
3260 using ValueType::Swap;
3261
3263
3271 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT
3272 {
3273 a.Swap(b);
3274 }
3275
3277
3281 template <typename Generator>
3283 {
3284 ClearStackOnExit scope(*this);
3285 if(g(*this))
3286 {
3287 RAPIDJSON_ASSERT(stack_.GetSize() ==
3288 sizeof(ValueType)); // Got one and only one root object
3290 *stack_.template Pop<ValueType>(1)); // Move value from stack to document
3291 }
3292 return *this;
3293 }
3294
3297
3299
3305 template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
3307 {
3309 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
3310 ClearStackOnExit scope(*this);
3311 parseResult_ = reader.template Parse<parseFlags>(is, *this);
3312 if(parseResult_)
3313 {
3314 RAPIDJSON_ASSERT(stack_.GetSize() ==
3315 sizeof(ValueType)); // Got one and only one root object
3317 *stack_.template Pop<ValueType>(1)); // Move value from stack to document
3318 }
3319 return *this;
3320 }
3321
3323
3328 template <unsigned parseFlags, typename InputStream>
3330 {
3332 }
3333
3335
3339 template <typename InputStream>
3344
3345
3348
3350
3354 template <unsigned parseFlags>
3360
3362
3367
3370
3372
3376 template <unsigned parseFlags, typename SourceEncoding>
3377 GenericDocument& Parse(const typename SourceEncoding::Ch* str)
3378 {
3379 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
3382 }
3383
3385
3388 template <unsigned parseFlags>
3390 {
3391 return Parse<parseFlags, Encoding>(str);
3392 }
3393
3395
3398
3399 template <unsigned parseFlags, typename SourceEncoding>
3400 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length)
3401 {
3402 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
3403 MemoryStream ms(reinterpret_cast<const char*>(str),
3404 length * sizeof(typename SourceEncoding::Ch));
3407 return *this;
3408 }
3409
3410 template <unsigned parseFlags>
3411 GenericDocument& Parse(const Ch* str, size_t length)
3412 {
3413 return Parse<parseFlags, Encoding>(str, length);
3414 }
3415
3416 GenericDocument& Parse(const Ch* str, size_t length)
3417 {
3418 return Parse<kParseDefaultFlags>(str, length);
3419 }
3420
3421#if RAPIDJSON_HAS_STDSTRING
3422 template <unsigned parseFlags, typename SourceEncoding>
3423 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str)
3424 {
3425 // c_str() is constant complexity according to standard. Should be faster than Parse(const
3426 // char*, size_t)
3427 return Parse<parseFlags, SourceEncoding>(str.c_str());
3428 }
3429
3430 template <unsigned parseFlags>
3431 GenericDocument& Parse(const std::basic_string<Ch>& str)
3432 {
3433 return Parse<parseFlags, Encoding>(str.c_str());
3434 }
3435
3436 GenericDocument& Parse(const std::basic_string<Ch>& str)
3437 {
3438 return Parse<kParseDefaultFlags>(str);
3439 }
3440#endif // RAPIDJSON_HAS_STDSTRING
3441
3443
3446
3448 bool HasParseError() const { return parseResult_.IsError(); }
3449
3451 ParseErrorCode GetParseError() const { return parseResult_.Code(); }
3452
3454 size_t GetErrorOffset() const { return parseResult_.Offset(); }
3455
3457#ifndef __clang // -Wdocumentation
3467#endif
3468 operator ParseResult() const { return parseResult_; }
3470
3473 {
3474 RAPIDJSON_ASSERT(allocator_);
3475 return *allocator_;
3476 }
3477
3479 size_t GetStackCapacity() const { return stack_.GetCapacity(); }
3480
3481 private:
3482 // clear stack on any exit from ParseStream, e.g. due to exception
3483 struct ClearStackOnExit
3484 {
3485 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
3486 ~ClearStackOnExit() { d_.ClearStack(); }
3487
3488 private:
3489 ClearStackOnExit(const ClearStackOnExit&);
3490 ClearStackOnExit& operator=(const ClearStackOnExit&);
3491 GenericDocument& d_;
3492 };
3493
3494 // callers of the following private Handler functions
3495 // template <typename,typename,typename> friend class GenericReader; // for parsing
3496 template <typename, typename>
3497 friend class GenericValue; // for deep copying
3498
3499 public:
3500 // Implementation of Handler
3501 bool Null()
3502 {
3503 new(stack_.template Push<ValueType>()) ValueType();
3504 return true;
3505 }
3506 bool Bool(bool b)
3507 {
3508 new(stack_.template Push<ValueType>()) ValueType(b);
3509 return true;
3510 }
3511 bool Int(int i)
3512 {
3513 new(stack_.template Push<ValueType>()) ValueType(i);
3514 return true;
3515 }
3516 bool Uint(unsigned i)
3517 {
3518 new(stack_.template Push<ValueType>()) ValueType(i);
3519 return true;
3520 }
3522 {
3523 new(stack_.template Push<ValueType>()) ValueType(i);
3524 return true;
3525 }
3527 {
3528 new(stack_.template Push<ValueType>()) ValueType(i);
3529 return true;
3530 }
3531 bool Double(double d)
3532 {
3533 new(stack_.template Push<ValueType>()) ValueType(d);
3534 return true;
3535 }
3536
3537 bool RawNumber(const Ch* str, SizeType length, bool copy)
3538 {
3539 if(copy)
3540 new(stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
3541 else
3542 new(stack_.template Push<ValueType>()) ValueType(str, length);
3543 return true;
3544 }
3545
3546 bool String(const Ch* str, SizeType length, bool copy)
3547 {
3548 if(copy)
3549 new(stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
3550 else
3551 new(stack_.template Push<ValueType>()) ValueType(str, length);
3552 return true;
3553 }
3554
3556 {
3557 new(stack_.template Push<ValueType>()) ValueType(kObjectType);
3558 return true;
3559 }
3560
3561 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
3562
3563 bool EndObject(SizeType memberCount)
3564 {
3565 typename ValueType::Member* members =
3566 stack_.template Pop<typename ValueType::Member>(memberCount);
3567 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
3568 return true;
3569 }
3570
3572 {
3573 new(stack_.template Push<ValueType>()) ValueType(kArrayType);
3574 return true;
3575 }
3576
3577 bool EndArray(SizeType elementCount)
3578 {
3579 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
3580 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
3581 return true;
3582 }
3583
3584 private:
3588 GenericDocument& operator=(const GenericDocument&);
3589
3590 void ClearStack()
3591 {
3592 if(Allocator::kNeedFree)
3593 while(stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue
3594 // (Member is actually 2 GenericValue objects)
3595 (stack_.template Pop<ValueType>(1))->~ValueType();
3596 else
3597 stack_.Clear();
3598 stack_.ShrinkToFit();
3599 }
3600
3601 void Destroy() { RAPIDJSON_DELETE(ownAllocator_); }
3602
3603 static const size_t kDefaultStackCapacity = 1024;
3604 Allocator* allocator_;
3605 Allocator* ownAllocator_;
3606 internal::Stack<StackAllocator> stack_;
3607 ParseResult parseResult_;
3608};
3609
3612
3614
3619template <bool Const, typename ValueT>
3621{
3622 public:
3625 typedef ValueT PlainType;
3626 typedef typename internal::MaybeAddConst<Const, PlainType>::Type ValueType;
3627 typedef ValueType* ValueIterator; // This may be const or non-const iterator
3628 typedef const ValueT* ConstValueIterator;
3629 typedef typename ValueType::AllocatorType AllocatorType;
3630 typedef typename ValueType::StringRefType StringRefType;
3631
3632 template <typename, typename>
3633 friend class GenericValue;
3634
3635 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
3637 {
3638 value_ = rhs.value_;
3639 return *this;
3640 }
3642
3643 operator ValueType&() const { return value_; }
3644 SizeType Size() const { return value_.Size(); }
3645 SizeType Capacity() const { return value_.Capacity(); }
3646 bool Empty() const { return value_.Empty(); }
3647 void Clear() const { value_.Clear(); }
3648 ValueType& operator[](SizeType index) const { return value_[index]; }
3649 ValueIterator Begin() const { return value_.Begin(); }
3650 ValueIterator End() const { return value_.End(); }
3651 GenericArray Reserve(SizeType newCapacity, AllocatorType& allocator) const
3652 {
3653 value_.Reserve(newCapacity, allocator);
3654 return *this;
3655 }
3657 {
3658 value_.PushBack(value, allocator);
3659 return *this;
3660 }
3661#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3663 {
3664 value_.PushBack(value, allocator);
3665 return *this;
3666 }
3667#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
3669 {
3670 value_.PushBack(value, allocator);
3671 return *this;
3672 }
3673 template <typename T>
3675 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>),
3676 (const GenericArray&))
3677 PushBack(T value, AllocatorType& allocator) const
3678 {
3679 value_.PushBack(value, allocator);
3680 return *this;
3681 }
3683 {
3684 value_.PopBack();
3685 return *this;
3686 }
3687 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
3689 {
3690 return value_.Erase(first, last);
3691 }
3692
3693#if RAPIDJSON_HAS_CXX11_RANGE_FOR
3694 ValueIterator begin() const { return value_.Begin(); }
3695 ValueIterator end() const { return value_.End(); }
3696#endif
3697
3698 private:
3699 GenericArray();
3700 GenericArray(ValueType& value) : value_(value) {}
3701 ValueType& value_;
3702};
3703
3705
3710template <bool Const, typename ValueT>
3712{
3713 public:
3716 typedef ValueT PlainType;
3717 typedef typename internal::MaybeAddConst<Const, PlainType>::Type ValueType;
3718 typedef GenericMemberIterator<Const,
3719 typename ValueT::EncodingType,
3720 typename ValueT::AllocatorType>
3721 MemberIterator; // This may be const or non-const iterator
3722 typedef GenericMemberIterator<true,
3723 typename ValueT::EncodingType,
3724 typename ValueT::AllocatorType>
3726 typedef typename ValueType::AllocatorType AllocatorType;
3727 typedef typename ValueType::StringRefType StringRefType;
3728 typedef typename ValueType::EncodingType EncodingType;
3729 typedef typename ValueType::Ch Ch;
3730
3731 template <typename, typename>
3732 friend class GenericValue;
3733
3734 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
3736 {
3737 value_ = rhs.value_;
3738 return *this;
3739 }
3741
3742 operator ValueType&() const { return value_; }
3743 SizeType MemberCount() const { return value_.MemberCount(); }
3744 SizeType MemberCapacity() const { return value_.MemberCapacity(); }
3745 bool ObjectEmpty() const { return value_.ObjectEmpty(); }
3746 template <typename T>
3747 ValueType& operator[](T* name) const
3748 {
3749 return value_[name];
3750 }
3751 template <typename SourceAllocator>
3753 {
3754 return value_[name];
3755 }
3756#if RAPIDJSON_HAS_STDSTRING
3757 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
3758#endif
3759 MemberIterator MemberBegin() const { return value_.MemberBegin(); }
3760 MemberIterator MemberEnd() const { return value_.MemberEnd(); }
3761 GenericObject MemberReserve(SizeType newCapacity, AllocatorType& allocator) const
3762 {
3763 value_.MemberReserve(newCapacity, allocator);
3764 return *this;
3765 }
3766 bool HasMember(const Ch* name) const { return value_.HasMember(name); }
3767#if RAPIDJSON_HAS_STDSTRING
3768 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
3769#endif
3770 template <typename SourceAllocator>
3772 {
3773 return value_.HasMember(name);
3774 }
3775 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
3776 template <typename SourceAllocator>
3778 {
3779 return value_.FindMember(name);
3780 }
3781#if RAPIDJSON_HAS_STDSTRING
3782 MemberIterator FindMember(const std::basic_string<Ch>& name) const
3783 {
3784 return value_.FindMember(name);
3785 }
3786#endif
3788 {
3789 value_.AddMember(name, value, allocator);
3790 return *this;
3791 }
3793 {
3794 value_.AddMember(name, value, allocator);
3795 return *this;
3796 }
3797#if RAPIDJSON_HAS_STDSTRING
3799 AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const
3800 {
3801 value_.AddMember(name, value, allocator);
3802 return *this;
3803 }
3804#endif
3805 template <typename T>
3807 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (ValueType&))
3808 AddMember(ValueType& name, T value, AllocatorType& allocator) const
3809 {
3810 value_.AddMember(name, value, allocator);
3811 return *this;
3812 }
3813#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3814 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const
3815 {
3816 value_.AddMember(name, value, allocator);
3817 return *this;
3818 }
3819 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const
3820 {
3821 value_.AddMember(name, value, allocator);
3822 return *this;
3823 }
3824 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const
3825 {
3826 value_.AddMember(name, value, allocator);
3827 return *this;
3828 }
3830 {
3831 value_.AddMember(name, value, allocator);
3832 return *this;
3833 }
3834#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
3836 {
3837 value_.AddMember(name, value, allocator);
3838 return *this;
3839 }
3841 {
3842 value_.AddMember(name, value, allocator);
3843 return *this;
3844 }
3845 template <typename T>
3847 (internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T>>), (GenericObject))
3848 AddMember(StringRefType name, T value, AllocatorType& allocator) const
3849 {
3850 value_.AddMember(name, value, allocator);
3851 return *this;
3852 }
3853 void RemoveAllMembers() { value_.RemoveAllMembers(); }
3854 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
3855#if RAPIDJSON_HAS_STDSTRING
3856 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
3857#endif
3858 template <typename SourceAllocator>
3860 {
3861 return value_.RemoveMember(name);
3862 }
3863 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
3864 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
3866 {
3867 return value_.EraseMember(first, last);
3868 }
3869 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
3870#if RAPIDJSON_HAS_STDSTRING
3871 bool EraseMember(const std::basic_string<Ch>& name) const
3872 {
3873 return EraseMember(ValueType(StringRef(name)));
3874 }
3875#endif
3876 template <typename SourceAllocator>
3878 {
3879 return value_.EraseMember(name);
3880 }
3881
3882#if RAPIDJSON_HAS_CXX11_RANGE_FOR
3883 MemberIterator begin() const { return value_.MemberBegin(); }
3884 MemberIterator end() const { return value_.MemberEnd(); }
3885#endif
3886
3887 private:
3888 GenericObject();
3889 GenericObject(ValueType& value) : value_(value) {}
3890 ValueType& value_;
3891};
3892
3894RAPIDJSON_DIAG_POP
3895
3896#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3897#pragma pop_macro("GetObject")
3898#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3899#endif
3900
3901#endif // RAPIDJSON_DOCUMENT_H_
T * Malloc(A &a, size_t n=1)
Definition allocators.h:479
T * Realloc(A &a, T *old_p, size_t old_n, size_t new_n)
Definition allocators.h:471
Input byte stream wrapper with a statically bound encoding.
Definition encodedstream.h:40
Helper class for accessing Value of array type.
Definition document.h:3621
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(const GenericArray &)) PushBack(T value
const ValueType * ConstValueIterator
Definition document.h:3628
GenericArray PushBack(ValueType &value, AllocatorType &allocator) const
Definition document.h:3656
ValueIterator End() const
Definition document.h:3650
ValueIterator Begin() const
Definition document.h:3649
void Clear() const
Definition document.h:3647
SizeType Size() const
Definition document.h:3644
GenericArray< false, ValueType > Array
Definition document.h:3624
GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const
Definition document.h:3651
GenericArray & operator=(const GenericArray &rhs)
Definition document.h:3636
GenericArray< true, ValueType > ConstArray
Definition document.h:3623
friend class GenericValue
Definition document.h:3633
ValueType::StringRefType StringRefType
Definition document.h:3630
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition document.h:3626
~GenericArray()
Definition document.h:3641
GenericArray(const GenericArray &rhs)
Definition document.h:3635
SizeType Capacity() const
Definition document.h:3645
ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const
Definition document.h:3688
GenericArray PushBack(StringRefType value, AllocatorType &allocator) const
Definition document.h:3668
ValueType PlainType
Definition document.h:3625
ValueIterator Erase(ConstValueIterator pos) const
Definition document.h:3687
bool Empty() const
Definition document.h:3646
ValueType::AllocatorType AllocatorType
Definition document.h:3629
ValueType & operator[](SizeType index) const
Definition document.h:3648
ValueType * ValueIterator
Definition document.h:3627
GenericArray PopBack() const
Definition document.h:3682
A document for parsing JSON text as DOM.
Definition document.h:3143
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition document.h:3271
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:3472
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition document.h:3355
bool EndArray(SizeType elementCount)
Definition document.h:3577
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition document.h:3248
Allocator AllocatorType
Allocator type from template parameter.
Definition document.h:3147
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition document.h:3389
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition document.h:3157
GenericDocument & Parse(const Ch *str, size_t length)
Parse JSON text from a read-only string (with Encoding conversion).
Definition document.h:3411
bool EndObject(SizeType memberCount)
Definition document.h:3563
StackAllocator StackAllocatorType
StackAllocator type from template parameter.
Definition document.h:3148
bool Bool(bool b)
Definition document.h:3506
bool Uint64(uint64_t i)
Definition document.h:3526
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition document.h:3448
bool Uint(unsigned i)
Definition document.h:3516
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition document.h:3329
bool Key(const Ch *str, SizeType length, bool copy)
Definition document.h:3561
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition document.h:3177
Encoding::Ch Ch
Character type derived from Encoding.
Definition document.h:3145
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags).
Definition document.h:3340
GenericDocument & Parse(const Ch *str, size_t length)
Parse JSON text from a read-only string (with Encoding conversion).
Definition document.h:3416
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion).
Definition document.h:3306
bool Null()
Definition document.h:3501
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition document.h:3146
friend class GenericValue
Definition document.h:3497
bool Int(int i)
Definition document.h:3511
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion).
Definition document.h:3377
bool Int64(int64_t i)
Definition document.h:3521
bool Double(double d)
Definition document.h:3531
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition document.h:3451
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags).
Definition document.h:3365
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition document.h:3479
~GenericDocument()
Definition document.h:3205
bool StartObject()
Definition document.h:3555
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition document.h:3282
bool String(const Ch *str, SizeType length, bool copy)
Definition document.h:3546
bool StartArray()
Definition document.h:3571
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition document.h:3454
GenericDocument & Parse(const typename SourceEncoding::Ch *str, size_t length)
Parse JSON text from a read-only string (with Encoding conversion).
Definition document.h:3400
bool RawNumber(const Ch *str, SizeType length, bool copy)
Definition document.h:3537
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags).
Definition document.h:3397
Name-value pair in a JSON object value.
Definition document.h:122
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition document.h:124
GenericValue< Encoding, Allocator > value
value of member.
Definition document.h:125
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition document.h:145
friend void swap(GenericMember &a, GenericMember &b) RAPIDJSON_NOEXCEPT
Definition document.h:156
(Constant) member iterator for a JSON object value
Definition document.h:194
ValueType & reference
Definition document.h:215
bool operator>(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition document.h:327
bool operator<=(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition document.h:312
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition document.h:249
GenericMemberIterator()
Default constructor (singular value).
Definition document.h:231
Iterator & operator=(const NonConstIterator &it)
Pointer to (const) GenericMember.
Definition document.h:250
Iterator operator-(DifferenceType n) const
Definition document.h:285
std::random_access_iterator_tag iterator_category
Definition document.h:217
Iterator & operator++()
Definition document.h:258
Reference operator[](DifferenceType n) const
raw pointer
Definition document.h:346
Iterator operator--(int)
Definition document.h:274
Iterator operator+(DifferenceType n) const
Definition document.h:284
Reference operator*() const
raw pointer
Definition document.h:344
Iterator & operator+=(DifferenceType n)
Definition document.h:287
ValueType value_type
Definition document.h:213
bool operator==(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition document.h:302
ValueType * pointer
Definition document.h:214
reference Reference
Definition document.h:223
Iterator operator++(int)
Definition document.h:268
friend class GenericMemberIterator
Definition document.h:198
Iterator & operator-=(DifferenceType n)
Definition document.h:292
difference_type DifferenceType
Definition document.h:225
bool operator<(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition document.h:322
bool operator>=(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition document.h:317
Pointer operator->() const
raw pointer
Definition document.h:345
pointer Pointer
Definition document.h:221
GenericMemberIterator Iterator
Iterator type itself.
Definition document.h:205
bool operator!=(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition document.h:307
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Definition document.h:209
DifferenceType operator-(ConstIterator that) const
Distance.
Definition document.h:350
Iterator & operator--()
Definition document.h:263
std::ptrdiff_t difference_type
Definition document.h:216
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition document.h:207
Helper class for accessing Value of object type.
Definition document.h:3712
MemberIterator RemoveMember(MemberIterator m) const
Definition document.h:3863
ValueType::AllocatorType AllocatorType
Definition document.h:3726
GenericObject AddMember(StringRefType name, ValueType &value, AllocatorType &allocator) const
Definition document.h:3835
SizeType MemberCapacity() const
Definition document.h:3744
bool HasMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition document.h:3771
GenericObject(const GenericObject &rhs)
Definition document.h:3734
void RemoveAllMembers()
Definition document.h:3853
MemberIterator FindMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition document.h:3777
T value
Definition document.h:3808
SizeType MemberCount() const
Definition document.h:3743
GenericMemberIterator< Const, typename ValueType::EncodingType, typename ValueType::AllocatorType > MemberIterator
Definition document.h:3721
ValueType & operator[](const GenericValue< EncodingType, SourceAllocator > &name) const
Definition document.h:3752
MemberIterator EraseMember(ConstMemberIterator pos) const
Definition document.h:3864
ValueType & operator[](T *name) const
Definition document.h:3747
GenericObject AddMember(ValueType &name, ValueType &value, AllocatorType &allocator) const
Definition document.h:3787
GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType &allocator) const
Definition document.h:3840
ValueType PlainType
Definition document.h:3716
bool EraseMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition document.h:3877
MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const
Definition document.h:3865
MemberIterator MemberEnd() const
Definition document.h:3760
friend class GenericValue
Definition document.h:3732
~GenericObject()
Definition document.h:3740
bool RemoveMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition document.h:3859
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition document.h:3717
ValueType::EncodingType EncodingType
Definition document.h:3728
MemberIterator FindMember(const Ch *name) const
Definition document.h:3775
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(ValueType &)) AddMember(ValueType &name
GenericObject & operator=(const GenericObject &rhs)
Definition document.h:3735
bool HasMember(const Ch *name) const
Definition document.h:3766
ValueType::StringRefType StringRefType
Definition document.h:3727
bool ObjectEmpty() const
Definition document.h:3745
ValueType::Ch Ch
Definition document.h:3729
GenericObject AddMember(ValueType &name, StringRefType value, AllocatorType &allocator) const
Definition document.h:3792
GenericObject< false, ValueType > Object
Definition document.h:3715
bool RemoveMember(const Ch *name) const
Definition document.h:3854
GenericObject< true, ValueType > ConstObject
Definition document.h:3714
bool EraseMember(const Ch *name) const
Definition document.h:3869
GenericMemberIterator< true, typename ValueType::EncodingType, typename ValueType::AllocatorType > ConstMemberIterator
Definition document.h:3725
MemberIterator MemberBegin() const
Definition document.h:3759
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(GenericObject)) AddMember(StringRefType name
GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const
Definition document.h:3761
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition reader.h:604
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition document.h:822
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition document.h:946
static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data &data)
Assignment with move semantics.
Definition document.h:2666
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition document.h:3060
GenericArray< false, ValueType > Array
Definition document.h:838
void DoCopyMembers(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings)
Assignment with move semantics.
Definition document.h:2993
static const SizeType kDefaultArrayCapacity
Assignment with move semantics.
Definition document.h:2559
RAPIDJSON_FORCEINLINE GenericValue * SetElementsPointer(GenericValue *elements)
Assignment with move semantics.
Definition document.h:2683
~GenericValue()
Destructor.
Definition document.h:1075
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition document.h:1004
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition document.h:3037
static const SizeType kDefaultObjectCapacity
Definition document.h:2560
Encoding EncodingType
Encoding type from template parameter.
Definition document.h:826
static RAPIDJSON_FORCEINLINE const Ch * DataString(const Data &data)
Assignment with move semantics.
Definition document.h:2662
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy).
Definition document.h:1142
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition document.h:829
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition document.h:831
void DoReserveMembers(SizeType newCapacity, Allocator &allocator)
Assignment with move semantics.
Definition document.h:2872
RAPIDJSON_FORCEINLINE GenericValue * GetElementsPointer() const
Assignment with move semantics.
Definition document.h:2679
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition document.h:837
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition document.h:836
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:1018
void DoClearMembers()
Assignment with move semantics.
Definition document.h:2894
GenericObject< true, ValueType > ConstObject
Definition document.h:841
MemberIterator DoFindMember(const GenericValue< Encoding, SourceAllocator > &name)
Assignment with move semantics.
Definition document.h:2885
RAPIDJSON_FORCEINLINE Member * SetMembersPointer(Member *members)
Assignment with move semantics.
Definition document.h:2691
MemberIterator DoRemoveMember(MemberIterator m)
Assignment with move semantics.
Definition document.h:2929
void DoAddMember(GenericValue &name, GenericValue &value, Allocator &allocator)
Assignment with move semantics.
Definition document.h:2910
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator).
Definition document.h:903
MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last)
Assignment with move semantics.
Definition document.h:2956
Allocator AllocatorType
Allocator type from template parameter.
Definition document.h:827
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition document.h:825
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition document.h:877
RAPIDJSON_FORCEINLINE Member * GetMembersPointer() const
Assignment with move semantics.
Definition document.h:2687
GenericArray< true, ValueType > ConstArray
Definition document.h:839
void SetArrayRaw(GenericValue *values, SizeType count, Allocator &allocator)
Assignment with move semantics.
Definition document.h:3021
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition document.h:1054
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition document.h:974
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition document.h:966
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string).
Definition document.h:1033
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition document.h:1066
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string).
Definition document.h:1027
void DoFreeMembers()
Assignment with move semantics.
Definition document.h:2901
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition document.h:833
Data data_
Definition document.h:3120
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition document.h:959
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition document.h:847
friend class GenericDocument
Assignment with move semantics.
Definition document.h:2515
RAPIDJSON_FORCEINLINE const Ch * SetStringPointer(const Ch *str)
Assignment with move semantics.
Definition document.h:2675
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string).
Definition document.h:1024
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition document.h:3090
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition document.h:1011
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition document.h:991
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition document.h:3068
bool StringEqual(const GenericValue< Encoding, SourceAllocator > &rhs) const
Assignment with move semantics.
Definition document.h:3098
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition document.h:1117
Encoding::Ch Ch
Character type derived from Encoding.
Definition document.h:828
RAPIDJSON_FORCEINLINE Member * DoAllocMembers(SizeType capacity, Allocator &allocator)
Assignment with move semantics.
Definition document.h:2867
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition document.h:834
GenericObject< false, ValueType > Object
Definition document.h:840
@ kCopyStringFlag
Definition document.h:2550
@ kCopyFlag
Definition document.h:2527
@ kNumberDoubleFlag
Definition document.h:2544
@ kConstStringFlag
Definition document.h:2549
@ kFalseFlag
Definition document.h:2535
@ kDoubleFlag
Definition document.h:2525
@ kTrueFlag
Definition document.h:2534
@ kTypeMask
Definition document.h:2556
@ kUintFlag
Definition document.h:2522
@ kInt64Flag
Definition document.h:2523
@ kNullFlag
Definition document.h:2531
@ kNumberFlag
Definition document.h:2520
@ kNumberUint64Flag
Definition document.h:2542
@ kNumberAnyFlag
Definition document.h:2546
@ kObjectFlag
Definition document.h:2553
@ kBoolFlag
Definition document.h:2519
@ kUint64Flag
Definition document.h:2524
@ kShortStringFlag
Definition document.h:2551
@ kNumberIntFlag
Definition document.h:2536
@ kNumberInt64Flag
Definition document.h:2540
@ kIntFlag
Definition document.h:2521
@ kInlineStrFlag
Definition document.h:2528
@ kNumberUintFlag
Definition document.h:2538
@ kStringFlag
Definition document.h:2526
@ kArrayFlag
Definition document.h:2554
RAPIDJSON_FORCEINLINE const Ch * GetStringPointer() const
Assignment with move semantics.
Definition document.h:2671
void Clear()
Definition stack.h:107
void ShrinkToFit()
Definition stack.h:109
size_t GetSize() const
Definition stack.h:206
Concept for allocating, resizing and freeing memory block.
Concept for encoding of Unicode characters.
__device__ void copy(const SrcTensorType &src_tensor, DstTensorType &dst_tensor)
Perform optimized copy between two tensors partitions (threadwise copy). Tensors must have the same s...
Definition copy.hpp:36
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition document.h:3124
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:530
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition document.h:3611
const CharType GenericStringRef< CharType >::emptyString[]
Definition document.h:514
GenericPointer< Value, CrtAllocator > Pointer
Definition fwd.h:145
#define RAPIDJSON_DEFAULT_ALLOCATOR
Allows to choose default allocator.
Definition document.h:78
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
User defined kDefaultArrayCapacity value.
Definition document.h:111
#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR
Allows to choose default stack allocator for Document.
Definition document.h:89
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition rapidjson.h:717
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition rapidjson.h:313
#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:518
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition rapidjson.h:531
#define RAPIDJSON_USE_MEMBERSMAP
Enable RapidJSON support for object members handling in a std::multimap.
Definition rapidjson.h:180
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:451
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:124
ParseErrorCode
Error code of parsing.
Definition error.h:65
CK_TILE_HOST_DEVICE constexpr bool operator!=(const array< T, Size > &a, const array< T, Size > &b)
Definition tile/core/container/array.hpp:280
@ Set
Definition ck.hpp:278
@ Empty
Definition blkgemmpipe_scheduler.hpp:46
__host__ __device__ constexpr bool operator==(Sequence< Xs... >, Sequence< Ys... >)
Definition utility/sequence.hpp:649
Definition allocators.h:459
void Swap(T &a, T &b) RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition swap.h:33
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition strfunc.h:32
STL namespace.
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1697
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1517
#define RAPIDJSON_SETPOINTER(type, p, x)
Definition rapidjson.h:363
Type
Type of JSON value.
Definition rapidjson.h:760
@ kFalseType
false
Definition rapidjson.h:762
@ kObjectType
object
Definition rapidjson.h:764
@ kTrueType
true
Definition rapidjson.h:763
@ kStringType
string
Definition rapidjson.h:766
@ kNullType
null
Definition rapidjson.h:761
@ kArrayType
array
Definition rapidjson.h:765
@ kNumberType
number
Definition rapidjson.h:767
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:746
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.).
Definition rapidjson.h:429
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition rapidjson.h:326
#define RAPIDJSON_GETPOINTER(type, p)
Definition rapidjson.h:364
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:742
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition rapidjson.h:500
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition reader.h:152
unsigned short uint16_t
Definition stdint.h:125
_W64 unsigned int uintptr_t
Definition stdint.h:164
signed __int64 int64_t
Definition stdint.h:135
unsigned __int64 uint64_t
Definition stdint.h:136
A read-write string stream.
Definition stream.h:210
Reference to a constant string (not taking a copy).
Definition document.h:417
CharType Ch
character type of the string
Definition document.h:418
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition document.h:494
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
Definition document.h:550
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition document.h:482
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition document.h:471
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:530
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition document.h:446
GenericStringRef(const GenericStringRef &rhs)
Definition document.h:488
const Ch *const s
plain CharType pointer
Definition document.h:493
Read-only string stream.
Definition stream.h:163
Definition document.h:2645
SizeType capacity
Definition document.h:2647
SizeType size
Definition document.h:2646
GenericValue * elements
Definition document.h:2648
Definition document.h:2563
uint16_t flags
Definition document.h:2571
char payload[sizeof(SizeType) *2+sizeof(void *)+2]
Definition document.h:2569
Definition document.h:2611
int i
Definition document.h:2612
char padding[4]
Definition document.h:2613
Definition document.h:2616
unsigned u
Definition document.h:2617
char padding2[4]
Definition document.h:2618
Definition document.h:2638
Member * members
Definition document.h:2641
SizeType capacity
Definition document.h:2640
SizeType size
Definition document.h:2639
Definition document.h:2591
Ch str[MaxChars]
Definition document.h:2598
SizeType GetLength() const
Definition document.h:2602
static bool Usable(SizeType len)
Definition document.h:2600
@ MaxChars
Definition document.h:2594
@ MaxSize
Definition document.h:2595
@ LenPos
Definition document.h:2596
void SetLength(SizeType len)
Definition document.h:2601
Definition document.h:2575
const Ch * str
Definition document.h:2578
SizeType hashcode
reserved
Definition document.h:2577
SizeType length
Definition document.h:2576
Represents an in-memory input byte stream.
Definition memorystream.h:42
Result of parsing (wraps ParseErrorCode).
Definition error.h:108
Definition document.h:595
Definition document.h:580
Definition allocators.h:462
static bool Is(const ValueType &v)
Definition document.h:613
static ValueType & Set(ValueType &v, bool data, typename ValueType::AllocatorType &)
Definition document.h:616
static ValueType & Set(ValueType &v, bool data)
Definition document.h:615
static bool Get(const ValueType &v)
Definition document.h:614
static StringType Get(const ValueType &v)
Definition document.h:727
static ValueType & Set(ValueType &v, const StringType data)
Definition document.h:728
static ValueType & Set(ValueType &v, const StringType data, typename ValueType::AllocatorType &a)
Definition document.h:732
const ValueType::Ch * StringType
Definition document.h:725
static bool Is(const ValueType &v)
Definition document.h:726
static ValueType & Set(ValueType &v, double data, typename ValueType::AllocatorType &)
Definition document.h:704
static bool Is(const ValueType &v)
Definition document.h:701
static ValueType & Set(ValueType &v, double data)
Definition document.h:703
static double Get(const ValueType &v)
Definition document.h:702
static bool Is(const ValueType &v)
Definition document.h:713
static ValueType & Set(ValueType &v, float data)
Definition document.h:715
static float Get(const ValueType &v)
Definition document.h:714
static ValueType & Set(ValueType &v, float data, typename ValueType::AllocatorType &)
Definition document.h:716
static ValueType & Set(ValueType &v, int64_t data, typename ValueType::AllocatorType &)
Definition document.h:680
static ValueType & Set(ValueType &v, int64_t data)
Definition document.h:679
static bool Is(const ValueType &v)
Definition document.h:677
static int64_t Get(const ValueType &v)
Definition document.h:678
static ValueType & Set(ValueType &v, int data, typename ValueType::AllocatorType &)
Definition document.h:628
static ValueType & Set(ValueType &v, int data)
Definition document.h:627
static int Get(const ValueType &v)
Definition document.h:626
static bool Is(const ValueType &v)
Definition document.h:625
static ArrayType Get(ValueType &v)
Definition document.h:761
static bool Is(const ValueType &v)
Definition document.h:760
static ValueType & Set(ValueType &v, ArrayType data)
Definition document.h:762
static ValueType & Set(ValueType &v, ArrayType data, typename ValueType::AllocatorType &)
Definition document.h:763
ValueType::Array ArrayType
Definition document.h:759
static ArrayType Get(const ValueType &v)
Definition document.h:774
static bool Is(const ValueType &v)
Definition document.h:773
ValueType::ConstArray ArrayType
Definition document.h:772
static bool Is(const ValueType &v)
Definition document.h:794
ValueType::ConstObject ObjectType
Definition document.h:793
static ObjectType Get(const ValueType &v)
Definition document.h:795
static ValueType & Set(ValueType &v, ObjectType data)
Definition document.h:783
static bool Is(const ValueType &v)
Definition document.h:781
ValueType::Object ObjectType
Definition document.h:780
static ObjectType Get(ValueType &v)
Definition document.h:782
static ValueType & Set(ValueType &v, ObjectType data, typename ValueType::AllocatorType &)
Definition document.h:784
static uint64_t Get(const ValueType &v)
Definition document.h:690
static bool Is(const ValueType &v)
Definition document.h:689
static ValueType & Set(ValueType &v, uint64_t data, typename ValueType::AllocatorType &)
Definition document.h:692
static ValueType & Set(ValueType &v, uint64_t data)
Definition document.h:691
static ValueType & Set(ValueType &v, unsigned data)
Definition document.h:639
static unsigned Get(const ValueType &v)
Definition document.h:638
static bool Is(const ValueType &v)
Definition document.h:637
static ValueType & Set(ValueType &v, unsigned data, typename ValueType::AllocatorType &)
Definition document.h:640
Definition document.h:607
Definition document.h:2652
Number n
Definition document.h:2655
ShortString ss
Definition document.h:2654
String s
Definition document.h:2653
Flag f
Definition document.h:2658
ArrayData a
Definition document.h:2657
ObjectData o
Definition document.h:2656
Definition document.h:2608
struct GenericValue::Number::I i
uint64_t u64
Definition document.h:2633
struct GenericValue::Number::U u
double d
Definition document.h:2634
int64_t i64
Definition document.h:2632