Arcane  v3.14.10.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
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>
134
135 friend class GenericValue<Encoding,Allocator>;
136 template <bool, typename, typename> friend class GenericMemberIterator;
137
139 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
140
141public:
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>
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) {
416 return GenericStringRef<CharType>(str, SizeType(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;
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>
648
650 template <typename StackAllocator>
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;
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>
2309 GenericDocument& ParseStream(InputStream& is) {
2310 return ParseStream<parseFlags, Encoding, InputStream>(is);
2311 }
2312
2314
2318 template <typename InputStream>
2319 GenericDocument& ParseStream(InputStream& is) {
2320 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2321 }
2323
2326
2328
2332 template <unsigned parseFlags>
2335 return ParseStream<parseFlags | kParseInsituFlag>(s);
2336 }
2337
2339
2343 return ParseInsitu<kParseDefaultFlags>(str);
2344 }
2346
2349
2351
2355 template <unsigned parseFlags, typename SourceEncoding>
2356 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2357 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2359 return ParseStream<parseFlags, SourceEncoding>(s);
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));
2383 ParseStream<parseFlags, SourceEncoding>(is);
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
2454 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2455 ~ClearStackOnExit() { d_.ClearStack(); }
2456 private:
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_;
2533 ParseResult parseResult_;
2534};
2535
2538
2540
2544template <bool Const, typename ValueT>
2546public:
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>
2599public:
2602 typedef ValueT PlainType;
2603 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
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_
Lecteur des fichiers de maillage via la bibliothèque LIMA.
Definition Lima.cc:120
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
(Constant) member iterator for a JSON object value
Definition document.h:133
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
reference Reference
Reference to (const) GenericMember.
Definition document.h:161
Pointer ptr_
raw pointer
Definition document.h:231
difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition document.h:163
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition document.h:147
pointer Pointer
Pointer to (const) GenericMember.
Definition document.h:159
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
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition pointer.h:80
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
A type-unsafe stack for storing different types of data.
Definition stack.h:38
Concept for allocating, resizing and freeing memory block.
Concept for encoding of Unicode characters.
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
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
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
static const Ch emptyString[]
Empty string - used when passing in a NULL pointer.
Definition document.h:370
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
ParseErrorCode Code() const
Get the error code.
Definition error.h:117
bool IsError() const
Whether the result is an error.
Definition error.h:124
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition error.h:119