File indexing completed on 2025-01-18 10:10:03
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef RAPIDJSON_DOCUMENT_H_
0016 #define RAPIDJSON_DOCUMENT_H_
0017
0018
0019
0020 #include "reader.h"
0021 #include "internal/meta.h"
0022 #include "internal/strfunc.h"
0023 #include "memorystream.h"
0024 #include "encodedstream.h"
0025 #include <new> // placement new
0026 #include <limits>
0027 #ifdef __cpp_lib_three_way_comparison
0028 #include <compare>
0029 #endif
0030
0031 RAPIDJSON_DIAG_PUSH
0032 #ifdef __clang__
0033 RAPIDJSON_DIAG_OFF(padded)
0034 RAPIDJSON_DIAG_OFF(switch-enum)
0035 RAPIDJSON_DIAG_OFF(c++98-compat)
0036 #elif defined(_MSC_VER)
0037 RAPIDJSON_DIAG_OFF(4127)
0038 RAPIDJSON_DIAG_OFF(4244)
0039 #endif
0040
0041 #ifdef __GNUC__
0042 RAPIDJSON_DIAG_OFF(effc++)
0043 #endif
0044
0045 #ifdef GetObject
0046
0047
0048
0049 #pragma push_macro("GetObject")
0050 #define RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
0051 #undef GetObject
0052 #endif
0053
0054 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
0055 #include <iterator> // std::random_access_iterator_tag
0056 #endif
0057
0058 #if RAPIDJSON_USE_MEMBERSMAP
0059 #include <map> // std::multimap
0060 #endif
0061
0062 RAPIDJSON_NAMESPACE_BEGIN
0063
0064
0065 template <typename Encoding, typename Allocator>
0066 class GenericValue;
0067
0068 template <typename Encoding, typename Allocator, typename StackAllocator>
0069 class GenericDocument;
0070
0071
0072
0073
0074
0075
0076
0077 #ifndef RAPIDJSON_DEFAULT_ALLOCATOR
0078 #define RAPIDJSON_DEFAULT_ALLOCATOR ::RAPIDJSON_NAMESPACE::MemoryPoolAllocator<::RAPIDJSON_NAMESPACE::CrtAllocator>
0079 #endif
0080
0081
0082
0083
0084
0085
0086
0087 #ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
0088 #define RAPIDJSON_DEFAULT_STACK_ALLOCATOR ::RAPIDJSON_NAMESPACE::CrtAllocator
0089 #endif
0090
0091
0092
0093
0094
0095
0096
0097 #ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
0098
0099 #define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
0100 #endif
0101
0102
0103
0104
0105
0106
0107
0108 #ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
0109
0110 #define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
0111 #endif
0112
0113
0114
0115
0116
0117
0118
0119 template <typename Encoding, typename Allocator>
0120 class GenericMember {
0121 public:
0122 GenericValue<Encoding, Allocator> name;
0123 GenericValue<Encoding, Allocator> value;
0124
0125 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
0126
0127 GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
0128 : name(std::move(rhs.name)),
0129 value(std::move(rhs.value))
0130 {
0131 }
0132
0133
0134 GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
0135 return *this = static_cast<GenericMember&>(rhs);
0136 }
0137 #endif
0138
0139
0140
0141
0142 GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
0143 if (RAPIDJSON_LIKELY(this != &rhs)) {
0144 name = rhs.name;
0145 value = rhs.value;
0146 }
0147 return *this;
0148 }
0149
0150
0151 friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
0152 a.name.Swap(b.name);
0153 a.value.Swap(b.value);
0154 }
0155
0156 private:
0157
0158 GenericMember(const GenericMember& rhs);
0159 };
0160
0161
0162
0163
0164 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185 template <bool Const, typename Encoding, typename Allocator>
0186 class GenericMemberIterator {
0187
0188 friend class GenericValue<Encoding,Allocator>;
0189 template <bool, typename, typename> friend class GenericMemberIterator;
0190
0191 typedef GenericMember<Encoding,Allocator> PlainType;
0192 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
0193
0194 public:
0195
0196 typedef GenericMemberIterator Iterator;
0197
0198 typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator;
0199
0200 typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
0201
0202
0203
0204 typedef ValueType value_type;
0205 typedef ValueType * pointer;
0206 typedef ValueType & reference;
0207 typedef std::ptrdiff_t difference_type;
0208 typedef std::random_access_iterator_tag iterator_category;
0209
0210
0211
0212 typedef pointer Pointer;
0213
0214 typedef reference Reference;
0215
0216 typedef difference_type DifferenceType;
0217
0218
0219
0220
0221
0222 GenericMemberIterator() : ptr_() {}
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240 GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
0241 Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
0242
0243
0244
0245 Iterator& operator++(){ ++ptr_; return *this; }
0246 Iterator& operator--(){ --ptr_; return *this; }
0247 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
0248 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
0249
0250
0251
0252
0253 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
0254 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
0255
0256 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
0257 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
0258
0259
0260
0261
0262 template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
0263 template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
0264 template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
0265 template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
0266 template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
0267 template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
0268
0269 #ifdef __cpp_lib_three_way_comparison
0270 template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
0271 #endif
0272
0273
0274
0275
0276 Reference operator*() const { return *ptr_; }
0277 Pointer operator->() const { return ptr_; }
0278 Reference operator[](DifferenceType n) const { return ptr_[n]; }
0279
0280
0281
0282 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
0283
0284 private:
0285
0286 explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
0287
0288 Pointer ptr_;
0289 };
0290
0291 #else
0292
0293
0294
0295 template <bool Const, typename Encoding, typename Allocator>
0296 class GenericMemberIterator;
0297
0298
0299 template <typename Encoding, typename Allocator>
0300 class GenericMemberIterator<false,Encoding,Allocator> {
0301 public:
0302
0303 typedef GenericMember<Encoding,Allocator>* Iterator;
0304 };
0305
0306 template <typename Encoding, typename Allocator>
0307 class GenericMemberIterator<true,Encoding,Allocator> {
0308 public:
0309
0310 typedef const GenericMember<Encoding,Allocator>* Iterator;
0311 };
0312
0313 #endif
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345 template<typename CharType>
0346 struct GenericStringRef {
0347 typedef CharType Ch;
0348
0349
0350 #ifndef __clang__
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373 #endif
0374 template<SizeType N>
0375 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
0376 : s(str), length(N-1) {}
0377
0378
0379 #ifndef __clang__
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 #endif
0399 explicit GenericStringRef(const CharType* str)
0400 : s(str), length(NotNullStrLen(str)) {}
0401
0402
0403 #ifndef __clang__
0404
0405
0406
0407
0408
0409
0410 #endif
0411 GenericStringRef(const CharType* str, SizeType len)
0412 : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
0413
0414 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
0415
0416
0417 operator const Ch *() const { return s; }
0418
0419 const Ch* const s;
0420 const SizeType length;
0421
0422 private:
0423 SizeType NotNullStrLen(const CharType* str) {
0424 RAPIDJSON_ASSERT(str != 0);
0425 return internal::StrLen(str);
0426 }
0427
0428
0429 static const Ch emptyString[];
0430
0431
0432 template<SizeType N>
0433 GenericStringRef(CharType (&str)[N]) ;
0434
0435 GenericStringRef& operator=(const GenericStringRef& rhs) ;
0436 };
0437
0438 template<typename CharType>
0439 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453 template<typename CharType>
0454 inline GenericStringRef<CharType> StringRef(const CharType* str) {
0455 return GenericStringRef<CharType>(str);
0456 }
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472
0473 template<typename CharType>
0474 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
0475 return GenericStringRef<CharType>(str, SizeType(length));
0476 }
0477
0478 #if RAPIDJSON_HAS_STDSTRING
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491 template<typename CharType>
0492 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
0493 return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
0494 }
0495 #endif
0496
0497
0498
0499 namespace internal {
0500
0501 template <typename T, typename Encoding = void, typename Allocator = void>
0502 struct IsGenericValueImpl : FalseType {};
0503
0504
0505 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
0506 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
0507
0508
0509 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
0510
0511 }
0512
0513
0514
0515
0516 namespace internal {
0517
0518 template <typename ValueType, typename T>
0519 struct TypeHelper {};
0520
0521 template<typename ValueType>
0522 struct TypeHelper<ValueType, bool> {
0523 static bool Is(const ValueType& v) { return v.IsBool(); }
0524 static bool Get(const ValueType& v) { return v.GetBool(); }
0525 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
0526 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
0527 };
0528
0529 template<typename ValueType>
0530 struct TypeHelper<ValueType, int> {
0531 static bool Is(const ValueType& v) { return v.IsInt(); }
0532 static int Get(const ValueType& v) { return v.GetInt(); }
0533 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
0534 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
0535 };
0536
0537 template<typename ValueType>
0538 struct TypeHelper<ValueType, unsigned> {
0539 static bool Is(const ValueType& v) { return v.IsUint(); }
0540 static unsigned Get(const ValueType& v) { return v.GetUint(); }
0541 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
0542 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
0543 };
0544
0545 #ifdef _MSC_VER
0546 RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
0547 template<typename ValueType>
0548 struct TypeHelper<ValueType, long> {
0549 static bool Is(const ValueType& v) { return v.IsInt(); }
0550 static long Get(const ValueType& v) { return v.GetInt(); }
0551 static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
0552 static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
0553 };
0554
0555 RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
0556 template<typename ValueType>
0557 struct TypeHelper<ValueType, unsigned long> {
0558 static bool Is(const ValueType& v) { return v.IsUint(); }
0559 static unsigned long Get(const ValueType& v) { return v.GetUint(); }
0560 static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
0561 static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
0562 };
0563 #endif
0564
0565 template<typename ValueType>
0566 struct TypeHelper<ValueType, int64_t> {
0567 static bool Is(const ValueType& v) { return v.IsInt64(); }
0568 static int64_t Get(const ValueType& v) { return v.GetInt64(); }
0569 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
0570 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
0571 };
0572
0573 template<typename ValueType>
0574 struct TypeHelper<ValueType, uint64_t> {
0575 static bool Is(const ValueType& v) { return v.IsUint64(); }
0576 static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
0577 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
0578 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
0579 };
0580
0581 template<typename ValueType>
0582 struct TypeHelper<ValueType, double> {
0583 static bool Is(const ValueType& v) { return v.IsDouble(); }
0584 static double Get(const ValueType& v) { return v.GetDouble(); }
0585 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
0586 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
0587 };
0588
0589 template<typename ValueType>
0590 struct TypeHelper<ValueType, float> {
0591 static bool Is(const ValueType& v) { return v.IsFloat(); }
0592 static float Get(const ValueType& v) { return v.GetFloat(); }
0593 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
0594 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
0595 };
0596
0597 template<typename ValueType>
0598 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
0599 typedef const typename ValueType::Ch* StringType;
0600 static bool Is(const ValueType& v) { return v.IsString(); }
0601 static StringType Get(const ValueType& v) { return v.GetString(); }
0602 static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
0603 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
0604 };
0605
0606 #if RAPIDJSON_HAS_STDSTRING
0607 template<typename ValueType>
0608 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
0609 typedef std::basic_string<typename ValueType::Ch> StringType;
0610 static bool Is(const ValueType& v) { return v.IsString(); }
0611 static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
0612 static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
0613 };
0614 #endif
0615
0616 template<typename ValueType>
0617 struct TypeHelper<ValueType, typename ValueType::Array> {
0618 typedef typename ValueType::Array ArrayType;
0619 static bool Is(const ValueType& v) { return v.IsArray(); }
0620 static ArrayType Get(ValueType& v) { return v.GetArray(); }
0621 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
0622 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
0623 };
0624
0625 template<typename ValueType>
0626 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
0627 typedef typename ValueType::ConstArray ArrayType;
0628 static bool Is(const ValueType& v) { return v.IsArray(); }
0629 static ArrayType Get(const ValueType& v) { return v.GetArray(); }
0630 };
0631
0632 template<typename ValueType>
0633 struct TypeHelper<ValueType, typename ValueType::Object> {
0634 typedef typename ValueType::Object ObjectType;
0635 static bool Is(const ValueType& v) { return v.IsObject(); }
0636 static ObjectType Get(ValueType& v) { return v.GetObject(); }
0637 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
0638 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
0639 };
0640
0641 template<typename ValueType>
0642 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
0643 typedef typename ValueType::ConstObject ObjectType;
0644 static bool Is(const ValueType& v) { return v.IsObject(); }
0645 static ObjectType Get(const ValueType& v) { return v.GetObject(); }
0646 };
0647
0648 }
0649
0650
0651 template <bool, typename> class GenericArray;
0652 template <bool, typename> class GenericObject;
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
0668 class GenericValue {
0669 public:
0670
0671 typedef GenericMember<Encoding, Allocator> Member;
0672 typedef Encoding EncodingType;
0673 typedef Allocator AllocatorType;
0674 typedef typename Encoding::Ch Ch;
0675 typedef GenericStringRef<Ch> StringRefType;
0676 typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator;
0677 typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator;
0678 typedef GenericValue* ValueIterator;
0679 typedef const GenericValue* ConstValueIterator;
0680 typedef GenericValue<Encoding, Allocator> ValueType;
0681 typedef GenericArray<false, ValueType> Array;
0682 typedef GenericArray<true, ValueType> ConstArray;
0683 typedef GenericObject<false, ValueType> Object;
0684 typedef GenericObject<true, ValueType> ConstObject;
0685
0686
0687
0688
0689
0690 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
0691
0692 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
0693
0694 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
0695 rhs.data_.f.flags = kNullFlag;
0696 }
0697 #endif
0698
0699 private:
0700
0701 GenericValue(const GenericValue& rhs);
0702
0703 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
0704
0705 template <typename StackAllocator>
0706 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
0707
0708
0709 template <typename StackAllocator>
0710 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
0711 #endif
0712
0713 public:
0714
0715
0716
0717
0718
0719
0720 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
0721 static const uint16_t defaultFlags[] = {
0722 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
0723 kNumberAnyFlag
0724 };
0725 RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
0726 data_.f.flags = defaultFlags[type];
0727
0728
0729 if (type == kStringType)
0730 data_.ss.SetLength(0);
0731 }
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741 template <typename SourceAllocator>
0742 GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
0743 switch (rhs.GetType()) {
0744 case kObjectType:
0745 DoCopyMembers(rhs, allocator, copyConstStrings);
0746 break;
0747 case kArrayType: {
0748 SizeType count = rhs.data_.a.size;
0749 GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
0750 const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
0751 for (SizeType i = 0; i < count; i++)
0752 new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
0753 data_.f.flags = kArrayFlag;
0754 data_.a.size = data_.a.capacity = count;
0755 SetElementsPointer(le);
0756 }
0757 break;
0758 case kStringType:
0759 if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
0760 data_.f.flags = rhs.data_.f.flags;
0761 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
0762 }
0763 else
0764 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
0765 break;
0766 default:
0767 data_.f.flags = rhs.data_.f.flags;
0768 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
0769 break;
0770 }
0771 }
0772
0773
0774
0775
0776
0777
0778
0779 #ifndef RAPIDJSON_DOXYGEN_RUNNING
0780 template <typename T>
0781 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT
0782 #else
0783 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
0784 #endif
0785 : data_() {
0786
0787 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
0788 data_.f.flags = b ? kTrueFlag : kFalseFlag;
0789 }
0790
0791
0792 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
0793 data_.n.i64 = i;
0794 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
0795 }
0796
0797
0798 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
0799 data_.n.u64 = u;
0800 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
0801 }
0802
0803
0804 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
0805 data_.n.i64 = i64;
0806 data_.f.flags = kNumberInt64Flag;
0807 if (i64 >= 0) {
0808 data_.f.flags |= kNumberUint64Flag;
0809 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
0810 data_.f.flags |= kUintFlag;
0811 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
0812 data_.f.flags |= kIntFlag;
0813 }
0814 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
0815 data_.f.flags |= kIntFlag;
0816 }
0817
0818
0819 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
0820 data_.n.u64 = u64;
0821 data_.f.flags = kNumberUint64Flag;
0822 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
0823 data_.f.flags |= kInt64Flag;
0824 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
0825 data_.f.flags |= kUintFlag;
0826 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
0827 data_.f.flags |= kIntFlag;
0828 }
0829
0830
0831 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
0832
0833
0834 explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
0835
0836
0837 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
0838
0839
0840 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
0841
0842
0843 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
0844
0845
0846 GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
0847
0848 #if RAPIDJSON_HAS_STDSTRING
0849
0850
0851
0852 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
0853 #endif
0854
0855
0856
0857
0858
0859
0860
0861 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
0862 a.value_.data_ = Data();
0863 a.value_.data_.f.flags = kArrayFlag;
0864 }
0865
0866
0867
0868
0869
0870
0871
0872 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
0873 o.value_.data_ = Data();
0874 o.value_.data_.f.flags = kObjectFlag;
0875 }
0876
0877
0878
0879
0880 ~GenericValue() {
0881
0882
0883 if (Allocator::kNeedFree || (RAPIDJSON_USE_MEMBERSMAP+0 &&
0884 internal::IsRefCounted<Allocator>::Value)) {
0885 switch(data_.f.flags) {
0886 case kArrayFlag:
0887 {
0888 GenericValue* e = GetElementsPointer();
0889 for (GenericValue* v = e; v != e + data_.a.size; ++v)
0890 v->~GenericValue();
0891 if (Allocator::kNeedFree) {
0892 Allocator::Free(e);
0893 }
0894 }
0895 break;
0896
0897 case kObjectFlag:
0898 DoFreeMembers();
0899 break;
0900
0901 case kCopyStringFlag:
0902 if (Allocator::kNeedFree) {
0903 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
0904 }
0905 break;
0906
0907 default:
0908 break;
0909 }
0910 }
0911 }
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
0922 if (RAPIDJSON_LIKELY(this != &rhs)) {
0923
0924
0925
0926 GenericValue temp;
0927 temp.RawAssign(rhs);
0928 this->~GenericValue();
0929 RawAssign(temp);
0930 }
0931 return *this;
0932 }
0933
0934 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
0935
0936 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
0937 return *this = rhs.Move();
0938 }
0939 #endif
0940
0941
0942
0943
0944
0945
0946 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
0947 GenericValue s(str);
0948 return *this = s;
0949 }
0950
0951
0952
0953
0954
0955
0956
0957
0958
0959
0960
0961
0962
0963 template <typename T>
0964 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
0965 operator=(T value) {
0966 GenericValue v(value);
0967 return *this = v;
0968 }
0969
0970
0971
0972
0973
0974
0975
0976
0977 template <typename SourceAllocator>
0978 GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
0979 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
0980 this->~GenericValue();
0981 new (this) GenericValue(rhs, allocator, copyConstStrings);
0982 return *this;
0983 }
0984
0985
0986
0987
0988
0989
0990 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
0991 GenericValue temp;
0992 temp.RawAssign(*this);
0993 RawAssign(other);
0994 other.RawAssign(temp);
0995 return *this;
0996 }
0997
0998
0999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1011
1012
1013
1014 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024 template <typename SourceAllocator>
1025 bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
1026 typedef GenericValue<Encoding, SourceAllocator> RhsType;
1027 if (GetType() != rhs.GetType())
1028 return false;
1029
1030 switch (GetType()) {
1031 case kObjectType:
1032 if (data_.o.size != rhs.data_.o.size)
1033 return false;
1034 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1035 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1036 if (rhsMemberItr == rhs.MemberEnd() || (!(lhsMemberItr->value == rhsMemberItr->value)))
1037 return false;
1038 }
1039 return true;
1040
1041 case kArrayType:
1042 if (data_.a.size != rhs.data_.a.size)
1043 return false;
1044 for (SizeType i = 0; i < data_.a.size; i++)
1045 if (!((*this)[i] == rhs[i]))
1046 return false;
1047 return true;
1048
1049 case kStringType:
1050 return StringEqual(rhs);
1051
1052 case kNumberType:
1053 if (IsDouble() || rhs.IsDouble()) {
1054 double a = GetDouble();
1055 double b = rhs.GetDouble();
1056 return a >= b && a <= b;
1057 }
1058 else
1059 return data_.n.u64 == rhs.data_.n.u64;
1060
1061 default:
1062 return true;
1063 }
1064 }
1065
1066
1067 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1068
1069 #if RAPIDJSON_HAS_STDSTRING
1070
1071
1072
1073 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
1074 #endif
1075
1076
1077
1078
1079 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
1080
1081 #ifndef __cpp_impl_three_way_comparison
1082
1083
1084
1085 template <typename SourceAllocator>
1086 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1087
1088
1089 bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1090
1091
1092
1093
1094 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1095
1096
1097
1098
1099 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1100
1101
1102
1103
1104 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1105
1106 #endif
1107
1108
1109
1110
1111 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1112 bool IsNull() const { return data_.f.flags == kNullFlag; }
1113 bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1114 bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1115 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1116 bool IsObject() const { return data_.f.flags == kObjectFlag; }
1117 bool IsArray() const { return data_.f.flags == kArrayFlag; }
1118 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1119 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1120 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1121 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1122 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1123 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1124 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1125
1126
1127 bool IsLosslessDouble() const {
1128 if (!IsNumber()) return false;
1129 if (IsUint64()) {
1130 uint64_t u = GetUint64();
1131 volatile double d = static_cast<double>(u);
1132 return (d >= 0.0)
1133 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1134 && (u == static_cast<uint64_t>(d));
1135 }
1136 if (IsInt64()) {
1137 int64_t i = GetInt64();
1138 volatile double d = static_cast<double>(i);
1139 return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1140 && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1141 && (i == static_cast<int64_t>(d));
1142 }
1143 return true;
1144 }
1145
1146
1147 bool IsFloat() const {
1148 if ((data_.f.flags & kDoubleFlag) == 0)
1149 return false;
1150 double d = GetDouble();
1151 return d >= -3.4028234e38 && d <= 3.4028234e38;
1152 }
1153
1154 bool IsLosslessFloat() const {
1155 if (!IsNumber()) return false;
1156 double a = GetDouble();
1157 if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1158 || a > static_cast<double>((std::numeric_limits<float>::max)()))
1159 return false;
1160 double b = static_cast<double>(static_cast<float>(a));
1161 return a >= b && a <= b;
1162 }
1163
1164
1165
1166
1167
1168
1169 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1170
1171
1172
1173
1174
1175
1176 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1177
1178
1179 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1180
1181
1182
1183
1184
1185
1186
1187
1188 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1189
1190
1191 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1192
1193
1194 SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1195
1196
1197 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208 template <typename T>
1209 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1210 GenericValue n(StringRef(name));
1211 return (*this)[n];
1212 }
1213 template <typename T>
1214 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(const GenericValue&)) operator[](T* name) const { return const_cast<GenericValue&>(*this)[name]; }
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225 template <typename SourceAllocator>
1226 GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1227 MemberIterator member = FindMember(name);
1228 if (member != MemberEnd())
1229 return member->value;
1230 else {
1231 RAPIDJSON_ASSERT(false);
1232
1233 #if RAPIDJSON_HAS_CXX11
1234
1235
1236
1237 alignas(GenericValue) thread_local static char buffer[sizeof(GenericValue)];
1238 return *new (buffer) GenericValue();
1239 #elif defined(_MSC_VER) && _MSC_VER < 1900
1240
1241
1242 __declspec(thread) static char buffer[sizeof(GenericValue)];
1243 return *new (buffer) GenericValue();
1244 #elif defined(__GNUC__) || defined(__clang__)
1245
1246
1247 __thread static GenericValue buffer;
1248 return buffer;
1249 #else
1250
1251
1252 static GenericValue buffer;
1253 return buffer;
1254 #endif
1255 }
1256 }
1257 template <typename SourceAllocator>
1258 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1259
1260 #if RAPIDJSON_HAS_STDSTRING
1261
1262 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1263 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1264 #endif
1265
1266
1267
1268 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1269
1270
1271 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1272
1273
1274 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1275
1276
1277 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1278
1279
1280
1281
1282
1283
1284
1285 GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1286 RAPIDJSON_ASSERT(IsObject());
1287 DoReserveMembers(newCapacity, allocator);
1288 return *this;
1289 }
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1300
1301 #if RAPIDJSON_HAS_STDSTRING
1302
1303
1304
1305
1306
1307
1308
1309
1310 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1311 #endif
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 template <typename SourceAllocator>
1323 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337 MemberIterator FindMember(const Ch* name) {
1338 GenericValue n(StringRef(name));
1339 return FindMember(n);
1340 }
1341
1342 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357 template <typename SourceAllocator>
1358 MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
1359 RAPIDJSON_ASSERT(IsObject());
1360 RAPIDJSON_ASSERT(name.IsString());
1361 return DoFindMember(name);
1362 }
1363 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1364
1365 #if RAPIDJSON_HAS_STDSTRING
1366
1367
1368
1369
1370
1371
1372
1373 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1374 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1375 #endif
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1388 RAPIDJSON_ASSERT(IsObject());
1389 RAPIDJSON_ASSERT(name.IsString());
1390 DoAddMember(name, value, allocator);
1391 return *this;
1392 }
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1404 GenericValue v(value);
1405 return AddMember(name, v, allocator);
1406 }
1407
1408 #if RAPIDJSON_HAS_STDSTRING
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1419 GenericValue v(value, allocator);
1420 return AddMember(name, v, allocator);
1421 }
1422 #endif
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441 template <typename T>
1442 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1443 AddMember(GenericValue& name, T value, Allocator& allocator) {
1444 GenericValue v(value);
1445 return AddMember(name, v, allocator);
1446 }
1447
1448 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1449 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1450 return AddMember(name, value, allocator);
1451 }
1452 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1453 return AddMember(name, value, allocator);
1454 }
1455 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1456 return AddMember(name, value, allocator);
1457 }
1458 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1459 GenericValue n(name);
1460 return AddMember(n, value, allocator);
1461 }
1462 #endif
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1476 GenericValue n(name);
1477 return AddMember(n, value, allocator);
1478 }
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1490 GenericValue v(value);
1491 return AddMember(name, v, allocator);
1492 }
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511 template <typename T>
1512 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1513 AddMember(StringRefType name, T value, Allocator& allocator) {
1514 GenericValue n(name);
1515 return AddMember(n, value, allocator);
1516 }
1517
1518
1519
1520
1521
1522 void RemoveAllMembers() {
1523 RAPIDJSON_ASSERT(IsObject());
1524 DoClearMembers();
1525 }
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535 bool RemoveMember(const Ch* name) {
1536 GenericValue n(StringRef(name));
1537 return RemoveMember(n);
1538 }
1539
1540 #if RAPIDJSON_HAS_STDSTRING
1541 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1542 #endif
1543
1544 template <typename SourceAllocator>
1545 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1546 MemberIterator m = FindMember(name);
1547 if (m != MemberEnd()) {
1548 RemoveMember(m);
1549 return true;
1550 }
1551 else
1552 return false;
1553 }
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563 MemberIterator RemoveMember(MemberIterator m) {
1564 RAPIDJSON_ASSERT(IsObject());
1565 RAPIDJSON_ASSERT(data_.o.size > 0);
1566 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1567 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1568 return DoRemoveMember(m);
1569 }
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580 MemberIterator EraseMember(ConstMemberIterator pos) {
1581 return EraseMember(pos, pos +1);
1582 }
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1594 RAPIDJSON_ASSERT(IsObject());
1595 RAPIDJSON_ASSERT(data_.o.size > 0);
1596 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1597 RAPIDJSON_ASSERT(first >= MemberBegin());
1598 RAPIDJSON_ASSERT(first <= last);
1599 RAPIDJSON_ASSERT(last <= MemberEnd());
1600 return DoEraseMembers(first, last);
1601 }
1602
1603
1604
1605
1606
1607
1608 bool EraseMember(const Ch* name) {
1609 GenericValue n(StringRef(name));
1610 return EraseMember(n);
1611 }
1612
1613 #if RAPIDJSON_HAS_STDSTRING
1614 bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1615 #endif
1616
1617 template <typename SourceAllocator>
1618 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1619 MemberIterator m = FindMember(name);
1620 if (m != MemberEnd()) {
1621 EraseMember(m);
1622 return true;
1623 }
1624 else
1625 return false;
1626 }
1627
1628 Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1629 Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1630 ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1631 ConstObject GetObj() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1632
1633
1634
1635
1636
1637
1638
1639
1640 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1641
1642
1643 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1644
1645
1646 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1647
1648
1649 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1650
1651
1652
1653
1654
1655 void Clear() {
1656 RAPIDJSON_ASSERT(IsArray());
1657 GenericValue* e = GetElementsPointer();
1658 for (GenericValue* v = e; v != e + data_.a.size; ++v)
1659 v->~GenericValue();
1660 data_.a.size = 0;
1661 }
1662
1663
1664
1665
1666
1667
1668 GenericValue& operator[](SizeType index) {
1669 RAPIDJSON_ASSERT(IsArray());
1670 RAPIDJSON_ASSERT(index < data_.a.size);
1671 return GetElementsPointer()[index];
1672 }
1673 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1674
1675
1676
1677 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1678
1679
1680 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1681
1682
1683 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1684
1685
1686 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1687
1688
1689
1690
1691
1692
1693
1694 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1695 RAPIDJSON_ASSERT(IsArray());
1696 if (newCapacity > data_.a.capacity) {
1697 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1698 data_.a.capacity = newCapacity;
1699 }
1700 return *this;
1701 }
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713 GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1714 RAPIDJSON_ASSERT(IsArray());
1715 if (data_.a.size >= data_.a.capacity)
1716 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1717 GetElementsPointer()[data_.a.size++].RawAssign(value);
1718 return *this;
1719 }
1720
1721 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1722 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1723 return PushBack(value, allocator);
1724 }
1725 #endif
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736 GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1737 return (*this).template PushBack<StringRefType>(value, allocator);
1738 }
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757 template <typename T>
1758 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1759 PushBack(T value, Allocator& allocator) {
1760 GenericValue v(value);
1761 return PushBack(v, allocator);
1762 }
1763
1764
1765
1766
1767
1768 GenericValue& PopBack() {
1769 RAPIDJSON_ASSERT(IsArray());
1770 RAPIDJSON_ASSERT(!Empty());
1771 GetElementsPointer()[--data_.a.size].~GenericValue();
1772 return *this;
1773 }
1774
1775
1776
1777
1778
1779
1780
1781
1782 ValueIterator Erase(ConstValueIterator pos) {
1783 return Erase(pos, pos + 1);
1784 }
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1795 RAPIDJSON_ASSERT(IsArray());
1796 RAPIDJSON_ASSERT(data_.a.size > 0);
1797 RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1798 RAPIDJSON_ASSERT(first >= Begin());
1799 RAPIDJSON_ASSERT(first <= last);
1800 RAPIDJSON_ASSERT(last <= End());
1801 ValueIterator pos = Begin() + (first - Begin());
1802 for (ValueIterator itr = pos; itr != last; ++itr)
1803 itr->~GenericValue();
1804 std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1805 data_.a.size -= static_cast<SizeType>(last - first);
1806 return pos;
1807 }
1808
1809 Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1810 ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1811
1812
1813
1814
1815
1816
1817 int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1818 unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1819 int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1820 uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1821
1822
1823
1824
1825 double GetDouble() const {
1826 RAPIDJSON_ASSERT(IsNumber());
1827 if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d;
1828 if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i;
1829 if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u;
1830 if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64);
1831 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64);
1832 }
1833
1834
1835
1836
1837 float GetFloat() const {
1838 return static_cast<float>(GetDouble());
1839 }
1840
1841 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1842 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1843 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1844 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1845 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1846 GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1847
1848
1849
1850
1851
1852
1853 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return DataString(data_); }
1854
1855
1856
1857
1858 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return DataStringLength(data_); }
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1869
1870
1871
1872
1873
1874
1875 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1886
1887
1888
1889
1890
1891
1892
1893 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1894
1895
1896
1897
1898
1899
1900
1901 GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1902
1903 #if RAPIDJSON_HAS_STDSTRING
1904
1905
1906
1907
1908
1909
1910
1911 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1912 #endif
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923 template <typename T>
1924 bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1925
1926 template <typename T>
1927 T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1928
1929 template <typename T>
1930 T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1931
1932 template<typename T>
1933 ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1934
1935 template<typename T>
1936 ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947 template <typename Handler>
1948 bool Accept(Handler& handler) const {
1949 switch(GetType()) {
1950 case kNullType: return handler.Null();
1951 case kFalseType: return handler.Bool(false);
1952 case kTrueType: return handler.Bool(true);
1953
1954 case kObjectType:
1955 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1956 return false;
1957 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1958 RAPIDJSON_ASSERT(m->name.IsString());
1959 if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1960 return false;
1961 if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1962 return false;
1963 }
1964 return handler.EndObject(data_.o.size);
1965
1966 case kArrayType:
1967 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1968 return false;
1969 for (ConstValueIterator v = Begin(); v != End(); ++v)
1970 if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1971 return false;
1972 return handler.EndArray(data_.a.size);
1973
1974 case kStringType:
1975 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1976
1977 default:
1978 RAPIDJSON_ASSERT(GetType() == kNumberType);
1979 if (IsDouble()) return handler.Double(data_.n.d);
1980 else if (IsInt()) return handler.Int(data_.n.i.i);
1981 else if (IsUint()) return handler.Uint(data_.n.u.u);
1982 else if (IsInt64()) return handler.Int64(data_.n.i64);
1983 else return handler.Uint64(data_.n.u64);
1984 }
1985 }
1986
1987 private:
1988 template <typename, typename> friend class GenericValue;
1989 template <typename, typename, typename> friend class GenericDocument;
1990
1991 enum {
1992 kBoolFlag = 0x0008,
1993 kNumberFlag = 0x0010,
1994 kIntFlag = 0x0020,
1995 kUintFlag = 0x0040,
1996 kInt64Flag = 0x0080,
1997 kUint64Flag = 0x0100,
1998 kDoubleFlag = 0x0200,
1999 kStringFlag = 0x0400,
2000 kCopyFlag = 0x0800,
2001 kInlineStrFlag = 0x1000,
2002
2003
2004 kNullFlag = kNullType,
2005
2006 kTrueFlag = static_cast<int>(kTrueType) | static_cast<int>(kBoolFlag),
2007 kFalseFlag = static_cast<int>(kFalseType) | static_cast<int>(kBoolFlag),
2008 kNumberIntFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag),
2009 kNumberUintFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag),
2010 kNumberInt64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kInt64Flag),
2011 kNumberUint64Flag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kUint64Flag),
2012 kNumberDoubleFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kDoubleFlag),
2013 kNumberAnyFlag = static_cast<int>(kNumberType) | static_cast<int>(kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag),
2014 kConstStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag),
2015 kCopyStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag),
2016 kShortStringFlag = static_cast<int>(kStringType) | static_cast<int>(kStringFlag | kCopyFlag | kInlineStrFlag),
2017 kObjectFlag = kObjectType,
2018 kArrayFlag = kArrayType,
2019
2020 kTypeMask = 0x07
2021 };
2022
2023 static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
2024 static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
2025
2026 struct Flag {
2027 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2028 char payload[sizeof(SizeType) * 2 + 6];
2029 #elif RAPIDJSON_64BIT
2030 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6];
2031 #else
2032 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2];
2033 #endif
2034 uint16_t flags;
2035 };
2036
2037 struct String {
2038 SizeType length;
2039 SizeType hashcode;
2040 const Ch* str;
2041 };
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051 struct ShortString {
2052 enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2053 Ch str[MaxChars];
2054
2055 inline static bool Usable(SizeType len) { return (MaxSize >= len); }
2056 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2057 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
2058 };
2059
2060
2061 union Number {
2062 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2063 struct I {
2064 int i;
2065 char padding[4];
2066 }i;
2067 struct U {
2068 unsigned u;
2069 char padding2[4];
2070 }u;
2071 #else
2072 struct I {
2073 char padding[4];
2074 int i;
2075 }i;
2076 struct U {
2077 char padding2[4];
2078 unsigned u;
2079 }u;
2080 #endif
2081 int64_t i64;
2082 uint64_t u64;
2083 double d;
2084 };
2085
2086 struct ObjectData {
2087 SizeType size;
2088 SizeType capacity;
2089 Member* members;
2090 };
2091
2092 struct ArrayData {
2093 SizeType size;
2094 SizeType capacity;
2095 GenericValue* elements;
2096 };
2097
2098 union Data {
2099 String s;
2100 ShortString ss;
2101 Number n;
2102 ObjectData o;
2103 ArrayData a;
2104 Flag f;
2105 };
2106
2107 static RAPIDJSON_FORCEINLINE const Ch* DataString(const Data& data) {
2108 return (data.f.flags & kInlineStrFlag) ? data.ss.str : RAPIDJSON_GETPOINTER(Ch, data.s.str);
2109 }
2110 static RAPIDJSON_FORCEINLINE SizeType DataStringLength(const Data& data) {
2111 return (data.f.flags & kInlineStrFlag) ? data.ss.GetLength() : data.s.length;
2112 }
2113
2114 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2115 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2116 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2117 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2118 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2119 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2120
2121 #if RAPIDJSON_USE_MEMBERSMAP
2122
2123 struct MapTraits {
2124 struct Less {
2125 bool operator()(const Data& s1, const Data& s2) const {
2126 SizeType n1 = DataStringLength(s1), n2 = DataStringLength(s2);
2127 int cmp = std::memcmp(DataString(s1), DataString(s2), sizeof(Ch) * (n1 < n2 ? n1 : n2));
2128 return cmp < 0 || (cmp == 0 && n1 < n2);
2129 }
2130 };
2131 typedef std::pair<const Data, SizeType> Pair;
2132 typedef std::multimap<Data, SizeType, Less, StdAllocator<Pair, Allocator> > Map;
2133 typedef typename Map::iterator Iterator;
2134 };
2135 typedef typename MapTraits::Map Map;
2136 typedef typename MapTraits::Less MapLess;
2137 typedef typename MapTraits::Pair MapPair;
2138 typedef typename MapTraits::Iterator MapIterator;
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148 static RAPIDJSON_FORCEINLINE size_t GetMapLayoutSize(SizeType capacity) {
2149 return RAPIDJSON_ALIGN(sizeof(Map*)) +
2150 RAPIDJSON_ALIGN(sizeof(SizeType)) +
2151 RAPIDJSON_ALIGN(capacity * sizeof(Member)) +
2152 capacity * sizeof(MapIterator);
2153 }
2154
2155 static RAPIDJSON_FORCEINLINE SizeType &GetMapCapacity(Map* &map) {
2156 return *reinterpret_cast<SizeType*>(reinterpret_cast<uintptr_t>(&map) +
2157 RAPIDJSON_ALIGN(sizeof(Map*)));
2158 }
2159
2160 static RAPIDJSON_FORCEINLINE Member* GetMapMembers(Map* &map) {
2161 return reinterpret_cast<Member*>(reinterpret_cast<uintptr_t>(&map) +
2162 RAPIDJSON_ALIGN(sizeof(Map*)) +
2163 RAPIDJSON_ALIGN(sizeof(SizeType)));
2164 }
2165
2166 static RAPIDJSON_FORCEINLINE MapIterator* GetMapIterators(Map* &map) {
2167 return reinterpret_cast<MapIterator*>(reinterpret_cast<uintptr_t>(&map) +
2168 RAPIDJSON_ALIGN(sizeof(Map*)) +
2169 RAPIDJSON_ALIGN(sizeof(SizeType)) +
2170 RAPIDJSON_ALIGN(GetMapCapacity(map) * sizeof(Member)));
2171 }
2172
2173 static RAPIDJSON_FORCEINLINE Map* &GetMap(Member* members) {
2174 RAPIDJSON_ASSERT(members != 0);
2175 return *reinterpret_cast<Map**>(reinterpret_cast<uintptr_t>(members) -
2176 RAPIDJSON_ALIGN(sizeof(SizeType)) -
2177 RAPIDJSON_ALIGN(sizeof(Map*)));
2178 }
2179
2180
2181 RAPIDJSON_FORCEINLINE MapIterator DropMapIterator(MapIterator& rhs) {
2182 #if RAPIDJSON_HAS_CXX11
2183 MapIterator ret = std::move(rhs);
2184 #else
2185 MapIterator ret = rhs;
2186 #endif
2187 rhs.~MapIterator();
2188 return ret;
2189 }
2190
2191 Map* &DoReallocMap(Map** oldMap, SizeType newCapacity, Allocator& allocator) {
2192 Map **newMap = static_cast<Map**>(allocator.Malloc(GetMapLayoutSize(newCapacity)));
2193 GetMapCapacity(*newMap) = newCapacity;
2194 if (!oldMap) {
2195 *newMap = new (allocator.Malloc(sizeof(Map))) Map(MapLess(), allocator);
2196 }
2197 else {
2198 *newMap = *oldMap;
2199 size_t count = (*oldMap)->size();
2200 std::memcpy(static_cast<void*>(GetMapMembers(*newMap)),
2201 static_cast<void*>(GetMapMembers(*oldMap)),
2202 count * sizeof(Member));
2203 MapIterator *oldIt = GetMapIterators(*oldMap),
2204 *newIt = GetMapIterators(*newMap);
2205 while (count--) {
2206 new (&newIt[count]) MapIterator(DropMapIterator(oldIt[count]));
2207 }
2208 Allocator::Free(oldMap);
2209 }
2210 return *newMap;
2211 }
2212
2213 RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2214 return GetMapMembers(DoReallocMap(0, capacity, allocator));
2215 }
2216
2217 void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2218 ObjectData& o = data_.o;
2219 if (newCapacity > o.capacity) {
2220 Member* oldMembers = GetMembersPointer();
2221 Map **oldMap = oldMembers ? &GetMap(oldMembers) : 0,
2222 *&newMap = DoReallocMap(oldMap, newCapacity, allocator);
2223 RAPIDJSON_SETPOINTER(Member, o.members, GetMapMembers(newMap));
2224 o.capacity = newCapacity;
2225 }
2226 }
2227
2228 template <typename SourceAllocator>
2229 MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2230 if (Member* members = GetMembersPointer()) {
2231 Map* &map = GetMap(members);
2232 MapIterator mit = map->find(reinterpret_cast<const Data&>(name.data_));
2233 if (mit != map->end()) {
2234 return MemberIterator(&members[mit->second]);
2235 }
2236 }
2237 return MemberEnd();
2238 }
2239
2240 void DoClearMembers() {
2241 if (Member* members = GetMembersPointer()) {
2242 Map* &map = GetMap(members);
2243 MapIterator* mit = GetMapIterators(map);
2244 for (SizeType i = 0; i < data_.o.size; i++) {
2245 map->erase(DropMapIterator(mit[i]));
2246 members[i].~Member();
2247 }
2248 data_.o.size = 0;
2249 }
2250 }
2251
2252 void DoFreeMembers() {
2253 if (Member* members = GetMembersPointer()) {
2254 GetMap(members)->~Map();
2255 for (SizeType i = 0; i < data_.o.size; i++) {
2256 members[i].~Member();
2257 }
2258 if (Allocator::kNeedFree) {
2259 Map** map = &GetMap(members);
2260 Allocator::Free(*map);
2261 Allocator::Free(map);
2262 }
2263 }
2264 }
2265
2266 #else
2267
2268 RAPIDJSON_FORCEINLINE Member* DoAllocMembers(SizeType capacity, Allocator& allocator) {
2269 return Malloc<Member>(allocator, capacity);
2270 }
2271
2272 void DoReserveMembers(SizeType newCapacity, Allocator& allocator) {
2273 ObjectData& o = data_.o;
2274 if (newCapacity > o.capacity) {
2275 Member* newMembers = Realloc<Member>(allocator, GetMembersPointer(), o.capacity, newCapacity);
2276 RAPIDJSON_SETPOINTER(Member, o.members, newMembers);
2277 o.capacity = newCapacity;
2278 }
2279 }
2280
2281 template <typename SourceAllocator>
2282 MemberIterator DoFindMember(const GenericValue<Encoding, SourceAllocator>& name) {
2283 MemberIterator member = MemberBegin();
2284 for ( ; member != MemberEnd(); ++member)
2285 if (name.StringEqual(member->name))
2286 break;
2287 return member;
2288 }
2289
2290 void DoClearMembers() {
2291 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2292 m->~Member();
2293 data_.o.size = 0;
2294 }
2295
2296 void DoFreeMembers() {
2297 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
2298 m->~Member();
2299 Allocator::Free(GetMembersPointer());
2300 }
2301
2302 #endif
2303
2304 void DoAddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
2305 ObjectData& o = data_.o;
2306 if (o.size >= o.capacity)
2307 DoReserveMembers(o.capacity ? (o.capacity + (o.capacity + 1) / 2) : kDefaultObjectCapacity, allocator);
2308 Member* members = GetMembersPointer();
2309 Member* m = members + o.size;
2310 m->name.RawAssign(name);
2311 m->value.RawAssign(value);
2312 #if RAPIDJSON_USE_MEMBERSMAP
2313 Map* &map = GetMap(members);
2314 MapIterator* mit = GetMapIterators(map);
2315 new (&mit[o.size]) MapIterator(map->insert(MapPair(m->name.data_, o.size)));
2316 #endif
2317 ++o.size;
2318 }
2319
2320 MemberIterator DoRemoveMember(MemberIterator m) {
2321 ObjectData& o = data_.o;
2322 Member* members = GetMembersPointer();
2323 #if RAPIDJSON_USE_MEMBERSMAP
2324 Map* &map = GetMap(members);
2325 MapIterator* mit = GetMapIterators(map);
2326 SizeType mpos = static_cast<SizeType>(&*m - members);
2327 map->erase(DropMapIterator(mit[mpos]));
2328 #endif
2329 MemberIterator last(members + (o.size - 1));
2330 if (o.size > 1 && m != last) {
2331 #if RAPIDJSON_USE_MEMBERSMAP
2332 new (&mit[mpos]) MapIterator(DropMapIterator(mit[&*last - members]));
2333 mit[mpos]->second = mpos;
2334 #endif
2335 *m = *last;
2336 }
2337 else {
2338 m->~Member();
2339 }
2340 --o.size;
2341 return m;
2342 }
2343
2344 MemberIterator DoEraseMembers(ConstMemberIterator first, ConstMemberIterator last) {
2345 ObjectData& o = data_.o;
2346 MemberIterator beg = MemberBegin(),
2347 pos = beg + (first - beg),
2348 end = MemberEnd();
2349 #if RAPIDJSON_USE_MEMBERSMAP
2350 Map* &map = GetMap(GetMembersPointer());
2351 MapIterator* mit = GetMapIterators(map);
2352 #endif
2353 for (MemberIterator itr = pos; itr != last; ++itr) {
2354 #if RAPIDJSON_USE_MEMBERSMAP
2355 map->erase(DropMapIterator(mit[itr - beg]));
2356 #endif
2357 itr->~Member();
2358 }
2359 #if RAPIDJSON_USE_MEMBERSMAP
2360 if (first != last) {
2361
2362 MemberIterator next = pos + (last - first);
2363 for (MemberIterator itr = pos; next != end; ++itr, ++next) {
2364 std::memcpy(static_cast<void*>(&*itr), &*next, sizeof(Member));
2365 SizeType mpos = static_cast<SizeType>(itr - beg);
2366 new (&mit[mpos]) MapIterator(DropMapIterator(mit[next - beg]));
2367 mit[mpos]->second = mpos;
2368 }
2369 }
2370 #else
2371 std::memmove(static_cast<void*>(&*pos), &*last,
2372 static_cast<size_t>(end - last) * sizeof(Member));
2373 #endif
2374 o.size -= static_cast<SizeType>(last - first);
2375 return pos;
2376 }
2377
2378 template <typename SourceAllocator>
2379 void DoCopyMembers(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings) {
2380 RAPIDJSON_ASSERT(rhs.GetType() == kObjectType);
2381
2382 data_.f.flags = kObjectFlag;
2383 SizeType count = rhs.data_.o.size;
2384 Member* lm = DoAllocMembers(count, allocator);
2385 const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
2386 #if RAPIDJSON_USE_MEMBERSMAP
2387 Map* &map = GetMap(lm);
2388 MapIterator* mit = GetMapIterators(map);
2389 #endif
2390 for (SizeType i = 0; i < count; i++) {
2391 new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
2392 new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
2393 #if RAPIDJSON_USE_MEMBERSMAP
2394 new (&mit[i]) MapIterator(map->insert(MapPair(lm[i].name.data_, i)));
2395 #endif
2396 }
2397 data_.o.size = data_.o.capacity = count;
2398 SetMembersPointer(lm);
2399 }
2400
2401
2402 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2403 data_.f.flags = kArrayFlag;
2404 if (count) {
2405 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2406 SetElementsPointer(e);
2407 std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2408 }
2409 else
2410 SetElementsPointer(0);
2411 data_.a.size = data_.a.capacity = count;
2412 }
2413
2414
2415 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2416 data_.f.flags = kObjectFlag;
2417 if (count) {
2418 Member* m = DoAllocMembers(count, allocator);
2419 SetMembersPointer(m);
2420 std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2421 #if RAPIDJSON_USE_MEMBERSMAP
2422 Map* &map = GetMap(m);
2423 MapIterator* mit = GetMapIterators(map);
2424 for (SizeType i = 0; i < count; i++) {
2425 new (&mit[i]) MapIterator(map->insert(MapPair(m[i].name.data_, i)));
2426 }
2427 #endif
2428 }
2429 else
2430 SetMembersPointer(0);
2431 data_.o.size = data_.o.capacity = count;
2432 }
2433
2434
2435 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2436 data_.f.flags = kConstStringFlag;
2437 SetStringPointer(s);
2438 data_.s.length = s.length;
2439 }
2440
2441
2442 void SetStringRaw(StringRefType s, Allocator& allocator) {
2443 Ch* str = 0;
2444 if (ShortString::Usable(s.length)) {
2445 data_.f.flags = kShortStringFlag;
2446 data_.ss.SetLength(s.length);
2447 str = data_.ss.str;
2448 } else {
2449 data_.f.flags = kCopyStringFlag;
2450 data_.s.length = s.length;
2451 str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2452 SetStringPointer(str);
2453 }
2454 std::memcpy(str, s, s.length * sizeof(Ch));
2455 str[s.length] = '\0';
2456 }
2457
2458
2459 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2460 data_ = rhs.data_;
2461
2462 rhs.data_.f.flags = kNullFlag;
2463 }
2464
2465 template <typename SourceAllocator>
2466 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2467 RAPIDJSON_ASSERT(IsString());
2468 RAPIDJSON_ASSERT(rhs.IsString());
2469
2470 const SizeType len1 = GetStringLength();
2471 const SizeType len2 = rhs.GetStringLength();
2472 if(len1 != len2) { return false; }
2473
2474 const Ch* const str1 = GetString();
2475 const Ch* const str2 = rhs.GetString();
2476 if(str1 == str2) { return true; }
2477
2478 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2479 }
2480
2481 Data data_;
2482 };
2483
2484
2485 typedef GenericValue<UTF8<> > Value;
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2499 class GenericDocument : public GenericValue<Encoding, Allocator> {
2500 public:
2501 typedef typename Encoding::Ch Ch;
2502 typedef GenericValue<Encoding, Allocator> ValueType;
2503 typedef Allocator AllocatorType;
2504 typedef StackAllocator StackAllocatorType;
2505
2506
2507
2508
2509
2510
2511
2512
2513 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2514 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2515 {
2516 if (!allocator_)
2517 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2518 }
2519
2520
2521
2522
2523
2524
2525
2526 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2527 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2528 {
2529 if (!allocator_)
2530 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2531 }
2532
2533 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2534
2535 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2536 : ValueType(std::forward<ValueType>(rhs)),
2537 allocator_(rhs.allocator_),
2538 ownAllocator_(rhs.ownAllocator_),
2539 stack_(std::move(rhs.stack_)),
2540 parseResult_(rhs.parseResult_)
2541 {
2542 rhs.allocator_ = 0;
2543 rhs.ownAllocator_ = 0;
2544 rhs.parseResult_ = ParseResult();
2545 }
2546 #endif
2547
2548 ~GenericDocument() {
2549
2550
2551
2552
2553 if (ownAllocator_) {
2554 ValueType::SetNull();
2555 }
2556 Destroy();
2557 }
2558
2559 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2560
2561 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2562 {
2563
2564
2565 ValueType::operator=(std::forward<ValueType>(rhs));
2566
2567
2568 Destroy();
2569
2570 allocator_ = rhs.allocator_;
2571 ownAllocator_ = rhs.ownAllocator_;
2572 stack_ = std::move(rhs.stack_);
2573 parseResult_ = rhs.parseResult_;
2574
2575 rhs.allocator_ = 0;
2576 rhs.ownAllocator_ = 0;
2577 rhs.parseResult_ = ParseResult();
2578
2579 return *this;
2580 }
2581 #endif
2582
2583
2584
2585
2586
2587
2588
2589 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2590 ValueType::Swap(rhs);
2591 stack_.Swap(rhs.stack_);
2592 internal::Swap(allocator_, rhs.allocator_);
2593 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2594 internal::Swap(parseResult_, rhs.parseResult_);
2595 return *this;
2596 }
2597
2598
2599
2600 using ValueType::Swap;
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2615
2616
2617
2618
2619
2620
2621 template <typename Generator>
2622 GenericDocument& Populate(Generator& g) {
2623 ClearStackOnExit scope(*this);
2624 if (g(*this)) {
2625 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType));
2626 ValueType::operator=(*stack_.template Pop<ValueType>(1));
2627 }
2628 return *this;
2629 }
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641 template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2642 GenericDocument& ParseStream(InputStream& is) {
2643 GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2644 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2645 ClearStackOnExit scope(*this);
2646 parseResult_ = reader.template Parse<parseFlags>(is, *this);
2647 if (parseResult_) {
2648 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType));
2649 ValueType::operator=(*stack_.template Pop<ValueType>(1));
2650 }
2651 return *this;
2652 }
2653
2654
2655
2656
2657
2658
2659
2660 template <unsigned parseFlags, typename InputStream>
2661 GenericDocument& ParseStream(InputStream& is) {
2662 return ParseStream<parseFlags, Encoding, InputStream>(is);
2663 }
2664
2665
2666
2667
2668
2669
2670 template <typename InputStream>
2671 GenericDocument& ParseStream(InputStream& is) {
2672 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2673 }
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684 template <unsigned parseFlags>
2685 GenericDocument& ParseInsitu(Ch* str) {
2686 GenericInsituStringStream<Encoding> s(str);
2687 return ParseStream<parseFlags | kParseInsituFlag>(s);
2688 }
2689
2690
2691
2692
2693
2694 GenericDocument& ParseInsitu(Ch* str) {
2695 return ParseInsitu<kParseDefaultFlags>(str);
2696 }
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707 template <unsigned parseFlags, typename SourceEncoding>
2708 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2709 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2710 GenericStringStream<SourceEncoding> s(str);
2711 return ParseStream<parseFlags, SourceEncoding>(s);
2712 }
2713
2714
2715
2716
2717
2718 template <unsigned parseFlags>
2719 GenericDocument& Parse(const Ch* str) {
2720 return Parse<parseFlags, Encoding>(str);
2721 }
2722
2723
2724
2725
2726 GenericDocument& Parse(const Ch* str) {
2727 return Parse<kParseDefaultFlags>(str);
2728 }
2729
2730 template <unsigned parseFlags, typename SourceEncoding>
2731 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2732 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2733 MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2734 EncodedInputStream<SourceEncoding, MemoryStream> is(ms);
2735 ParseStream<parseFlags, SourceEncoding>(is);
2736 return *this;
2737 }
2738
2739 template <unsigned parseFlags>
2740 GenericDocument& Parse(const Ch* str, size_t length) {
2741 return Parse<parseFlags, Encoding>(str, length);
2742 }
2743
2744 GenericDocument& Parse(const Ch* str, size_t length) {
2745 return Parse<kParseDefaultFlags>(str, length);
2746 }
2747
2748 #if RAPIDJSON_HAS_STDSTRING
2749 template <unsigned parseFlags, typename SourceEncoding>
2750 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2751
2752 return Parse<parseFlags, SourceEncoding>(str.c_str());
2753 }
2754
2755 template <unsigned parseFlags>
2756 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2757 return Parse<parseFlags, Encoding>(str.c_str());
2758 }
2759
2760 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2761 return Parse<kParseDefaultFlags>(str);
2762 }
2763 #endif
2764
2765
2766
2767
2768
2769
2770
2771 bool HasParseError() const { return parseResult_.IsError(); }
2772
2773
2774 ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2775
2776
2777 size_t GetErrorOffset() const { return parseResult_.Offset(); }
2778
2779
2780 #ifndef __clang
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790 #endif
2791 operator ParseResult() const { return parseResult_; }
2792
2793
2794
2795 Allocator& GetAllocator() {
2796 RAPIDJSON_ASSERT(allocator_);
2797 return *allocator_;
2798 }
2799
2800
2801 size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2802
2803 private:
2804
2805 struct ClearStackOnExit {
2806 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2807 ~ClearStackOnExit() { d_.ClearStack(); }
2808 private:
2809 ClearStackOnExit(const ClearStackOnExit&);
2810 ClearStackOnExit& operator=(const ClearStackOnExit&);
2811 GenericDocument& d_;
2812 };
2813
2814
2815
2816 template <typename, typename> friend class GenericValue;
2817
2818 public:
2819
2820 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2821 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2822 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2823 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2824 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2825 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2826 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2827
2828 bool RawNumber(const Ch* str, SizeType length, bool copy) {
2829 if (copy)
2830 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2831 else
2832 new (stack_.template Push<ValueType>()) ValueType(str, length);
2833 return true;
2834 }
2835
2836 bool String(const Ch* str, SizeType length, bool copy) {
2837 if (copy)
2838 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2839 else
2840 new (stack_.template Push<ValueType>()) ValueType(str, length);
2841 return true;
2842 }
2843
2844 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2845
2846 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2847
2848 bool EndObject(SizeType memberCount) {
2849 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2850 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2851 return true;
2852 }
2853
2854 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2855
2856 bool EndArray(SizeType elementCount) {
2857 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2858 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2859 return true;
2860 }
2861
2862 private:
2863
2864 GenericDocument(const GenericDocument&);
2865
2866 GenericDocument& operator=(const GenericDocument&);
2867
2868 void ClearStack() {
2869 if (Allocator::kNeedFree)
2870 while (stack_.GetSize() > 0)
2871 (stack_.template Pop<ValueType>(1))->~ValueType();
2872 else
2873 stack_.Clear();
2874 stack_.ShrinkToFit();
2875 }
2876
2877 void Destroy() {
2878 RAPIDJSON_DELETE(ownAllocator_);
2879 }
2880
2881 static const size_t kDefaultStackCapacity = 1024;
2882 Allocator* allocator_;
2883 Allocator* ownAllocator_;
2884 internal::Stack<StackAllocator> stack_;
2885 ParseResult parseResult_;
2886 };
2887
2888
2889 typedef GenericDocument<UTF8<> > Document;
2890
2891
2892
2893
2894
2895
2896
2897 template <bool Const, typename ValueT>
2898 class GenericArray {
2899 public:
2900 typedef GenericArray<true, ValueT> ConstArray;
2901 typedef GenericArray<false, ValueT> Array;
2902 typedef ValueT PlainType;
2903 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2904 typedef ValueType* ValueIterator;
2905 typedef const ValueT* ConstValueIterator;
2906 typedef typename ValueType::AllocatorType AllocatorType;
2907 typedef typename ValueType::StringRefType StringRefType;
2908
2909 template <typename, typename>
2910 friend class GenericValue;
2911
2912 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2913 GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2914 ~GenericArray() {}
2915
2916 operator ValueType&() const { return value_; }
2917 SizeType Size() const { return value_.Size(); }
2918 SizeType Capacity() const { return value_.Capacity(); }
2919 bool Empty() const { return value_.Empty(); }
2920 void Clear() const { value_.Clear(); }
2921 ValueType& operator[](SizeType index) const { return value_[index]; }
2922 ValueIterator Begin() const { return value_.Begin(); }
2923 ValueIterator End() const { return value_.End(); }
2924 GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2925 GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2926 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2927 GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2928 #endif
2929 GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2930 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; }
2931 GenericArray PopBack() const { value_.PopBack(); return *this; }
2932 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2933 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2934
2935 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2936 ValueIterator begin() const { return value_.Begin(); }
2937 ValueIterator end() const { return value_.End(); }
2938 #endif
2939
2940 private:
2941 GenericArray();
2942 GenericArray(ValueType& value) : value_(value) {}
2943 ValueType& value_;
2944 };
2945
2946
2947
2948
2949
2950
2951 template <bool Const, typename ValueT>
2952 class GenericObject {
2953 public:
2954 typedef GenericObject<true, ValueT> ConstObject;
2955 typedef GenericObject<false, ValueT> Object;
2956 typedef ValueT PlainType;
2957 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2958 typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator;
2959 typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;
2960 typedef typename ValueType::AllocatorType AllocatorType;
2961 typedef typename ValueType::StringRefType StringRefType;
2962 typedef typename ValueType::EncodingType EncodingType;
2963 typedef typename ValueType::Ch Ch;
2964
2965 template <typename, typename>
2966 friend class GenericValue;
2967
2968 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2969 GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2970 ~GenericObject() {}
2971
2972 operator ValueType&() const { return value_; }
2973 SizeType MemberCount() const { return value_.MemberCount(); }
2974 SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2975 bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2976 template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2977 template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2978 #if RAPIDJSON_HAS_STDSTRING
2979 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2980 #endif
2981 MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2982 MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2983 GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2984 bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2985 #if RAPIDJSON_HAS_STDSTRING
2986 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2987 #endif
2988 template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2989 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2990 template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2991 #if RAPIDJSON_HAS_STDSTRING
2992 MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2993 #endif
2994 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2995 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2996 #if RAPIDJSON_HAS_STDSTRING
2997 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2998 #endif
2999 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; }
3000 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
3001 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3002 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3003 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3004 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3005 #endif
3006 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3007 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
3008 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; }
3009 void RemoveAllMembers() { value_.RemoveAllMembers(); }
3010 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
3011 #if RAPIDJSON_HAS_STDSTRING
3012 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
3013 #endif
3014 template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
3015 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
3016 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
3017 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
3018 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
3019 #if RAPIDJSON_HAS_STDSTRING
3020 bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
3021 #endif
3022 template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
3023
3024 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
3025 MemberIterator begin() const { return value_.MemberBegin(); }
3026 MemberIterator end() const { return value_.MemberEnd(); }
3027 #endif
3028
3029 private:
3030 GenericObject();
3031 GenericObject(ValueType& value) : value_(value) {}
3032 ValueType& value_;
3033 };
3034
3035 RAPIDJSON_NAMESPACE_END
3036 RAPIDJSON_DIAG_POP
3037
3038 #ifdef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3039 #pragma pop_macro("GetObject")
3040 #undef RAPIDJSON_WINDOWS_GETOBJECT_WORKAROUND_APPLIED
3041 #endif
3042
3043 #endif