15 #ifndef RAPIDJSON_DOCUMENT_H_
16 #define RAPIDJSON_DOCUMENT_H_
21 #include "internal/meta.h"
22 #include "internal/strfunc.h"
23 #include "memorystream.h"
24 #include "encodedstream.h"
27 #ifdef __cpp_lib_three_way_comparison
33 RAPIDJSON_DIAG_OFF(padded)
34 RAPIDJSON_DIAG_OFF(
switch-
enum)
35 RAPIDJSON_DIAG_OFF(c++98-compat)
36 #elif defined(_MSC_VER)
37 RAPIDJSON_DIAG_OFF(4127)
38 RAPIDJSON_DIAG_OFF(4244)
42 RAPIDJSON_DIAG_OFF(effc++)
49 #pragma push_macro("GetObject")
50 #define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
54 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
58 #if RAPIDJSON_USE_MEMBERSMAP
62 RAPIDJSON_NAMESPACE_BEGIN
65 template <
typename Encoding,
typename Allocator>
68 template <
typename Encoding,
typename Allocator,
typename StackAllocator>
77 #ifndef RAPIDJSON_DEFAULT_ALLOCATOR
78 #define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
87 #ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
88 #define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
97 #ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
99 #define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
108 #ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
110 #define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
119 template <
typename Encoding,
typename Allocator>
125 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
128 : name(std::move(rhs.name)),
129 value(std::move(rhs.value))
135 return *
this = static_cast<GenericMember&>(rhs);
153 a.value.Swap(b.value);
158 GenericMember(
const GenericMember& rhs);
164 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
185 template <
bool Const,
typename Encoding,
typename Allocator>
204 typedef ValueType value_type;
205 typedef ValueType * pointer;
206 typedef ValueType & reference;
207 typedef std::ptrdiff_t difference_type;
208 typedef std::random_access_iterator_tag iterator_category;
241 Iterator& operator=(
const NonConstIterator & it) { ptr_ = it.ptr_;
return *
this; }
245 Iterator& operator++(){ ++ptr_;
return *
this; }
246 Iterator& operator--(){ --ptr_;
return *
this; }
247 Iterator operator++(
int){ Iterator old(*
this); ++ptr_;
return old; }
248 Iterator operator--(
int){ Iterator old(*
this); --ptr_;
return old; }
253 Iterator operator+(DifferenceType n)
const {
return Iterator(ptr_+n); }
254 Iterator operator-(DifferenceType n)
const {
return Iterator(ptr_-n); }
256 Iterator& operator+=(DifferenceType n) { ptr_+=n;
return *
this; }
257 Iterator& operator-=(DifferenceType n) { ptr_-=n;
return *
this; }
262 template <
bool Const_>
bool operator==(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ == that.ptr_; }
263 template <
bool Const_>
bool operator!=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ != that.ptr_; }
264 template <
bool Const_>
bool operator<=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ <= that.ptr_; }
265 template <
bool Const_>
bool operator>=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ >= that.ptr_; }
266 template <
bool Const_>
bool operator< (
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ < that.ptr_; }
267 template <
bool Const_>
bool operator> (
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ > that.ptr_; }
269 #ifdef __cpp_lib_three_way_comparison
270 template <
bool Const_> std::strong_ordering operator<=>(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ <=> that.ptr_; }
276 Reference operator*()
const {
return *ptr_; }
277 Pointer operator->()
const {
return ptr_; }
278 Reference operator[](DifferenceType n)
const {
return ptr_[n]; }
291 #else // RAPIDJSON_NOMEMBERITERATORCLASS
295 template <
bool Const,
typename Encoding,
typename Allocator>
296 class GenericMemberIterator;
299 template <
typename Encoding,
typename Allocator>
303 typedef GenericMember<Encoding,Allocator>* Iterator;
306 template <
typename Encoding,
typename Allocator>
310 typedef const GenericMember<Encoding,Allocator>* Iterator;
313 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
345 template<
typename CharType>
350 #ifndef __clang__ // -Wdocumentation
376 : s(str), length(N-1) {}
379 #ifndef __clang__ // -Wdocumentation
400 : s(str), length(NotNullStrLen(str)) {}
403 #ifndef __clang__ // -Wdocumentation
417 operator const Ch *()
const {
return s; }
423 SizeType NotNullStrLen(
const CharType* str) {
425 return internal::StrLen(str);
429 static const Ch emptyString[];
438 template<
typename CharType>
439 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
453 template<
typename CharType>
473 template<
typename CharType>
478 #if RAPIDJSON_HAS_STDSTRING
491 template<
typename CharType>
501 template <
typename T,
typename Encoding =
void,
typename Allocator =
void>
502 struct IsGenericValueImpl : FalseType {};
505 template <
typename T>
struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>
::Type, typename Void<typename T::AllocatorType>
::Type>
506 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>
::Type {};
509 template <
typename T>
struct IsGenericValue : IsGenericValueImpl<T>
::Type {};
518 template <
typename ValueType,
typename T>
519 struct TypeHelper {};
521 template<
typename ValueType>
522 struct TypeHelper<ValueType, bool> {
523 static bool Is(
const ValueType& v) {
return v.IsBool(); }
524 static bool Get(
const ValueType& v) {
return v.GetBool(); }
525 static ValueType& Set(ValueType& v,
bool data) {
return v.SetBool(data); }
526 static ValueType& Set(ValueType& v,
bool data,
typename ValueType::AllocatorType&) {
return v.SetBool(data); }
529 template<
typename ValueType>
530 struct TypeHelper<ValueType, int> {
531 static bool Is(
const ValueType& v) {
return v.IsInt(); }
532 static int Get(
const ValueType& v) {
return v.GetInt(); }
533 static ValueType& Set(ValueType& v,
int data) {
return v.SetInt(data); }
534 static ValueType& Set(ValueType& v,
int data,
typename ValueType::AllocatorType&) {
return v.SetInt(data); }
537 template<
typename ValueType>
538 struct TypeHelper<ValueType, unsigned> {
539 static bool Is(
const ValueType& v) {
return v.IsUint(); }
540 static unsigned Get(
const ValueType& v) {
return v.GetUint(); }
541 static ValueType& Set(ValueType& v,
unsigned data) {
return v.SetUint(data); }
542 static ValueType& Set(ValueType& v,
unsigned data,
typename ValueType::AllocatorType&) {
return v.SetUint(data); }
547 template<
typename ValueType>
548 struct TypeHelper<ValueType, long> {
549 static bool Is(
const ValueType& v) {
return v.IsInt(); }
550 static long Get(
const ValueType& v) {
return v.GetInt(); }
551 static ValueType& Set(ValueType& v,
long data) {
return v.SetInt(data); }
552 static ValueType& Set(ValueType& v,
long data,
typename ValueType::AllocatorType&) {
return v.SetInt(data); }
556 template<
typename ValueType>
557 struct TypeHelper<ValueType, unsigned long> {
558 static bool Is(
const ValueType& v) {
return v.IsUint(); }
559 static unsigned long Get(
const ValueType& v) {
return v.GetUint(); }
560 static ValueType& Set(ValueType& v,
unsigned long data) {
return v.SetUint(data); }
561 static ValueType& Set(ValueType& v,
unsigned long data,
typename ValueType::AllocatorType&) {
return v.SetUint(data); }
565 template<
typename ValueType>
566 struct TypeHelper<ValueType, int64_t> {
567 static bool Is(
const ValueType& v) {
return v.IsInt64(); }
568 static int64_t Get(
const ValueType& v) {
return v.GetInt64(); }
569 static ValueType& Set(ValueType& v, int64_t data) {
return v.SetInt64(data); }
570 static ValueType& Set(ValueType& v, int64_t data,
typename ValueType::AllocatorType&) {
return v.SetInt64(data); }
573 template<
typename ValueType>
574 struct TypeHelper<ValueType, uint64_t> {
575 static bool Is(
const ValueType& v) {
return v.IsUint64(); }
576 static uint64_t Get(
const ValueType& v) {
return v.GetUint64(); }
577 static ValueType& Set(ValueType& v, uint64_t data) {
return v.SetUint64(data); }
578 static ValueType& Set(ValueType& v, uint64_t data,
typename ValueType::AllocatorType&) {
return v.SetUint64(data); }
581 template<
typename ValueType>
582 struct TypeHelper<ValueType, double> {
583 static bool Is(
const ValueType& v) {
return v.IsDouble(); }
584 static double Get(
const ValueType& v) {
return v.GetDouble(); }
585 static ValueType& Set(ValueType& v,
double data) {
return v.SetDouble(data); }
586 static ValueType& Set(ValueType& v,
double data,
typename ValueType::AllocatorType&) {
return v.SetDouble(data); }
589 template<
typename ValueType>
590 struct TypeHelper<ValueType, float> {
591 static bool Is(
const ValueType& v) {
return v.IsFloat(); }
592 static float Get(
const ValueType& v) {
return v.GetFloat(); }
593 static ValueType& Set(ValueType& v,
float data) {
return v.SetFloat(data); }
594 static ValueType& Set(ValueType& v,
float data,
typename ValueType::AllocatorType&) {
return v.SetFloat(data); }
597 template<
typename ValueType>
598 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
599 typedef const typename ValueType::Ch* StringType;
600 static bool Is(
const ValueType& v) {
return v.IsString(); }
601 static StringType Get(
const ValueType& v) {
return v.GetString(); }
602 static ValueType& Set(ValueType& v,
const StringType data) {
return v.SetString(
typename ValueType::StringRefType(data)); }
603 static ValueType& Set(ValueType& v,
const StringType data,
typename ValueType::AllocatorType& a) {
return v.SetString(data, a); }
606 #if RAPIDJSON_HAS_STDSTRING
607 template<
typename ValueType>
608 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
609 typedef std::basic_string<typename ValueType::Ch> StringType;
610 static bool Is(
const ValueType& v) {
return v.IsString(); }
611 static StringType Get(
const ValueType& v) {
return StringType(v.GetString(), v.GetStringLength()); }
612 static ValueType& Set(ValueType& v,
const StringType& data,
typename ValueType::AllocatorType& a) {
return v.SetString(data, a); }
616 template<
typename ValueType>
617 struct TypeHelper<ValueType, typename ValueType::Array> {
618 typedef typename ValueType::Array ArrayType;
619 static bool Is(
const ValueType& v) {
return v.IsArray(); }
620 static ArrayType Get(ValueType& v) {
return v.GetArray(); }
621 static ValueType& Set(ValueType& v, ArrayType data) {
return v = data; }
622 static ValueType& Set(ValueType& v, ArrayType data,
typename ValueType::AllocatorType&) {
return v = data; }
625 template<
typename ValueType>
626 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
627 typedef typename ValueType::ConstArray ArrayType;
628 static bool Is(
const ValueType& v) {
return v.IsArray(); }
629 static ArrayType Get(
const ValueType& v) {
return v.GetArray(); }
632 template<
typename ValueType>
633 struct TypeHelper<ValueType, typename ValueType::Object> {
634 typedef typename ValueType::Object ObjectType;
635 static bool Is(
const ValueType& v) {
return v.IsObject(); }
636 static ObjectType Get(ValueType& v) {
return v.GetObject(); }
637 static ValueType& Set(ValueType& v, ObjectType data) {
return v = data; }
638 static ValueType& Set(ValueType& v, ObjectType data,
typename ValueType::AllocatorType&) {
return v = data; }
641 template<
typename ValueType>
642 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
643 typedef typename ValueType::ConstObject ObjectType;
644 static bool Is(
const ValueType& v) {
return v.IsObject(); }
645 static ObjectType Get(
const ValueType& v) {
return v.GetObject(); }
667 template <
typename Encoding,
typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
674 typedef typename Encoding::Ch
Ch;
690 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
692 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
695 rhs.data_.f.flags = kNullFlag;
701 GenericValue(
const GenericValue& rhs);
703 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
705 template <
typename StackAllocator>
706 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
709 template <
typename StackAllocator>
710 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
721 static const uint16_t defaultFlags[] = {
722 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
726 data_.f.flags = defaultFlags[type];
730 data_.ss.SetLength(0);
741 template <
typename SourceAllocator>
743 switch (rhs.GetType()) {
745 DoCopyMembers(rhs, allocator, copyConstStrings);
751 for (
SizeType i = 0; i < count; i++)
752 new (&le[i])
GenericValue(re[i], allocator, copyConstStrings);
753 data_.f.flags = kArrayFlag;
754 data_.a.size = data_.a.capacity = count;
755 SetElementsPointer(le);
759 if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
760 data_.f.flags = rhs.data_.f.flags;
761 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
764 SetStringRaw(
StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
767 data_.f.flags = rhs.data_.f.flags;
768 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
779 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
780 template <
typename T>
781 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT
788 data_.f.flags = b ? kTrueFlag : kFalseFlag;
794 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
800 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
806 data_.f.flags = kNumberInt64Flag;
808 data_.f.flags |= kNumberUint64Flag;
810 data_.f.flags |= kUintFlag;
812 data_.f.flags |= kIntFlag;
815 data_.f.flags |= kIntFlag;
821 data_.f.flags = kNumberUint64Flag;
823 data_.f.flags |= kInt64Flag;
825 data_.f.flags |= kUintFlag;
827 data_.f.flags |= kIntFlag;
831 explicit GenericValue(
double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
834 explicit GenericValue(
float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
848 #if RAPIDJSON_HAS_STDSTRING
862 a.value_.data_ = Data();
863 a.value_.data_.f.flags = kArrayFlag;
873 o.value_.data_ = Data();
874 o.value_.data_.f.flags = kObjectFlag;
885 switch(data_.f.flags) {
891 if (Allocator::kNeedFree) {
901 case kCopyStringFlag:
902 if (Allocator::kNeedFree) {
903 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
934 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
937 return *
this = rhs.Move();
963 template <
typename T>
964 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (
GenericValue&))
977 template <
typename SourceAllocator>
978 GenericValue& CopyFrom(
const GenericValue<Encoding, SourceAllocator>& rhs,
Allocator& allocator,
bool copyConstStrings =
false) {
979 RAPIDJSON_ASSERT(static_cast<void*>(
this) != static_cast<void const*>(&rhs));
980 this->~GenericValue();
981 new (
this) GenericValue(rhs, allocator, copyConstStrings);
990 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
992 temp.RawAssign(*
this);
994 other.RawAssign(temp);
1010 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1014 GenericValue& Move() RAPIDJSON_NOEXCEPT {
return *
this; }
1024 template <
typename SourceAllocator>
1025 bool operator==(
const GenericValue<Encoding, SourceAllocator>& rhs)
const {
1026 typedef GenericValue<Encoding, SourceAllocator> RhsType;
1027 if (GetType() != rhs.GetType())
1030 switch (GetType()) {
1032 if (data_.o.size != rhs.data_.o.size)
1034 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1035 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1036 if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
1042 if (data_.a.size != rhs.data_.a.size)
1044 for (
SizeType i = 0; i < data_.a.size; i++)
1045 if ((*
this)[i] != rhs[i])
1050 return StringEqual(rhs);
1053 if (IsDouble() || rhs.IsDouble()) {
1054 double a = GetDouble();
1055 double b = rhs.GetDouble();
1056 return a >= b && a <= b;
1059 return data_.n.u64 == rhs.data_.n.u64;
1067 bool operator==(
const Ch* rhs)
const {
return *
this == GenericValue(
StringRef(rhs)); }
1069 #if RAPIDJSON_HAS_STDSTRING
1073 bool operator==(
const std::basic_string<Ch>& rhs)
const {
return *
this == GenericValue(
StringRef(rhs)); }
1079 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (
bool)) operator==(
const T& rhs)
const {
return *
this == GenericValue(rhs); }
1084 template <
typename SourceAllocator>
1085 bool operator!=(
const GenericValue<Encoding, SourceAllocator>& rhs)
const {
return !(*
this == rhs); }
1088 bool operator!=(
const Ch* rhs)
const {
return !(*
this == rhs); }
1093 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (
bool)) operator!=(
const T& rhs)
const {
return !(*
this == rhs); }
1095 #ifndef __cpp_lib_three_way_comparison
1099 template <
typename T>
friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (
bool)) operator==(
const T& lhs,
const GenericValue& rhs) {
return rhs == lhs; }
1104 template <
typename T>
friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (
bool)) operator!=(
const T& lhs,
const GenericValue& rhs) {
return !(rhs == lhs); }
1111 Type GetType()
const {
return static_cast<Type>(data_.f.flags & kTypeMask); }
1112 bool IsNull()
const {
return data_.f.flags == kNullFlag; }
1113 bool IsFalse()
const {
return data_.f.flags == kFalseFlag; }
1114 bool IsTrue()
const {
return data_.f.flags == kTrueFlag; }
1115 bool IsBool()
const {
return (data_.f.flags & kBoolFlag) != 0; }
1116 bool IsObject()
const {
return data_.f.flags == kObjectFlag; }
1117 bool IsArray()
const {
return data_.f.flags == kArrayFlag; }
1118 bool IsNumber()
const {
return (data_.f.flags & kNumberFlag) != 0; }
1119 bool IsInt()
const {
return (data_.f.flags & kIntFlag) != 0; }
1120 bool IsUint()
const {
return (data_.f.flags & kUintFlag) != 0; }
1121 bool IsInt64()
const {
return (data_.f.flags & kInt64Flag) != 0; }
1122 bool IsUint64()
const {
return (data_.f.flags & kUint64Flag) != 0; }
1123 bool IsDouble()
const {
return (data_.f.flags & kDoubleFlag) != 0; }
1124 bool IsString()
const {
return (data_.f.flags & kStringFlag) != 0; }
1127 bool IsLosslessDouble()
const {
1128 if (!IsNumber())
return false;
1130 uint64_t u = GetUint64();
1131 volatile double d = static_cast<double>(u);
1133 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1134 && (u == static_cast<uint64_t>(d));
1137 int64_t i = GetInt64();
1138 volatile double d = static_cast<double>(i);
1139 return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1140 && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1141 && (i == static_cast<int64_t>(d));
1147 bool IsFloat()
const {
1148 if ((data_.f.flags & kDoubleFlag) == 0)
1150 double d = GetDouble();
1151 return d >= -3.4028234e38 && d <= 3.4028234e38;
1154 bool IsLosslessFloat()
const {
1155 if (!IsNumber())
return false;
1156 double a = GetDouble();
1157 if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1158 || a > static_cast<double>((std::numeric_limits<float>::max)()))
1160 double b = static_cast<double>(static_cast<float>(a));
1161 return a >= b && a <= b;
1169 GenericValue& SetNull() { this->~GenericValue();
new (
this) GenericValue();
return *
this; }
1176 bool GetBool()
const {
RAPIDJSON_ASSERT(IsBool());
return data_.f.flags == kTrueFlag; }
1179 GenericValue& SetBool(
bool b) { this->~GenericValue();
new (
this) GenericValue(b);
return *
this; }
1188 GenericValue& SetObject() { this->~GenericValue();
new (
this) GenericValue(
kObjectType);
return *
this; }
1197 bool ObjectEmpty()
const {
RAPIDJSON_ASSERT(IsObject());
return data_.o.size == 0; }
1208 template <
typename T>
1209 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<
typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1213 template <
typename T>
1214 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<
typename internal::RemoveConst<T>::Type, Ch> >),(
const GenericValue&)) operator[](T* name)
const {
return const_cast<GenericValue&>(*
this)[name]; }
1225 template <
typename SourceAllocator>
1226 GenericValue& operator[](
const GenericValue<Encoding, SourceAllocator>& name) {
1227 MemberIterator member = FindMember(name);
1228 if (member != MemberEnd())
1229 return member->value;
1238 static char buffer[
sizeof(GenericValue)];
1239 return *
new (buffer) GenericValue();
1242 template <
typename SourceAllocator>
1243 const GenericValue& operator[](
const GenericValue<Encoding, SourceAllocator>& name)
const {
return const_cast<GenericValue&>(*
this)[name]; }
1245 #if RAPIDJSON_HAS_STDSTRING
1247 GenericValue& operator[](
const std::basic_string<Ch>& name) {
return (*
this)[GenericValue(
StringRef(name))]; }
1248 const GenericValue& operator[](
const std::basic_string<Ch>& name)
const {
return (*
this)[GenericValue(
StringRef(name))]; }
1253 ConstMemberIterator MemberBegin()
const {
RAPIDJSON_ASSERT(IsObject());
return ConstMemberIterator(GetMembersPointer()); }
1256 ConstMemberIterator MemberEnd()
const {
RAPIDJSON_ASSERT(IsObject());
return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1259 MemberIterator MemberBegin() {
RAPIDJSON_ASSERT(IsObject());
return MemberIterator(GetMembersPointer()); }
1262 MemberIterator MemberEnd() {
RAPIDJSON_ASSERT(IsObject());
return MemberIterator(GetMembersPointer() + data_.o.size); }
1272 DoReserveMembers(newCapacity, allocator);
1284 bool HasMember(
const Ch* name)
const {
return FindMember(name) != MemberEnd(); }
1286 #if RAPIDJSON_HAS_STDSTRING
1295 bool HasMember(
const std::basic_string<Ch>& name)
const {
return FindMember(name) != MemberEnd(); }
1307 template <
typename SourceAllocator>
1308 bool HasMember(
const GenericValue<Encoding, SourceAllocator>& name)
const {
return FindMember(name) != MemberEnd(); }
1322 MemberIterator FindMember(
const Ch* name) {
1324 return FindMember(n);
1327 ConstMemberIterator FindMember(
const Ch* name)
const {
return const_cast<GenericValue&>(*this).FindMember(name); }
1342 template <
typename SourceAllocator>
1343 MemberIterator FindMember(
const GenericValue<Encoding, SourceAllocator>& name) {
1346 return DoFindMember(name);
1348 template <
typename SourceAllocator> ConstMemberIterator FindMember(
const GenericValue<Encoding, SourceAllocator>& name)
const {
return const_cast<GenericValue&>(*this).FindMember(name); }
1350 #if RAPIDJSON_HAS_STDSTRING
1358 MemberIterator FindMember(
const std::basic_string<Ch>& name) {
return FindMember(GenericValue(
StringRef(name))); }
1359 ConstMemberIterator FindMember(
const std::basic_string<Ch>& name)
const {
return FindMember(GenericValue(
StringRef(name))); }
1372 GenericValue& AddMember(GenericValue& name, GenericValue& value,
Allocator& allocator) {
1375 DoAddMember(name, value, allocator);
1388 GenericValue& AddMember(GenericValue& name, StringRefType value,
Allocator& allocator) {
1389 GenericValue v(value);
1390 return AddMember(name, v, allocator);
1393 #if RAPIDJSON_HAS_STDSTRING
1403 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value,
Allocator& allocator) {
1404 GenericValue v(value, allocator);
1405 return AddMember(name, v, allocator);
1426 template <
typename T>
1427 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1428 AddMember(GenericValue& name, T value,
Allocator& allocator) {
1429 GenericValue v(value);
1430 return AddMember(name, v, allocator);
1433 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1434 GenericValue& AddMember(GenericValue&& name, GenericValue&& value,
Allocator& allocator) {
1435 return AddMember(name, value, allocator);
1437 GenericValue& AddMember(GenericValue&& name, GenericValue& value,
Allocator& allocator) {
1438 return AddMember(name, value, allocator);
1440 GenericValue& AddMember(GenericValue& name, GenericValue&& value,
Allocator& allocator) {
1441 return AddMember(name, value, allocator);
1443 GenericValue& AddMember(StringRefType name, GenericValue&& value,
Allocator& allocator) {
1444 GenericValue n(name);
1445 return AddMember(n, value, allocator);
1447 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1460 GenericValue& AddMember(StringRefType name, GenericValue& value,
Allocator& allocator) {
1461 GenericValue n(name);
1462 return AddMember(n, value, allocator);
1474 GenericValue& AddMember(StringRefType name, StringRefType value,
Allocator& allocator) {
1475 GenericValue v(value);
1476 return AddMember(name, v, allocator);
1496 template <
typename T>
1497 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1498 AddMember(StringRefType name, T value,
Allocator& allocator) {
1499 GenericValue n(name);
1500 return AddMember(n, value, allocator);
1507 void RemoveAllMembers() {
1520 bool RemoveMember(
const Ch* name) {
1522 return RemoveMember(n);
1525 #if RAPIDJSON_HAS_STDSTRING
1526 bool RemoveMember(
const std::basic_string<Ch>& name) {
return RemoveMember(GenericValue(
StringRef(name))); }
1529 template <
typename SourceAllocator>
1530 bool RemoveMember(
const GenericValue<Encoding, SourceAllocator>& name) {
1531 MemberIterator m = FindMember(name);
1532 if (m != MemberEnd()) {
1548 MemberIterator RemoveMember(MemberIterator m) {
1553 return DoRemoveMember(m);
1565 MemberIterator EraseMember(ConstMemberIterator pos) {
1566 return EraseMember(pos, pos +1);
1578 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1585 return DoEraseMembers(first, last);
1593 bool EraseMember(
const Ch* name) {
1595 return EraseMember(n);
1598 #if RAPIDJSON_HAS_STDSTRING
1599 bool EraseMember(
const std::basic_string<Ch>& name) {
return EraseMember(GenericValue(
StringRef(name))); }
1602 template <
typename SourceAllocator>
1603 bool EraseMember(
const GenericValue<Encoding, SourceAllocator>& name) {
1604 MemberIterator m = FindMember(name);
1605 if (m != MemberEnd()) {
1615 ConstObject GetObject()
const {
RAPIDJSON_ASSERT(IsObject());
return ConstObject(*
this); }
1616 ConstObject GetObj()
const {
RAPIDJSON_ASSERT(IsObject());
return ConstObject(*
this); }
1625 GenericValue& SetArray() { this->~GenericValue();
new (
this) GenericValue(
kArrayType);
return *
this; }
1634 bool Empty()
const {
RAPIDJSON_ASSERT(IsArray());
return data_.a.size == 0; }
1642 GenericValue* e = GetElementsPointer();
1643 for (GenericValue* v = e; v != e + data_.a.size; ++v)
1653 GenericValue& operator[](
SizeType index) {
1656 return GetElementsPointer()[index];
1658 const GenericValue& operator[](
SizeType index)
const {
return const_cast<GenericValue&>(*
this)[index]; }
1662 ValueIterator Begin() {
RAPIDJSON_ASSERT(IsArray());
return GetElementsPointer(); }
1665 ValueIterator End() {
RAPIDJSON_ASSERT(IsArray());
return GetElementsPointer() + data_.a.size; }
1668 ConstValueIterator Begin()
const {
return const_cast<GenericValue&>(*this).Begin(); }
1671 ConstValueIterator End()
const {
return const_cast<GenericValue&>(*this).End(); }
1681 if (newCapacity > data_.a.capacity) {
1682 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity *
sizeof(GenericValue), newCapacity *
sizeof(GenericValue))));
1683 data_.a.capacity = newCapacity;
1698 GenericValue& PushBack(GenericValue& value,
Allocator& allocator) {
1700 if (data_.a.size >= data_.a.capacity)
1701 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1702 GetElementsPointer()[data_.a.size++].RawAssign(value);
1706 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1707 GenericValue& PushBack(GenericValue&& value,
Allocator& allocator) {
1708 return PushBack(value, allocator);
1710 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1721 GenericValue& PushBack(StringRefType value,
Allocator& allocator) {
1722 return (*this).template PushBack<StringRefType>(value, allocator);
1742 template <
typename T>
1743 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1744 PushBack(T value,
Allocator& allocator) {
1745 GenericValue v(value);
1746 return PushBack(v, allocator);
1753 GenericValue& PopBack() {
1756 GetElementsPointer()[--data_.a.size].~GenericValue();
1767 ValueIterator Erase(ConstValueIterator pos) {
1768 return Erase(pos, pos + 1);
1779 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1786 ValueIterator pos = Begin() + (first - Begin());
1787 for (ValueIterator itr = pos; itr != last; ++itr)
1788 itr->~GenericValue();
1789 std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) *
sizeof(GenericValue));
1790 data_.a.size -= static_cast<SizeType>(last - first);
1795 ConstArray GetArray()
const {
RAPIDJSON_ASSERT(IsArray());
return ConstArray(*
this); }
1802 int GetInt()
const {
RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);
return data_.n.i.i; }
1803 unsigned GetUint()
const {
RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);
return data_.n.u.u; }
1804 int64_t GetInt64()
const {
RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag);
return data_.n.i64; }
1805 uint64_t GetUint64()
const {
RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag);
return data_.n.u64; }
1810 double GetDouble()
const {
1812 if ((data_.f.flags & kDoubleFlag) != 0)
return data_.n.d;
1813 if ((data_.f.flags & kIntFlag) != 0)
return data_.n.i.i;
1814 if ((data_.f.flags & kUintFlag) != 0)
return data_.n.u.u;
1815 if ((data_.f.flags & kInt64Flag) != 0)
return static_cast<double>(data_.n.i64);
1816 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);
return static_cast<double>(data_.n.u64);
1822 float GetFloat()
const {
1823 return static_cast<float>(GetDouble());
1826 GenericValue& SetInt(
int i) { this->~GenericValue();
new (
this) GenericValue(i);
return *
this; }
1827 GenericValue& SetUint(
unsigned u) { this->~GenericValue();
new (
this) GenericValue(u);
return *
this; }
1828 GenericValue& SetInt64(int64_t i64) { this->~GenericValue();
new (
this) GenericValue(i64);
return *
this; }
1829 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue();
new (
this) GenericValue(u64);
return *
this; }
1830 GenericValue& SetDouble(
double d) { this->~GenericValue();
new (
this) GenericValue(d);
return *
this; }
1831 GenericValue& SetFloat(
float f) { this->~GenericValue();
new (
this) GenericValue(static_cast<double>(f));
return *
this; }
1838 const Ch* GetString()
const {
RAPIDJSON_ASSERT(IsString());
return DataString(data_); }
1853 GenericValue& SetString(
const Ch* s,
SizeType length) {
return SetString(
StringRef(s, length)); }
1860 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s);
return *
this; }
1870 GenericValue& SetString(
const Ch* s,
SizeType length,
Allocator& allocator) {
return SetString(
StringRef(s, length), allocator); }
1878 GenericValue& SetString(
const Ch* s,
Allocator& allocator) {
return SetString(
StringRef(s), allocator); }
1886 GenericValue& SetString(StringRefType s,
Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator);
return *
this; }
1888 #if RAPIDJSON_HAS_STDSTRING
1896 GenericValue& SetString(
const std::basic_string<Ch>& s,
Allocator& allocator) {
return SetString(
StringRef(s), allocator); }
1908 template <
typename T>
1909 bool Is()
const {
return internal::TypeHelper<ValueType, T>::Is(*
this); }
1911 template <
typename T>
1912 T Get()
const {
return internal::TypeHelper<ValueType, T>::Get(*
this); }
1914 template <
typename T>
1915 T Get() {
return internal::TypeHelper<ValueType, T>::Get(*
this); }
1917 template<
typename T>
1918 ValueType& Set(
const T& data) {
return internal::TypeHelper<ValueType, T>::Set(*
this, data); }
1920 template<
typename T>
1921 ValueType& Set(
const T& data, AllocatorType& allocator) {
return internal::TypeHelper<ValueType, T>::Set(*
this, data, allocator); }
1932 template <
typename Handler>
1933 bool Accept(
Handler& handler)
const {
1937 case kTrueType:
return handler.Bool(
true);
1942 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1944 if (
RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1949 return handler.EndObject(data_.o.size);
1954 for (
const GenericValue* v = Begin(); v != End(); ++v)
1957 return handler.EndArray(data_.a.size);
1960 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1964 if (IsDouble())
return handler.Double(data_.n.d);
1965 else if (IsInt())
return handler.Int(data_.n.i.i);
1966 else if (IsUint())
return handler.Uint(data_.n.u.u);
1967 else if (IsInt64())
return handler.Int64(data_.n.i64);
1968 else return handler.Uint64(data_.n.u64);
1973 template <
typename,
typename>
friend class GenericValue;
1974 template <
typename,
typename,
typename>
friend class GenericDocument;
1978 kNumberFlag = 0x0010,
1981 kInt64Flag = 0x0080,
1982 kUint64Flag = 0x0100,
1983 kDoubleFlag = 0x0200,
1984 kStringFlag = 0x0400,
1986 kInlineStrFlag = 0x1000,
1991 kTrueFlag = static_cast<int>(
kTrueType) | static_cast<int>(kBoolFlag),
1992 kFalseFlag = static_cast<int>(
kFalseType) | static_cast<int>(kBoolFlag),
1993 kNumberIntFlag = static_cast<int>(
kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
1994 kNumberUintFlag = static_cast<int>(
kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
1995 kNumberInt64Flag = static_cast<int>(
kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
1996 kNumberUint64Flag = static_cast<int>(
kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
1997 kNumberDoubleFlag = static_cast<int>(
kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
1998 kNumberAnyFlag = static_cast<int>(
kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
1999 kConstStringFlag = static_cast<int>(
kStringType) | static_cast<int>(kStringFlag),
2000 kCopyStringFlag = static_cast<int>(
kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
2001 kShortStringFlag = static_cast<int>(
kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2012 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2013 char payload[
sizeof(
SizeType) * 2 + 6];
2014 #elif RAPIDJSON_64BIT
2015 char payload[
sizeof(
SizeType) * 2 +
sizeof(
void*) + 6];
2017 char payload[
sizeof(
SizeType) * 2 +
sizeof(
void*) + 2];
2037 enum { MaxChars =
sizeof(static_cast<Flag*>(0)->payload) /
sizeof(
Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2040 inline static bool Usable(
SizeType len) {
return (MaxSize >= len); }
2041 inline void SetLength(
SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2042 inline SizeType GetLength()
const {
return static_cast<SizeType>(MaxSize - str[LenPos]); }
2047 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2092 static RAPIDJSON_FORCEINLINE
const Ch* DataString(
const Data& data) {
2093 return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(
Ch, data.s.str);
2095 static RAPIDJSON_FORCEINLINE
SizeType DataStringLength(
const Data& data) {
2096 return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2099 RAPIDJSON_FORCEINLINE
const Ch* GetStringPointer()
const {
return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2100 RAPIDJSON_FORCEINLINE
const Ch* SetStringPointer(
const Ch* str) {
return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2101 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer()
const {
return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2102 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) {
return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2103 RAPIDJSON_FORCEINLINE Member* GetMembersPointer()
const {
return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2104 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) {
return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2106 #if RAPIDJSON_USE_MEMBERSMAP
2110 bool operator()(
const Data& s1,
const Data& s2)
const {
2111 SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
2112 int cmp = std::memcmp(DataString(s1), DataString(s2),
sizeof(Ch) * (n1 < n2 ? n1 : n2));
2113 return cmp < 0 || (cmp == 0 && n1 < n2);
2116 typedef std::pair<const Data, SizeType> Pair;
2117 typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
2118 typedef typename Map::iterator Iterator;
2120 typedef typename MapTraits::Map Map;
2121 typedef typename MapTraits::Less MapLess;
2122 typedef typename MapTraits::Pair MapPair;
2123 typedef typename MapTraits::Iterator MapIterator;
2133 static RAPIDJSON_FORCEINLINE
size_t GetMapLayoutSize(
SizeType capacity) {
2137 capacity *
sizeof(MapIterator);
2140 static RAPIDJSON_FORCEINLINE
SizeType &GetMapCapacity(Map* &map) {
2141 return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
2145 static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) {
2146 return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
2151 static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
2152 return reinterpret_cast<MapIterator*>(reinterpret_cast<uintptr_t>(&map) +
2158 static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) {
2160 return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
2166 RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
2167 #if RAPIDJSON_HAS_CXX11
2168 MapIterator ret = std::move(rhs);
2170 MapIterator ret = rhs;
2177 Map **newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
2178 GetMapCapacity(*newMap) = newCapacity;
2180 *newMap =
new (allocator.Malloc(
sizeof(Map))) Map(MapLess(), allocator);
2184 size_t count = (*oldMap)->size();
2185 std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
2186 static_cast<void*>(GetMapMembers(*oldMap)),
2187 count *
sizeof(Member));
2188 MapIterator *oldIt = GetMapIterators(*oldMap),
2189 *newIt = GetMapIterators(*newMap);
2191 new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
2193 Allocator::Free(oldMap);
2198 RAPIDJSON_FORCEINLINE Member* DoAllocMembers(
SizeType capacity,
Allocator& allocator) {
2199 return GetMapMembers(DoReallocMap(0, capacity, allocator));
2203 ObjectData& o = data_.o;
2204 if (newCapacity > o.capacity) {
2205 Member* oldMembers = GetMembersPointer();
2206 Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
2207 *&newMap = DoReallocMap(oldMap, newCapacity, allocator);
2208 RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
2209 o.capacity = newCapacity;
2213 template <
typename SourceAllocator>
2214 MemberIterator DoFindMember(
const GenericValue<Encoding, SourceAllocator>& name) {
2215 if (Member* members = GetMembersPointer()) {
2216 Map* &map = GetMap(members);
2217 MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
2218 if (mit != map->end()) {
2219 return MemberIterator(&members[mit->second]);
2225 void DoClearMembers() {
2226 if (Member* members = GetMembersPointer()) {
2227 Map* &map = GetMap(members);
2228 MapIterator* mit = GetMapIterators(map);
2229 for (
SizeType i = 0; i < data_.o.size; i++) {
2230 map->erase(DropMapIterator(mit[i]));
2231 members[i].~Member();
2237 void DoFreeMembers() {
2238 if (Member* members = GetMembersPointer()) {
2239 GetMap(members)->~Map();
2240 for (
SizeType i = 0; i < data_.o.size; i++) {
2241 members[i].~Member();
2243 if (Allocator::kNeedFree) {
2244 Map** map = &GetMap(members);
2245 Allocator::Free(*map);
2246 Allocator::Free(map);
2251 #else // !RAPIDJSON_USE_MEMBERSMAP
2253 RAPIDJSON_FORCEINLINE Member* DoAllocMembers(
SizeType capacity,
Allocator& allocator) {
2254 return Malloc<Member>(allocator, capacity);
2258 ObjectData& o = data_.o;
2259 if (newCapacity > o.capacity) {
2260 Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2261 RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
2262 o.capacity = newCapacity;
2266 template <
typename SourceAllocator>
2267 MemberIterator DoFindMember(
const GenericValue<Encoding, SourceAllocator>& name) {
2268 MemberIterator member = MemberBegin();
2269 for ( ; member != MemberEnd(); ++member)
2270 if (name.StringEqual(member->name))
2275 void DoClearMembers() {
2276 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2281 void DoFreeMembers() {
2282 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2284 Allocator::Free(GetMembersPointer());
2287 #endif // !RAPIDJSON_USE_MEMBERSMAP
2289 void DoAddMember(GenericValue& name, GenericValue& value,
Allocator& allocator) {
2290 ObjectData& o = data_.o;
2291 if (o.size >= o.capacity)
2292 DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
2293 Member* members = GetMembersPointer();
2294 Member* m = members + o.size;
2295 m->name.RawAssign(name);
2296 m->value.RawAssign(value);
2297 #if RAPIDJSON_USE_MEMBERSMAP
2298 Map* &map = GetMap(members);
2299 MapIterator* mit = GetMapIterators(map);
2300 new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
2305 MemberIterator DoRemoveMember(MemberIterator m) {
2306 ObjectData& o = data_.o;
2307 Member* members = GetMembersPointer();
2308 #if RAPIDJSON_USE_MEMBERSMAP
2309 Map* &map = GetMap(members);
2310 MapIterator* mit = GetMapIterators(map);
2311 SizeType mpos = static_cast<SizeType>(&*m - members);
2312 map->erase(DropMapIterator(mit[mpos]));
2314 MemberIterator last(members + (o.size - 1));
2315 if (o.size > 1 && m != last) {
2316 #if RAPIDJSON_USE_MEMBERSMAP
2317 new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
2318 mit[mpos]->second = mpos;
2329 MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) {
2330 ObjectData& o = data_.o;
2331 MemberIterator beg = MemberBegin(),
2332 pos = beg + (first - beg),
2334 #if RAPIDJSON_USE_MEMBERSMAP
2335 Map* &map = GetMap(GetMembersPointer());
2336 MapIterator* mit = GetMapIterators(map);
2338 for (MemberIterator itr = pos; itr != last; ++itr) {
2339 #if RAPIDJSON_USE_MEMBERSMAP
2340 map->erase(DropMapIterator(mit[itr - beg]));
2344 #if RAPIDJSON_USE_MEMBERSMAP
2345 if (first != last) {
2347 MemberIterator next = pos + (last - first);
2348 for (MemberIterator itr = pos; next != end; ++itr, ++next) {
2349 std::memcpy(static_cast<void*>(&*itr), &*next,
sizeof(Member));
2350 SizeType mpos = static_cast<SizeType>(itr - beg);
2351 new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
2352 mit[mpos]->second = mpos;
2356 std::memmove(static_cast<void*>(&*pos), &*last,
2357 static_cast<size_t>(end - last) *
sizeof(Member));
2359 o.size -= static_cast<SizeType>(last - first);
2363 template <
typename SourceAllocator>
2364 void DoCopyMembers(
const GenericValue<Encoding,SourceAllocator>& rhs,
Allocator& allocator,
bool copyConstStrings) {
2367 data_.f.flags = kObjectFlag;
2369 Member* lm = DoAllocMembers(count, allocator);
2370 const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
2371 #if RAPIDJSON_USE_MEMBERSMAP
2372 Map* &map = GetMap(lm);
2373 MapIterator* mit = GetMapIterators(map);
2375 for (
SizeType i = 0; i < count; i++) {
2376 new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
2377 new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
2378 #if RAPIDJSON_USE_MEMBERSMAP
2379 new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
2382 data_.o.size = data_.o.capacity = count;
2383 SetMembersPointer(lm);
2388 data_.f.flags = kArrayFlag;
2390 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count *
sizeof(GenericValue)));
2391 SetElementsPointer(e);
2392 std::memcpy(static_cast<void*>(e), values, count *
sizeof(GenericValue));
2395 SetElementsPointer(0);
2396 data_.a.size = data_.a.capacity = count;
2401 data_.f.flags = kObjectFlag;
2403 Member* m = DoAllocMembers(count, allocator);
2404 SetMembersPointer(m);
2405 std::memcpy(static_cast<void*>(m), members, count *
sizeof(
Member));
2406 #if RAPIDJSON_USE_MEMBERSMAP
2407 Map* &map = GetMap(m);
2408 MapIterator* mit = GetMapIterators(map);
2409 for (
SizeType i = 0; i < count; i++) {
2410 new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
2415 SetMembersPointer(0);
2416 data_.o.size = data_.o.capacity = count;
2421 data_.f.flags = kConstStringFlag;
2422 SetStringPointer(s);
2423 data_.s.length = s.length;
2429 if (ShortString::Usable(s.
length)) {
2430 data_.f.flags = kShortStringFlag;
2431 data_.ss.SetLength(s.
length);
2434 data_.f.flags = kCopyStringFlag;
2435 data_.s.length = s.
length;
2436 str = static_cast<Ch *>(allocator.Malloc((s.
length + 1) *
sizeof(
Ch)));
2437 SetStringPointer(str);
2439 std::memcpy(str, s, s.
length *
sizeof(
Ch));
2447 rhs.data_.f.flags = kNullFlag;
2450 template <
typename SourceAllocator>
2455 const SizeType len1 = GetStringLength();
2456 const SizeType len2 = rhs.GetStringLength();
2457 if(len1 != len2) {
return false; }
2459 const Ch*
const str1 = GetString();
2460 const Ch*
const str2 = rhs.GetString();
2461 if(str1 == str2) {
return true; }
2463 return (std::memcmp(str1, str2,
sizeof(Ch) * len1) == 0);
2483 template <
typename Encoding,
typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR,
typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2486 typedef typename Encoding::Ch
Ch;
2511 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2517 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2520 : ValueType(std::forward<ValueType>(rhs)),
2521 allocator_(rhs.allocator_),
2522 ownAllocator_(rhs.ownAllocator_),
2523 stack_(std::move(rhs.stack_)),
2524 parseResult_(rhs.parseResult_)
2527 rhs.ownAllocator_ = 0;
2532 ~GenericDocument() {
2537 if (ownAllocator_) {
2538 ValueType::SetNull();
2543 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2545 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2549 ValueType::operator=(std::forward<ValueType>(rhs));
2554 allocator_ = rhs.allocator_;
2555 ownAllocator_ = rhs.ownAllocator_;
2556 stack_ = std::move(rhs.stack_);
2557 parseResult_ = rhs.parseResult_;
2560 rhs.ownAllocator_ = 0;
2561 rhs.parseResult_ = ParseResult();
2574 ValueType::Swap(rhs);
2575 stack_.Swap(rhs.stack_);
2576 internal::Swap(allocator_, rhs.allocator_);
2577 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2578 internal::Swap(parseResult_, rhs.parseResult_);
2584 using ValueType::Swap;
2605 template <
typename Generator>
2607 ClearStackOnExit scope(*
this);
2610 ValueType::operator=(*stack_.template Pop<ValueType>(1));
2625 template <
unsigned parseFlags,
typename SourceEncoding,
typename InputStream>
2628 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2629 ClearStackOnExit scope(*
this);
2630 parseResult_ = reader.template Parse<parseFlags>(is, *
this);
2633 ValueType::operator=(*stack_.template Pop<ValueType>(1));
2644 template <
unsigned parseFlags,
typename InputStream>
2646 return ParseStream<parseFlags, Encoding, InputStream>(is);
2654 template <
typename InputStream>
2656 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2668 template <
unsigned parseFlags>
2671 return ParseStream<parseFlags | kParseInsituFlag>(s);
2679 return ParseInsitu<kParseDefaultFlags>(str);
2691 template <
unsigned parseFlags,
typename SourceEncoding>
2695 return ParseStream<parseFlags, SourceEncoding>(s);
2702 template <
unsigned parseFlags>
2704 return Parse<parseFlags, Encoding>(str);
2711 return Parse<kParseDefaultFlags>(str);
2714 template <
unsigned parseFlags,
typename SourceEncoding>
2715 GenericDocument& Parse(
const typename SourceEncoding::Ch* str,
size_t length) {
2717 MemoryStream ms(reinterpret_cast<const char*>(str), length *
sizeof(
typename SourceEncoding::Ch));
2719 ParseStream<parseFlags, SourceEncoding>(is);
2723 template <
unsigned parseFlags>
2724 GenericDocument& Parse(
const Ch* str,
size_t length) {
2725 return Parse<parseFlags, Encoding>(str, length);
2728 GenericDocument& Parse(
const Ch* str,
size_t length) {
2729 return Parse<kParseDefaultFlags>(str, length);
2732 #if RAPIDJSON_HAS_STDSTRING
2733 template <
unsigned parseFlags,
typename SourceEncoding>
2734 GenericDocument& Parse(
const std::basic_string<typename SourceEncoding::Ch>& str) {
2736 return Parse<parseFlags, SourceEncoding>(str.c_str());
2739 template <
unsigned parseFlags>
2740 GenericDocument& Parse(
const std::basic_string<Ch>& str) {
2741 return Parse<parseFlags, Encoding>(str.c_str());
2744 GenericDocument& Parse(
const std::basic_string<Ch>& str) {
2745 return Parse<kParseDefaultFlags>(str);
2747 #endif // RAPIDJSON_HAS_STDSTRING
2764 #ifndef __clang // -Wdocumentation
2789 struct ClearStackOnExit {
2791 ~ClearStackOnExit() { d_.ClearStack(); }
2793 ClearStackOnExit(
const ClearStackOnExit&);
2794 ClearStackOnExit& operator=(
const ClearStackOnExit&);
2795 GenericDocument& d_;
2800 template <
typename,
typename>
friend class GenericValue;
2804 bool Null() {
new (stack_.template Push<ValueType>()) ValueType();
return true; }
2805 bool Bool(
bool b) {
new (stack_.template Push<ValueType>()) ValueType(b);
return true; }
2806 bool Int(
int i) {
new (stack_.template Push<ValueType>()) ValueType(i);
return true; }
2807 bool Uint(
unsigned i) {
new (stack_.template Push<ValueType>()) ValueType(i);
return true; }
2808 bool Int64(int64_t i) {
new (stack_.template Push<ValueType>()) ValueType(i);
return true; }
2809 bool Uint64(uint64_t i) {
new (stack_.template Push<ValueType>()) ValueType(i);
return true; }
2810 bool Double(
double d) {
new (stack_.template Push<ValueType>()) ValueType(d);
return true; }
2812 bool RawNumber(
const Ch* str,
SizeType length,
bool copy) {
2814 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2816 new (stack_.template Push<ValueType>()) ValueType(str, length);
2820 bool String(
const Ch* str,
SizeType length,
bool copy) {
2822 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2824 new (stack_.template Push<ValueType>()) ValueType(str, length);
2828 bool StartObject() {
new (stack_.template Push<ValueType>()) ValueType(
kObjectType);
return true; }
2830 bool Key(
const Ch* str,
SizeType length,
bool copy) {
return String(str, length, copy); }
2832 bool EndObject(
SizeType memberCount) {
2833 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2834 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2838 bool StartArray() {
new (stack_.template Push<ValueType>()) ValueType(
kArrayType);
return true; }
2840 bool EndArray(
SizeType elementCount) {
2841 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2842 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2848 GenericDocument(
const GenericDocument&);
2850 GenericDocument& operator=(
const GenericDocument&);
2853 if (Allocator::kNeedFree)
2854 while (stack_.GetSize() > 0)
2855 (stack_.template Pop<ValueType>(1))->~ValueType();
2858 stack_.ShrinkToFit();
2865 static const size_t kDefaultStackCapacity = 1024;
2868 internal::Stack<StackAllocator> stack_;
2869 ParseResult parseResult_;
2881 template <
bool Const,
typename ValueT>
2886 typedef ValueT PlainType;
2888 typedef ValueType* ValueIterator;
2889 typedef const ValueT* ConstValueIterator;
2890 typedef typename ValueType::AllocatorType AllocatorType;
2891 typedef typename ValueType::StringRefType StringRefType;
2893 template <
typename,
typename>
2900 operator ValueType&()
const {
return value_; }
2901 SizeType Size()
const {
return value_.Size(); }
2902 SizeType Capacity()
const {
return value_.Capacity(); }
2903 bool Empty()
const {
return value_.Empty(); }
2904 void Clear()
const { value_.Clear(); }
2905 ValueType& operator[](
SizeType index)
const {
return value_[index]; }
2906 ValueIterator Begin()
const {
return value_.Begin(); }
2907 ValueIterator End()
const {
return value_.End(); }
2908 GenericArray Reserve(
SizeType newCapacity, AllocatorType &allocator)
const { value_.Reserve(newCapacity, allocator);
return *
this; }
2909 GenericArray PushBack(ValueType& value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2910 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2911 GenericArray PushBack(ValueType&& value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2912 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2913 GenericArray PushBack(StringRefType value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2914 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (
const GenericArray&)) PushBack(T value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2915 GenericArray PopBack()
const { value_.PopBack();
return *
this; }
2916 ValueIterator Erase(ConstValueIterator pos)
const {
return value_.Erase(pos); }
2917 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)
const {
return value_.Erase(first, last); }
2919 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2920 ValueIterator begin()
const {
return value_.Begin(); }
2921 ValueIterator end()
const {
return value_.End(); }
2935 template <
bool Const,
typename ValueT>
2936 class GenericObject {
2938 typedef GenericObject<true, ValueT> ConstObject;
2939 typedef GenericObject<false, ValueT> Object;
2940 typedef ValueT PlainType;
2942 typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator;
2943 typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;
2944 typedef typename ValueType::AllocatorType AllocatorType;
2945 typedef typename ValueType::StringRefType StringRefType;
2946 typedef typename ValueType::EncodingType EncodingType;
2947 typedef typename ValueType::Ch Ch;
2949 template <
typename,
typename>
2950 friend class GenericValue;
2952 GenericObject(
const GenericObject& rhs) : value_(rhs.value_) {}
2953 GenericObject& operator=(
const GenericObject& rhs) { value_ = rhs.value_;
return *
this; }
2956 operator ValueType&()
const {
return value_; }
2957 SizeType MemberCount()
const {
return value_.MemberCount(); }
2958 SizeType MemberCapacity()
const {
return value_.MemberCapacity(); }
2959 bool ObjectEmpty()
const {
return value_.ObjectEmpty(); }
2960 template <
typename T> ValueType& operator[](T* name)
const {
return value_[name]; }
2961 template <
typename SourceAllocator> ValueType& operator[](
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_[name]; }
2962 #if RAPIDJSON_HAS_STDSTRING
2963 ValueType& operator[](
const std::basic_string<Ch>& name)
const {
return value_[name]; }
2965 MemberIterator MemberBegin()
const {
return value_.MemberBegin(); }
2966 MemberIterator MemberEnd()
const {
return value_.MemberEnd(); }
2967 GenericObject MemberReserve(
SizeType newCapacity, AllocatorType &allocator)
const { value_.MemberReserve(newCapacity, allocator);
return *
this; }
2968 bool HasMember(
const Ch* name)
const {
return value_.HasMember(name); }
2969 #if RAPIDJSON_HAS_STDSTRING
2970 bool HasMember(
const std::basic_string<Ch>& name)
const {
return value_.HasMember(name); }
2972 template <
typename SourceAllocator>
bool HasMember(
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_.HasMember(name); }
2973 MemberIterator FindMember(
const Ch* name)
const {
return value_.FindMember(name); }
2974 template <
typename SourceAllocator> MemberIterator FindMember(
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_.FindMember(name); }
2975 #if RAPIDJSON_HAS_STDSTRING
2976 MemberIterator FindMember(
const std::basic_string<Ch>& name)
const {
return value_.FindMember(name); }
2978 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2979 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2980 #if RAPIDJSON_HAS_STDSTRING
2981 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2983 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2984 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2985 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2986 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2987 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2988 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2989 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2990 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2991 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2992 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2993 void RemoveAllMembers() { value_.RemoveAllMembers(); }
2994 bool RemoveMember(
const Ch* name)
const {
return value_.RemoveMember(name); }
2995 #if RAPIDJSON_HAS_STDSTRING
2996 bool RemoveMember(
const std::basic_string<Ch>& name)
const {
return value_.RemoveMember(name); }
2998 template <
typename SourceAllocator>
bool RemoveMember(
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_.RemoveMember(name); }
2999 MemberIterator RemoveMember(MemberIterator m)
const {
return value_.RemoveMember(m); }
3000 MemberIterator EraseMember(ConstMemberIterator pos)
const {
return value_.EraseMember(pos); }
3001 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last)
const {
return value_.EraseMember(first, last); }
3002 bool EraseMember(
const Ch* name)
const {
return value_.EraseMember(name); }
3003 #if RAPIDJSON_HAS_STDSTRING
3004 bool EraseMember(
const std::basic_string<Ch>& name)
const {
return EraseMember(ValueType(
StringRef(name))); }
3006 template <
typename SourceAllocator>
bool EraseMember(
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_.EraseMember(name); }
3008 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
3009 MemberIterator begin()
const {
return value_.MemberBegin(); }
3010 MemberIterator end()
const {
return value_.MemberEnd(); }
3015 GenericObject(ValueType& value) : value_(value) {}
3019 RAPIDJSON_NAMESPACE_END
3022 #ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3023 #pragma pop_macro("GetObject")
3024 #undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3027 #endif // RAPIDJSON_DOCUMENT_H_