16#ifndef RAPIDJSON_DOCUMENT_H_
17#define RAPIDJSON_DOCUMENT_H_
22#include "internal/meta.h"
23#include "internal/strfunc.h"
24#include "memorystream.h"
25#include "encodedstream.h"
28#ifdef __cpp_lib_three_way_comparison
34RAPIDJSON_DIAG_OFF(padded)
35RAPIDJSON_DIAG_OFF(
switch-
enum)
36RAPIDJSON_DIAG_OFF(c++98-compat)
37#elif defined(_MSC_VER)
38RAPIDJSON_DIAG_OFF(4127)
39RAPIDJSON_DIAG_OFF(4244)
43RAPIDJSON_DIAG_OFF(effc++)
50#pragma push_macro("GetObject")
51#define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
55#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
59#if RAPIDJSON_USE_MEMBERSMAP
66template <
typename Encoding,
typename Allocator>
69template <
typename Encoding,
typename Allocator,
typename StackAllocator>
78#ifndef RAPIDJSON_DEFAULT_ALLOCATOR
79#define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
88#ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
89#define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
98#ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
100#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
109#ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
111#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
120template <
typename Encoding,
typename Allocator>
126#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
129 :
name(std::move(rhs.name)),
130 value(std::move(rhs.value))
154 a.value.Swap(b.value);
165#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
186template <
bool Const,
typename Encoding,
typename Allocator>
187class GenericMemberIterator {
190 template <
bool,
typename,
typename>
friend class GenericMemberIterator;
193 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
205 typedef ValueType value_type;
206 typedef ValueType * pointer;
207 typedef ValueType & reference;
208 typedef std::ptrdiff_t difference_type;
209 typedef std::random_access_iterator_tag iterator_category;
263 template <
bool Const_>
bool operator==(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ == that.
ptr_; }
264 template <
bool Const_>
bool operator!=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ != that.
ptr_; }
265 template <
bool Const_>
bool operator<=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ <= that.
ptr_; }
266 template <
bool Const_>
bool operator>=(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ >= that.
ptr_; }
267 template <
bool Const_>
bool operator< (
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ < that.
ptr_; }
268 template <
bool Const_>
bool operator> (
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ > that.
ptr_; }
270#ifdef __cpp_lib_three_way_comparison
271 template <
bool Const_> std::strong_ordering operator<=>(
const GenericMemberIterator<Const_, Encoding, Allocator>& that)
const {
return ptr_ <=> that.
ptr_; }
296template <
bool Const,
typename Encoding,
typename Allocator>
300template <
typename Encoding,
typename Allocator>
307template <
typename Encoding,
typename Allocator>
311 typedef const GenericMember<Encoding,Allocator>*
Iterator;
346template<
typename CharType>
401 :
s(str),
length(NotNullStrLen(str)) {}
418 operator const Ch *()
const {
return s; }
424 SizeType NotNullStrLen(
const CharType* str) {
426 return internal::StrLen(str);
439template<
typename CharType>
454template<
typename CharType>
474template<
typename CharType>
479#if RAPIDJSON_HAS_STDSTRING
492template<
typename CharType>
502template <
typename T,
typename Encoding =
void,
typename Allocator =
void>
507 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>
::Type {};
519template <
typename ValueType,
typename T>
522template<
typename ValueType>
524 static bool Is(
const ValueType& v) {
return v.IsBool(); }
525 static bool Get(
const ValueType& v) {
return v.GetBool(); }
526 static ValueType& Set(ValueType& v,
bool data) {
return v.SetBool(data); }
527 static ValueType& Set(ValueType& v,
bool data,
typename ValueType::AllocatorType&) {
return v.SetBool(data); }
530template<
typename ValueType>
532 static bool Is(
const ValueType& v) {
return v.IsInt(); }
533 static int Get(
const ValueType& v) {
return v.GetInt(); }
534 static ValueType& Set(ValueType& v,
int data) {
return v.SetInt(data); }
535 static ValueType& Set(ValueType& v,
int data,
typename ValueType::AllocatorType&) {
return v.SetInt(data); }
538template<
typename ValueType>
540 static bool Is(
const ValueType& v) {
return v.IsUint(); }
541 static unsigned Get(
const ValueType& v) {
return v.GetUint(); }
542 static ValueType& Set(ValueType& v,
unsigned data) {
return v.SetUint(data); }
543 static ValueType& Set(ValueType& v,
unsigned data,
typename ValueType::AllocatorType&) {
return v.SetUint(data); }
548template<
typename ValueType>
550 static bool Is(
const ValueType& v) {
return v.IsInt(); }
551 static long Get(
const ValueType& v) {
return v.GetInt(); }
552 static ValueType& Set(ValueType& v,
long data) {
return v.SetInt(data); }
553 static ValueType& Set(ValueType& v,
long data,
typename ValueType::AllocatorType&) {
return v.SetInt(data); }
557template<
typename ValueType>
559 static bool Is(
const ValueType& v) {
return v.IsUint(); }
560 static unsigned long Get(
const ValueType& v) {
return v.GetUint(); }
561 static ValueType& Set(ValueType& v,
unsigned long data) {
return v.SetUint(data); }
562 static ValueType& Set(ValueType& v,
unsigned long data,
typename ValueType::AllocatorType&) {
return v.SetUint(data); }
566template<
typename ValueType>
568 static bool Is(
const ValueType& v) {
return v.IsInt64(); }
569 static int64_t Get(
const ValueType& v) {
return v.GetInt64(); }
570 static ValueType& Set(ValueType& v, int64_t data) {
return v.SetInt64(data); }
571 static ValueType& Set(ValueType& v, int64_t data,
typename ValueType::AllocatorType&) {
return v.SetInt64(data); }
574template<
typename ValueType>
576 static bool Is(
const ValueType& v) {
return v.IsUint64(); }
577 static uint64_t Get(
const ValueType& v) {
return v.GetUint64(); }
578 static ValueType& Set(ValueType& v, uint64_t data) {
return v.SetUint64(data); }
579 static ValueType& Set(ValueType& v, uint64_t data,
typename ValueType::AllocatorType&) {
return v.SetUint64(data); }
582template<
typename ValueType>
584 static bool Is(
const ValueType& v) {
return v.IsDouble(); }
585 static double Get(
const ValueType& v) {
return v.GetDouble(); }
586 static ValueType& Set(ValueType& v,
double data) {
return v.SetDouble(data); }
587 static ValueType& Set(ValueType& v,
double data,
typename ValueType::AllocatorType&) {
return v.SetDouble(data); }
590template<
typename ValueType>
592 static bool Is(
const ValueType& v) {
return v.IsFloat(); }
593 static float Get(
const ValueType& v) {
return v.GetFloat(); }
594 static ValueType& Set(ValueType& v,
float data) {
return v.SetFloat(data); }
595 static ValueType& Set(ValueType& v,
float data,
typename ValueType::AllocatorType&) {
return v.SetFloat(data); }
598template<
typename ValueType>
600 typedef const typename ValueType::Ch* StringType;
601 static bool Is(
const ValueType& v) {
return v.IsString(); }
602 static StringType Get(
const ValueType& v) {
return v.GetString(); }
603 static ValueType& Set(ValueType& v,
const StringType data) {
return v.SetString(
typename ValueType::StringRefType(data)); }
604 static ValueType& Set(ValueType& v,
const StringType data,
typename ValueType::AllocatorType& a) {
return v.SetString(data, a); }
607#if RAPIDJSON_HAS_STDSTRING
608template<
typename ValueType>
609struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
610 typedef std::basic_string<typename ValueType::Ch> StringType;
611 static bool Is(
const ValueType& v) {
return v.IsString(); }
612 static StringType Get(
const ValueType& v) {
return StringType(v.GetString(), v.GetStringLength()); }
613 static ValueType& Set(ValueType& v,
const StringType& data,
typename ValueType::AllocatorType& a) {
return v.SetString(data, a); }
617template<
typename ValueType>
619 typedef typename ValueType::Array ArrayType;
620 static bool Is(
const ValueType& v) {
return v.IsArray(); }
621 static ArrayType Get(ValueType& v) {
return v.GetArray(); }
622 static ValueType& Set(ValueType& v, ArrayType data) {
return v = data; }
623 static ValueType& Set(ValueType& v, ArrayType data,
typename ValueType::AllocatorType&) {
return v = data; }
626template<
typename ValueType>
627struct TypeHelper<ValueType, typename ValueType::ConstArray> {
628 typedef typename ValueType::ConstArray ArrayType;
629 static bool Is(
const ValueType& v) {
return v.IsArray(); }
630 static ArrayType Get(
const ValueType& v) {
return v.GetArray(); }
633template<
typename ValueType>
635 typedef typename ValueType::Object ObjectType;
636 static bool Is(
const ValueType& v) {
return v.IsObject(); }
637 static ObjectType Get(ValueType& v) {
return v.GetObject(); }
638 static ValueType& Set(ValueType& v, ObjectType data) {
return v = data; }
639 static ValueType& Set(ValueType& v, ObjectType data,
typename ValueType::AllocatorType&) {
return v = data; }
642template<
typename ValueType>
643struct TypeHelper<ValueType, typename ValueType::ConstObject> {
644 typedef typename ValueType::ConstObject ObjectType;
645 static bool Is(
const ValueType& v) {
return v.IsObject(); }
646 static ObjectType Get(
const ValueType& v) {
return v.GetObject(); }
668template <
typename Encoding,
typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
675 typedef typename Encoding::Ch
Ch;
691 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
693#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
696 rhs.data_.f.flags = kNullFlag;
704#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
706 template <
typename StackAllocator>
707 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
710 template <
typename StackAllocator>
722 static const uint16_t defaultFlags[] = {
723 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
727 data_.f.flags = defaultFlags[type];
731 data_.ss.SetLength(0);
742 template <
typename SourceAllocator>
744 switch (rhs.GetType()) {
746 DoCopyMembers(rhs, allocator, copyConstStrings);
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
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;
886 switch(data_.f.flags) {
892 if (Allocator::kNeedFree) {
902 case kCopyStringFlag:
903 if (Allocator::kNeedFree) {
904 Allocator::Free(
const_cast<Ch*
>(GetStringPointer()));
935#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
938 return *
this = rhs.Move();
964 template <
typename T>
978 template <
typename SourceAllocator>
980 RAPIDJSON_ASSERT(
static_cast<void*
>(
this) !=
static_cast<void const*
>(&rhs));
982 new (
this)
GenericValue(rhs, allocator, copyConstStrings);
995 other.RawAssign(temp);
1015 GenericValue& Move() RAPIDJSON_NOEXCEPT {
return *
this; }
1025 template <
typename SourceAllocator>
1028 if (GetType() != rhs.GetType())
1031 switch (GetType()) {
1033 if (data_.o.size != rhs.data_.o.size)
1035 for (
ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1036 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1037 if (rhsMemberItr == rhs.MemberEnd() || (!(lhsMemberItr->value == rhsMemberItr->value)))
1043 if (data_.a.size != rhs.data_.a.size)
1045 for (
SizeType i = 0; i < data_.a.size; i++)
1046 if (!((*
this)[i] == rhs[i]))
1051 return StringEqual(rhs);
1054 if (IsDouble() || rhs.IsDouble()) {
1055 double a = GetDouble();
1056 double b = rhs.GetDouble();
1057 return a >= b && a <= b;
1060 return data_.n.u64 == rhs.data_.n.u64;
1070#if RAPIDJSON_HAS_STDSTRING
1074 bool operator==(
const std::basic_string<Ch>& rhs)
const {
return *
this ==
GenericValue(
StringRef(rhs)); }
1080 template <
typename T>
RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (
bool)) operator==(
const T& rhs)
const {
return *
this ==
GenericValue(rhs); }
1082#ifndef __cpp_impl_three_way_comparison
1086 template <
typename SourceAllocator>
1090 bool operator!=(
const Ch* rhs)
const {
return !(*
this == rhs); }
1095 template <
typename T>
RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (
bool)) operator!=(
const T& rhs)
const {
return !(*
this == rhs); }
1112 Type GetType()
const {
return static_cast<Type>(data_.f.flags & kTypeMask); }
1113 bool IsNull()
const {
return data_.f.flags == kNullFlag; }
1114 bool IsFalse()
const {
return data_.f.flags == kFalseFlag; }
1115 bool IsTrue()
const {
return data_.f.flags == kTrueFlag; }
1116 bool IsBool()
const {
return (data_.f.flags & kBoolFlag) != 0; }
1117 bool IsObject()
const {
return data_.f.flags == kObjectFlag; }
1118 bool IsArray()
const {
return data_.f.flags == kArrayFlag; }
1119 bool IsNumber()
const {
return (data_.f.flags & kNumberFlag) != 0; }
1120 bool IsInt()
const {
return (data_.f.flags & kIntFlag) != 0; }
1121 bool IsUint()
const {
return (data_.f.flags & kUintFlag) != 0; }
1122 bool IsInt64()
const {
return (data_.f.flags & kInt64Flag) != 0; }
1123 bool IsUint64()
const {
return (data_.f.flags & kUint64Flag) != 0; }
1124 bool IsDouble()
const {
return (data_.f.flags & kDoubleFlag) != 0; }
1125 bool IsString()
const {
return (data_.f.flags & kStringFlag) != 0; }
1128 bool IsLosslessDouble()
const {
1129 if (!IsNumber())
return false;
1131 uint64_t u = GetUint64();
1132 volatile double d =
static_cast<double>(u);
1134 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1135 && (u ==
static_cast<uint64_t
>(d));
1138 int64_t i = GetInt64();
1139 volatile double d =
static_cast<double>(i);
1140 return (d >=
static_cast<double>((std::numeric_limits<int64_t>::min)()))
1141 && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1142 && (i ==
static_cast<int64_t
>(d));
1148 bool IsFloat()
const {
1149 if ((data_.f.flags & kDoubleFlag) == 0)
1151 double d = GetDouble();
1152 return d >= -3.4028234e38 && d <= 3.4028234e38;
1155 bool IsLosslessFloat()
const {
1156 if (!IsNumber())
return false;
1157 double a = GetDouble();
1158 if (a <
static_cast<double>(-(std::numeric_limits<float>::max)())
1159 || a >
static_cast<double>((std::numeric_limits<float>::max)()))
1161 double b =
static_cast<double>(
static_cast<float>(a));
1162 return a >= b && a <= b;
1177 bool GetBool()
const {
RAPIDJSON_ASSERT(IsBool());
return data_.f.flags == kTrueFlag; }
1198 bool ObjectEmpty()
const {
RAPIDJSON_ASSERT(IsObject());
return data_.o.size == 0; }
1209 template <
typename T>
1214 template <
typename T>
1226 template <
typename SourceAllocator>
1229 if (member != MemberEnd())
1230 return member->value;
1234#if RAPIDJSON_HAS_CXX11
1240#elif defined(_MSC_VER) && _MSC_VER < 1900
1243 __declspec(thread)
static char buffer[
sizeof(
GenericValue)];
1245#elif defined(__GNUC__) || defined(__clang__)
1258 template <
typename SourceAllocator>
1261#if RAPIDJSON_HAS_STDSTRING
1288 DoReserveMembers(newCapacity, allocator);
1300 bool HasMember(
const Ch* name)
const {
return FindMember(name) != MemberEnd(); }
1302#if RAPIDJSON_HAS_STDSTRING
1311 bool HasMember(
const std::basic_string<Ch>& name)
const {
return FindMember(name) != MemberEnd(); }
1323 template <
typename SourceAllocator>
1340 return FindMember(n);
1358 template <
typename SourceAllocator>
1362 return DoFindMember(name);
1366#if RAPIDJSON_HAS_STDSTRING
1391 DoAddMember(name, value, allocator);
1406 return AddMember(name, v, allocator);
1409#if RAPIDJSON_HAS_STDSTRING
1421 return AddMember(name, v, allocator);
1442 template <
typename T>
1444 AddMember(
GenericValue& name, T value, Allocator& allocator) {
1446 return AddMember(name, v, allocator);
1449#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1451 return AddMember(name, value, allocator);
1454 return AddMember(name, value, allocator);
1457 return AddMember(name, value, allocator);
1461 return AddMember(n, value, allocator);
1478 return AddMember(n, value, allocator);
1492 return AddMember(name, v, allocator);
1512 template <
typename T>
1514 AddMember(
StringRefType name, T value, Allocator& allocator) {
1516 return AddMember(n, value, allocator);
1523 void RemoveAllMembers() {
1536 bool RemoveMember(
const Ch* name) {
1538 return RemoveMember(n);
1541#if RAPIDJSON_HAS_STDSTRING
1542 bool RemoveMember(
const std::basic_string<Ch>& name) {
return RemoveMember(
GenericValue(
StringRef(name))); }
1545 template <
typename SourceAllocator>
1548 if (m != MemberEnd()) {
1569 return DoRemoveMember(m);
1582 return EraseMember(pos, pos +1);
1601 return DoEraseMembers(first, last);
1609 bool EraseMember(
const Ch* name) {
1611 return EraseMember(n);
1614#if RAPIDJSON_HAS_STDSTRING
1615 bool EraseMember(
const std::basic_string<Ch>& name) {
return EraseMember(
GenericValue(
StringRef(name))); }
1618 template <
typename SourceAllocator>
1621 if (m != MemberEnd()) {
1631 ConstObject GetObject()
const {
RAPIDJSON_ASSERT(IsObject());
return ConstObject(*
this); }
1632 ConstObject GetObj()
const {
RAPIDJSON_ASSERT(IsObject());
return ConstObject(*
this); }
1650 bool Empty()
const {
RAPIDJSON_ASSERT(IsArray());
return data_.a.size == 0; }
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);
1738 return (*this).template PushBack<StringRefType>(value, allocator);
1758 template <
typename T>
1760 PushBack(T value, Allocator& allocator) {
1762 return PushBack(v, allocator);
1772 GetElementsPointer()[--data_.a.size].~GenericValue();
1784 return Erase(pos, pos + 1);
1804 itr->~GenericValue();
1805 std::memmove(
static_cast<void*
>(pos), last,
static_cast<size_t>(End() - last) *
sizeof(
GenericValue));
1806 data_.a.size -=
static_cast<SizeType>(last - first);
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; }
1826 double GetDouble()
const {
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);
1838 float GetFloat()
const {
1839 return static_cast<float>(GetDouble());
1854 const Ch* GetString()
const {
RAPIDJSON_ASSERT(IsString());
return DataString(data_); }
1904#if RAPIDJSON_HAS_STDSTRING
1912 GenericValue& SetString(
const std::basic_string<Ch>& s, Allocator& allocator) {
return SetString(
StringRef(s), allocator); }
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>
1949 bool Accept(Handler& handler)
const {
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;
1990 template <
typename,
typename,
typename>
friend class GenericDocument;
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];
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 static RAPIDJSON_FORCEINLINE
const Ch* DataString(
const Data& data) {
2109 return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(
Ch, data.s.str);
2111 static RAPIDJSON_FORCEINLINE
SizeType DataStringLength(
const Data& data) {
2112 return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2115 RAPIDJSON_FORCEINLINE
const Ch* GetStringPointer()
const {
return RAPIDJSON_GETPOINTER(
Ch, data_.s.str); }
2116 RAPIDJSON_FORCEINLINE
const Ch* SetStringPointer(
const Ch* str) {
return RAPIDJSON_SETPOINTER(
Ch, data_.s.str, str); }
2117 RAPIDJSON_FORCEINLINE
GenericValue* GetElementsPointer()
const {
return RAPIDJSON_GETPOINTER(
GenericValue, data_.a.elements); }
2119 RAPIDJSON_FORCEINLINE
Member* GetMembersPointer()
const {
return RAPIDJSON_GETPOINTER(
Member, data_.o.members); }
2120 RAPIDJSON_FORCEINLINE
Member* SetMembersPointer(
Member* members) {
return RAPIDJSON_SETPOINTER(
Member, data_.o.members, members); }
2122#if RAPIDJSON_USE_MEMBERSMAP
2126 bool operator()(
const Data& s1,
const Data& s2)
const {
2127 SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
2128 int cmp = std::memcmp(DataString(s1), DataString(s2),
sizeof(Ch) * (n1 < n2 ? n1 : n2));
2129 return cmp < 0 || (cmp == 0 && n1 < n2);
2132 typedef std::pair<const Data, SizeType> Pair;
2133 typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
2134 typedef typename Map::iterator Iterator;
2136 typedef typename MapTraits::Map Map;
2137 typedef typename MapTraits::Less MapLess;
2138 typedef typename MapTraits::Pair MapPair;
2139 typedef typename MapTraits::Iterator MapIterator;
2149 static RAPIDJSON_FORCEINLINE
size_t GetMapLayoutSize(
SizeType capacity) {
2153 capacity *
sizeof(MapIterator);
2156 static RAPIDJSON_FORCEINLINE
SizeType &GetMapCapacity(Map* &map) {
2157 return *
reinterpret_cast<SizeType*
>(
reinterpret_cast<uintptr_t
>(&map) +
2161 static RAPIDJSON_FORCEINLINE
Member* GetMapMembers(Map* &map) {
2162 return reinterpret_cast<Member*
>(
reinterpret_cast<uintptr_t
>(&map) +
2167 static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
2168 return reinterpret_cast<MapIterator*
>(
reinterpret_cast<uintptr_t
>(&map) +
2174 static RAPIDJSON_FORCEINLINE Map* &GetMap(
Member* members) {
2176 return *
reinterpret_cast<Map**
>(
reinterpret_cast<uintptr_t
>(members) -
2182 RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
2183#if RAPIDJSON_HAS_CXX11
2184 MapIterator ret = std::move(rhs);
2186 MapIterator ret = rhs;
2192 Map* &DoReallocMap(Map** oldMap,
SizeType newCapacity, Allocator& allocator) {
2193 Map **newMap =
static_cast<Map**
>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
2194 GetMapCapacity(*newMap) = newCapacity;
2196 *newMap =
new (allocator.Malloc(
sizeof(Map))) Map(MapLess(), allocator);
2200 size_t count = (*oldMap)->size();
2201 std::memcpy(
static_cast<void*
>(GetMapMembers(*newMap)),
2202 static_cast<void*
>(GetMapMembers(*oldMap)),
2204 MapIterator *oldIt = GetMapIterators(*oldMap),
2205 *newIt = GetMapIterators(*newMap);
2207 new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
2209 Allocator::Free(oldMap);
2214 RAPIDJSON_FORCEINLINE
Member* DoAllocMembers(
SizeType capacity, Allocator& allocator) {
2215 return GetMapMembers(DoReallocMap(0, capacity, allocator));
2218 void DoReserveMembers(
SizeType newCapacity, Allocator& allocator) {
2220 if (newCapacity > o.capacity) {
2221 Member* oldMembers = GetMembersPointer();
2222 Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
2223 *&newMap = DoReallocMap(oldMap, newCapacity, allocator);
2224 RAPIDJSON_SETPOINTER(
Member, o.members, GetMapMembers(newMap));
2225 o.capacity = newCapacity;
2229 template <
typename SourceAllocator>
2231 if (
Member* members = GetMembersPointer()) {
2232 Map* &map = GetMap(members);
2233 MapIterator mit = map->find(
reinterpret_cast<const Data&
>(name.data_));
2234 if (mit != map->end()) {
2241 void DoClearMembers() {
2242 if (
Member* members = GetMembersPointer()) {
2243 Map* &map = GetMap(members);
2244 MapIterator* mit = GetMapIterators(map);
2245 for (
SizeType i = 0; i < data_.o.size; i++) {
2246 map->erase(DropMapIterator(mit[i]));
2247 members[i].~Member();
2253 void DoFreeMembers() {
2254 if (
Member* members = GetMembersPointer()) {
2255 GetMap(members)->~Map();
2256 for (
SizeType i = 0; i < data_.o.size; i++) {
2257 members[i].~Member();
2259 if (Allocator::kNeedFree) {
2260 Map** map = &GetMap(members);
2261 Allocator::Free(*map);
2262 Allocator::Free(map);
2269 RAPIDJSON_FORCEINLINE
Member* DoAllocMembers(
SizeType capacity, Allocator& allocator) {
2270 return Malloc<Member>(allocator, capacity);
2273 void DoReserveMembers(
SizeType newCapacity, Allocator& allocator) {
2275 if (newCapacity > o.capacity) {
2276 Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2277 RAPIDJSON_SETPOINTER(
Member, o.members, newMembers);
2278 o.capacity = newCapacity;
2282 template <
typename SourceAllocator>
2285 for ( ; member != MemberEnd(); ++member)
2286 if (name.StringEqual(member->name))
2291 void DoClearMembers() {
2297 void DoFreeMembers() {
2300 Allocator::Free(GetMembersPointer());
2307 if (o.size >= o.capacity)
2308 DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
2309 Member* members = GetMembersPointer();
2310 Member* m = members + o.size;
2311 m->name.RawAssign(name);
2312 m->value.RawAssign(value);
2313#if RAPIDJSON_USE_MEMBERSMAP
2314 Map* &map = GetMap(members);
2315 MapIterator* mit = GetMapIterators(map);
2316 new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
2323 Member* members = GetMembersPointer();
2324#if RAPIDJSON_USE_MEMBERSMAP
2325 Map* &map = GetMap(members);
2326 MapIterator* mit = GetMapIterators(map);
2328 map->erase(DropMapIterator(mit[mpos]));
2331 if (o.size > 1 && m != last) {
2332#if RAPIDJSON_USE_MEMBERSMAP
2333 new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
2334 mit[mpos]->second = mpos;
2348 pos = beg + (first - beg),
2350#if RAPIDJSON_USE_MEMBERSMAP
2351 Map* &map = GetMap(GetMembersPointer());
2352 MapIterator* mit = GetMapIterators(map);
2355#if RAPIDJSON_USE_MEMBERSMAP
2356 map->erase(DropMapIterator(mit[itr - beg]));
2360#if RAPIDJSON_USE_MEMBERSMAP
2361 if (first != last) {
2365 std::memcpy(
static_cast<void*
>(&*itr), &*next,
sizeof(
Member));
2367 new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
2368 mit[mpos]->second = mpos;
2372 std::memmove(
static_cast<void*
>(&*pos), &*last,
2373 static_cast<size_t>(end - last) *
sizeof(
Member));
2375 o.size -=
static_cast<SizeType>(last - first);
2379 template <
typename SourceAllocator>
2383 data_.f.flags = kObjectFlag;
2385 Member* lm = DoAllocMembers(count, allocator);
2387#if RAPIDJSON_USE_MEMBERSMAP
2388 Map* &map = GetMap(lm);
2389 MapIterator* mit = GetMapIterators(map);
2391 for (
SizeType i = 0; i < count; i++) {
2392 new (&lm[i].name)
GenericValue(rm[i].name, allocator, copyConstStrings);
2393 new (&lm[i].value)
GenericValue(rm[i].value, allocator, copyConstStrings);
2394#if RAPIDJSON_USE_MEMBERSMAP
2395 new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
2398 data_.o.size = data_.o.capacity = count;
2399 SetMembersPointer(lm);
2404 data_.f.flags = kArrayFlag;
2407 SetElementsPointer(e);
2408 std::memcpy(
static_cast<void*
>(e), values, count *
sizeof(
GenericValue));
2411 SetElementsPointer(0);
2412 data_.a.size = data_.a.capacity = count;
2417 data_.f.flags = kObjectFlag;
2419 Member* m = DoAllocMembers(count, allocator);
2420 SetMembersPointer(m);
2421 std::memcpy(
static_cast<void*
>(m), members, count *
sizeof(
Member));
2422#if RAPIDJSON_USE_MEMBERSMAP
2423 Map* &map = GetMap(m);
2424 MapIterator* mit = GetMapIterators(map);
2425 for (
SizeType i = 0; i < count; i++) {
2426 new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
2431 SetMembersPointer(0);
2432 data_.o.size = data_.o.capacity = count;
2437 data_.f.flags = kConstStringFlag;
2438 SetStringPointer(s);
2439 data_.s.length = s.length;
2445 if (ShortString::Usable(s.
length)) {
2446 data_.f.flags = kShortStringFlag;
2447 data_.ss.SetLength(s.
length);
2449 std::memmove(str, s, s.
length *
sizeof(
Ch));
2451 data_.f.flags = kCopyStringFlag;
2452 data_.s.length = s.
length;
2453 str =
static_cast<Ch *
>(allocator.Malloc((s.
length + 1) *
sizeof(
Ch)));
2454 SetStringPointer(str);
2455 std::memcpy(str, s, s.
length *
sizeof(
Ch));
2464 rhs.data_.f.flags = kNullFlag;
2467 template <
typename SourceAllocator>
2472 const SizeType len1 = GetStringLength();
2473 const SizeType len2 = rhs.GetStringLength();
2474 if(len1 != len2) {
return false; }
2476 const Ch*
const str1 = GetString();
2477 const Ch*
const str2 = rhs.GetString();
2478 if(str1 == str2) {
return true; }
2480 return (std::memcmp(str1, str2,
sizeof(
Ch) * len1) == 0);
2500template <
typename Encoding,
typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR,
typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2503 typedef typename Encoding::Ch
Ch;
2516 GenericValue<
Encoding,
Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2529 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2535#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2538 :
ValueType(std::forward<ValueType>(rhs)),
2539 allocator_(rhs.allocator_),
2540 ownAllocator_(rhs.ownAllocator_),
2541 stack_(std::move(rhs.stack_)),
2542 parseResult_(rhs.parseResult_)
2545 rhs.ownAllocator_ = 0;
2555 if (ownAllocator_) {
2556 ValueType::SetNull();
2561#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2572 allocator_ = rhs.allocator_;
2573 ownAllocator_ = rhs.ownAllocator_;
2574 stack_ = std::move(rhs.stack_);
2575 parseResult_ = rhs.parseResult_;
2578 rhs.ownAllocator_ = 0;
2579 rhs.parseResult_ = ParseResult();
2592 ValueType::Swap(rhs);
2593 stack_.Swap(rhs.stack_);
2594 internal::Swap(allocator_, rhs.allocator_);
2595 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2596 internal::Swap(parseResult_, rhs.parseResult_);
2602 using ValueType::Swap;
2623 template <
typename Generator>
2625 ClearStackOnExit scope(*
this);
2643 template <
unsigned parseFlags,
typename SourceEncoding,
typename InputStream>
2646 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2647 ClearStackOnExit scope(*
this);
2662 template <
unsigned parseFlags,
typename InputStream>
2672 template <
typename InputStream>
2686 template <
unsigned parseFlags>
2709 template <
unsigned parseFlags,
typename SourceEncoding>
2720 template <
unsigned parseFlags>
2732 template <
unsigned parseFlags,
typename SourceEncoding>
2735 MemoryStream ms(
reinterpret_cast<const char*
>(str), length *
sizeof(
typename SourceEncoding::Ch));
2741 template <
unsigned parseFlags>
2750#if RAPIDJSON_HAS_STDSTRING
2751 template <
unsigned parseFlags,
typename SourceEncoding>
2757 template <
unsigned parseFlags>
2807 struct ClearStackOnExit {
2809 ~ClearStackOnExit() { d_.ClearStack(); }
2811 ClearStackOnExit(
const ClearStackOnExit&);
2812 ClearStackOnExit& operator=(
const ClearStackOnExit&);
2818 template <
typename,
typename>
friend class GenericValue;
2822 bool Null() {
new (stack_.template Push<ValueType>())
ValueType();
return true; }
2823 bool Bool(
bool b) {
new (stack_.template Push<ValueType>())
ValueType(b);
return true; }
2824 bool Int(
int i) {
new (stack_.template Push<ValueType>())
ValueType(i);
return true; }
2825 bool Uint(
unsigned i) {
new (stack_.template Push<ValueType>())
ValueType(i);
return true; }
2826 bool Int64(int64_t i) {
new (stack_.template Push<ValueType>())
ValueType(i);
return true; }
2827 bool Uint64(uint64_t i) {
new (stack_.template Push<ValueType>())
ValueType(i);
return true; }
2828 bool Double(
double d) {
new (stack_.template Push<ValueType>())
ValueType(d);
return true; }
2830 bool RawNumber(
const Ch* str,
SizeType length,
bool copy) {
2834 new (stack_.template Push<ValueType>())
ValueType(str, length);
2838 bool String(
const Ch* str,
SizeType length,
bool copy) {
2842 new (stack_.template Push<ValueType>())
ValueType(str, length);
2846 bool StartObject() {
new (stack_.template Push<ValueType>())
ValueType(
kObjectType);
return true; }
2848 bool Key(
const Ch* str,
SizeType length,
bool copy) {
return String(str, length, copy); }
2850 bool EndObject(
SizeType memberCount) {
2851 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2852 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount,
GetAllocator());
2856 bool StartArray() {
new (stack_.template Push<ValueType>())
ValueType(
kArrayType);
return true; }
2858 bool EndArray(
SizeType elementCount) {
2859 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2860 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount,
GetAllocator());
2871 if (Allocator::kNeedFree)
2872 while (stack_.GetSize() > 0)
2873 (stack_.template Pop<ValueType>(1))->~
ValueType();
2876 stack_.ShrinkToFit();
2883 static const size_t kDefaultStackCapacity = 1024;
2884 Allocator* allocator_;
2885 Allocator* ownAllocator_;
2886 internal::Stack<StackAllocator> stack_;
2887 ParseResult parseResult_;
2899template <
bool Const,
typename ValueT>
2902 typedef GenericArray<true, ValueT> ConstArray;
2903 typedef GenericArray<false, ValueT> Array;
2904 typedef ValueT PlainType;
2905 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2906 typedef ValueType* ValueIterator;
2907 typedef const ValueT* ConstValueIterator;
2908 typedef typename ValueType::AllocatorType AllocatorType;
2909 typedef typename ValueType::StringRefType StringRefType;
2911 template <
typename,
typename>
2912 friend class GenericValue;
2914 GenericArray(
const GenericArray& rhs) : value_(rhs.value_) {}
2915 GenericArray& operator=(
const GenericArray& rhs) { value_ = rhs.value_;
return *
this; }
2918 operator ValueType&()
const {
return value_; }
2919 SizeType Size()
const {
return value_.Size(); }
2920 SizeType Capacity()
const {
return value_.Capacity(); }
2921 bool Empty()
const {
return value_.Empty(); }
2922 void Clear()
const { value_.Clear(); }
2923 ValueType& operator[](
SizeType index)
const {
return value_[index]; }
2924 ValueIterator Begin()
const {
return value_.Begin(); }
2925 ValueIterator End()
const {
return value_.End(); }
2926 GenericArray Reserve(
SizeType newCapacity, AllocatorType &allocator)
const { value_.Reserve(newCapacity, allocator);
return *
this; }
2927 GenericArray PushBack(ValueType& value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2928#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2929 GenericArray PushBack(ValueType&& value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2931 GenericArray PushBack(StringRefType value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2932 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,
internal::IsGenericValue<T> >), (
const GenericArray&)) PushBack(T value, AllocatorType& allocator)
const { value_.PushBack(value, allocator);
return *
this; }
2933 GenericArray PopBack()
const { value_.PopBack();
return *
this; }
2934 ValueIterator Erase(ConstValueIterator pos)
const {
return value_.Erase(pos); }
2935 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)
const {
return value_.Erase(first, last); }
2937#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2938 ValueIterator begin()
const {
return value_.Begin(); }
2939 ValueIterator end()
const {
return value_.End(); }
2944 GenericArray(ValueType& value) : value_(value) {}
2953template <
bool Const,
typename ValueT>
2954class GenericObject {
2956 typedef GenericObject<true, ValueT> ConstObject;
2957 typedef GenericObject<false, ValueT> Object;
2958 typedef ValueT PlainType;
2959 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2962 typedef typename ValueType::AllocatorType AllocatorType;
2963 typedef typename ValueType::StringRefType StringRefType;
2964 typedef typename ValueType::EncodingType EncodingType;
2965 typedef typename ValueType::Ch Ch;
2967 template <
typename,
typename>
2968 friend class GenericValue;
2970 GenericObject(
const GenericObject& rhs) : value_(rhs.value_) {}
2971 GenericObject& operator=(
const GenericObject& rhs) { value_ = rhs.value_;
return *
this; }
2974 operator ValueType&()
const {
return value_; }
2975 SizeType MemberCount()
const {
return value_.MemberCount(); }
2976 SizeType MemberCapacity()
const {
return value_.MemberCapacity(); }
2977 bool ObjectEmpty()
const {
return value_.ObjectEmpty(); }
2978 template <
typename T> ValueType& operator[](T* name)
const {
return value_[name]; }
2979 template <
typename SourceAllocator> ValueType& operator[](
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_[name]; }
2980#if RAPIDJSON_HAS_STDSTRING
2981 ValueType& operator[](
const std::basic_string<Ch>& name)
const {
return value_[name]; }
2983 MemberIterator MemberBegin()
const {
return value_.MemberBegin(); }
2984 MemberIterator MemberEnd()
const {
return value_.MemberEnd(); }
2985 GenericObject MemberReserve(
SizeType newCapacity, AllocatorType &allocator)
const { value_.MemberReserve(newCapacity, allocator);
return *
this; }
2986 bool HasMember(
const Ch* name)
const {
return value_.HasMember(name); }
2987#if RAPIDJSON_HAS_STDSTRING
2988 bool HasMember(
const std::basic_string<Ch>& name)
const {
return value_.HasMember(name); }
2990 template <
typename SourceAllocator>
bool HasMember(
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_.HasMember(name); }
2991 MemberIterator FindMember(
const Ch* name)
const {
return value_.FindMember(name); }
2992 template <
typename SourceAllocator> MemberIterator FindMember(
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_.FindMember(name); }
2993#if RAPIDJSON_HAS_STDSTRING
2994 MemberIterator FindMember(
const std::basic_string<Ch>& name)
const {
return value_.FindMember(name); }
2996 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2997 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
2998#if RAPIDJSON_HAS_STDSTRING
2999 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3001 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,
internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3002#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3003 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3004 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3005 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3006 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3008 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3009 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3010 template <
typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,
internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator)
const { value_.AddMember(name, value, allocator);
return *
this; }
3011 void RemoveAllMembers() { value_.RemoveAllMembers(); }
3012 bool RemoveMember(
const Ch* name)
const {
return value_.RemoveMember(name); }
3013#if RAPIDJSON_HAS_STDSTRING
3014 bool RemoveMember(
const std::basic_string<Ch>& name)
const {
return value_.RemoveMember(name); }
3016 template <
typename SourceAllocator>
bool RemoveMember(
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_.RemoveMember(name); }
3017 MemberIterator RemoveMember(MemberIterator m)
const {
return value_.RemoveMember(m); }
3018 MemberIterator EraseMember(ConstMemberIterator pos)
const {
return value_.EraseMember(pos); }
3019 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last)
const {
return value_.EraseMember(first, last); }
3020 bool EraseMember(
const Ch* name)
const {
return value_.EraseMember(name); }
3021#if RAPIDJSON_HAS_STDSTRING
3022 bool EraseMember(
const std::basic_string<Ch>& name)
const {
return EraseMember(ValueType(
StringRef(name))); }
3024 template <
typename SourceAllocator>
bool EraseMember(
const GenericValue<EncodingType, SourceAllocator>& name)
const {
return value_.EraseMember(name); }
3026#if RAPIDJSON_HAS_CXX11_RANGE_FOR
3027 MemberIterator begin()
const {
return value_.MemberBegin(); }
3028 MemberIterator end()
const {
return value_.MemberEnd(); }
3033 GenericObject(ValueType& value) : value_(value) {}
3040#ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3041#pragma pop_macro("GetObject")
3042#undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
Helper class for accessing Value of array type.
A document for parsing JSON text as DOM.
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Allocator & GetAllocator()
Get the allocator of this document.
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Allocator AllocatorType
Allocator type from template parameter.
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
StackAllocator StackAllocatorType
StackAllocator type from template parameter.
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
GenericDocument(const GenericDocument &)
Prohibit copying.
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Encoding::Ch Ch
Character type derived from Encoding.
GenericDocument & operator=(const GenericDocument &)
Prohibit assignment.
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
GenericMemberIterator()
Default constructor (singular value)
GenericMemberIterator(Pointer p)
Internal constructor from plain pointer.
difference_type DifferenceType
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
GenericMemberIterator Iterator
Iterator type itself.
DifferenceType operator-(ConstIterator that) const
Distance.
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Name-value pair in a JSON object value.
GenericValue< Encoding, Allocator > name
name of member (must be a string)
GenericValue< Encoding, Allocator > value
value of member.
GenericMember(const GenericMember &rhs)
Copy constructor is not permitted.
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Helper class for accessing Value of object type.
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
~GenericValue()
Destructor.
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Encoding EncodingType
Encoding type from template parameter.
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
GenericStringRef< Ch > StringRefType
Reference to a constant string.
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator)
Allocator AllocatorType
Allocator type from template parameter.
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
GenericValue(const GenericValue &rhs)
Copy constructor is not permitted.
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Encoding::Ch Ch
Character type derived from Encoding.
GenericValue * ValueIterator
Value iterator for iterating in array.
Concept for allocating, resizing and freeing memory block.
Concept for encoding of Unicode characters.
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
#define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
User defined kDefaultArrayCapacity value.
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
#define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
User defined kDefaultObjectCapacity value.
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
#define RAPIDJSON_USE_MEMBERSMAP
Enable RapidJSON support for object members handling in a std::multimap.
#define RAPIDJSON_ASSERT(x)
Assertion.
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
ParseErrorCode
Error code of parsing.
void swap(UniqueArray< T > &v1, UniqueArray< T > &v2)
Échange les valeurs de v1 et v2.
#define RAPIDJSON_DELETE(x)
! customization point for global delete
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
@ kParseInsituFlag
In-situ(destructive) parsing.
A read-write string stream.
Reference to a constant string (not taking a copy)
GenericStringRef & operator=(const GenericStringRef &rhs)
Copy assignment operator not permitted - immutable type.
CharType Ch
character type of the string
static const Ch emptyString[]
const SizeType length
length of the string (excluding the trailing NULL terminator)
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
GenericStringRef(CharType(&str)[N])
Disallow construction from non-const array.
const Ch *const s
plain CharType pointer
SizeType hashcode
reserved
Represents an in-memory input byte stream.
Result of parsing (wraps ParseErrorCode)