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++)
45 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
49 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
53 RAPIDJSON_NAMESPACE_BEGIN
56 template <
typename Encoding,
typename Allocator>
59 template <
typename Encoding,
typename Allocator,
typename StackAllocator>
60 class GenericDocument;
68 #ifndef RAPIDJSON_DEFAULT_ALLOCATOR
69 #define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
78 #ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
79 #define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
88 #ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
90 #define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
99 #ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
101 #define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
110 template <
typename Encoding,
typename Allocator>
116 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
119 : name(std::move(rhs.name)),
120 value(std::move(rhs.value))
144 a.value.Swap(b.value);
149 GenericMember(
const GenericMember& rhs);
155 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
176 template <
bool Const,
typename Encoding,
typename Allocator>
195 typedef ValueType value_type;
196 typedef ValueType * pointer;
197 typedef ValueType & reference;
198 typedef std::ptrdiff_t difference_type;
199 typedef std::random_access_iterator_tag iterator_category;
232 Iterator& operator=(
const NonConstIterator & it) { ptr_ = it.ptr_;
return *
this; }
236 Iterator& operator++(){ ++ptr_;
return *
this; }
237 Iterator& operator--(){ --ptr_;
return *
this; }
238 Iterator operator++(
int){ Iterator old(*
this); ++ptr_;
return old; }
239 Iterator operator--(
int){ Iterator old(*
this); --ptr_;
return old; }
244 Iterator operator+(DifferenceType n)
const {
return Iterator(ptr_+n); }
245 Iterator operator-(DifferenceType n)
const {
return Iterator(ptr_-n); }
247 Iterator& operator+=(DifferenceType n) { ptr_+=n;
return *
this; }
248 Iterator& operator-=(DifferenceType n) { ptr_-=n;
return *
this; }
253 template <
bool Const_>
bool operator==(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ == that.ptr_; }
254 template <
bool Const_>
bool operator!=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ != that.ptr_; }
255 template <
bool Const_>
bool operator<=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ <= that.ptr_; }
256 template <
bool Const_>
bool operator>=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ >= that.ptr_; }
257 template <
bool Const_>
bool operator< (
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ < that.ptr_; }
258 template <
bool Const_>
bool operator> (
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ > that.ptr_; }
260 #ifdef __cpp_lib_three_way_comparison
261 template <
bool Const_> std::strong_ordering operator<=>(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ <=> that.ptr_; }
267 Reference operator*()
const {
return *ptr_; }
268 Pointer operator->()
const {
return ptr_; }
269 Reference operator[](DifferenceType n)
const {
return ptr_[n]; }
282 #else // RAPIDJSON_NOMEMBERITERATORCLASS
286 template <
bool Const,
typename Encoding,
typename Allocator>
287 class GenericMemberIterator;
290 template <
typename Encoding,
typename Allocator>
294 typedef GenericMember<Encoding,Allocator>* Iterator;
297 template <
typename Encoding,
typename Allocator>
301 typedef const GenericMember<Encoding,Allocator>* Iterator;
304 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
336 template<
typename CharType>
341 #ifndef __clang__ // -Wdocumentation
367 : s(str), length(N-1) {}
370 #ifndef __clang__ // -Wdocumentation
391 : s(str), length(NotNullStrLen(str)) {}
394 #ifndef __clang__ // -Wdocumentation
408 operator const Ch *()
const {
return s; }
414 SizeType NotNullStrLen(
const CharType* str) {
416 return internal::StrLen(str);
420 static const Ch emptyString[];
429 template<
typename CharType>
430 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
444 template<
typename CharType>
464 template<
typename CharType>
469 #if RAPIDJSON_HAS_STDSTRING
482 template<
typename CharType>
492 template <
typename T,
typename Encoding =
void,
typename Allocator =
void>
493 struct IsGenericValueImpl : FalseType {};
496 template <
typename T>
struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>
::Type, typename Void<typename T::AllocatorType>
::Type>
497 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>
::Type {};
500 template <
typename T>
struct IsGenericValue : IsGenericValueImpl<T>
::Type {};
509 template <
typename ValueType,
typename T>
510 struct TypeHelper {};
512 template<
typename ValueType>
513 struct TypeHelper<ValueType, bool> {
514 static bool Is(
const ValueType& v) {
return v.IsBool(); }
515 static bool Get(
const ValueType& v) {
return v.GetBool(); }
516 static ValueType& Set(ValueType& v,
bool data) {
return v.SetBool(data); }
517 static ValueType& Set(ValueType& v,
bool data,
typename ValueType::AllocatorType&) {
return v.SetBool(data); }
520 template<
typename ValueType>
521 struct TypeHelper<ValueType, int> {
522 static bool Is(
const ValueType& v) {
return v.IsInt(); }
523 static int Get(
const ValueType& v) {
return v.GetInt(); }
524 static ValueType& Set(ValueType& v,
int data) {
return v.SetInt(data); }
525 static ValueType& Set(ValueType& v,
int data,
typename ValueType::AllocatorType&) {
return v.SetInt(data); }
528 template<
typename ValueType>
529 struct TypeHelper<ValueType, unsigned> {
530 static bool Is(
const ValueType& v) {
return v.IsUint(); }
531 static unsigned Get(
const ValueType& v) {
return v.GetUint(); }
532 static ValueType& Set(ValueType& v,
unsigned data) {
return v.SetUint(data); }
533 static ValueType& Set(ValueType& v,
unsigned data,
typename ValueType::AllocatorType&) {
return v.SetUint(data); }
538 template<
typename ValueType>
539 struct TypeHelper<ValueType, long> {
540 static bool Is(
const ValueType& v) {
return v.IsInt(); }
541 static long Get(
const ValueType& v) {
return v.GetInt(); }
542 static ValueType& Set(ValueType& v,
long data) {
return v.SetInt(data); }
543 static ValueType& Set(ValueType& v,
long data,
typename ValueType::AllocatorType&) {
return v.SetInt(data); }
547 template<
typename ValueType>
548 struct TypeHelper<ValueType, unsigned long> {
549 static bool Is(
const ValueType& v) {
return v.IsUint(); }
550 static unsigned long Get(
const ValueType& v) {
return v.GetUint(); }
551 static ValueType& Set(ValueType& v,
unsigned long data) {
return v.SetUint(data); }
552 static ValueType& Set(ValueType& v,
unsigned long data,
typename ValueType::AllocatorType&) {
return v.SetUint(data); }
556 template<
typename ValueType>
557 struct TypeHelper<ValueType, int64_t> {
558 static bool Is(
const ValueType& v) {
return v.IsInt64(); }
559 static int64_t Get(
const ValueType& v) {
return v.GetInt64(); }
560 static ValueType& Set(ValueType& v, int64_t data) {
return v.SetInt64(data); }
561 static ValueType& Set(ValueType& v, int64_t data,
typename ValueType::AllocatorType&) {
return v.SetInt64(data); }
564 template<
typename ValueType>
565 struct TypeHelper<ValueType, uint64_t> {
566 static bool Is(
const ValueType& v) {
return v.IsUint64(); }
567 static uint64_t Get(
const ValueType& v) {
return v.GetUint64(); }
568 static ValueType& Set(ValueType& v, uint64_t data) {
return v.SetUint64(data); }
569 static ValueType& Set(ValueType& v, uint64_t data,
typename ValueType::AllocatorType&) {
return v.SetUint64(data); }
572 template<
typename ValueType>
573 struct TypeHelper<ValueType, double> {
574 static bool Is(
const ValueType& v) {
return v.IsDouble(); }
575 static double Get(
const ValueType& v) {
return v.GetDouble(); }
576 static ValueType& Set(ValueType& v,
double data) {
return v.SetDouble(data); }
577 static ValueType& Set(ValueType& v,
double data,
typename ValueType::AllocatorType&) {
return v.SetDouble(data); }
580 template<
typename ValueType>
581 struct TypeHelper<ValueType, float> {
582 static bool Is(
const ValueType& v) {
return v.IsFloat(); }
583 static float Get(
const ValueType& v) {
return v.GetFloat(); }
584 static ValueType& Set(ValueType& v,
float data) {
return v.SetFloat(data); }
585 static ValueType& Set(ValueType& v,
float data,
typename ValueType::AllocatorType&) {
return v.SetFloat(data); }
588 template<
typename ValueType>
589 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
590 typedef const typename ValueType::Ch* StringType;
591 static bool Is(
const ValueType& v) {
return v.IsString(); }
592 static StringType Get(
const ValueType& v) {
return v.GetString(); }
593 static ValueType& Set(ValueType& v,
const StringType data) {
return v.SetString(
typename ValueType::StringRefType(data)); }
594 static ValueType& Set(ValueType& v,
const StringType data,
typename ValueType::AllocatorType& a) {
return v.SetString(data, a); }
597 #if RAPIDJSON_HAS_STDSTRING
598 template<
typename ValueType>
599 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
600 typedef std::basic_string<typename ValueType::Ch> StringType;
601 static bool Is(
const ValueType& v) {
return v.IsString(); }
602 static StringType Get(
const ValueType& v) {
return StringType(v.GetString(), v.GetStringLength()); }
603 static ValueType& Set(ValueType& v,
const StringType& data,
typename ValueType::AllocatorType& a) {
return v.SetString(data, a); }
607 template<
typename ValueType>
608 struct TypeHelper<ValueType, typename ValueType::Array> {
609 typedef typename ValueType::Array ArrayType;
610 static bool Is(
const ValueType& v) {
return v.IsArray(); }
611 static ArrayType Get(ValueType& v) {
return v.GetArray(); }
612 static ValueType& Set(ValueType& v, ArrayType data) {
return v = data; }
613 static ValueType& Set(ValueType& v, ArrayType data,
typename ValueType::AllocatorType&) {
return v = data; }
616 template<
typename ValueType>
617 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
618 typedef typename ValueType::ConstArray ArrayType;
619 static bool Is(
const ValueType& v) {
return v.IsArray(); }
620 static ArrayType Get(
const ValueType& v) {
return v.GetArray(); }
623 template<
typename ValueType>
624 struct TypeHelper<ValueType, typename ValueType::Object> {
625 typedef typename ValueType::Object ObjectType;
626 static bool Is(
const ValueType& v) {
return v.IsObject(); }
627 static ObjectType Get(ValueType& v) {
return v.GetObject(); }
628 static ValueType& Set(ValueType& v, ObjectType data) {
return v = data; }
629 static ValueType& Set(ValueType& v, ObjectType data,
typename ValueType::AllocatorType&) {
return v = data; }
632 template<
typename ValueType>
633 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
634 typedef typename ValueType::ConstObject ObjectType;
635 static bool Is(
const ValueType& v) {
return v.IsObject(); }
636 static ObjectType Get(
const ValueType& v) {
return v.GetObject(); }
642 template <
bool,
typename>
class GenericArray;
643 template <
bool,
typename>
class GenericObject;
658 template <
typename Encoding,
typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
665 typedef typename Encoding::Ch
Ch;
681 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
683 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
686 rhs.data_.f.flags = kNullFlag;
692 GenericValue(
const GenericValue& rhs);
694 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
696 template <
typename StackAllocator>
697 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
700 template <
typename StackAllocator>
701 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
712 static const uint16_t defaultFlags[] = {
713 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
717 data_.f.flags = defaultFlags[type];
721 data_.ss.SetLength(0);
732 template <
typename SourceAllocator>
734 switch (rhs.GetType()) {
739 for (
SizeType i = 0; i < count; i++) {
743 data_.f.flags = kObjectFlag;
744 data_.o.size = data_.o.capacity = count;
745 SetMembersPointer(lm);
752 for (
SizeType i = 0; i < count; i++)
753 new (&le[i])
GenericValue(re[i], allocator, copyConstStrings);
754 data_.f.flags = kArrayFlag;
755 data_.a.size = data_.a.capacity = count;
756 SetElementsPointer(le);
760 if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
761 data_.f.flags = rhs.data_.f.flags;
762 data_ = *
reinterpret_cast<const Data*
>(&rhs.data_);
768 data_.f.flags = rhs.data_.f.flags;
769 data_ = *
reinterpret_cast<const Data*
>(&rhs.data_);
780 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
781 template <
typename T>
782 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT
789 data_.f.flags = b ? kTrueFlag : kFalseFlag;
795 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
801 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
807 data_.f.flags = kNumberInt64Flag;
809 data_.f.flags |= kNumberUint64Flag;
811 data_.f.flags |= kUintFlag;
813 data_.f.flags |= kIntFlag;
816 data_.f.flags |= kIntFlag;
822 data_.f.flags = kNumberUint64Flag;
824 data_.f.flags |= kInt64Flag;
826 data_.f.flags |= kUintFlag;
828 data_.f.flags |= kIntFlag;
832 explicit GenericValue(
double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
835 explicit GenericValue(
float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d =
static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
849 #if RAPIDJSON_HAS_STDSTRING
863 a.value_.data_ = Data();
864 a.value_.data_.f.flags = kArrayFlag;
874 o.value_.data_ = Data();
875 o.value_.data_.f.flags = kObjectFlag;
882 if (Allocator::kNeedFree) {
883 switch(data_.f.flags) {
896 Allocator::Free(GetMembersPointer());
899 case kCopyStringFlag:
900 Allocator::Free(
const_cast<Ch*
>(GetStringPointer()));
925 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
928 return *
this = rhs.
Move();
954 template <
typename T>
955 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (
GenericValue&))
968 template <
typename SourceAllocator>
970 RAPIDJSON_ASSERT(
static_cast<void*
>(
this) !=
static_cast<void const*
>(&rhs));
972 new (
this)
GenericValue(rhs, allocator, copyConstStrings);
983 temp.RawAssign(*
this);
985 other.RawAssign(temp);
1015 template <
typename SourceAllocator>
1018 if (GetType() != rhs.GetType())
1021 switch (GetType()) {
1023 if (data_.o.size != rhs.data_.o.size)
1025 for (
ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1026 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.
FindMember(lhsMemberItr->name);
1027 if (rhsMemberItr == rhs.
MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
1033 if (data_.a.size != rhs.data_.a.size)
1035 for (
SizeType i = 0; i < data_.a.size; i++)
1036 if ((*
this)[i] != rhs[i])
1041 return StringEqual(rhs);
1044 if (IsDouble() || rhs.IsDouble()) {
1045 double a = GetDouble();
1047 return a >= b && a <= b;
1050 return data_.n.u64 == rhs.data_.n.u64;
1060 #if RAPIDJSON_HAS_STDSTRING
1070 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (
bool))
operator==(
const T& rhs)
const {
return *
this ==
GenericValue(rhs); }
1075 template <
typename SourceAllocator>
1084 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (
bool))
operator!=(
const T& rhs)
const {
return !(*
this == rhs); }
1089 template <
typename T>
friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (
bool))
operator==(
const T& lhs,
const GenericValue& rhs) {
return rhs == lhs; }
1094 template <
typename T>
friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (
bool))
operator!=(
const T& lhs,
const GenericValue& rhs) {
return !(rhs == lhs); }
1100 Type GetType()
const {
return static_cast<Type>(data_.f.flags & kTypeMask); }
1101 bool IsNull()
const {
return data_.f.flags == kNullFlag; }
1102 bool IsFalse()
const {
return data_.f.flags == kFalseFlag; }
1103 bool IsTrue()
const {
return data_.f.flags == kTrueFlag; }
1104 bool IsBool()
const {
return (data_.f.flags & kBoolFlag) != 0; }
1105 bool IsObject()
const {
return data_.f.flags == kObjectFlag; }
1106 bool IsArray()
const {
return data_.f.flags == kArrayFlag; }
1107 bool IsNumber()
const {
return (data_.f.flags & kNumberFlag) != 0; }
1108 bool IsInt()
const {
return (data_.f.flags & kIntFlag) != 0; }
1109 bool IsUint()
const {
return (data_.f.flags & kUintFlag) != 0; }
1110 bool IsInt64()
const {
return (data_.f.flags & kInt64Flag) != 0; }
1111 bool IsUint64()
const {
return (data_.f.flags & kUint64Flag) != 0; }
1112 bool IsDouble()
const {
return (data_.f.flags & kDoubleFlag) != 0; }
1113 bool IsString()
const {
return (data_.f.flags & kStringFlag) != 0; }
1116 bool IsLosslessDouble()
const {
1117 if (!IsNumber())
return false;
1119 uint64_t u = GetUint64();
1120 volatile double d =
static_cast<double>(u);
1122 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1123 && (u ==
static_cast<uint64_t
>(d));
1126 int64_t i = GetInt64();
1127 volatile double d =
static_cast<double>(i);
1128 return (d >=
static_cast<double>((std::numeric_limits<int64_t>::min)()))
1129 && (d <
static_cast<double>((std::numeric_limits<int64_t>::max)()))
1130 && (i ==
static_cast<int64_t
>(d));
1136 bool IsFloat()
const {
1137 if ((data_.f.flags & kDoubleFlag) == 0)
1139 double d = GetDouble();
1140 return d >= -3.4028234e38 && d <= 3.4028234e38;
1143 bool IsLosslessFloat()
const {
1144 if (!IsNumber())
return false;
1145 double a = GetDouble();
1146 if (a <
static_cast<double>(-(std::numeric_limits<float>::max)())
1147 || a >
static_cast<double>((std::numeric_limits<float>::max)()))
1149 double b =
static_cast<double>(
static_cast<float>(a));
1150 return a >= b && a <= b;
1158 GenericValue& SetNull() { this->~GenericValue();
new (
this) GenericValue();
return *
this; }
1197 template <
typename T>
1202 template <
typename T>
1214 template <
typename SourceAllocator>
1217 if (member != MemberEnd())
1218 return member->value;
1231 template <
typename SourceAllocator>
1234 #if RAPIDJSON_HAS_STDSTRING
1261 if (newCapacity > data_.o.capacity) {
1262 SetMembersPointer(
reinterpret_cast<Member*
>(allocator.Realloc(GetMembersPointer(), data_.o.capacity *
sizeof(
Member), newCapacity *
sizeof(
Member))));
1263 data_.o.capacity = newCapacity;
1276 bool HasMember(
const Ch* name)
const {
return FindMember(name) != MemberEnd(); }
1278 #if RAPIDJSON_HAS_STDSTRING
1287 bool HasMember(
const std::basic_string<Ch>& name)
const {
return FindMember(name) != MemberEnd(); }
1299 template <
typename SourceAllocator>
1316 return FindMember(n);
1319 ConstMemberIterator FindMember(
const Ch* name)
const {
return const_cast<GenericValue&
>(*this).
FindMember(name); }
1334 template <
typename SourceAllocator>
1339 for ( ; member != MemberEnd(); ++member)
1340 if (name.StringEqual(member->name))
1346 #if RAPIDJSON_HAS_STDSTRING
1355 ConstMemberIterator FindMember(
const std::basic_string<Ch>& name)
const {
return FindMember(
GenericValue(
StringRef(name))); }
1372 ObjectData& o = data_.o;
1373 if (o.size >= o.capacity)
1374 MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1375 Member* members = GetMembersPointer();
1376 members[o.size].
name.RawAssign(name);
1377 members[o.size].
value.RawAssign(value);
1393 return AddMember(name, v, allocator);
1396 #if RAPIDJSON_HAS_STDSTRING
1408 return AddMember(name, v, allocator);
1429 template <
typename T>
1430 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (
GenericValue&))
1433 return AddMember(name, v, allocator);
1436 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1438 return AddMember(name, value, allocator);
1440 GenericValue& AddMember(GenericValue&& name, GenericValue& value,
Allocator& allocator) {
1441 return AddMember(name, value, allocator);
1443 GenericValue& AddMember(GenericValue& name, GenericValue&& value,
Allocator& allocator) {
1444 return AddMember(name, value, allocator);
1446 GenericValue& AddMember(StringRefType name, GenericValue&& value,
Allocator& allocator) {
1447 GenericValue n(name);
1448 return AddMember(n, value, allocator);
1450 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1465 return AddMember(n, value, allocator);
1479 return AddMember(name, v, allocator);
1499 template <
typename T>
1500 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (
GenericValue&))
1503 return AddMember(n, value, allocator);
1527 return RemoveMember(n);
1530 #if RAPIDJSON_HAS_STDSTRING
1531 bool RemoveMember(
const std::basic_string<Ch>& name) {
return RemoveMember(
GenericValue(
StringRef(name))); }
1534 template <
typename SourceAllocator>
1535 bool RemoveMember(
const GenericValue<Encoding, SourceAllocator>& name) {
1536 MemberIterator m = FindMember(name);
1537 if (m != MemberEnd()) {
1560 if (data_.o.size > 1 && m != last)
1578 return EraseMember(pos, pos +1);
1601 std::memmove(
static_cast<void*
>(&*pos), &*last,
static_cast<size_t>(MemberEnd() - last) *
sizeof(
Member));
1602 data_.o.size -=
static_cast<SizeType>(last - first);
1613 return EraseMember(n);
1616 #if RAPIDJSON_HAS_STDSTRING
1617 bool EraseMember(
const std::basic_string<Ch>& name) {
return EraseMember(
GenericValue(
StringRef(name))); }
1620 template <
typename SourceAllocator>
1621 bool EraseMember(
const GenericValue<Encoding, SourceAllocator>& name) {
1622 MemberIterator m = FindMember(name);
1623 if (m != MemberEnd()) {
1632 ConstObject GetObject()
const {
RAPIDJSON_ASSERT(IsObject());
return ConstObject(*
this); }
1672 return GetElementsPointer()[index];
1697 if (newCapacity > data_.a.capacity) {
1699 data_.a.capacity = newCapacity;
1716 if (data_.a.size >= data_.a.capacity)
1717 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1718 GetElementsPointer()[data_.a.size++].RawAssign(value);
1722 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1724 return PushBack(value, allocator);
1726 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1738 return (*this).template PushBack<StringRefType>(value, allocator);
1758 template <
typename T>
1759 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (
GenericValue&))
1762 return PushBack(v, allocator);
1772 GetElementsPointer()[--data_.a.size].~GenericValue();
1784 return Erase(pos, pos + 1);
1805 std::memmove(
static_cast<void*
>(pos), last,
static_cast<size_t>(End() - last) *
sizeof(
GenericValue));
1806 data_.a.size -=
static_cast<SizeType>(last - first);
1811 ConstArray GetArray()
const {
RAPIDJSON_ASSERT(IsArray());
return ConstArray(*
this); }
1818 int GetInt()
const {
RAPIDJSON_ASSERT(data_.f.flags & kIntFlag);
return data_.n.i.i; }
1819 unsigned GetUint()
const {
RAPIDJSON_ASSERT(data_.f.flags & kUintFlag);
return data_.n.u.u; }
1820 int64_t GetInt64()
const {
RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag);
return data_.n.i64; }
1821 uint64_t GetUint64()
const {
RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag);
return data_.n.u64; }
1828 if ((data_.f.flags & kDoubleFlag) != 0)
return data_.n.d;
1829 if ((data_.f.flags & kIntFlag) != 0)
return data_.n.i.i;
1830 if ((data_.f.flags & kUintFlag) != 0)
return data_.n.u.u;
1831 if ((data_.f.flags & kInt64Flag) != 0)
return static_cast<double>(data_.n.i64);
1832 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0);
return static_cast<double>(data_.n.u64);
1839 return static_cast<float>(GetDouble());
1843 GenericValue& SetUint(
unsigned u) { this->~GenericValue();
new (
this) GenericValue(u);
return *
this; }
1844 GenericValue& SetInt64(int64_t i64) { this->~GenericValue();
new (
this) GenericValue(i64);
return *
this; }
1845 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue();
new (
this) GenericValue(u64);
return *
this; }
1846 GenericValue& SetDouble(
double d) { this->~GenericValue();
new (
this) GenericValue(d);
return *
this; }
1847 GenericValue& SetFloat(
float f) { this->~GenericValue();
new (
this) GenericValue(
static_cast<double>(f));
return *
this; }
1854 const Ch* GetString()
const {
RAPIDJSON_ASSERT(IsString());
return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1904 #if RAPIDJSON_HAS_STDSTRING
1924 template <
typename T>
1925 bool Is()
const {
return internal::TypeHelper<ValueType, T>::Is(*
this); }
1927 template <
typename T>
1928 T Get()
const {
return internal::TypeHelper<ValueType, T>::Get(*
this); }
1930 template <
typename T>
1931 T Get() {
return internal::TypeHelper<ValueType, T>::Get(*
this); }
1933 template<
typename T>
1934 ValueType& Set(
const T& data) {
return internal::TypeHelper<ValueType, T>::Set(*
this, data); }
1936 template<
typename T>
1937 ValueType& Set(
const T& data, AllocatorType& allocator) {
return internal::TypeHelper<ValueType, T>::Set(*
this, data, allocator); }
1948 template <
typename Handler>
1953 case kTrueType:
return handler.Bool(
true);
1960 if (
RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1965 return handler.EndObject(data_.o.size);
1973 return handler.EndArray(data_.a.size);
1976 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1980 if (IsDouble())
return handler.Double(data_.n.d);
1981 else if (IsInt())
return handler.Int(data_.n.i.i);
1982 else if (IsUint())
return handler.Uint(data_.n.u.u);
1983 else if (IsInt64())
return handler.Int64(data_.n.i64);
1984 else return handler.Uint64(data_.n.u64);
1989 template <
typename,
typename>
friend class GenericValue;
1994 kNumberFlag = 0x0010,
1997 kInt64Flag = 0x0080,
1998 kUint64Flag = 0x0100,
1999 kDoubleFlag = 0x0200,
2000 kStringFlag = 0x0400,
2002 kInlineStrFlag = 0x1000,
2007 kTrueFlag =
static_cast<int>(
kTrueType) |
static_cast<int>(kBoolFlag),
2008 kFalseFlag =
static_cast<int>(
kFalseType) |
static_cast<int>(kBoolFlag),
2009 kNumberIntFlag =
static_cast<int>(
kNumberType) |
static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
2010 kNumberUintFlag =
static_cast<int>(
kNumberType) |
static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
2011 kNumberInt64Flag =
static_cast<int>(
kNumberType) |
static_cast<int>(kNumberFlag | kInt64Flag),
2012 kNumberUint64Flag =
static_cast<int>(
kNumberType) |
static_cast<int>(kNumberFlag | kUint64Flag),
2013 kNumberDoubleFlag =
static_cast<int>(
kNumberType) |
static_cast<int>(kNumberFlag | kDoubleFlag),
2014 kNumberAnyFlag =
static_cast<int>(
kNumberType) |
static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
2015 kConstStringFlag =
static_cast<int>(
kStringType) |
static_cast<int>(kStringFlag),
2016 kCopyStringFlag =
static_cast<int>(
kStringType) |
static_cast<int>(kStringFlag | kCopyFlag),
2017 kShortStringFlag =
static_cast<int>(
kStringType) |
static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2028 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2029 char payload[
sizeof(
SizeType) * 2 + 6];
2030 #elif RAPIDJSON_64BIT
2031 char payload[
sizeof(
SizeType) * 2 +
sizeof(
void*) + 6];
2033 char payload[
sizeof(
SizeType) * 2 +
sizeof(
void*) + 2];
2052 struct ShortString {
2053 enum { MaxChars =
sizeof(
static_cast<Flag*
>(0)->payload) /
sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2056 inline static bool Usable(
SizeType len) {
return (MaxSize >= len); }
2057 inline void SetLength(
SizeType len) { str[LenPos] =
static_cast<Ch
>(MaxSize - len); }
2058 inline SizeType GetLength()
const {
return static_cast<SizeType>(MaxSize - str[LenPos]); }
2063 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2108 RAPIDJSON_FORCEINLINE
const Ch* GetStringPointer()
const {
return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2109 RAPIDJSON_FORCEINLINE
const Ch* SetStringPointer(
const Ch* str) {
return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2110 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer()
const {
return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2111 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) {
return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2112 RAPIDJSON_FORCEINLINE Member* GetMembersPointer()
const {
return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2113 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) {
return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2117 data_.f.flags = kArrayFlag;
2119 GenericValue* e =
static_cast<GenericValue*
>(allocator.Malloc(count *
sizeof(GenericValue)));
2120 SetElementsPointer(e);
2121 std::memcpy(
static_cast<void*
>(e), values, count *
sizeof(GenericValue));
2124 SetElementsPointer(0);
2125 data_.a.size = data_.a.capacity = count;
2130 data_.f.flags = kObjectFlag;
2132 Member* m =
static_cast<Member*
>(allocator.Malloc(count *
sizeof(Member)));
2133 SetMembersPointer(m);
2134 std::memcpy(
static_cast<void*
>(m), members, count *
sizeof(Member));
2137 SetMembersPointer(0);
2138 data_.o.size = data_.o.capacity = count;
2142 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2143 data_.f.flags = kConstStringFlag;
2144 SetStringPointer(s);
2145 data_.s.length = s.length;
2149 void SetStringRaw(StringRefType s,
Allocator& allocator) {
2151 if (ShortString::Usable(s.length)) {
2152 data_.f.flags = kShortStringFlag;
2153 data_.ss.SetLength(s.length);
2156 data_.f.flags = kCopyStringFlag;
2157 data_.s.length = s.length;
2158 str =
static_cast<Ch *
>(allocator.Malloc((s.length + 1) *
sizeof(Ch)));
2159 SetStringPointer(str);
2161 std::memcpy(str, s, s.length *
sizeof(Ch));
2162 str[s.length] =
'\0';
2166 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2169 rhs.data_.f.flags = kNullFlag;
2172 template <
typename SourceAllocator>
2173 bool StringEqual(
const GenericValue<Encoding, SourceAllocator>& rhs)
const {
2177 const SizeType len1 = GetStringLength();
2178 const SizeType len2 = rhs.GetStringLength();
2179 if(len1 != len2) {
return false; }
2181 const Ch*
const str1 = GetString();
2182 const Ch*
const str2 = rhs.GetString();
2183 if(str1 == str2) {
return true; }
2185 return (std::memcmp(str1, str2,
sizeof(Ch) * len1) == 0);
2205 template <
typename Encoding,
typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR,
typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2208 typedef typename Encoding::Ch
Ch;
2233 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2239 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2242 : ValueType(std::forward<ValueType>(rhs)),
2243 allocator_(rhs.allocator_),
2244 ownAllocator_(rhs.ownAllocator_),
2245 stack_(std::move(rhs.stack_)),
2246 parseResult_(rhs.parseResult_)
2249 rhs.ownAllocator_ = 0;
2254 ~GenericDocument() {
2258 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2260 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2264 ValueType::operator=(std::forward<ValueType>(rhs));
2269 allocator_ = rhs.allocator_;
2270 ownAllocator_ = rhs.ownAllocator_;
2271 stack_ = std::move(rhs.stack_);
2272 parseResult_ = rhs.parseResult_;
2275 rhs.ownAllocator_ = 0;
2276 rhs.parseResult_ = ParseResult();
2289 ValueType::Swap(rhs);
2290 stack_.Swap(rhs.stack_);
2291 internal::Swap(allocator_, rhs.allocator_);
2292 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2293 internal::Swap(parseResult_, rhs.parseResult_);
2299 using ValueType::Swap;
2320 template <
typename Generator>
2322 ClearStackOnExit scope(*
this);
2325 ValueType::operator=(*stack_.template Pop<ValueType>(1));
2340 template <
unsigned parseFlags,
typename SourceEncoding,
typename InputStream>
2343 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2344 ClearStackOnExit scope(*
this);
2345 parseResult_ = reader.template Parse<parseFlags>(is, *
this);
2348 ValueType::operator=(*stack_.template Pop<ValueType>(1));
2359 template <
unsigned parseFlags,
typename InputStream>
2361 return ParseStream<parseFlags, Encoding, InputStream>(is);
2369 template <
typename InputStream>
2371 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2383 template <
unsigned parseFlags>
2386 return ParseStream<parseFlags | kParseInsituFlag>(s);
2394 return ParseInsitu<kParseDefaultFlags>(str);
2406 template <
unsigned parseFlags,
typename SourceEncoding>
2410 return ParseStream<parseFlags, SourceEncoding>(s);
2417 template <
unsigned parseFlags>
2419 return Parse<parseFlags, Encoding>(str);
2426 return Parse<kParseDefaultFlags>(str);
2429 template <
unsigned parseFlags,
typename SourceEncoding>
2430 GenericDocument& Parse(
const typename SourceEncoding::Ch* str,
size_t length) {
2432 MemoryStream ms(
reinterpret_cast<const char*
>(str), length *
sizeof(
typename SourceEncoding::Ch));
2434 ParseStream<parseFlags, SourceEncoding>(is);
2438 template <
unsigned parseFlags>
2439 GenericDocument& Parse(
const Ch* str,
size_t length) {
2440 return Parse<parseFlags, Encoding>(str, length);
2443 GenericDocument& Parse(
const Ch* str,
size_t length) {
2444 return Parse<kParseDefaultFlags>(str, length);
2447 #if RAPIDJSON_HAS_STDSTRING
2448 template <
unsigned parseFlags,
typename SourceEncoding>
2449 GenericDocument& Parse(
const std::basic_string<typename SourceEncoding::Ch>& str) {
2451 return Parse<parseFlags, SourceEncoding>(str.c_str());
2454 template <
unsigned parseFlags>
2455 GenericDocument& Parse(
const std::basic_string<Ch>& str) {
2456 return Parse<parseFlags, Encoding>(str.c_str());
2459 GenericDocument& Parse(
const std::basic_string<Ch>& str) {
2460 return Parse<kParseDefaultFlags>(str);
2462 #endif // RAPIDJSON_HAS_STDSTRING
2479 #ifndef __clang // -Wdocumentation
2504 struct ClearStackOnExit {
2506 ~ClearStackOnExit() { d_.ClearStack(); }
2508 ClearStackOnExit(
const ClearStackOnExit&);
2509 ClearStackOnExit& operator=(
const ClearStackOnExit&);
2510 GenericDocument& d_;
2515 template <
typename,
typename>
friend class GenericValue;
2519 bool Null() {
new (stack_.template Push<ValueType>()) ValueType();
return true; }
2520 bool Bool(
bool b) {
new (stack_.template Push<ValueType>()) ValueType(b);
return true; }
2521 bool Int(
int i) {
new (stack_.template Push<ValueType>()) ValueType(i);
return true; }
2522 bool Uint(
unsigned i) {
new (stack_.template Push<ValueType>()) ValueType(i);
return true; }
2523 bool Int64(int64_t i) {
new (stack_.template Push<ValueType>()) ValueType(i);
return true; }
2524 bool Uint64(uint64_t i) {
new (stack_.template Push<ValueType>()) ValueType(i);
return true; }
2525 bool Double(
double d) {
new (stack_.template Push<ValueType>()) ValueType(d);
return true; }
2527 bool RawNumber(
const Ch* str,
SizeType length,
bool copy) {
2529 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2531 new (stack_.template Push<ValueType>()) ValueType(str, length);
2535 bool String(
const Ch* str,
SizeType length,
bool copy) {
2537 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2539 new (stack_.template Push<ValueType>()) ValueType(str, length);
2543 bool StartObject() {
new (stack_.template Push<ValueType>()) ValueType(
kObjectType);
return true; }
2545 bool Key(
const Ch* str,
SizeType length,
bool copy) {
return String(str, length, copy); }
2547 bool EndObject(
SizeType memberCount) {
2548 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2549 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2553 bool StartArray() {
new (stack_.template Push<ValueType>()) ValueType(
kArrayType);
return true; }
2555 bool EndArray(
SizeType elementCount) {
2556 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2557 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2563 GenericDocument(
const GenericDocument&);
2565 GenericDocument& operator=(
const GenericDocument&);
2568 if (Allocator::kNeedFree)
2569 while (stack_.GetSize() > 0)
2570 (stack_.template Pop<ValueType>(1))->~ValueType();
2573 stack_.ShrinkToFit();
2580 static const size_t kDefaultStackCapacity = 1024;
2583 internal::Stack<StackAllocator> stack_;
2584 ParseResult parseResult_;
2596 template <
bool Const,
typename ValueT>
2601 typedef ValueT PlainType;
2603 typedef ValueType* ValueIterator;
2604 typedef const ValueT* ConstValueIterator;
2605 typedef typename ValueType::AllocatorType AllocatorType;
2606 typedef typename ValueType::StringRefType StringRefType;
2608 template <
typename,
typename>
2615 operator ValueType&()
const {
return value_; }
2616 SizeType Size()
const {
return value_.Size(); }
2617 SizeType Capacity()
const {
return value_.Capacity(); }
2618 bool Empty()
const {
return value_.Empty(); }
2619 void Clear()
const { value_.Clear(); }
2620 ValueType& operator[](
SizeType index)
const {
return value_[index]; }
2621 ValueIterator Begin()
const {
return value_.Begin(); }
2622 ValueIterator End()
const {
return value_.End(); }
2623 GenericArray Reserve(
SizeType newCapacity, AllocatorType &allocator)
const { value_.Reserve(newCapacity, allocator);
return *
this; }
2624 GenericArray PushBack(ValueType& value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2625 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2626 GenericArray PushBack(ValueType&& value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2627 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2628 GenericArray PushBack(StringRefType value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2629 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; }
2630 GenericArray PopBack()
const { value_.PopBack();
return *
this; }
2631 ValueIterator Erase(ConstValueIterator pos)
const {
return value_.Erase(pos); }
2632 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)
const {
return value_.Erase(first, last); }
2634 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2635 ValueIterator begin()
const {
return value_.Begin(); }
2636 ValueIterator end()
const {
return value_.End(); }
2650 template <
bool Const,
typename ValueT>
2655 typedef ValueT PlainType;
2659 typedef typename ValueType::AllocatorType AllocatorType;
2660 typedef typename ValueType::StringRefType StringRefType;
2661 typedef typename ValueType::EncodingType EncodingType;
2662 typedef typename ValueType::Ch Ch;
2664 template <
typename,
typename>
2671 operator ValueType&()
const {
return value_; }
2672 SizeType MemberCount()
const {
return value_.MemberCount(); }
2673 SizeType MemberCapacity()
const {
return value_.MemberCapacity(); }
2674 bool ObjectEmpty()
const {
return value_.ObjectEmpty(); }
2675 template <
typename T> ValueType& operator[](T* name)
const {
return value_[name]; }
2677 #if RAPIDJSON_HAS_STDSTRING
2678 ValueType& operator[](
const std::basic_string<Ch>& name)
const {
return value_[name]; }
2680 MemberIterator MemberBegin()
const {
return value_.MemberBegin(); }
2682 GenericObject MemberReserve(
SizeType newCapacity, AllocatorType &allocator)
const { value_.MemberReserve(newCapacity, allocator);
return *
this; }
2683 bool HasMember(
const Ch* name)
const {
return value_.HasMember(name); }
2684 #if RAPIDJSON_HAS_STDSTRING
2685 bool HasMember(
const std::basic_string<Ch>& name)
const {
return value_.HasMember(name); }
2688 MemberIterator FindMember(
const Ch* name)
const {
return value_.FindMember(name); }
2690 #if RAPIDJSON_HAS_STDSTRING
2691 MemberIterator FindMember(
const std::basic_string<Ch>& name)
const {
return value_.FindMember(name); }
2693 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2694 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2695 #if RAPIDJSON_HAS_STDSTRING
2696 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2698 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; }
2699 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2700 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2701 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2702 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2703 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2704 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2705 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2706 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2707 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; }
2708 void RemoveAllMembers() { value_.RemoveAllMembers(); }
2709 bool RemoveMember(
const Ch* name)
const {
return value_.RemoveMember(name); }
2710 #if RAPIDJSON_HAS_STDSTRING
2711 bool RemoveMember(
const std::basic_string<Ch>& name)
const {
return value_.RemoveMember(name); }
2717 bool EraseMember(
const Ch* name)
const {
return value_.EraseMember(name); }
2718 #if RAPIDJSON_HAS_STDSTRING
2719 bool EraseMember(
const std::basic_string<Ch>& name)
const {
return EraseMember(ValueType(
StringRef(name))); }
2723 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2734 RAPIDJSON_NAMESPACE_END
2737 #endif // RAPIDJSON_DOCUMENT_H_