Arcane  v3.16.0.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
document.h
Aller à la documentation de ce fichier.
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2// Tencent is pleased to support the open source community by making RapidJSON available.
3//
4// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
5//
6// Licensed under the MIT License (the "License"); you may not use this file except
7// in compliance with the License. You may obtain a copy of the License at
8//
9// http://opensource.org/licenses/MIT
10//
11// Unless required by applicable law or agreed to in writing, software distributed
12// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13// CONDITIONS OF ANY KIND, either express or implied. See the License for the
14// specific language governing permissions and limitations under the License.
15
16#ifndef RAPIDJSON_DOCUMENT_H_
17#define RAPIDJSON_DOCUMENT_H_
18
20
21#include "reader.h"
22#include "internal/meta.h"
23#include "internal/strfunc.h"
24#include "memorystream.h"
25#include "encodedstream.h"
26#include <new> // placement new
27#include <limits>
28
29RAPIDJSON_DIAG_PUSH
30#ifdef __clang__
31RAPIDJSON_DIAG_OFF(padded)
32RAPIDJSON_DIAG_OFF(switch-enum)
33RAPIDJSON_DIAG_OFF(c++98-compat)
34#elif defined(_MSC_VER)
35RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
36RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
37#endif
38
39#ifdef __GNUC__
40RAPIDJSON_DIAG_OFF(effc++)
41#endif // __GNUC__
42
43#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
44#include <iterator> // std::random_access_iterator_tag
45#endif
46
47#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
48#include <utility> // std::move
49#endif
50
52
53// Forward declaration.
54template <typename Encoding, typename Allocator>
55class GenericValue;
56
57template <typename Encoding, typename Allocator, typename StackAllocator>
58class GenericDocument;
59
61
66template <typename Encoding, typename Allocator>
68public:
71
72#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
74 GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
75 : name(std::move(rhs.name)),
76 value(std::move(rhs.value))
77 {
78 }
79
81 GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
82 return *this = static_cast<GenericMember&>(rhs);
83 }
84#endif
85
87
89 GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
90 if (RAPIDJSON_LIKELY(this != &rhs)) {
91 name = rhs.name;
92 value = rhs.value;
93 }
94 return *this;
95 }
96
97 // swap() for std::sort() and other potential use in STL.
98 friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
99 a.name.Swap(b.name);
100 a.value.Swap(b.value);
101 }
102
103private:
106};
107
109// GenericMemberIterator
110
111#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
112
114
132template <bool Const, typename Encoding, typename Allocator>
133class GenericMemberIterator {
134
135 friend class GenericValue<Encoding,Allocator>;
136 template <bool, typename, typename> friend class GenericMemberIterator;
137
138 typedef GenericMember<Encoding,Allocator> PlainType;
139 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
140
141public:
143 typedef GenericMemberIterator Iterator;
145 typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator;
147 typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
148
151 typedef ValueType value_type;
152 typedef ValueType * pointer;
153 typedef ValueType & reference;
154 typedef std::ptrdiff_t difference_type;
155 typedef std::random_access_iterator_tag iterator_category;
157
159 typedef pointer Pointer;
161 typedef reference Reference;
163 typedef difference_type DifferenceType;
164
166
170
172
188 Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
189
191
192 Iterator& operator++(){ ++ptr_; return *this; }
193 Iterator& operator--(){ --ptr_; return *this; }
194 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
195 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
197
199
200 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
201 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
202
203 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
204 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
206
208
209 bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
210 bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
211 bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
212 bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
213 bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
214 bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
216
218
219 Reference operator*() const { return *ptr_; }
220 Pointer operator->() const { return ptr_; }
221 Reference operator[](DifferenceType n) const { return ptr_[n]; }
223
225 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
226
227private:
230
232};
233
234#else // RAPIDJSON_NOMEMBERITERATORCLASS
235
236// class-based member iterator implementation disabled, use plain pointers
237
238template <bool Const, typename Encoding, typename Allocator>
240
242template <typename Encoding, typename Allocator>
246};
248template <typename Encoding, typename Allocator>
251 typedef const GenericMember<Encoding,Allocator>* Iterator;
252};
253
254#endif // RAPIDJSON_NOMEMBERITERATORCLASS
255
257// GenericStringRef
258
260
286template<typename CharType>
288 typedef CharType Ch;
289
291#ifndef __clang__ // -Wdocumentation
314#endif
315 template<SizeType N>
316 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
317 : s(str), length(N-1) {}
318
320#ifndef __clang__ // -Wdocumentation
339#endif
340 explicit GenericStringRef(const CharType* str)
341 : s(str), length(NotNullStrLen(str)) {}
342
344#ifndef __clang__ // -Wdocumentation
351#endif
352 GenericStringRef(const CharType* str, SizeType len)
353 : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
354
355 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
356
358 operator const Ch *() const { return s; }
359
360 const Ch* const s;
362
363private:
364 SizeType NotNullStrLen(const CharType* str) {
365 RAPIDJSON_ASSERT(str != 0);
366 return internal::StrLen(str);
367 }
368
370 static const Ch emptyString[];
371
373 template<SizeType N>
374 GenericStringRef(CharType (&str)[N]) /* = delete */;
376 GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
377};
378
379template<typename CharType>
380const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
381
383
394template<typename CharType>
395inline GenericStringRef<CharType> StringRef(const CharType* str) {
396 return GenericStringRef<CharType>(str);
397}
398
400
414template<typename CharType>
415inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
417}
418
419#if RAPIDJSON_HAS_STDSTRING
421
432template<typename CharType>
433inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
434 return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
435}
436#endif
437
439// GenericValue type traits
440namespace internal {
441
442template <typename T, typename Encoding = void, typename Allocator = void>
443struct IsGenericValueImpl : FalseType {};
444
445// select candidates according to nested encoding and allocator types
446template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
447 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
448
449// helper to match arbitrary GenericValue instantiations, including derived classes
450template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
451
452} // namespace internal
453
455// TypeHelper
456
457namespace internal {
458
459template <typename ValueType, typename T>
460struct TypeHelper {};
461
462template<typename ValueType>
463struct TypeHelper<ValueType, bool> {
464 static bool Is(const ValueType& v) { return v.IsBool(); }
465 static bool Get(const ValueType& v) { return v.GetBool(); }
466 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
467 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
468};
469
470template<typename ValueType>
471struct TypeHelper<ValueType, int> {
472 static bool Is(const ValueType& v) { return v.IsInt(); }
473 static int Get(const ValueType& v) { return v.GetInt(); }
474 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
475 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
476};
477
478template<typename ValueType>
479struct TypeHelper<ValueType, unsigned> {
480 static bool Is(const ValueType& v) { return v.IsUint(); }
481 static unsigned Get(const ValueType& v) { return v.GetUint(); }
482 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
483 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
484};
485
486#ifdef _MSC_VER
487RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
488template<typename ValueType>
489struct TypeHelper<ValueType, long> {
490 static bool Is(const ValueType& v) { return v.IsInt(); }
491 static long Get(const ValueType& v) { return v.GetInt(); }
492 static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
493 static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
494};
495
496RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
497template<typename ValueType>
498struct TypeHelper<ValueType, unsigned long> {
499 static bool Is(const ValueType& v) { return v.IsUint(); }
500 static unsigned long Get(const ValueType& v) { return v.GetUint(); }
501 static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
502 static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
503};
504#endif
505
506template<typename ValueType>
507struct TypeHelper<ValueType, int64_t> {
508 static bool Is(const ValueType& v) { return v.IsInt64(); }
509 static int64_t Get(const ValueType& v) { return v.GetInt64(); }
510 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
511 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
512};
513
514template<typename ValueType>
515struct TypeHelper<ValueType, uint64_t> {
516 static bool Is(const ValueType& v) { return v.IsUint64(); }
517 static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
518 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
519 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
520};
521
522template<typename ValueType>
523struct TypeHelper<ValueType, double> {
524 static bool Is(const ValueType& v) { return v.IsDouble(); }
525 static double Get(const ValueType& v) { return v.GetDouble(); }
526 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
527 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
528};
529
530template<typename ValueType>
531struct TypeHelper<ValueType, float> {
532 static bool Is(const ValueType& v) { return v.IsFloat(); }
533 static float Get(const ValueType& v) { return v.GetFloat(); }
534 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
535 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
536};
537
538template<typename ValueType>
539struct TypeHelper<ValueType, const typename ValueType::Ch*> {
540 typedef const typename ValueType::Ch* StringType;
541 static bool Is(const ValueType& v) { return v.IsString(); }
542 static StringType Get(const ValueType& v) { return v.GetString(); }
543 static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
544 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
545};
546
547#if RAPIDJSON_HAS_STDSTRING
548template<typename ValueType>
549struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
550 typedef std::basic_string<typename ValueType::Ch> StringType;
551 static bool Is(const ValueType& v) { return v.IsString(); }
552 static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
553 static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
554};
555#endif
556
557template<typename ValueType>
558struct TypeHelper<ValueType, typename ValueType::Array> {
559 typedef typename ValueType::Array ArrayType;
560 static bool Is(const ValueType& v) { return v.IsArray(); }
561 static ArrayType Get(ValueType& v) { return v.GetArray(); }
562 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
563 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
564};
565
566template<typename ValueType>
567struct TypeHelper<ValueType, typename ValueType::ConstArray> {
568 typedef typename ValueType::ConstArray ArrayType;
569 static bool Is(const ValueType& v) { return v.IsArray(); }
570 static ArrayType Get(const ValueType& v) { return v.GetArray(); }
571};
572
573template<typename ValueType>
574struct TypeHelper<ValueType, typename ValueType::Object> {
575 typedef typename ValueType::Object ObjectType;
576 static bool Is(const ValueType& v) { return v.IsObject(); }
577 static ObjectType Get(ValueType& v) { return v.GetObject(); }
578 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
579 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
580};
581
582template<typename ValueType>
583struct TypeHelper<ValueType, typename ValueType::ConstObject> {
584 typedef typename ValueType::ConstObject ObjectType;
585 static bool Is(const ValueType& v) { return v.IsObject(); }
586 static ObjectType Get(const ValueType& v) { return v.GetObject(); }
587};
588
589} // namespace internal
590
591// Forward declarations
592template <bool, typename> class GenericArray;
593template <bool, typename> class GenericObject;
594
596// GenericValue
597
599
608template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
610public:
615 typedef typename Encoding::Ch Ch;
622 typedef GenericArray<false, ValueType> Array;
623 typedef GenericArray<true, ValueType> ConstArray;
624 typedef GenericObject<false, ValueType> Object;
625 typedef GenericObject<true, ValueType> ConstObject;
626
628
629
631 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
632
633#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
635 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
636 rhs.data_.f.flags = kNullFlag; // give up contents
637 }
638#endif
639
640private:
643
644#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
646 template <typename StackAllocator>
647 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
648
650 template <typename StackAllocator>
651 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
652#endif
653
654public:
655
657
661 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
662 static const uint16_t defaultFlags[] = {
663 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
664 kNumberAnyFlag
665 };
667 data_.f.flags = defaultFlags[type];
668
669 // Use ShortString to store empty string.
670 if (type == kStringType)
671 data_.ss.SetLength(0);
672 }
673
675
682 template <typename SourceAllocator>
683 GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
684 switch (rhs.GetType()) {
685 case kObjectType: {
686 SizeType count = rhs.data_.o.size;
687 Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
688 const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
689 for (SizeType i = 0; i < count; i++) {
690 new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
691 new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
692 }
693 data_.f.flags = kObjectFlag;
694 data_.o.size = data_.o.capacity = count;
695 SetMembersPointer(lm);
696 }
697 break;
698 case kArrayType: {
699 SizeType count = rhs.data_.a.size;
700 GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
701 const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
702 for (SizeType i = 0; i < count; i++)
703 new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
704 data_.f.flags = kArrayFlag;
705 data_.a.size = data_.a.capacity = count;
706 SetElementsPointer(le);
707 }
708 break;
709 case kStringType:
710 if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
711 data_.f.flags = rhs.data_.f.flags;
712 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
713 }
714 else
715 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
716 break;
717 default:
718 data_.f.flags = rhs.data_.f.flags;
719 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
720 break;
721 }
722 }
723
725
730#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
731 template <typename T>
732 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
733#else
734 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
735#endif
736 : data_() {
737 // safe-guard against failing SFINAE
738 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
739 data_.f.flags = b ? kTrueFlag : kFalseFlag;
740 }
741
743 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
744 data_.n.i64 = i;
745 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
746 }
747
749 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
750 data_.n.u64 = u;
751 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
752 }
753
755 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
756 data_.n.i64 = i64;
757 data_.f.flags = kNumberInt64Flag;
758 if (i64 >= 0) {
759 data_.f.flags |= kNumberUint64Flag;
760 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
761 data_.f.flags |= kUintFlag;
762 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
763 data_.f.flags |= kIntFlag;
764 }
765 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
766 data_.f.flags |= kIntFlag;
767 }
768
770 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
771 data_.n.u64 = u64;
772 data_.f.flags = kNumberUint64Flag;
773 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
774 data_.f.flags |= kInt64Flag;
775 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
776 data_.f.flags |= kUintFlag;
777 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
778 data_.f.flags |= kIntFlag;
779 }
780
782 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
783
785 explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
786
788 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
789
791 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
792
794 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
795
797 GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
798
799#if RAPIDJSON_HAS_STDSTRING
801
803 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
804#endif
805
807
812 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
813 a.value_.data_ = Data();
814 a.value_.data_.f.flags = kArrayFlag;
815 }
816
818
823 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
824 o.value_.data_ = Data();
825 o.value_.data_.f.flags = kObjectFlag;
826 }
827
829
832 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
833 switch(data_.f.flags) {
834 case kArrayFlag:
835 {
836 GenericValue* e = GetElementsPointer();
837 for (GenericValue* v = e; v != e + data_.a.size; ++v)
838 v->~GenericValue();
839 Allocator::Free(e);
840 }
841 break;
842
843 case kObjectFlag:
844 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
845 m->~Member();
846 Allocator::Free(GetMembersPointer());
847 break;
848
849 case kCopyStringFlag:
850 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
851 break;
852
853 default:
854 break; // Do nothing for other types.
855 }
856 }
857 }
858
860
862
863
865
867 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
868 if (RAPIDJSON_LIKELY(this != &rhs)) {
869 this->~GenericValue();
870 RawAssign(rhs);
871 }
872 return *this;
873 }
874
875#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
877 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
878 return *this = rhs.Move();
879 }
880#endif
881
883
887 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
888 GenericValue s(str);
889 return *this = s;
890 }
891
893
904 template <typename T>
905 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
906 operator=(T value) {
907 GenericValue v(value);
908 return *this = v;
909 }
910
912
918 template <typename SourceAllocator>
919 GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
920 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
921 this->~GenericValue();
922 new (this) GenericValue(rhs, allocator, copyConstStrings);
923 return *this;
924 }
925
927
931 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
932 GenericValue temp;
933 temp.RawAssign(*this);
934 RawAssign(other);
935 other.RawAssign(temp);
936 return *this;
937 }
938
940
951 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
952
954
955 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
957
959
960
965 template <typename SourceAllocator>
966 bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
968 if (GetType() != rhs.GetType())
969 return false;
970
971 switch (GetType()) {
972 case kObjectType: // Warning: O(n^2) inner-loop
973 if (data_.o.size != rhs.data_.o.size)
974 return false;
975 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
976 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
977 if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
978 return false;
979 }
980 return true;
981
982 case kArrayType:
983 if (data_.a.size != rhs.data_.a.size)
984 return false;
985 for (SizeType i = 0; i < data_.a.size; i++)
986 if ((*this)[i] != rhs[i])
987 return false;
988 return true;
989
990 case kStringType:
991 return StringEqual(rhs);
992
993 case kNumberType:
994 if (IsDouble() || rhs.IsDouble()) {
995 double a = GetDouble(); // May convert from integer to double.
996 double b = rhs.GetDouble(); // Ditto
997 return a >= b && a <= b; // Prevent -Wfloat-equal
998 }
999 else
1000 return data_.n.u64 == rhs.data_.n.u64;
1001
1002 default:
1003 return true;
1004 }
1005 }
1006
1008 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1009
1010#if RAPIDJSON_HAS_STDSTRING
1012
1014 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
1015#endif
1016
1018
1020 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
1021
1023
1025 template <typename SourceAllocator>
1026 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1027
1029 bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1030
1032
1034 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1035
1037
1039 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1040
1042
1044 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1046
1048
1049
1050 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1051 bool IsNull() const { return data_.f.flags == kNullFlag; }
1052 bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1053 bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1054 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1055 bool IsObject() const { return data_.f.flags == kObjectFlag; }
1056 bool IsArray() const { return data_.f.flags == kArrayFlag; }
1057 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1058 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1059 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1060 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1061 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1062 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1063 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1064
1065 // Checks whether a number can be losslessly converted to a double.
1066 bool IsLosslessDouble() const {
1067 if (!IsNumber()) return false;
1068 if (IsUint64()) {
1069 uint64_t u = GetUint64();
1070 volatile double d = static_cast<double>(u);
1071 return (d >= 0.0)
1072 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1073 && (u == static_cast<uint64_t>(d));
1074 }
1075 if (IsInt64()) {
1076 int64_t i = GetInt64();
1077 volatile double d = static_cast<double>(i);
1078 return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1079 && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1080 && (i == static_cast<int64_t>(d));
1081 }
1082 return true; // double, int, uint are always lossless
1083 }
1084
1085 // Checks whether a number is a float (possible lossy).
1086 bool IsFloat() const {
1087 if ((data_.f.flags & kDoubleFlag) == 0)
1088 return false;
1089 double d = GetDouble();
1090 return d >= -3.4028234e38 && d <= 3.4028234e38;
1091 }
1092 // Checks whether a number can be losslessly converted to a float.
1093 bool IsLosslessFloat() const {
1094 if (!IsNumber()) return false;
1095 double a = GetDouble();
1096 if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1097 || a > static_cast<double>((std::numeric_limits<float>::max)()))
1098 return false;
1099 double b = static_cast<double>(static_cast<float>(a));
1100 return a >= b && a <= b; // Prevent -Wfloat-equal
1101 }
1102
1104
1106
1107
1108 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1109
1111
1113
1114
1115 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1117
1118 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1119
1121
1123
1124
1126
1127 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1128
1130 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1131
1133 SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1134
1136 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1137
1139
1147 template <typename T>
1148 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1149 GenericValue n(StringRef(name));
1150 return (*this)[n];
1151 }
1152 template <typename T>
1153 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]; }
1154
1156
1164 template <typename SourceAllocator>
1165 GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1166 MemberIterator member = FindMember(name);
1167 if (member != MemberEnd())
1168 return member->value;
1169 else {
1170 RAPIDJSON_ASSERT(false); // see above note
1171
1172 // This will generate -Wexit-time-destructors in clang
1173 // static GenericValue NullValue;
1174 // return NullValue;
1175
1176 // Use static buffer and placement-new to prevent destruction
1177 static char buffer[sizeof(GenericValue)];
1178 return *new (buffer) GenericValue();
1179 }
1180 }
1181 template <typename SourceAllocator>
1182 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1183
1184#if RAPIDJSON_HAS_STDSTRING
1186 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1187 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1188#endif
1189
1191
1192 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1194
1195 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1197
1198 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1200
1201 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1202
1204
1209 GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1210 RAPIDJSON_ASSERT(IsObject());
1211 if (newCapacity > data_.o.capacity) {
1212 SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
1213 data_.o.capacity = newCapacity;
1214 }
1215 return *this;
1216 }
1217
1219
1226 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1227
1228#if RAPIDJSON_HAS_STDSTRING
1230
1237 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1238#endif
1239
1241
1249 template <typename SourceAllocator>
1250 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1251
1253
1264 MemberIterator FindMember(const Ch* name) {
1265 GenericValue n(StringRef(name));
1266 return FindMember(n);
1267 }
1268
1269 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1270
1272
1284 template <typename SourceAllocator>
1286 RAPIDJSON_ASSERT(IsObject());
1287 RAPIDJSON_ASSERT(name.IsString());
1288 MemberIterator member = MemberBegin();
1289 for ( ; member != MemberEnd(); ++member)
1290 if (name.StringEqual(member->name))
1291 break;
1292 return member;
1293 }
1294 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1295
1296#if RAPIDJSON_HAS_STDSTRING
1298
1304 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1305 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1306#endif
1307
1309
1318 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1319 RAPIDJSON_ASSERT(IsObject());
1320 RAPIDJSON_ASSERT(name.IsString());
1321
1322 ObjectData& o = data_.o;
1323 if (o.size >= o.capacity)
1324 MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1325 Member* members = GetMembersPointer();
1326 members[o.size].name.RawAssign(name);
1327 members[o.size].value.RawAssign(value);
1328 o.size++;
1329 return *this;
1330 }
1331
1333
1341 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1342 GenericValue v(value);
1343 return AddMember(name, v, allocator);
1344 }
1345
1346#if RAPIDJSON_HAS_STDSTRING
1348
1356 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1357 GenericValue v(value, allocator);
1358 return AddMember(name, v, allocator);
1359 }
1360#endif
1361
1363
1379 template <typename T>
1380 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1381 AddMember(GenericValue& name, T value, Allocator& allocator) {
1382 GenericValue v(value);
1383 return AddMember(name, v, allocator);
1384 }
1385
1386#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1387 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1388 return AddMember(name, value, allocator);
1389 }
1390 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1391 return AddMember(name, value, allocator);
1392 }
1393 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1394 return AddMember(name, value, allocator);
1395 }
1396 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1397 GenericValue n(name);
1398 return AddMember(n, value, allocator);
1399 }
1400#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1401
1402
1404
1413 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1414 GenericValue n(name);
1415 return AddMember(n, value, allocator);
1416 }
1417
1419
1427 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1428 GenericValue v(value);
1429 return AddMember(name, v, allocator);
1430 }
1431
1433
1449 template <typename T>
1450 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1451 AddMember(StringRefType name, T value, Allocator& allocator) {
1452 GenericValue n(name);
1453 return AddMember(n, value, allocator);
1454 }
1455
1457
1460 void RemoveAllMembers() {
1461 RAPIDJSON_ASSERT(IsObject());
1462 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1463 m->~Member();
1464 data_.o.size = 0;
1465 }
1466
1468
1475 bool RemoveMember(const Ch* name) {
1476 GenericValue n(StringRef(name));
1477 return RemoveMember(n);
1478 }
1479
1480#if RAPIDJSON_HAS_STDSTRING
1481 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1482#endif
1483
1484 template <typename SourceAllocator>
1485 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1486 MemberIterator m = FindMember(name);
1487 if (m != MemberEnd()) {
1488 RemoveMember(m);
1489 return true;
1490 }
1491 else
1492 return false;
1493 }
1494
1496
1503 MemberIterator RemoveMember(MemberIterator m) {
1504 RAPIDJSON_ASSERT(IsObject());
1505 RAPIDJSON_ASSERT(data_.o.size > 0);
1506 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1507 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1508
1509 MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1510 if (data_.o.size > 1 && m != last)
1511 *m = *last; // Move the last one to this place
1512 else
1513 m->~Member(); // Only one left, just destroy
1514 --data_.o.size;
1515 return m;
1516 }
1517
1519
1527 MemberIterator EraseMember(ConstMemberIterator pos) {
1528 return EraseMember(pos, pos +1);
1529 }
1530
1532
1540 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1541 RAPIDJSON_ASSERT(IsObject());
1542 RAPIDJSON_ASSERT(data_.o.size > 0);
1543 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1544 RAPIDJSON_ASSERT(first >= MemberBegin());
1545 RAPIDJSON_ASSERT(first <= last);
1546 RAPIDJSON_ASSERT(last <= MemberEnd());
1547
1548 MemberIterator pos = MemberBegin() + (first - MemberBegin());
1549 for (MemberIterator itr = pos; itr != last; ++itr)
1550 itr->~Member();
1551 std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1552 data_.o.size -= static_cast<SizeType>(last - first);
1553 return pos;
1554 }
1555
1557
1561 bool EraseMember(const Ch* name) {
1562 GenericValue n(StringRef(name));
1563 return EraseMember(n);
1564 }
1565
1566#if RAPIDJSON_HAS_STDSTRING
1567 bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1568#endif
1569
1570 template <typename SourceAllocator>
1571 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1572 MemberIterator m = FindMember(name);
1573 if (m != MemberEnd()) {
1574 EraseMember(m);
1575 return true;
1576 }
1577 else
1578 return false;
1579 }
1580
1581 Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1582 ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1583
1585
1587
1588
1590
1591 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1592
1594 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1595
1597 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1598
1600 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1601
1603
1606 void Clear() {
1607 RAPIDJSON_ASSERT(IsArray());
1608 GenericValue* e = GetElementsPointer();
1609 for (GenericValue* v = e; v != e + data_.a.size; ++v)
1610 v->~GenericValue();
1611 data_.a.size = 0;
1612 }
1613
1615
1619 GenericValue& operator[](SizeType index) {
1620 RAPIDJSON_ASSERT(IsArray());
1621 RAPIDJSON_ASSERT(index < data_.a.size);
1622 return GetElementsPointer()[index];
1623 }
1624 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1625
1627
1628 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1630
1631 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1633
1634 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1636
1637 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1638
1640
1645 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1646 RAPIDJSON_ASSERT(IsArray());
1647 if (newCapacity > data_.a.capacity) {
1648 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1649 data_.a.capacity = newCapacity;
1650 }
1651 return *this;
1652 }
1653
1655
1664 GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1665 RAPIDJSON_ASSERT(IsArray());
1666 if (data_.a.size >= data_.a.capacity)
1667 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1668 GetElementsPointer()[data_.a.size++].RawAssign(value);
1669 return *this;
1670 }
1671
1672#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1673 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1674 return PushBack(value, allocator);
1675 }
1676#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1677
1679
1687 GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1688 return (*this).template PushBack<StringRefType>(value, allocator);
1689 }
1690
1692
1708 template <typename T>
1709 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1710 PushBack(T value, Allocator& allocator) {
1711 GenericValue v(value);
1712 return PushBack(v, allocator);
1713 }
1714
1716
1719 GenericValue& PopBack() {
1720 RAPIDJSON_ASSERT(IsArray());
1721 RAPIDJSON_ASSERT(!Empty());
1722 GetElementsPointer()[--data_.a.size].~GenericValue();
1723 return *this;
1724 }
1725
1727
1734 return Erase(pos, pos + 1);
1735 }
1736
1738
1746 RAPIDJSON_ASSERT(IsArray());
1747 RAPIDJSON_ASSERT(data_.a.size > 0);
1748 RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1749 RAPIDJSON_ASSERT(first >= Begin());
1750 RAPIDJSON_ASSERT(first <= last);
1751 RAPIDJSON_ASSERT(last <= End());
1752 ValueIterator pos = Begin() + (first - Begin());
1753 for (ValueIterator itr = pos; itr != last; ++itr)
1754 itr->~GenericValue();
1755 std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1756 data_.a.size -= static_cast<SizeType>(last - first);
1757 return pos;
1758 }
1759
1760 Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1761 ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1762
1764
1766
1767
1768 int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1769 unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1770 int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1771 uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1772
1774
1776 double GetDouble() const {
1777 RAPIDJSON_ASSERT(IsNumber());
1778 if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1779 if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1780 if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1781 if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1782 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1783 }
1784
1786
1788 float GetFloat() const {
1789 return static_cast<float>(GetDouble());
1790 }
1791
1792 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1793 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1794 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1795 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1796 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1797 GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1798
1800
1802
1803
1804 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1805
1807
1809 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1810
1812
1819 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1820
1822
1826 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1827
1829
1836 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1837
1839
1844 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1845
1847
1852 GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1853
1854#if RAPIDJSON_HAS_STDSTRING
1856
1862 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1863#endif
1864
1866
1868
1869
1871
1874 template <typename T>
1875 bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1876
1877 template <typename T>
1878 T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1879
1880 template <typename T>
1881 T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1882
1883 template<typename T>
1884 ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1885
1886 template<typename T>
1887 ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1888
1890
1892
1898 template <typename Handler>
1899 bool Accept(Handler& handler) const {
1900 switch(GetType()) {
1901 case kNullType: return handler.Null();
1902 case kFalseType: return handler.Bool(false);
1903 case kTrueType: return handler.Bool(true);
1904
1905 case kObjectType:
1906 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1907 return false;
1908 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1909 RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1910 if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1911 return false;
1912 if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1913 return false;
1914 }
1915 return handler.EndObject(data_.o.size);
1916
1917 case kArrayType:
1918 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1919 return false;
1920 for (const GenericValue* v = Begin(); v != End(); ++v)
1921 if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1922 return false;
1923 return handler.EndArray(data_.a.size);
1924
1925 case kStringType:
1926 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1927
1928 default:
1929 RAPIDJSON_ASSERT(GetType() == kNumberType);
1930 if (IsDouble()) return handler.Double(data_.n.d);
1931 else if (IsInt()) return handler.Int(data_.n.i.i);
1932 else if (IsUint()) return handler.Uint(data_.n.u.u);
1933 else if (IsInt64()) return handler.Int64(data_.n.i64);
1934 else return handler.Uint64(data_.n.u64);
1935 }
1936 }
1937
1938private:
1939 template <typename, typename> friend class GenericValue;
1940 template <typename, typename, typename> friend class GenericDocument;
1941
1942 enum {
1943 kBoolFlag = 0x0008,
1944 kNumberFlag = 0x0010,
1945 kIntFlag = 0x0020,
1946 kUintFlag = 0x0040,
1947 kInt64Flag = 0x0080,
1948 kUint64Flag = 0x0100,
1949 kDoubleFlag = 0x0200,
1950 kStringFlag = 0x0400,
1951 kCopyFlag = 0x0800,
1952 kInlineStrFlag = 0x1000,
1953
1954 // Initial flags of different types.
1955 kNullFlag = kNullType,
1956 kTrueFlag = kTrueType | kBoolFlag,
1957 kFalseFlag = kFalseType | kBoolFlag,
1958 kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
1959 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
1960 kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
1961 kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
1962 kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
1963 kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
1964 kConstStringFlag = kStringType | kStringFlag,
1965 kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
1966 kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
1967 kObjectFlag = kObjectType,
1968 kArrayFlag = kArrayType,
1969
1970 kTypeMask = 0x07
1971 };
1972
1973 static const SizeType kDefaultArrayCapacity = 16;
1974 static const SizeType kDefaultObjectCapacity = 16;
1975
1976 struct Flag {
1977#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
1978 char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
1979#elif RAPIDJSON_64BIT
1980 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
1981#else
1982 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
1983#endif
1984 uint16_t flags;
1985 };
1986
1987 struct String {
1988 SizeType length;
1990 const Ch* str;
1991 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1992
1993 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1994 // (excluding the terminating zero) and store a value to determine the length of the contained
1995 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1996 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1997 // the string terminator as well. For getting the string length back from that value just use
1998 // "MaxSize - str[LenPos]".
1999 // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2000 // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
2002 enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2003 Ch str[MaxChars];
2004
2005 inline static bool Usable(SizeType len) { return (MaxSize >= len); }
2006 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2007 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
2008 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2009
2010 // By using proper binary layout, retrieval of different integer types do not need conversions.
2011 union Number {
2012#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2013 struct I {
2014 int i;
2015 char padding[4];
2016 }i;
2017 struct U {
2018 unsigned u;
2019 char padding2[4];
2020 }u;
2021#else
2022 struct I {
2023 char padding[4];
2024 int i;
2025 }i;
2026 struct U {
2027 char padding2[4];
2028 unsigned u;
2029 }u;
2030#endif
2031 int64_t i64;
2032 uint64_t u64;
2033 double d;
2034 }; // 8 bytes
2035
2036 struct ObjectData {
2037 SizeType size;
2038 SizeType capacity;
2039 Member* members;
2040 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2041
2042 struct ArrayData {
2043 SizeType size;
2044 SizeType capacity;
2045 GenericValue* elements;
2046 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2047
2048 union Data {
2049 String s;
2050 ShortString ss;
2051 Number n;
2052 ObjectData o;
2053 ArrayData a;
2054 Flag f;
2055 }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2056
2057 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2058 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2059 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2060 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2061 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2062 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2063
2064 // Initialize this value as array with initial data, without calling destructor.
2065 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2066 data_.f.flags = kArrayFlag;
2067 if (count) {
2068 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2069 SetElementsPointer(e);
2070 std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2071 }
2072 else
2073 SetElementsPointer(0);
2074 data_.a.size = data_.a.capacity = count;
2075 }
2076
2078 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2079 data_.f.flags = kObjectFlag;
2080 if (count) {
2081 Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2082 SetMembersPointer(m);
2083 std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2084 }
2085 else
2086 SetMembersPointer(0);
2087 data_.o.size = data_.o.capacity = count;
2088 }
2089
2091 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2092 data_.f.flags = kConstStringFlag;
2093 SetStringPointer(s);
2094 data_.s.length = s.length;
2095 }
2096
2099 Ch* str = 0;
2100 if (ShortString::Usable(s.length)) {
2101 data_.f.flags = kShortStringFlag;
2102 data_.ss.SetLength(s.length);
2103 str = data_.ss.str;
2104 } else {
2105 data_.f.flags = kCopyStringFlag;
2106 data_.s.length = s.length;
2107 str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2108 SetStringPointer(str);
2109 }
2110 std::memcpy(str, s, s.length * sizeof(Ch));
2111 str[s.length] = '\0';
2112 }
2113
2115 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2116 data_ = rhs.data_;
2117 // data_.f.flags = rhs.data_.f.flags;
2118 rhs.data_.f.flags = kNullFlag;
2119 }
2120
2121 template <typename SourceAllocator>
2122 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2123 RAPIDJSON_ASSERT(IsString());
2124 RAPIDJSON_ASSERT(rhs.IsString());
2125
2126 const SizeType len1 = GetStringLength();
2127 const SizeType len2 = rhs.GetStringLength();
2128 if(len1 != len2) { return false; }
2129
2130 const Ch* const str1 = GetString();
2131 const Ch* const str2 = rhs.GetString();
2132 if(str1 == str2) { return true; } // fast path for constant string
2133
2134 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2135 }
2136
2137 Data data_;
2138};
2139
2142
2144// GenericDocument
2145
2147
2154template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
2155class GenericDocument : public GenericValue<Encoding, Allocator> {
2156public:
2157 typedef typename Encoding::Ch Ch;
2158 typedef GenericValue<Encoding, Allocator> ValueType;
2160
2162
2168 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2169 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2170 {
2171 if (!allocator_)
2172 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2173 }
2174
2176
2181 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2182 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2183 {
2184 if (!allocator_)
2185 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2186 }
2187
2188#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2190 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2191 : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2192 allocator_(rhs.allocator_),
2193 ownAllocator_(rhs.ownAllocator_),
2194 stack_(std::move(rhs.stack_)),
2195 parseResult_(rhs.parseResult_)
2196 {
2197 rhs.allocator_ = 0;
2198 rhs.ownAllocator_ = 0;
2199 rhs.parseResult_ = ParseResult();
2200 }
2201#endif
2202
2204 Destroy();
2205 }
2206
2207#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2209 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2210 {
2211 // The cast to ValueType is necessary here, because otherwise it would
2212 // attempt to call GenericValue's templated assignment operator.
2213 ValueType::operator=(std::forward<ValueType>(rhs));
2214
2215 // Calling the destructor here would prematurely call stack_'s destructor
2216 Destroy();
2217
2218 allocator_ = rhs.allocator_;
2219 ownAllocator_ = rhs.ownAllocator_;
2220 stack_ = std::move(rhs.stack_);
2221 parseResult_ = rhs.parseResult_;
2222
2223 rhs.allocator_ = 0;
2224 rhs.ownAllocator_ = 0;
2225 rhs.parseResult_ = ParseResult();
2226
2227 return *this;
2228 }
2229#endif
2230
2232
2237 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2238 ValueType::Swap(rhs);
2239 stack_.Swap(rhs.stack_);
2240 internal::Swap(allocator_, rhs.allocator_);
2241 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2242 internal::Swap(parseResult_, rhs.parseResult_);
2243 return *this;
2244 }
2245
2246 // Allow Swap with ValueType.
2247 // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2248 using ValueType::Swap;
2249
2251
2262 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2263
2265
2269 template <typename Generator>
2270 GenericDocument& Populate(Generator& g) {
2271 ClearStackOnExit scope(*this);
2272 if (g(*this)) {
2273 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2274 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2275 }
2276 return *this;
2277 }
2278
2281
2283
2289 template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2290 GenericDocument& ParseStream(InputStream& is) {
2292 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2293 ClearStackOnExit scope(*this);
2294 parseResult_ = reader.template Parse<parseFlags>(is, *this);
2295 if (parseResult_) {
2296 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2297 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2298 }
2299 return *this;
2300 }
2301
2303
2308 template <unsigned parseFlags, typename InputStream>
2312
2314
2318 template <typename InputStream>
2322
2323
2326
2328
2332 template <unsigned parseFlags>
2337
2339
2345
2346
2349
2351
2355 template <unsigned parseFlags, typename SourceEncoding>
2356 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2357 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2360 }
2361
2363
2366 template <unsigned parseFlags>
2367 GenericDocument& Parse(const Ch* str) {
2368 return Parse<parseFlags, Encoding>(str);
2369 }
2370
2372
2374 GenericDocument& Parse(const Ch* str) {
2375 return Parse<kParseDefaultFlags>(str);
2376 }
2377
2378 template <unsigned parseFlags, typename SourceEncoding>
2379 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2380 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2381 MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2384 return *this;
2385 }
2386
2387 template <unsigned parseFlags>
2388 GenericDocument& Parse(const Ch* str, size_t length) {
2389 return Parse<parseFlags, Encoding>(str, length);
2390 }
2391
2392 GenericDocument& Parse(const Ch* str, size_t length) {
2393 return Parse<kParseDefaultFlags>(str, length);
2394 }
2395
2396#if RAPIDJSON_HAS_STDSTRING
2397 template <unsigned parseFlags, typename SourceEncoding>
2398 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2399 // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2400 return Parse<parseFlags, SourceEncoding>(str.c_str());
2401 }
2402
2403 template <unsigned parseFlags>
2404 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2405 return Parse<parseFlags, Encoding>(str.c_str());
2406 }
2407
2408 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2409 return Parse<kParseDefaultFlags>(str);
2410 }
2411#endif // RAPIDJSON_HAS_STDSTRING
2412
2414
2417
2419 bool HasParseError() const { return parseResult_.IsError(); }
2420
2422 ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2423
2425 size_t GetErrorOffset() const { return parseResult_.Offset(); }
2426
2428#ifndef __clang // -Wdocumentation
2438#endif
2439 operator ParseResult() const { return parseResult_; }
2441
2444 RAPIDJSON_ASSERT(allocator_);
2445 return *allocator_;
2446 }
2447
2449 size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2450
2451private:
2452 // clear stack on any exit from ParseStream, e.g. due to exception
2453 struct ClearStackOnExit {
2454 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2455 ~ClearStackOnExit() { d_.ClearStack(); }
2456 private:
2457 ClearStackOnExit(const ClearStackOnExit&);
2458 ClearStackOnExit& operator=(const ClearStackOnExit&);
2459 GenericDocument& d_;
2460 };
2461
2462 // callers of the following private Handler functions
2463 // template <typename,typename,typename> friend class GenericReader; // for parsing
2464 template <typename, typename> friend class GenericValue; // for deep copying
2465
2466public:
2467 // Implementation of Handler
2468 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2469 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2470 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2471 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2472 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2473 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2474 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2475
2476 bool RawNumber(const Ch* str, SizeType length, bool copy) {
2477 if (copy)
2478 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2479 else
2480 new (stack_.template Push<ValueType>()) ValueType(str, length);
2481 return true;
2482 }
2483
2484 bool String(const Ch* str, SizeType length, bool copy) {
2485 if (copy)
2486 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2487 else
2488 new (stack_.template Push<ValueType>()) ValueType(str, length);
2489 return true;
2490 }
2491
2492 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2493
2494 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2495
2496 bool EndObject(SizeType memberCount) {
2497 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2498 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2499 return true;
2500 }
2501
2502 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2503
2504 bool EndArray(SizeType elementCount) {
2505 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2506 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2507 return true;
2508 }
2509
2510private:
2515
2516 void ClearStack() {
2517 if (Allocator::kNeedFree)
2518 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2519 (stack_.template Pop<ValueType>(1))->~ValueType();
2520 else
2521 stack_.Clear();
2522 stack_.ShrinkToFit();
2523 }
2524
2525 void Destroy() {
2526 RAPIDJSON_DELETE(ownAllocator_);
2527 }
2528
2529 static const size_t kDefaultStackCapacity = 1024;
2530 Allocator* allocator_;
2531 Allocator* ownAllocator_;
2532 internal::Stack<StackAllocator> stack_;
2533 ParseResult parseResult_;
2534};
2535
2538
2540
2544template <bool Const, typename ValueT>
2545class GenericArray {
2546public:
2547 typedef GenericArray<true, ValueT> ConstArray;
2548 typedef GenericArray<false, ValueT> Array;
2549 typedef ValueT PlainType;
2550 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2551 typedef ValueType* ValueIterator; // This may be const or non-const iterator
2552 typedef const ValueT* ConstValueIterator;
2553 typedef typename ValueType::AllocatorType AllocatorType;
2554 typedef typename ValueType::StringRefType StringRefType;
2555
2556 template <typename, typename>
2557 friend class GenericValue;
2558
2559 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2560 GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2561 ~GenericArray() {}
2562
2563 SizeType Size() const { return value_.Size(); }
2564 SizeType Capacity() const { return value_.Capacity(); }
2565 bool Empty() const { return value_.Empty(); }
2566 void Clear() const { value_.Clear(); }
2567 ValueType& operator[](SizeType index) const { return value_[index]; }
2568 ValueIterator Begin() const { return value_.Begin(); }
2569 ValueIterator End() const { return value_.End(); }
2570 GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2571 GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2572#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2573 GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2574#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2575 GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2576 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; }
2577 GenericArray PopBack() const { value_.PopBack(); return *this; }
2578 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2579 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2580
2581#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2582 ValueIterator begin() const { return value_.Begin(); }
2583 ValueIterator end() const { return value_.End(); }
2584#endif
2585
2586private:
2587 GenericArray();
2588 GenericArray(ValueType& value) : value_(value) {}
2589 ValueType& value_;
2590};
2591
2593
2597template <bool Const, typename ValueT>
2598class GenericObject {
2599public:
2600 typedef GenericObject<true, ValueT> ConstObject;
2601 typedef GenericObject<false, ValueT> Object;
2602 typedef ValueT PlainType;
2603 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2604 typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
2606 typedef typename ValueType::AllocatorType AllocatorType;
2607 typedef typename ValueType::StringRefType StringRefType;
2608 typedef typename ValueType::EncodingType EncodingType;
2609 typedef typename ValueType::Ch Ch;
2610
2611 template <typename, typename>
2612 friend class GenericValue;
2613
2614 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2615 GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2616 ~GenericObject() {}
2617
2618 SizeType MemberCount() const { return value_.MemberCount(); }
2619 SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2620 bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2621 template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2622 template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2623#if RAPIDJSON_HAS_STDSTRING
2624 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2625#endif
2626 MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2627 MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2628 GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2629 bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2630#if RAPIDJSON_HAS_STDSTRING
2631 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2632#endif
2633 template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2634 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2635 template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2636#if RAPIDJSON_HAS_STDSTRING
2637 MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2638#endif
2639 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2640 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2641#if RAPIDJSON_HAS_STDSTRING
2642 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2643#endif
2644 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; }
2645#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2646 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2647 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2648 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2649 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2650#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2651 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2652 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2653 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; }
2654 void RemoveAllMembers() { value_.RemoveAllMembers(); }
2655 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2656#if RAPIDJSON_HAS_STDSTRING
2657 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2658#endif
2659 template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2660 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2661 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
2662 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2663 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2664#if RAPIDJSON_HAS_STDSTRING
2665 bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2666#endif
2667 template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2668
2669#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2670 MemberIterator begin() const { return value_.MemberBegin(); }
2671 MemberIterator end() const { return value_.MemberEnd(); }
2672#endif
2673
2674private:
2675 GenericObject();
2676 GenericObject(ValueType& value) : value_(value) {}
2677 ValueType& value_;
2678};
2679
2681RAPIDJSON_DIAG_POP
2682
2683#endif // RAPIDJSON_DOCUMENT_H_
Input byte stream wrapper with a statically bound encoding.
Helper class for accessing Value of array type.
Definition document.h:2545
A document for parsing JSON text as DOM.
Definition document.h:2155
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition document.h:2262
Allocator & GetAllocator()
Get the allocator of this document.
Definition document.h:2443
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition document.h:2333
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition document.h:2237
Allocator AllocatorType
Allocator type from template parameter.
Definition document.h:2159
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition document.h:2367
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition document.h:2168
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition document.h:2419
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition document.h:2309
GenericDocument(const GenericDocument &)
Prohibit copying.
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition document.h:2181
Encoding::Ch Ch
Character type derived from Encoding.
Definition document.h:2157
GenericDocument & operator=(const GenericDocument &)
Prohibit assignment.
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition document.h:2319
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition document.h:2290
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition document.h:2158
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition document.h:2356
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition document.h:2422
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition document.h:2342
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition document.h:2449
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition document.h:2270
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition document.h:2425
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition document.h:2374
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition document.h:187
GenericMemberIterator()
Default constructor (singular value)
Definition document.h:169
GenericMemberIterator(Pointer p)
Internal constructor from plain pointer.
Definition document.h:229
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Definition document.h:147
GenericMemberIterator Iterator
Iterator type itself.
Definition document.h:143
DifferenceType operator-(ConstIterator that) const
Distance.
Definition document.h:225
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition document.h:145
Name-value pair in a JSON object value.
Definition document.h:67
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition document.h:69
GenericValue< Encoding, Allocator > value
value of member.
Definition document.h:70
GenericMember(const GenericMember &rhs)
Copy constructor is not permitted.
GenericMember & operator=(GenericMember &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition document.h:89
Helper class for accessing Value of object type.
Definition document.h:2598
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition reader.h:539
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition document.h:609
GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition document.h:732
void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition document.h:2091
~GenericValue()
Destructor.
Definition document.h:831
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition document.h:782
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition document.h:2078
Encoding EncodingType
Encoding type from template parameter.
Definition document.h:613
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition document.h:887
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition document.h:616
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition document.h:617
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition document.h:621
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition document.h:620
RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition document.h:788
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator)
Definition document.h:683
Allocator AllocatorType
Allocator type from template parameter.
Definition document.h:614
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition document.h:612
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition document.h:661
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition document.h:812
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition document.h:755
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition document.h:749
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition document.h:797
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition document.h:823
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition document.h:794
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition document.h:618
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition document.h:743
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition document.h:631
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition document.h:791
void RawAssign(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition document.h:2115
GenericValue(const GenericValue &rhs)
Copy constructor is not permitted.
GenericValue(float f) RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition document.h:785
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition document.h:770
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition document.h:2098
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition document.h:867
Encoding::Ch Ch
Character type derived from Encoding.
Definition document.h:615
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition document.h:619
Concept for allocating, resizing and freeing memory block.
Concept for encoding of Unicode characters.
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition document.h:2141
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:395
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition document.h:2537
#define RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition rapidjson.h:639
#define RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition rapidjson.h:464
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition rapidjson.h:477
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:407
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:122
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:125
ParseErrorCode
Error code of parsing.
Definition error.h:65
void swap(UniqueArray< T > &v1, UniqueArray< T > &v2)
Échange les valeurs de v1 et v2.
Type
Type of JSON value.
Definition rapidjson.h:665
@ kFalseType
false
Definition rapidjson.h:667
@ kObjectType
object
Definition rapidjson.h:669
@ kTrueType
true
Definition rapidjson.h:668
@ kStringType
string
Definition rapidjson.h:671
@ kNullType
null
Definition rapidjson.h:666
@ kArrayType
array
Definition rapidjson.h:670
@ kNumberType
number
Definition rapidjson.h:672
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:652
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition rapidjson.h:385
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition rapidjson.h:290
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:648
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition rapidjson.h:446
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition reader.h:149
A read-write string stream.
Definition stream.h:189
Reference to a constant string (not taking a copy)
Definition document.h:287
GenericStringRef & operator=(const GenericStringRef &rhs)
Copy assignment operator not permitted - immutable type.
CharType Ch
character type of the string
Definition document.h:288
static const Ch emptyString[]
Definition document.h:370
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition document.h:361
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
Definition document.h:415
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition document.h:352
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition document.h:340
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition document.h:395
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition document.h:316
GenericStringRef(CharType(&str)[N])
Disallow construction from non-const array.
const Ch *const s
plain CharType pointer
Definition document.h:360
Read-only string stream.
Definition stream.h:155
SizeType hashcode
reserved
Definition document.h:1989
Represents an in-memory input byte stream.
Result of parsing (wraps ParseErrorCode)
Definition error.h:107