NDDEM
document.h
Go to the documentation of this file.
1 // Tencent is pleased to support the open source community by making RapidJSON available.
2 //
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 //
5 // Licensed under the MIT License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // http://opensource.org/licenses/MIT
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14 
15 #ifndef CEREAL_RAPIDJSON_DOCUMENT_H_
16 #define CEREAL_RAPIDJSON_DOCUMENT_H_
17 
20 #include "reader.h"
21 #include "internal/meta.h"
22 #include "internal/strfunc.h"
23 #include "memorystream.h"
24 #include "encodedstream.h"
25 #include <new> // placement new
26 #include <limits>
27 #ifdef __cpp_lib_three_way_comparison
28 #include <compare>
29 #endif
30 
31 CEREAL_RAPIDJSON_DIAG_PUSH
32 #ifdef __clang__
33 CEREAL_RAPIDJSON_DIAG_OFF(padded)
34 CEREAL_RAPIDJSON_DIAG_OFF(switch-enum)
35 CEREAL_RAPIDJSON_DIAG_OFF(c++98-compat)
36 #elif defined(_MSC_VER)
37 CEREAL_RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
38 CEREAL_RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
39 #endif
40 
41 #ifdef __GNUC__
42 CEREAL_RAPIDJSON_DIAG_OFF(effc++)
43 #endif // __GNUC__
44 
45 #ifndef CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS
46 #include <iterator> // std::random_access_iterator_tag
47 #endif
48 
49 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
50 #include <utility> // std::move
51 #endif
52 
54 
55 // Forward declaration.
56 template <typename Encoding, typename Allocator>
57 class GenericValue;
58 
59 template <typename Encoding, typename Allocator, typename StackAllocator>
60 class GenericDocument;
61 
63 
68 template <typename Encoding, typename Allocator>
69 struct GenericMember {
72 
73  // swap() for std::sort() and other potential use in STL.
74  friend inline void swap(GenericMember& a, GenericMember& b) CEREAL_RAPIDJSON_NOEXCEPT {
75  a.name.Swap(b.name);
76  a.value.Swap(b.value);
77  }
78 };
79 
81 // GenericMemberIterator
82 
83 #ifndef CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS
84 
86 
104 template <bool Const, typename Encoding, typename Allocator>
106 
107  friend class GenericValue<Encoding,Allocator>;
108  template <bool, typename, typename> friend class GenericMemberIterator;
109 
112 
113 public:
120 
124  typedef ValueType * pointer;
125  typedef ValueType & reference;
126  typedef std::ptrdiff_t difference_type;
127  typedef std::random_access_iterator_tag iterator_category;
129 
131  typedef pointer Pointer;
136 
138 
142 
144 
160  Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
161 
163 
164  Iterator& operator++(){ ++ptr_; return *this; }
165  Iterator& operator--(){ --ptr_; return *this; }
166  Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
167  Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
169 
171 
174 
175  Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
176  Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
178 
180 
181  template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
182  template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
183  template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
184  template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
185  template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
186  template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
187 
188 #ifdef __cpp_lib_three_way_comparison
189  template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
190 #endif
192 
194 
195  Reference operator*() const { return *ptr_; }
196  Pointer operator->() const { return ptr_; }
197  Reference operator[](DifferenceType n) const { return ptr_[n]; }
199 
201  DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
202 
203 private:
205  explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
206 
208 };
209 
210 #else // CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS
211 
212 // class-based member iterator implementation disabled, use plain pointers
213 
214 template <bool Const, typename Encoding, typename Allocator>
216 
218 template <typename Encoding, typename Allocator>
222 };
224 template <typename Encoding, typename Allocator>
228 };
229 
230 #endif // CEREAL_RAPIDJSON_NOMEMBERITERATORCLASS
231 
233 // GenericStringRef
234 
236 
262 template<typename CharType>
264  typedef CharType Ch;
265 
267 #ifndef __clang__ // -Wdocumentation
290 #endif
291  template<SizeType N>
292  GenericStringRef(const CharType (&str)[N]) CEREAL_RAPIDJSON_NOEXCEPT
293  : s(str), length(N-1) {}
294 
296 #ifndef __clang__ // -Wdocumentation
315 #endif
316  explicit GenericStringRef(const CharType* str)
317  : s(str), length(NotNullStrLen(str)) {}
318 
320 #ifndef __clang__ // -Wdocumentation
327 #endif
328  GenericStringRef(const CharType* str, SizeType len)
329  : s(CEREAL_RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { CEREAL_RAPIDJSON_ASSERT(str != 0 || len == 0u); }
330 
331  GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
332 
334  operator const Ch *() const { return s; }
335 
336  const Ch* const s;
337  const SizeType length;
338 
339 private:
340  SizeType NotNullStrLen(const CharType* str) {
341  CEREAL_RAPIDJSON_ASSERT(str != 0);
342  return internal::StrLen(str);
343  }
344 
346  static const Ch emptyString[];
347 
349  template<SizeType N>
350  GenericStringRef(CharType (&str)[N]) /* = delete */;
352  GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
353 };
354 
355 template<typename CharType>
356 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
357 
359 
370 template<typename CharType>
371 inline GenericStringRef<CharType> StringRef(const CharType* str) {
372  return GenericStringRef<CharType>(str);
373 }
374 
376 
390 template<typename CharType>
391 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
392  return GenericStringRef<CharType>(str, SizeType(length));
393 }
394 
395 #if CEREAL_RAPIDJSON_HAS_STDSTRING
397 
408 template<typename CharType>
409 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
410  return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
411 }
412 #endif
413 
415 // GenericValue type traits
416 namespace internal {
417 
418 template <typename T, typename Encoding = void, typename Allocator = void>
419 struct IsGenericValueImpl : FalseType {};
420 
421 // select candidates according to nested encoding and allocator types
422 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
423  : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
424 
425 // helper to match arbitrary GenericValue instantiations, including derived classes
426 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
427 
428 } // namespace internal
429 
431 // TypeHelper
432 
433 namespace internal {
434 
435 template <typename ValueType, typename T>
436 struct TypeHelper {};
437 
438 template<typename ValueType>
439 struct TypeHelper<ValueType, bool> {
440  static bool Is(const ValueType& v) { return v.IsBool(); }
441  static bool Get(const ValueType& v) { return v.GetBool(); }
442  static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
443  static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
444 };
445 
446 template<typename ValueType>
447 struct TypeHelper<ValueType, int> {
448  static bool Is(const ValueType& v) { return v.IsInt(); }
449  static int Get(const ValueType& v) { return v.GetInt(); }
450  static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
451  static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
452 };
453 
454 template<typename ValueType>
455 struct TypeHelper<ValueType, unsigned> {
456  static bool Is(const ValueType& v) { return v.IsUint(); }
457  static unsigned Get(const ValueType& v) { return v.GetUint(); }
458  static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
459  static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
460 };
461 
462 #ifdef _MSC_VER
463 CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
464 template<typename ValueType>
465 struct TypeHelper<ValueType, long> {
466  static bool Is(const ValueType& v) { return v.IsInt(); }
467  static long Get(const ValueType& v) { return v.GetInt(); }
468  static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
469  static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
470 };
471 
472 CEREAL_RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
473 template<typename ValueType>
474 struct TypeHelper<ValueType, unsigned long> {
475  static bool Is(const ValueType& v) { return v.IsUint(); }
476  static unsigned long Get(const ValueType& v) { return v.GetUint(); }
477  static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
478  static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
479 };
480 #endif
481 
482 template<typename ValueType>
483 struct TypeHelper<ValueType, int64_t> {
484  static bool Is(const ValueType& v) { return v.IsInt64(); }
485  static int64_t Get(const ValueType& v) { return v.GetInt64(); }
486  static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
487  static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
488 };
489 
490 template<typename ValueType>
491 struct TypeHelper<ValueType, uint64_t> {
492  static bool Is(const ValueType& v) { return v.IsUint64(); }
493  static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
494  static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
495  static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
496 };
497 
498 template<typename ValueType>
499 struct TypeHelper<ValueType, double> {
500  static bool Is(const ValueType& v) { return v.IsDouble(); }
501  static double Get(const ValueType& v) { return v.GetDouble(); }
502  static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
503  static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
504 };
505 
506 template<typename ValueType>
507 struct TypeHelper<ValueType, float> {
508  static bool Is(const ValueType& v) { return v.IsFloat(); }
509  static float Get(const ValueType& v) { return v.GetFloat(); }
510  static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
511  static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
512 };
513 
514 template<typename ValueType>
515 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
516  typedef const typename ValueType::Ch* StringType;
517  static bool Is(const ValueType& v) { return v.IsString(); }
518  static StringType Get(const ValueType& v) { return v.GetString(); }
519  static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
520  static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
521 };
522 
523 #if CEREAL_RAPIDJSON_HAS_STDSTRING
524 template<typename ValueType>
525 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
526  typedef std::basic_string<typename ValueType::Ch> StringType;
527  static bool Is(const ValueType& v) { return v.IsString(); }
528  static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
529  static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
530 };
531 #endif
532 
533 template<typename ValueType>
534 struct TypeHelper<ValueType, typename ValueType::Array> {
535  typedef typename ValueType::Array ArrayType;
536  static bool Is(const ValueType& v) { return v.IsArray(); }
537  static ArrayType Get(ValueType& v) { return v.GetArray(); }
538  static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
539  static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
540 };
541 
542 template<typename ValueType>
543 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
544  typedef typename ValueType::ConstArray ArrayType;
545  static bool Is(const ValueType& v) { return v.IsArray(); }
546  static ArrayType Get(const ValueType& v) { return v.GetArray(); }
547 };
548 
549 template<typename ValueType>
550 struct TypeHelper<ValueType, typename ValueType::Object> {
551  typedef typename ValueType::Object ObjectType;
552  static bool Is(const ValueType& v) { return v.IsObject(); }
553  static ObjectType Get(ValueType& v) { return v.GetObject(); }
554  static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
555  static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
556 };
557 
558 template<typename ValueType>
559 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
560  typedef typename ValueType::ConstObject ObjectType;
561  static bool Is(const ValueType& v) { return v.IsObject(); }
562  static ObjectType Get(const ValueType& v) { return v.GetObject(); }
563 };
564 
565 } // namespace internal
566 
567 // Forward declarations
568 template <bool, typename> class GenericArray;
569 template <bool, typename> class GenericObject;
570 
572 // GenericValue
573 
575 
584 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
586 public:
591  typedef typename Encoding::Ch Ch;
602 
604 
605 
607  GenericValue() CEREAL_RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
608 
609 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
611  GenericValue(GenericValue&& rhs) CEREAL_RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
612  rhs.data_.f.flags = kNullFlag; // give up contents
613  }
614 #endif
615 
616 private:
619 
620 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
622  template <typename StackAllocator>
624 
626  template <typename StackAllocator>
628 #endif
629 
630 public:
631 
633 
637  explicit GenericValue(Type type) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
638  static const uint16_t defaultFlags[] = {
641  };
643  data_.f.flags = defaultFlags[type];
644 
645  // Use ShortString to store empty string.
646  if (type == kStringType)
647  data_.ss.SetLength(0);
648  }
649 
651 
658  template <typename SourceAllocator>
659  GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
660  switch (rhs.GetType()) {
661  case kObjectType: {
662  SizeType count = rhs.data_.o.size;
663  Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
665  for (SizeType i = 0; i < count; i++) {
666  new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
667  new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
668  }
670  data_.o.size = data_.o.capacity = count;
671  SetMembersPointer(lm);
672  }
673  break;
674  case kArrayType: {
675  SizeType count = rhs.data_.a.size;
676  GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
678  for (SizeType i = 0; i < count; i++)
679  new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
681  data_.a.size = data_.a.capacity = count;
682  SetElementsPointer(le);
683  }
684  break;
685  case kStringType:
686  if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
687  data_.f.flags = rhs.data_.f.flags;
688  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
689  }
690  else
691  SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
692  break;
693  default:
694  data_.f.flags = rhs.data_.f.flags;
695  data_ = *reinterpret_cast<const Data*>(&rhs.data_);
696  break;
697  }
698  }
699 
701 
706 #ifndef CEREAL_RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
707  template <typename T>
708  explicit GenericValue(T b, CEREAL_RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) CEREAL_RAPIDJSON_NOEXCEPT // See #472
709 #else
710  explicit GenericValue(bool b) CEREAL_RAPIDJSON_NOEXCEPT
711 #endif
712  : data_() {
713  // safe-guard against failing SFINAE
715  data_.f.flags = b ? kTrueFlag : kFalseFlag;
716  }
717 
719  explicit GenericValue(int i) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
720  data_.n.i64 = i;
722  }
723 
725  explicit GenericValue(unsigned u) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
726  data_.n.u64 = u;
727  data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
728  }
729 
731  explicit GenericValue(int64_t i64) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
732  data_.n.i64 = i64;
734  if (i64 >= 0) {
736  if (!(static_cast<uint64_t>(i64) & CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
737  data_.f.flags |= kUintFlag;
738  if (!(static_cast<uint64_t>(i64) & CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
739  data_.f.flags |= kIntFlag;
740  }
741  else if (i64 >= static_cast<int64_t>(CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
742  data_.f.flags |= kIntFlag;
743  }
744 
746  explicit GenericValue(uint64_t u64) CEREAL_RAPIDJSON_NOEXCEPT : data_() {
747  data_.n.u64 = u64;
749  if (!(u64 & CEREAL_RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
750  data_.f.flags |= kInt64Flag;
751  if (!(u64 & CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
752  data_.f.flags |= kUintFlag;
753  if (!(u64 & CEREAL_RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
754  data_.f.flags |= kIntFlag;
755  }
756 
758  explicit GenericValue(double d) CEREAL_RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
759 
761  explicit GenericValue(float f) CEREAL_RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
762 
764  GenericValue(const Ch* s, SizeType length) CEREAL_RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
765 
767  explicit GenericValue(StringRefType s) CEREAL_RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
768 
770  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
771 
773  GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
774 
775 #if CEREAL_RAPIDJSON_HAS_STDSTRING
777 
779  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
780 #endif
781 
783 
788  GenericValue(Array a) CEREAL_RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
789  a.value_.data_ = Data();
790  a.value_.data_.f.flags = kArrayFlag;
791  }
792 
794 
799  GenericValue(Object o) CEREAL_RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
800  o.value_.data_ = Data();
801  o.value_.data_.f.flags = kObjectFlag;
802  }
803 
805 
808  if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
809  switch(data_.f.flags) {
810  case kArrayFlag:
811  {
813  for (GenericValue* v = e; v != e + data_.a.size; ++v)
814  v->~GenericValue();
815  Allocator::Free(e);
816  }
817  break;
818 
819  case kObjectFlag:
820  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
821  m->~Member();
822  Allocator::Free(GetMembersPointer());
823  break;
824 
825  case kCopyStringFlag:
826  Allocator::Free(const_cast<Ch*>(GetStringPointer()));
827  break;
828 
829  default:
830  break; // Do nothing for other types.
831  }
832  }
833  }
834 
836 
838 
839 
841 
843  GenericValue& operator=(GenericValue& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
844  if (CEREAL_RAPIDJSON_LIKELY(this != &rhs)) {
845  this->~GenericValue();
846  RawAssign(rhs);
847  }
848  return *this;
849  }
850 
851 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
853  GenericValue& operator=(GenericValue&& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
854  return *this = rhs.Move();
855  }
856 #endif
857 
859 
863  GenericValue& operator=(StringRefType str) CEREAL_RAPIDJSON_NOEXCEPT {
864  GenericValue s(str);
865  return *this = s;
866  }
867 
869 
880  template <typename T>
881  CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
882  operator=(T value) {
883  GenericValue v(value);
884  return *this = v;
885  }
886 
888 
894  template <typename SourceAllocator>
895  GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
896  CEREAL_RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
897  this->~GenericValue();
898  new (this) GenericValue(rhs, allocator, copyConstStrings);
899  return *this;
900  }
901 
903 
907  GenericValue& Swap(GenericValue& other) CEREAL_RAPIDJSON_NOEXCEPT {
908  GenericValue temp;
909  temp.RawAssign(*this);
910  RawAssign(other);
911  other.RawAssign(temp);
912  return *this;
913  }
914 
916 
927  friend inline void swap(GenericValue& a, GenericValue& b) CEREAL_RAPIDJSON_NOEXCEPT { a.Swap(b); }
928 
930 
931  GenericValue& Move() CEREAL_RAPIDJSON_NOEXCEPT { return *this; }
933 
935 
936 
941  template <typename SourceAllocator>
942  bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
944  if (GetType() != rhs.GetType())
945  return false;
946 
947  switch (GetType()) {
948  case kObjectType: // Warning: O(n^2) inner-loop
949  if (data_.o.size != rhs.data_.o.size)
950  return false;
951  for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
952  typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
953  if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
954  return false;
955  }
956  return true;
957 
958  case kArrayType:
959  if (data_.a.size != rhs.data_.a.size)
960  return false;
961  for (SizeType i = 0; i < data_.a.size; i++)
962  if ((*this)[i] != rhs[i])
963  return false;
964  return true;
965 
966  case kStringType:
967  return StringEqual(rhs);
968 
969  case kNumberType:
970  if (IsDouble() || rhs.IsDouble()) {
971  double a = GetDouble(); // May convert from integer to double.
972  double b = rhs.GetDouble(); // Ditto
973  return a >= b && a <= b; // Prevent -Wfloat-equal
974  }
975  else
976  return data_.n.u64 == rhs.data_.n.u64;
977 
978  default:
979  return true;
980  }
981  }
982 
984  bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
985 
986 #if CEREAL_RAPIDJSON_HAS_STDSTRING
988 
990  bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
991 #endif
992 
994 
996  template <typename T> CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
997 
999 
1001  template <typename SourceAllocator>
1002  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1003 
1005  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1006 
1008 
1010  template <typename T> CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1011 
1013 
1015  template <typename T> friend CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1016 
1018 
1020  template <typename T> friend CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1022 
1024 
1025 
1026  Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1027  bool IsNull() const { return data_.f.flags == kNullFlag; }
1028  bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1029  bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1030  bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1031  bool IsObject() const { return data_.f.flags == kObjectFlag; }
1032  bool IsArray() const { return data_.f.flags == kArrayFlag; }
1033  bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1034  bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1035  bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1036  bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1037  bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1038  bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1039  bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1040 
1041  // Checks whether a number can be losslessly converted to a double.
1042  bool IsLosslessDouble() const {
1043  if (!IsNumber()) return false;
1044  if (IsUint64()) {
1045  uint64_t u = GetUint64();
1046  volatile double d = static_cast<double>(u);
1047  return (d >= 0.0)
1048  && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1049  && (u == static_cast<uint64_t>(d));
1050  }
1051  if (IsInt64()) {
1052  int64_t i = GetInt64();
1053  volatile double d = static_cast<double>(i);
1054  return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1055  && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1056  && (i == static_cast<int64_t>(d));
1057  }
1058  return true; // double, int, uint are always lossless
1059  }
1060 
1061  // Checks whether a number is a float (possible lossy).
1062  bool IsFloat() const {
1063  if ((data_.f.flags & kDoubleFlag) == 0)
1064  return false;
1065  double d = GetDouble();
1066  return d >= -3.4028234e38 && d <= 3.4028234e38;
1067  }
1068  // Checks whether a number can be losslessly converted to a float.
1069  bool IsLosslessFloat() const {
1070  if (!IsNumber()) return false;
1071  double a = GetDouble();
1072  if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1073  || a > static_cast<double>((std::numeric_limits<float>::max)()))
1074  return false;
1075  double b = static_cast<double>(static_cast<float>(a));
1076  return a >= b && a <= b; // Prevent -Wfloat-equal
1077  }
1078 
1080 
1082 
1083 
1084  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1085 
1087 
1089 
1090 
1091  bool GetBool() const { CEREAL_RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1093 
1094  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1095 
1097 
1099 
1100 
1102 
1103  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1104 
1106  SizeType MemberCount() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1107 
1109  SizeType MemberCapacity() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1110 
1112  bool ObjectEmpty() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1113 
1115 
1123  template <typename T>
1124  CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1125  GenericValue n(StringRef(name));
1126  return (*this)[n];
1127  }
1128  template <typename T>
1129  CEREAL_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]; }
1130 
1132 
1140  template <typename SourceAllocator>
1141  GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1142  MemberIterator member = FindMember(name);
1143  if (member != MemberEnd())
1144  return member->value;
1145  else {
1146  CEREAL_RAPIDJSON_ASSERT(false); // see above note
1147 
1148  // This will generate -Wexit-time-destructors in clang
1149  // static GenericValue NullValue;
1150  // return NullValue;
1151 
1152  // Use static buffer and placement-new to prevent destruction
1153  static char buffer[sizeof(GenericValue)];
1154  return *new (buffer) GenericValue();
1155  }
1156  }
1157  template <typename SourceAllocator>
1158  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1159 
1160 #if CEREAL_RAPIDJSON_HAS_STDSTRING
1162  GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1163  const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1164 #endif
1165 
1167 
1168  ConstMemberIterator MemberBegin() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1170 
1171  ConstMemberIterator MemberEnd() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1173 
1174  MemberIterator MemberBegin() { CEREAL_RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1176 
1177  MemberIterator MemberEnd() { CEREAL_RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1178 
1180 
1185  GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1186  CEREAL_RAPIDJSON_ASSERT(IsObject());
1187  if (newCapacity > data_.o.capacity) {
1188  SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
1189  data_.o.capacity = newCapacity;
1190  }
1191  return *this;
1192  }
1193 
1195 
1202  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1203 
1204 #if CEREAL_RAPIDJSON_HAS_STDSTRING
1206 
1213  bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1214 #endif
1215 
1217 
1225  template <typename SourceAllocator>
1226  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1227 
1229 
1240  MemberIterator FindMember(const Ch* name) {
1241  GenericValue n(StringRef(name));
1242  return FindMember(n);
1243  }
1244 
1245  ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1246 
1248 
1260  template <typename SourceAllocator>
1262  CEREAL_RAPIDJSON_ASSERT(IsObject());
1263  CEREAL_RAPIDJSON_ASSERT(name.IsString());
1264  MemberIterator member = MemberBegin();
1265  for ( ; member != MemberEnd(); ++member)
1266  if (name.StringEqual(member->name))
1267  break;
1268  return member;
1269  }
1270  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1271 
1272 #if CEREAL_RAPIDJSON_HAS_STDSTRING
1274 
1280  MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1281  ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1282 #endif
1283 
1285 
1294  GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1295  CEREAL_RAPIDJSON_ASSERT(IsObject());
1296  CEREAL_RAPIDJSON_ASSERT(name.IsString());
1297 
1298  ObjectData& o = data_.o;
1299  if (o.size >= o.capacity)
1300  MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1301  Member* members = GetMembersPointer();
1302  members[o.size].name.RawAssign(name);
1303  members[o.size].value.RawAssign(value);
1304  o.size++;
1305  return *this;
1306  }
1307 
1309 
1317  GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1318  GenericValue v(value);
1319  return AddMember(name, v, allocator);
1320  }
1321 
1322 #if CEREAL_RAPIDJSON_HAS_STDSTRING
1324 
1332  GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1333  GenericValue v(value, allocator);
1334  return AddMember(name, v, allocator);
1335  }
1336 #endif
1337 
1339 
1355  template <typename T>
1356  CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1357  AddMember(GenericValue& name, T value, Allocator& allocator) {
1358  GenericValue v(value);
1359  return AddMember(name, v, allocator);
1360  }
1361 
1362 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
1363  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1364  return AddMember(name, value, allocator);
1365  }
1366  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1367  return AddMember(name, value, allocator);
1368  }
1369  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1370  return AddMember(name, value, allocator);
1371  }
1372  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1373  GenericValue n(name);
1374  return AddMember(n, value, allocator);
1375  }
1376 #endif // CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
1377 
1378 
1380 
1389  GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1390  GenericValue n(name);
1391  return AddMember(n, value, allocator);
1392  }
1393 
1395 
1403  GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1404  GenericValue v(value);
1405  return AddMember(name, v, allocator);
1406  }
1407 
1409 
1425  template <typename T>
1426  CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1427  AddMember(StringRefType name, T value, Allocator& allocator) {
1428  GenericValue n(name);
1429  return AddMember(n, value, allocator);
1430  }
1431 
1433 
1436  void RemoveAllMembers() {
1437  CEREAL_RAPIDJSON_ASSERT(IsObject());
1438  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1439  m->~Member();
1440  data_.o.size = 0;
1441  }
1442 
1444 
1451  bool RemoveMember(const Ch* name) {
1452  GenericValue n(StringRef(name));
1453  return RemoveMember(n);
1454  }
1455 
1456 #if CEREAL_RAPIDJSON_HAS_STDSTRING
1457  bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1458 #endif
1459 
1460  template <typename SourceAllocator>
1461  bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1462  MemberIterator m = FindMember(name);
1463  if (m != MemberEnd()) {
1464  RemoveMember(m);
1465  return true;
1466  }
1467  else
1468  return false;
1469  }
1470 
1472 
1479  MemberIterator RemoveMember(MemberIterator m) {
1480  CEREAL_RAPIDJSON_ASSERT(IsObject());
1483  CEREAL_RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1484 
1485  MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1486  if (data_.o.size > 1 && m != last)
1487  *m = *last; // Move the last one to this place
1488  else
1489  m->~Member(); // Only one left, just destroy
1490  --data_.o.size;
1491  return m;
1492  }
1493 
1495 
1503  MemberIterator EraseMember(ConstMemberIterator pos) {
1504  return EraseMember(pos, pos +1);
1505  }
1506 
1508 
1516  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1517  CEREAL_RAPIDJSON_ASSERT(IsObject());
1520  CEREAL_RAPIDJSON_ASSERT(first >= MemberBegin());
1521  CEREAL_RAPIDJSON_ASSERT(first <= last);
1522  CEREAL_RAPIDJSON_ASSERT(last <= MemberEnd());
1523 
1524  MemberIterator pos = MemberBegin() + (first - MemberBegin());
1525  for (MemberIterator itr = pos; itr != last; ++itr)
1526  itr->~Member();
1527  std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1528  data_.o.size -= static_cast<SizeType>(last - first);
1529  return pos;
1530  }
1531 
1533 
1537  bool EraseMember(const Ch* name) {
1538  GenericValue n(StringRef(name));
1539  return EraseMember(n);
1540  }
1541 
1542 #if CEREAL_RAPIDJSON_HAS_STDSTRING
1543  bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1544 #endif
1545 
1546  template <typename SourceAllocator>
1547  bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1548  MemberIterator m = FindMember(name);
1549  if (m != MemberEnd()) {
1550  EraseMember(m);
1551  return true;
1552  }
1553  else
1554  return false;
1555  }
1556 
1557  Object GetObject() { CEREAL_RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1558  ConstObject GetObject() const { CEREAL_RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1559 
1561 
1563 
1564 
1566 
1567  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1568 
1570  SizeType Size() const { CEREAL_RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1571 
1573  SizeType Capacity() const { CEREAL_RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1574 
1576  bool Empty() const { CEREAL_RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1577 
1579 
1582  void Clear() {
1583  CEREAL_RAPIDJSON_ASSERT(IsArray());
1585  for (GenericValue* v = e; v != e + data_.a.size; ++v)
1586  v->~GenericValue();
1587  data_.a.size = 0;
1588  }
1589 
1591 
1595  GenericValue& operator[](SizeType index) {
1596  CEREAL_RAPIDJSON_ASSERT(IsArray());
1598  return GetElementsPointer()[index];
1599  }
1600  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1601 
1603 
1604  ValueIterator Begin() { CEREAL_RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1606 
1607  ValueIterator End() { CEREAL_RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1609 
1610  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1612 
1613  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1614 
1616 
1621  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1622  CEREAL_RAPIDJSON_ASSERT(IsArray());
1623  if (newCapacity > data_.a.capacity) {
1624  SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1625  data_.a.capacity = newCapacity;
1626  }
1627  return *this;
1628  }
1629 
1631 
1640  GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1641  CEREAL_RAPIDJSON_ASSERT(IsArray());
1642  if (data_.a.size >= data_.a.capacity)
1643  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1645  return *this;
1646  }
1647 
1648 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
1649  GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1650  return PushBack(value, allocator);
1651  }
1652 #endif // CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
1653 
1655 
1663  GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1664  return (*this).template PushBack<StringRefType>(value, allocator);
1665  }
1666 
1668 
1684  template <typename T>
1685  CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1686  PushBack(T value, Allocator& allocator) {
1687  GenericValue v(value);
1688  return PushBack(v, allocator);
1689  }
1690 
1692 
1695  GenericValue& PopBack() {
1696  CEREAL_RAPIDJSON_ASSERT(IsArray());
1697  CEREAL_RAPIDJSON_ASSERT(!Empty());
1699  return *this;
1700  }
1701 
1703 
1710  return Erase(pos, pos + 1);
1711  }
1712 
1714 
1722  CEREAL_RAPIDJSON_ASSERT(IsArray());
1725  CEREAL_RAPIDJSON_ASSERT(first >= Begin());
1726  CEREAL_RAPIDJSON_ASSERT(first <= last);
1727  CEREAL_RAPIDJSON_ASSERT(last <= End());
1728  ValueIterator pos = Begin() + (first - Begin());
1729  for (ValueIterator itr = pos; itr != last; ++itr)
1730  itr->~GenericValue();
1731  std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1732  data_.a.size -= static_cast<SizeType>(last - first);
1733  return pos;
1734  }
1735 
1736  Array GetArray() { CEREAL_RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1737  ConstArray GetArray() const { CEREAL_RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1738 
1740 
1742 
1743 
1744  int GetInt() const { CEREAL_RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1745  unsigned GetUint() const { CEREAL_RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1746  int64_t GetInt64() const { CEREAL_RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1747  uint64_t GetUint64() const { CEREAL_RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1748 
1750 
1752  double GetDouble() const {
1753  CEREAL_RAPIDJSON_ASSERT(IsNumber());
1754  if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1755  if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1756  if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1757  if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1758  CEREAL_RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1759  }
1760 
1762 
1764  float GetFloat() const {
1765  return static_cast<float>(GetDouble());
1766  }
1767 
1768  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1769  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1770  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1771  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1772  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1773  GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1774 
1776 
1778 
1779 
1780  const Ch* GetString() const { CEREAL_RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1781 
1783 
1785  SizeType GetStringLength() const { CEREAL_RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1786 
1788 
1795  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1796 
1798 
1802  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1803 
1805 
1812  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1813 
1815 
1820  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1821 
1823 
1828  GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1829 
1830 #if CEREAL_RAPIDJSON_HAS_STDSTRING
1832 
1838  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1839 #endif
1840 
1842 
1844 
1845 
1847 
1850  template <typename T>
1851  bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1852 
1853  template <typename T>
1854  T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1855 
1856  template <typename T>
1857  T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1858 
1859  template<typename T>
1860  ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1861 
1862  template<typename T>
1863  ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1864 
1866 
1868 
1874  template <typename Handler>
1875  bool Accept(Handler& handler) const {
1876  switch(GetType()) {
1877  case kNullType: return handler.Null();
1878  case kFalseType: return handler.Bool(false);
1879  case kTrueType: return handler.Bool(true);
1880 
1881  case kObjectType:
1882  if (CEREAL_RAPIDJSON_UNLIKELY(!handler.StartObject()))
1883  return false;
1884  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1885  CEREAL_RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1886  if (CEREAL_RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1887  return false;
1888  if (CEREAL_RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1889  return false;
1890  }
1891  return handler.EndObject(data_.o.size);
1892 
1893  case kArrayType:
1894  if (CEREAL_RAPIDJSON_UNLIKELY(!handler.StartArray()))
1895  return false;
1896  for (const GenericValue* v = Begin(); v != End(); ++v)
1897  if (CEREAL_RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1898  return false;
1899  return handler.EndArray(data_.a.size);
1900 
1901  case kStringType:
1902  return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1903 
1904  default:
1905  CEREAL_RAPIDJSON_ASSERT(GetType() == kNumberType);
1906  if (IsDouble()) return handler.Double(data_.n.d);
1907  else if (IsInt()) return handler.Int(data_.n.i.i);
1908  else if (IsUint()) return handler.Uint(data_.n.u.u);
1909  else if (IsInt64()) return handler.Int64(data_.n.i64);
1910  else return handler.Uint64(data_.n.u64);
1911  }
1912  }
1913 
1914 private:
1915  template <typename, typename> friend class GenericValue;
1916  template <typename, typename, typename> friend class GenericDocument;
1917 
1918  enum {
1919  kBoolFlag = 0x0008,
1920  kNumberFlag = 0x0010,
1921  kIntFlag = 0x0020,
1922  kUintFlag = 0x0040,
1923  kInt64Flag = 0x0080,
1924  kUint64Flag = 0x0100,
1925  kDoubleFlag = 0x0200,
1926  kStringFlag = 0x0400,
1927  kCopyFlag = 0x0800,
1928  kInlineStrFlag = 0x1000,
1929 
1930  // Initial flags of different types.
1945 
1946  kTypeMask = 0x07
1947  };
1948 
1949  static const SizeType kDefaultArrayCapacity = 16;
1951 
1952  struct Flag {
1953 #if CEREAL_RAPIDJSON_48BITPOINTER_OPTIMIZATION
1954  char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
1955 #elif CEREAL_RAPIDJSON_64BIT
1956  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
1957 #else
1958  char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
1959 #endif
1961  };
1962 
1963  struct String {
1966  const Ch* str;
1967  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1968 
1969  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1970  // (excluding the terminating zero) and store a value to determine the length of the contained
1971  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1972  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1973  // the string terminator as well. For getting the string length back from that value just use
1974  // "MaxSize - str[LenPos]".
1975  // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
1976  // 13-chars strings for CEREAL_RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
1977  struct ShortString {
1978  enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
1980 
1981  inline static bool Usable(SizeType len) { return (MaxSize >= len); }
1982  inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
1983  inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
1984  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1985 
1986  // By using proper binary layout, retrieval of different integer types do not need conversions.
1987  union Number {
1988 #if CEREAL_RAPIDJSON_ENDIAN == CEREAL_RAPIDJSON_LITTLEENDIAN
1989  struct I {
1990  int i;
1991  char padding[4];
1992  }i;
1993  struct U {
1994  unsigned u;
1995  char padding2[4];
1996  }u;
1997 #else
1998  struct I {
1999  char padding[4];
2000  int i;
2001  }i;
2002  struct U {
2003  char padding2[4];
2004  unsigned u;
2005  }u;
2006 #endif
2009  double d;
2010  }; // 8 bytes
2011 
2012  struct ObjectData {
2016  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2017 
2018  struct ArrayData {
2022  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2023 
2024  union Data {
2031  }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with CEREAL_RAPIDJSON_48BITPOINTER_OPTIMIZATION
2032 
2033  CEREAL_RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return CEREAL_RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2034  CEREAL_RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return CEREAL_RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2035  CEREAL_RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return CEREAL_RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2036  CEREAL_RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return CEREAL_RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2037  CEREAL_RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return CEREAL_RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2038  CEREAL_RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return CEREAL_RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2039 
2040  // Initialize this value as array with initial data, without calling destructor.
2041  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2042  data_.f.flags = kArrayFlag;
2043  if (count) {
2044  GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2045  SetElementsPointer(e);
2046  std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2047  }
2048  else
2049  SetElementsPointer(0);
2050  data_.a.size = data_.a.capacity = count;
2051  }
2052 
2054  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2056  if (count) {
2057  Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2058  SetMembersPointer(m);
2059  std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2060  }
2061  else
2062  SetMembersPointer(0);
2063  data_.o.size = data_.o.capacity = count;
2064  }
2065 
2067  void SetStringRaw(StringRefType s) CEREAL_RAPIDJSON_NOEXCEPT {
2069  SetStringPointer(s);
2070  data_.s.length = s.length;
2071  }
2072 
2074  void SetStringRaw(StringRefType s, Allocator& allocator) {
2075  Ch* str = 0;
2076  if (ShortString::Usable(s.length)) {
2078  data_.ss.SetLength(s.length);
2079  str = data_.ss.str;
2080  } else {
2082  data_.s.length = s.length;
2083  str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2084  SetStringPointer(str);
2085  }
2086  std::memcpy(str, s, s.length * sizeof(Ch));
2087  str[s.length] = '\0';
2088  }
2089 
2091  void RawAssign(GenericValue& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
2092  data_ = rhs.data_;
2093  // data_.f.flags = rhs.data_.f.flags;
2094  rhs.data_.f.flags = kNullFlag;
2095  }
2096 
2097  template <typename SourceAllocator>
2099  CEREAL_RAPIDJSON_ASSERT(IsString());
2100  CEREAL_RAPIDJSON_ASSERT(rhs.IsString());
2101 
2102  const SizeType len1 = GetStringLength();
2103  const SizeType len2 = rhs.GetStringLength();
2104  if(len1 != len2) { return false; }
2105 
2106  const Ch* const str1 = GetString();
2107  const Ch* const str2 = rhs.GetString();
2108  if(str1 == str2) { return true; } // fast path for constant string
2109 
2110  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2111  }
2112 
2114 };
2115 
2118 
2120 // GenericDocument
2121 
2123 
2130 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
2131 class GenericDocument : public GenericValue<Encoding, Allocator> {
2132 public:
2133  typedef typename Encoding::Ch Ch;
2136 
2138 
2144  explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2145  GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2146  {
2147  if (!allocator_)
2149  }
2150 
2152 
2157  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2158  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2159  {
2160  if (!allocator_)
2162  }
2163 
2164 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
2166  GenericDocument(GenericDocument&& rhs) CEREAL_RAPIDJSON_NOEXCEPT
2167  : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2168  allocator_(rhs.allocator_),
2169  ownAllocator_(rhs.ownAllocator_),
2170  stack_(std::move(rhs.stack_)),
2171  parseResult_(rhs.parseResult_)
2172  {
2173  rhs.allocator_ = 0;
2174  rhs.ownAllocator_ = 0;
2175  rhs.parseResult_ = ParseResult();
2176  }
2177 #endif
2178 
2180  Destroy();
2181  }
2182 
2183 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
2185  GenericDocument& operator=(GenericDocument&& rhs) CEREAL_RAPIDJSON_NOEXCEPT
2186  {
2187  // The cast to ValueType is necessary here, because otherwise it would
2188  // attempt to call GenericValue's templated assignment operator.
2189  ValueType::operator=(std::forward<ValueType>(rhs));
2190 
2191  // Calling the destructor here would prematurely call stack_'s destructor
2192  Destroy();
2193 
2194  allocator_ = rhs.allocator_;
2195  ownAllocator_ = rhs.ownAllocator_;
2196  stack_ = std::move(rhs.stack_);
2197  parseResult_ = rhs.parseResult_;
2198 
2199  rhs.allocator_ = 0;
2200  rhs.ownAllocator_ = 0;
2201  rhs.parseResult_ = ParseResult();
2202 
2203  return *this;
2204  }
2205 #endif
2206 
2208 
2213  GenericDocument& Swap(GenericDocument& rhs) CEREAL_RAPIDJSON_NOEXCEPT {
2214  ValueType::Swap(rhs);
2215  stack_.Swap(rhs.stack_);
2216  internal::Swap(allocator_, rhs.allocator_);
2217  internal::Swap(ownAllocator_, rhs.ownAllocator_);
2218  internal::Swap(parseResult_, rhs.parseResult_);
2219  return *this;
2220  }
2221 
2222  // Allow Swap with ValueType.
2223  // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2224  using ValueType::Swap;
2225 
2227 
2238  friend inline void swap(GenericDocument& a, GenericDocument& b) CEREAL_RAPIDJSON_NOEXCEPT { a.Swap(b); }
2239 
2241 
2245  template <typename Generator>
2246  GenericDocument& Populate(Generator& g) {
2247  ClearStackOnExit scope(*this);
2248  if (g(*this)) {
2249  CEREAL_RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2250  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2251  }
2252  return *this;
2253  }
2254 
2257 
2259 
2265  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2266  GenericDocument& ParseStream(InputStream& is) {
2268  stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2269  ClearStackOnExit scope(*this);
2270  parseResult_ = reader.template Parse<parseFlags>(is, *this);
2271  if (parseResult_) {
2272  CEREAL_RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2273  ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2274  }
2275  return *this;
2276  }
2277 
2279 
2284  template <unsigned parseFlags, typename InputStream>
2285  GenericDocument& ParseStream(InputStream& is) {
2286  return ParseStream<parseFlags, Encoding, InputStream>(is);
2287  }
2288 
2290 
2294  template <typename InputStream>
2295  GenericDocument& ParseStream(InputStream& is) {
2296  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2297  }
2299 
2302 
2304 
2308  template <unsigned parseFlags>
2311  return ParseStream<parseFlags | kParseInsituFlag>(s);
2312  }
2313 
2315 
2319  return ParseInsitu<kParseDefaultFlags>(str);
2320  }
2322 
2325 
2327 
2331  template <unsigned parseFlags, typename SourceEncoding>
2332  GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2333  CEREAL_RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2335  return ParseStream<parseFlags, SourceEncoding>(s);
2336  }
2337 
2339 
2342  template <unsigned parseFlags>
2343  GenericDocument& Parse(const Ch* str) {
2344  return Parse<parseFlags, Encoding>(str);
2345  }
2346 
2348 
2350  GenericDocument& Parse(const Ch* str) {
2351  return Parse<kParseDefaultFlags>(str);
2352  }
2353 
2354  template <unsigned parseFlags, typename SourceEncoding>
2355  GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2356  CEREAL_RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2357  MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2359  ParseStream<parseFlags, SourceEncoding>(is);
2360  return *this;
2361  }
2362 
2363  template <unsigned parseFlags>
2364  GenericDocument& Parse(const Ch* str, size_t length) {
2365  return Parse<parseFlags, Encoding>(str, length);
2366  }
2367 
2368  GenericDocument& Parse(const Ch* str, size_t length) {
2369  return Parse<kParseDefaultFlags>(str, length);
2370  }
2371 
2372 #if CEREAL_RAPIDJSON_HAS_STDSTRING
2373  template <unsigned parseFlags, typename SourceEncoding>
2374  GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2375  // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2376  return Parse<parseFlags, SourceEncoding>(str.c_str());
2377  }
2378 
2379  template <unsigned parseFlags>
2380  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2381  return Parse<parseFlags, Encoding>(str.c_str());
2382  }
2383 
2384  GenericDocument& Parse(const std::basic_string<Ch>& str) {
2385  return Parse<kParseDefaultFlags>(str);
2386  }
2387 #endif // CEREAL_RAPIDJSON_HAS_STDSTRING
2388 
2390 
2393 
2395  bool HasParseError() const { return parseResult_.IsError(); }
2396 
2399 
2401  size_t GetErrorOffset() const { return parseResult_.Offset(); }
2402 
2404 #ifndef __clang // -Wdocumentation
2414 #endif
2415  operator ParseResult() const { return parseResult_; }
2417 
2421  return *allocator_;
2422  }
2423 
2425  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2426 
2427 private:
2428  // clear stack on any exit from ParseStream, e.g. due to exception
2432  private:
2436  };
2437 
2438  // callers of the following private Handler functions
2439  // template <typename,typename,typename> friend class GenericReader; // for parsing
2440  template <typename, typename> friend class GenericValue; // for deep copying
2441 
2442 public:
2443  // Implementation of Handler
2444  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2445  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2446  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2447  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2448  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2449  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2450  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2451 
2452  bool RawNumber(const Ch* str, SizeType length, bool copy) {
2453  if (copy)
2454  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2455  else
2456  new (stack_.template Push<ValueType>()) ValueType(str, length);
2457  return true;
2458  }
2459 
2460  bool String(const Ch* str, SizeType length, bool copy) {
2461  if (copy)
2462  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2463  else
2464  new (stack_.template Push<ValueType>()) ValueType(str, length);
2465  return true;
2466  }
2467 
2468  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2469 
2470  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2471 
2472  bool EndObject(SizeType memberCount) {
2473  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2474  stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2475  return true;
2476  }
2477 
2478  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2479 
2480  bool EndArray(SizeType elementCount) {
2481  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2482  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2483  return true;
2484  }
2485 
2486 private:
2491 
2492  void ClearStack() {
2493  if (Allocator::kNeedFree)
2494  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2495  (stack_.template Pop<ValueType>(1))->~ValueType();
2496  else
2497  stack_.Clear();
2498  stack_.ShrinkToFit();
2499  }
2500 
2501  void Destroy() {
2503  }
2504 
2505  static const size_t kDefaultStackCapacity = 1024;
2510 };
2511 
2514 
2516 
2520 template <bool Const, typename ValueT>
2522 public:
2525  typedef ValueT PlainType;
2527  typedef ValueType* ValueIterator; // This may be const or non-const iterator
2528  typedef const ValueT* ConstValueIterator;
2529  typedef typename ValueType::AllocatorType AllocatorType;
2530  typedef typename ValueType::StringRefType StringRefType;
2531 
2532  template <typename, typename>
2533  friend class GenericValue;
2534 
2535  GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2536  GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2538 
2539  SizeType Size() const { return value_.Size(); }
2540  SizeType Capacity() const { return value_.Capacity(); }
2541  bool Empty() const { return value_.Empty(); }
2542  void Clear() const { value_.Clear(); }
2543  ValueType& operator[](SizeType index) const { return value_[index]; }
2544  ValueIterator Begin() const { return value_.Begin(); }
2545  ValueIterator End() const { return value_.End(); }
2546  GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2547  GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2548 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
2549  GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2550 #endif // CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
2551  GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2552  template <typename T> CEREAL_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; }
2553  GenericArray PopBack() const { value_.PopBack(); return *this; }
2555  ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2556 
2557 #if CEREAL_RAPIDJSON_HAS_CXX11_RANGE_FOR
2558  ValueIterator begin() const { return value_.Begin(); }
2559  ValueIterator end() const { return value_.End(); }
2560 #endif
2561 
2562 private:
2566 };
2567 
2569 
2573 template <bool Const, typename ValueT>
2575 public:
2578  typedef ValueT PlainType;
2582  typedef typename ValueType::AllocatorType AllocatorType;
2583  typedef typename ValueType::StringRefType StringRefType;
2585  typedef typename ValueType::Ch Ch;
2586 
2587  template <typename, typename>
2588  friend class GenericValue;
2589 
2591  GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2593 
2594  SizeType MemberCount() const { return value_.MemberCount(); }
2595  SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2596  bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2597  template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2598  template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2599 #if CEREAL_RAPIDJSON_HAS_STDSTRING
2600  ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2601 #endif
2602  MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2603  MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2604  GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2605  bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2606 #if CEREAL_RAPIDJSON_HAS_STDSTRING
2607  bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2608 #endif
2609  template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2610  MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2611  template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2612 #if CEREAL_RAPIDJSON_HAS_STDSTRING
2613  MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2614 #endif
2615  GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2616  GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2617 #if CEREAL_RAPIDJSON_HAS_STDSTRING
2618  GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2619 #endif
2620  template <typename T> CEREAL_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; }
2621 #if CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
2622  GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2623  GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2624  GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2625  GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2626 #endif // CEREAL_RAPIDJSON_HAS_CXX11_RVALUE_REFS
2627  GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2628  GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2629  template <typename T> CEREAL_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; }
2630  void RemoveAllMembers() { value_.RemoveAllMembers(); }
2631  bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2632 #if CEREAL_RAPIDJSON_HAS_STDSTRING
2633  bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2634 #endif
2635  template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2636  MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2638  MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2639  bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2640 #if CEREAL_RAPIDJSON_HAS_STDSTRING
2641  bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2642 #endif
2643  template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2644 
2645 #if CEREAL_RAPIDJSON_HAS_CXX11_RANGE_FOR
2646  MemberIterator begin() const { return value_.MemberBegin(); }
2647  MemberIterator end() const { return value_.MemberEnd(); }
2648 #endif
2649 
2650 private:
2654 };
2655 
2657 CEREAL_RAPIDJSON_DIAG_POP
2658 
2659 #endif // CEREAL_RAPIDJSON_DOCUMENT_H_
#define CEREAL_RAPIDJSON_ASSERT(x)
Definition: json.hpp:50
bool operator!=(const json_pointer< RefStringTypeLhs > &lhs, const json_pointer< RefStringTypeRhs > &rhs) noexcept
Definition: json.hpp:15536
EncodingType
Definition: Xml.h:26
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
Helper class for accessing Value of array type.
Definition: document.h:2521
const ValueT * ConstValueIterator
Definition: document.h:2528
GenericArray PushBack(ValueType &value, AllocatorType &allocator) const
Definition: document.h:2547
CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(const GenericArray &)) PushBack(T value
ValueIterator End() const
Definition: document.h:2545
ValueIterator Begin() const
Definition: document.h:2544
void Clear() const
Definition: document.h:2542
SizeType Size() const
Definition: document.h:2539
GenericArray< false, ValueT > Array
Definition: document.h:2524
GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const
Definition: document.h:2546
GenericArray< true, ValueT > ConstArray
Definition: document.h:2523
ValueType::StringRefType StringRefType
Definition: document.h:2530
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition: document.h:2526
~GenericArray()
Definition: document.h:2537
ValueType & operator[](SizeType index) const
Definition: document.h:2543
GenericArray(const GenericArray &rhs)
Definition: document.h:2535
SizeType Capacity() const
Definition: document.h:2540
ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const
Definition: document.h:2555
GenericArray & operator=(const GenericArray &rhs)
Definition: document.h:2536
GenericArray PushBack(StringRefType value, AllocatorType &allocator) const
Definition: document.h:2551
ValueT PlainType
Definition: document.h:2525
ValueIterator Erase(ConstValueIterator pos) const
Definition: document.h:2554
GenericArray(ValueType &value)
Definition: document.h:2564
bool Empty() const
Definition: document.h:2541
ValueType::AllocatorType AllocatorType
Definition: document.h:2529
ValueType & value_
Definition: document.h:2565
ValueType * ValueIterator
Definition: document.h:2527
GenericArray PopBack() const
Definition: document.h:2553
A document for parsing JSON text as DOM.
Definition: document.h:2131
bool EndArray(SizeType elementCount)
Definition: document.h:2480
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:2309
friend void swap(GenericDocument &a, GenericDocument &b) CEREAL_RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:2238
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2135
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2246
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2144
bool EndObject(SizeType memberCount)
Definition: document.h:2472
GenericDocument & Parse(const typename SourceEncoding::Ch *str, size_t length)
Definition: document.h:2355
ParseResult parseResult_
Definition: document.h:2509
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:2350
bool Bool(bool b)
Definition: document.h:2445
bool Uint64(uint64_t i)
Definition: document.h:2449
bool HasParseError() const
Whether a parse error has occurred in the last parsing.
Definition: document.h:2395
bool Uint(unsigned i)
Definition: document.h:2447
GenericDocument(const GenericDocument &)
Prohibit copying.
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:2343
bool Key(const Ch *str, SizeType length, bool copy)
Definition: document.h:2470
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2157
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:2285
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2133
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:2318
bool Null()
Definition: document.h:2444
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2134
bool Int(int i)
Definition: document.h:2446
static const size_t kDefaultStackCapacity
Definition: document.h:2505
bool Int64(int64_t i)
Definition: document.h:2448
bool Double(double d)
Definition: document.h:2450
GenericDocument & Parse(const Ch *str, size_t length)
Definition: document.h:2364
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:2398
Allocator * allocator_
Definition: document.h:2506
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:2425
GenericDocument & Swap(GenericDocument &rhs) CEREAL_RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:2213
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2419
void ClearStack()
Definition: document.h:2492
~GenericDocument()
Definition: document.h:2179
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2332
GenericDocument & Parse(const Ch *str, size_t length)
Definition: document.h:2368
bool StartObject()
Definition: document.h:2468
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:2295
internal::Stack< StackAllocator > stack_
Definition: document.h:2508
bool String(const Ch *str, SizeType length, bool copy)
Definition: document.h:2460
void Destroy()
Definition: document.h:2501
Allocator * ownAllocator_
Definition: document.h:2507
bool StartArray()
Definition: document.h:2478
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:2401
GenericDocument & operator=(const GenericDocument &)
Prohibit assignment.
bool RawNumber(const Ch *str, SizeType length, bool copy)
Definition: document.h:2452
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:2266
(Constant) member iterator for a JSON object value
Definition: document.h:105
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition: document.h:111
ValueType & reference
Definition: document.h:125
bool operator>(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition: document.h:186
bool operator<=(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition: document.h:183
Iterator & operator+=(DifferenceType n)
Definition: document.h:175
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:159
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:141
Iterator operator-(DifferenceType n) const
Definition: document.h:173
std::random_access_iterator_tag iterator_category
Definition: document.h:127
Reference operator[](DifferenceType n) const
Definition: document.h:197
Iterator operator--(int)
Definition: document.h:167
Iterator operator+(DifferenceType n) const
Definition: document.h:172
Iterator & operator=(const NonConstIterator &it)
Definition: document.h:160
Reference operator*() const
Definition: document.h:195
Iterator & operator--()
Definition: document.h:165
GenericMemberIterator(Pointer p)
Internal constructor from plain pointer.
Definition: document.h:205
ValueType value_type
Definition: document.h:123
bool operator==(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition: document.h:181
ValueType * pointer
Definition: document.h:124
Iterator & operator-=(DifferenceType n)
Definition: document.h:176
reference Reference
Reference to (const) GenericMember.
Definition: document.h:133
Iterator operator++(int)
Definition: document.h:166
Pointer ptr_
raw pointer
Definition: document.h:207
difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:135
bool operator<(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition: document.h:185
bool operator>=(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition: document.h:184
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:119
Pointer operator->() const
Definition: document.h:196
pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:131
GenericMember< Encoding, Allocator > PlainType
Definition: document.h:110
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:115
bool operator!=(const GenericMemberIterator< Const_, Encoding, Allocator > &that) const
Definition: document.h:182
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:201
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:117
std::ptrdiff_t difference_type
Definition: document.h:126
Iterator & operator++()
Definition: document.h:164
Helper class for accessing Value of object type.
Definition: document.h:2574
MemberIterator RemoveMember(MemberIterator m) const
Definition: document.h:2636
ValueType::AllocatorType AllocatorType
Definition: document.h:2582
GenericObject AddMember(StringRefType name, ValueType &value, AllocatorType &allocator) const
Definition: document.h:2627
SizeType MemberCapacity() const
Definition: document.h:2595
bool HasMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:2609
GenericObject(const GenericObject &rhs)
Definition: document.h:2590
void RemoveAllMembers()
Definition: document.h:2630
MemberIterator FindMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:2611
T value
Definition: document.h:2620
SizeType MemberCount() const
Definition: document.h:2594
ValueType & operator[](const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:2598
GenericMemberIterator< Const, typename ValueT::EncodingType, typename ValueT::AllocatorType > MemberIterator
Definition: document.h:2580
ValueType & value_
Definition: document.h:2653
MemberIterator EraseMember(ConstMemberIterator pos) const
Definition: document.h:2637
ValueType & operator[](T *name) const
Definition: document.h:2597
GenericObject AddMember(ValueType &name, ValueType &value, AllocatorType &allocator) const
Definition: document.h:2615
GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType &allocator) const
Definition: document.h:2628
ValueT PlainType
Definition: document.h:2578
bool EraseMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:2643
GenericObject(ValueType &value)
Definition: document.h:2652
MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const
Definition: document.h:2638
MemberIterator MemberEnd() const
Definition: document.h:2603
~GenericObject()
Definition: document.h:2592
bool RemoveMember(const GenericValue< EncodingType, SourceAllocator > &name) const
Definition: document.h:2635
internal::MaybeAddConst< Const, PlainType >::Type ValueType
Definition: document.h:2579
ValueType::EncodingType EncodingType
Definition: document.h:2584
MemberIterator FindMember(const Ch *name) const
Definition: document.h:2610
bool HasMember(const Ch *name) const
Definition: document.h:2605
ValueType::StringRefType StringRefType
Definition: document.h:2583
bool ObjectEmpty() const
Definition: document.h:2596
CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(ValueType &)) AddMember(ValueType &name
CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr< internal::IsPointer< T >, internal::IsGenericValue< T > >),(GenericObject)) AddMember(StringRefType name
ValueType::Ch Ch
Definition: document.h:2585
GenericObject AddMember(ValueType &name, StringRefType value, AllocatorType &allocator) const
Definition: document.h:2616
GenericObject< false, ValueT > Object
Definition: document.h:2577
bool RemoveMember(const Ch *name) const
Definition: document.h:2631
GenericObject< true, ValueT > ConstObject
Definition: document.h:2576
bool EraseMember(const Ch *name) const
Definition: document.h:2639
GenericMemberIterator< true, typename ValueT::EncodingType, typename ValueT::AllocatorType > ConstMemberIterator
Definition: document.h:2581
MemberIterator MemberBegin() const
Definition: document.h:2602
GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const
Definition: document.h:2604
GenericObject & operator=(const GenericObject &rhs)
Definition: document.h:2591
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:537
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:585
GenericValue(int64_t i64) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:731
void RawAssign(GenericValue &rhs) CEREAL_RAPIDJSON_NOEXCEPT
Assignment without calling destructor.
Definition: document.h:2091
GenericArray< false, ValueType > Array
Definition: document.h:598
GenericValue & operator=(GenericValue &rhs) CEREAL_RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:843
void SetStringRaw(StringRefType s) CEREAL_RAPIDJSON_NOEXCEPT
Initialize this value as constant string, without calling destructor.
Definition: document.h:2067
static const SizeType kDefaultArrayCapacity
Definition: document.h:1949
GenericValue(double d) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:758
~GenericValue()
Destructor.
Definition: document.h:807
void SetObjectRaw(Member *members, SizeType count, Allocator &allocator)
Initialize this value as object with initial data, without calling destructor.
Definition: document.h:2054
static const SizeType kDefaultObjectCapacity
Definition: document.h:1950
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:589
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:592
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:593
GenericValue(float f) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for float value.
Definition: document.h:761
CEREAL_RAPIDJSON_FORCEINLINE GenericValue * SetElementsPointer(GenericValue *elements)
Definition: document.h:2036
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:597
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:596
GenericValue(T b, CEREAL_RAPIDJSON_ENABLEIF((internal::IsSame< bool, T >))) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:708
GenericValue(unsigned u) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:725
GenericObject< true, ValueType > ConstObject
Definition: document.h:601
GenericValue & operator=(StringRefType str) CEREAL_RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:863
CEREAL_RAPIDJSON_FORCEINLINE const Ch * SetStringPointer(const Ch *str)
Definition: document.h:2034
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator, bool copyConstStrings=false)
Explicit copy constructor (with allocator)
Definition: document.h:659
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:590
GenericValue() CEREAL_RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:607
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:588
GenericValue(StringRefType s) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:767
GenericArray< true, ValueType > ConstArray
Definition: document.h:599
CEREAL_RAPIDJSON_FORCEINLINE const Ch * GetStringPointer() const
Definition: document.h:2033
void SetArrayRaw(GenericValue *values, SizeType count, Allocator &allocator)
Definition: document.h:2041
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:773
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:770
CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer< T >),(GenericValue &)) operator
Assignment with primitive types.
GenericValue(int i) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:719
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:594
@ kCopyStringFlag
Definition: document.h:1941
@ kCopyFlag
Definition: document.h:1927
@ kNumberDoubleFlag
Definition: document.h:1938
@ kConstStringFlag
Definition: document.h:1940
@ kFalseFlag
Definition: document.h:1933
@ kDoubleFlag
Definition: document.h:1925
@ kTrueFlag
Definition: document.h:1932
@ kTypeMask
Definition: document.h:1946
@ kUintFlag
Definition: document.h:1922
@ kInt64Flag
Definition: document.h:1923
@ kNullFlag
Definition: document.h:1931
@ kNumberFlag
Definition: document.h:1920
@ kNumberUint64Flag
Definition: document.h:1937
@ kNumberAnyFlag
Definition: document.h:1939
@ kObjectFlag
Definition: document.h:1943
@ kBoolFlag
Definition: document.h:1919
@ kUint64Flag
Definition: document.h:1924
@ kShortStringFlag
Definition: document.h:1942
@ kNumberIntFlag
Definition: document.h:1934
@ kNumberInt64Flag
Definition: document.h:1936
@ kIntFlag
Definition: document.h:1921
@ kInlineStrFlag
Definition: document.h:1928
@ kNumberUintFlag
Definition: document.h:1935
@ kStringFlag
Definition: document.h:1926
@ kArrayFlag
Definition: document.h:1944
CEREAL_RAPIDJSON_FORCEINLINE Member * GetMembersPointer() const
Definition: document.h:2037
Data data_
Definition: document.h:2113
friend class GenericDocument
Definition: document.h:1916
CEREAL_RAPIDJSON_FORCEINLINE Member * SetMembersPointer(Member *members)
Definition: document.h:2038
GenericValue(const Ch *s, SizeType length) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:764
CEREAL_RAPIDJSON_FORCEINLINE GenericValue * GetElementsPointer() const
Definition: document.h:2035
GenericValue(const GenericValue &rhs)
Copy constructor is not permitted.
GenericValue(Array a) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition: document.h:788
void SetStringRaw(StringRefType s, Allocator &allocator)
Initialize this value as copy string with initial data, without calling destructor.
Definition: document.h:2074
bool StringEqual(const GenericValue< Encoding, SourceAllocator > &rhs) const
Definition: document.h:2098
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:591
GenericValue(Type type) CEREAL_RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:637
GenericValue(Object o) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition: document.h:799
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:595
GenericObject< false, ValueType > Object
Definition: document.h:600
GenericValue(uint64_t u64) CEREAL_RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:746
void Clear()
Definition: stack.h:99
void ShrinkToFit()
Definition: stack.h:101
bool HasAllocator() const
Definition: stack.h:168
size_t GetCapacity() const
Definition: stack.h:179
Allocator & GetAllocator()
Definition: stack.h:172
size_t GetSize() const
Definition: stack.h:178
void Swap(Stack &rhs) CEREAL_RAPIDJSON_NOEXCEPT
Definition: stack.h:90
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:2117
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:371
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2513
#define CEREAL_RAPIDJSON_NOEXCEPT_ASSERT(x)
Assertion (in non-throwing contexts).
Definition: rapidjson.h:618
#define CEREAL_RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition: rapidjson.h:121
#define CEREAL_RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:476
#define CEREAL_RAPIDJSON_LIKELY(x)
Compiler branching hint for expression with high probability to be true.
Definition: rapidjson.h:463
#define CEREAL_RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition: rapidjson.h:124
ParseErrorCode
Error code of parsing.
Definition: error.h:64
bool operator==(const cp< d > &a, const cp< d > &b)
Contact equivalence is based solely on the index of objects in contact i and j.
Definition: ContactList.h:291
@ pos
Definition: Typedefs.h:19
uint d
int N
type
The type the bitset is encoded with.
Definition: bitset.hpp:44
Definition: document.h:416
SizeType StrLen(const Ch *s)
Custom strlen() which works on different character types.
Definition: strfunc.h:31
void Swap(T &a, T &b) CEREAL_RAPIDJSON_NOEXCEPT
Custom swap() to avoid dependency on C++ <algorithm> header.
Definition: swap.h:33
Definition: json.hpp:5678
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1282
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1181
void swap(T &lhs, T &rhs)
Definition: pugixml.cpp:7597
#define CEREAL_RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:445
Type
Type of JSON value.
Definition: rapidjson.h:644
@ kFalseType
false
Definition: rapidjson.h:646
@ kObjectType
object
Definition: rapidjson.h:648
@ kTrueType
true
Definition: rapidjson.h:647
@ kStringType
string
Definition: rapidjson.h:650
@ kNullType
null
Definition: rapidjson.h:645
@ kArrayType
array
Definition: rapidjson.h:649
@ kNumberType
number
Definition: rapidjson.h:651
#define CEREAL_RAPIDJSON_GETPOINTER(type, p)
Definition: rapidjson.h:319
#define CEREAL_RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:631
#define CEREAL_RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
#define CEREAL_RAPIDJSON_SETPOINTER(type, p, x)
Definition: rapidjson.h:318
#define CEREAL_RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition: rapidjson.h:627
CEREAL_RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:384
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition: reader.h:147
unsigned short uint16_t
Definition: stdint.h:125
signed __int64 int64_t
Definition: stdint.h:135
unsigned __int64 uint64_t
Definition: stdint.h:136
Definition: document.h:2429
ClearStackOnExit & operator=(const ClearStackOnExit &)
GenericDocument & d_
Definition: document.h:2435
ClearStackOnExit(GenericDocument &d)
Definition: document.h:2430
~ClearStackOnExit()
Definition: document.h:2431
ClearStackOnExit(const ClearStackOnExit &)
A read-write string stream.
Definition: stream.h:188
Name-value pair in a JSON object value.
Definition: document.h:69
friend void swap(GenericMember &a, GenericMember &b) CEREAL_RAPIDJSON_NOEXCEPT
Definition: document.h:74
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:70
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:71
Reference to a constant string (not taking a copy)
Definition: document.h:263
CharType Ch
character type of the string
Definition: document.h:264
GenericStringRef(const CharType(&str)[N]) CEREAL_RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:292
GenericStringRef & operator=(const GenericStringRef &rhs)
Copy assignment operator not permitted - immutable type.
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:337
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
Definition: document.h:391
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:328
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:316
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:371
GenericStringRef(const GenericStringRef &rhs)
Definition: document.h:331
GenericStringRef(CharType(&str)[N])
Disallow construction from non-const array.
const Ch *const s
plain CharType pointer
Definition: document.h:336
static const Ch emptyString[]
Empty string - used when passing in a NULL pointer.
Definition: document.h:346
SizeType NotNullStrLen(const CharType *str)
Definition: document.h:340
Read-only string stream.
Definition: stream.h:154
Definition: document.h:2018
SizeType capacity
Definition: document.h:2020
SizeType size
Definition: document.h:2019
GenericValue * elements
Definition: document.h:2021
Definition: document.h:1952
uint16_t flags
Definition: document.h:1960
char payload[sizeof(SizeType) *2+sizeof(void *)+2]
Definition: document.h:1958
Definition: document.h:1989
int i
Definition: document.h:1990
char padding[4]
Definition: document.h:1991
Definition: document.h:1993
unsigned u
Definition: document.h:1994
char padding2[4]
Definition: document.h:1995
Definition: document.h:2012
Member * members
Definition: document.h:2015
SizeType capacity
Definition: document.h:2014
SizeType size
Definition: document.h:2013
Definition: document.h:1977
Ch str[MaxChars]
Definition: document.h:1979
SizeType GetLength() const
Definition: document.h:1983
static bool Usable(SizeType len)
Definition: document.h:1981
@ MaxChars
Definition: document.h:1978
@ MaxSize
Definition: document.h:1978
@ LenPos
Definition: document.h:1978
void SetLength(SizeType len)
Definition: document.h:1982
Definition: document.h:1963
const Ch * str
Definition: document.h:1966
SizeType hashcode
reserved
Definition: document.h:1965
SizeType length
Definition: document.h:1964
Represents an in-memory input byte stream.
Definition: memorystream.h:40
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
ParseErrorCode Code() const
Get the error code.
Definition: error.h:116
bool IsError() const
Whether the result is an error.
Definition: error.h:123
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:118
Definition: document.h:419
Definition: document.h:426
static ValueType & Set(ValueType &v, bool data, typename ValueType::AllocatorType &)
Definition: document.h:443
static ValueType & Set(ValueType &v, bool data)
Definition: document.h:442
static bool Is(const ValueType &v)
Definition: document.h:440
static bool Get(const ValueType &v)
Definition: document.h:441
static StringType Get(const ValueType &v)
Definition: document.h:518
const ValueType::Ch * StringType
Definition: document.h:516
static ValueType & Set(ValueType &v, const StringType data, typename ValueType::AllocatorType &a)
Definition: document.h:520
static bool Is(const ValueType &v)
Definition: document.h:517
static ValueType & Set(ValueType &v, const StringType data)
Definition: document.h:519
static ValueType & Set(ValueType &v, double data)
Definition: document.h:502
static ValueType & Set(ValueType &v, double data, typename ValueType::AllocatorType &)
Definition: document.h:503
static bool Is(const ValueType &v)
Definition: document.h:500
static double Get(const ValueType &v)
Definition: document.h:501
static bool Is(const ValueType &v)
Definition: document.h:508
static ValueType & Set(ValueType &v, float data)
Definition: document.h:510
static ValueType & Set(ValueType &v, float data, typename ValueType::AllocatorType &)
Definition: document.h:511
static float Get(const ValueType &v)
Definition: document.h:509
static ValueType & Set(ValueType &v, int64_t data)
Definition: document.h:486
static bool Is(const ValueType &v)
Definition: document.h:484
static ValueType & Set(ValueType &v, int64_t data, typename ValueType::AllocatorType &)
Definition: document.h:487
static int64_t Get(const ValueType &v)
Definition: document.h:485
static ValueType & Set(ValueType &v, int data, typename ValueType::AllocatorType &)
Definition: document.h:451
static int Get(const ValueType &v)
Definition: document.h:449
static bool Is(const ValueType &v)
Definition: document.h:448
static ValueType & Set(ValueType &v, int data)
Definition: document.h:450
static ArrayType Get(ValueType &v)
Definition: document.h:537
static bool Is(const ValueType &v)
Definition: document.h:536
static ValueType & Set(ValueType &v, ArrayType data)
Definition: document.h:538
ValueType::Array ArrayType
Definition: document.h:535
static ValueType & Set(ValueType &v, ArrayType data, typename ValueType::AllocatorType &)
Definition: document.h:539
static ArrayType Get(const ValueType &v)
Definition: document.h:546
static bool Is(const ValueType &v)
Definition: document.h:545
ValueType::ConstArray ArrayType
Definition: document.h:544
static bool Is(const ValueType &v)
Definition: document.h:561
ValueType::ConstObject ObjectType
Definition: document.h:560
static ObjectType Get(const ValueType &v)
Definition: document.h:562
static ValueType & Set(ValueType &v, ObjectType data, typename ValueType::AllocatorType &)
Definition: document.h:555
static bool Is(const ValueType &v)
Definition: document.h:552
static ValueType & Set(ValueType &v, ObjectType data)
Definition: document.h:554
ValueType::Object ObjectType
Definition: document.h:551
static ObjectType Get(ValueType &v)
Definition: document.h:553
static uint64_t Get(const ValueType &v)
Definition: document.h:493
static ValueType & Set(ValueType &v, uint64_t data)
Definition: document.h:494
static ValueType & Set(ValueType &v, uint64_t data, typename ValueType::AllocatorType &)
Definition: document.h:495
static bool Is(const ValueType &v)
Definition: document.h:492
static ValueType & Set(ValueType &v, unsigned data)
Definition: document.h:458
static unsigned Get(const ValueType &v)
Definition: document.h:457
static ValueType & Set(ValueType &v, unsigned data, typename ValueType::AllocatorType &)
Definition: document.h:459
static bool Is(const ValueType &v)
Definition: document.h:456
Definition: document.h:436
Definition: document.h:2024
Number n
Definition: document.h:2027
ShortString ss
Definition: document.h:2026
String s
Definition: document.h:2025
Flag f
Definition: document.h:2030
ArrayData a
Definition: document.h:2029
ObjectData o
Definition: document.h:2028
Definition: document.h:1987
struct GenericValue::Number::I i
uint64_t u64
Definition: document.h:2008
struct GenericValue::Number::U u
double d
Definition: document.h:2009
int64_t i64
Definition: document.h:2007
#define const
Definition: zconf.h:233