1 // Tencent is pleased to support the open source community by making RapidJSON available.
3 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
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
8 // http://opensource.org/licenses/MIT
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.
15 #ifndef RAPIDJSON_DOCUMENT_H_
16 #define RAPIDJSON_DOCUMENT_H_
18 /*! \file document.h */
21 #include "internal/meta.h"
22 #include "internal/strfunc.h"
23 #include "memorystream.h"
24 #include "encodedstream.h"
25 #include <new> // placement new
30 RAPIDJSON_DIAG_OFF(padded)
31 RAPIDJSON_DIAG_OFF(switch-enum)
32 RAPIDJSON_DIAG_OFF(c++98-compat)
33 #elif defined(_MSC_VER)
34 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
35 RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
39 RAPIDJSON_DIAG_OFF(effc++)
42 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
43 #include <iterator> // std::random_access_iterator_tag
46 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
47 #include <utility> // std::move
50 RAPIDJSON_NAMESPACE_BEGIN
52 // Forward declaration.
53 template <typename Encoding, typename Allocator>
56 template <typename Encoding, typename Allocator, typename StackAllocator>
57 class GenericDocument;
59 //! Name-value pair in a JSON object value.
61 This class was internal to GenericValue. It used to be a inner struct.
62 But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
63 https://code.google.com/p/rapidjson/issues/detail?id=64
65 template <typename Encoding, typename Allocator>
66 struct GenericMember {
67 GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
68 GenericValue<Encoding, Allocator> value; //!< value of member.
71 ///////////////////////////////////////////////////////////////////////////////
72 // GenericMemberIterator
74 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
76 //! (Constant) member iterator for a JSON object value
78 \tparam Const Is this a constant iterator?
79 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
80 \tparam Allocator Allocator type for allocating memory of object, array and string.
82 This class implements a Random Access Iterator for GenericMember elements
83 of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
85 \note This iterator implementation is mainly intended to avoid implicit
86 conversions from iterator values to \c NULL,
87 e.g. from GenericValue::FindMember.
89 \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
90 pointer-based implementation, if your platform doesn't provide
91 the C++ <iterator> header.
93 \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
95 template <bool Const, typename Encoding, typename Allocator>
96 class GenericMemberIterator {
98 friend class GenericValue<Encoding,Allocator>;
99 template <bool, typename, typename> friend class GenericMemberIterator;
101 typedef GenericMember<Encoding,Allocator> PlainType;
102 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
105 //! Iterator type itself
106 typedef GenericMemberIterator Iterator;
107 //! Constant iterator type
108 typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator;
109 //! Non-constant iterator type
110 typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
112 /** \name std::iterator_traits support */
114 typedef ValueType value_type;
115 typedef ValueType * pointer;
116 typedef ValueType & reference;
117 typedef std::ptrdiff_t difference_type;
118 typedef std::random_access_iterator_tag iterator_category;
121 //! Pointer to (const) GenericMember
122 typedef pointer Pointer;
123 //! Reference to (const) GenericMember
124 typedef reference Reference;
125 //! Signed integer type (e.g. \c ptrdiff_t)
126 typedef difference_type DifferenceType;
128 //! Default constructor (singular value)
129 /*! Creates an iterator pointing to no element.
130 \note All operations, except for comparisons, are undefined on such values.
132 GenericMemberIterator() : ptr_() {}
134 //! Iterator conversions to more const
136 \param it (Non-const) iterator to copy from
138 Allows the creation of an iterator from another GenericMemberIterator
139 that is "less const". Especially, creating a non-constant iterator
140 from a constant iterator are disabled:
141 \li const -> non-const (not ok)
142 \li const -> const (ok)
143 \li non-const -> const (ok)
144 \li non-const -> non-const (ok)
146 \note If the \c Const template parameter is already \c false, this
147 constructor effectively defines a regular copy-constructor.
148 Otherwise, the copy constructor is implicitly defined.
150 GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
151 Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
155 Iterator& operator++(){ ++ptr_; return *this; }
156 Iterator& operator--(){ --ptr_; return *this; }
157 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
158 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
161 //! @name increment/decrement
163 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
164 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
166 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
167 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
172 bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
173 bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
174 bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
175 bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
176 bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
177 bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
180 //! @name dereference
182 Reference operator*() const { return *ptr_; }
183 Pointer operator->() const { return ptr_; }
184 Reference operator[](DifferenceType n) const { return ptr_[n]; }
188 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
191 //! Internal constructor from plain pointer
192 explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
194 Pointer ptr_; //!< raw pointer
197 #else // RAPIDJSON_NOMEMBERITERATORCLASS
199 // class-based member iterator implementation disabled, use plain pointers
201 template <bool Const, typename Encoding, typename Allocator>
202 struct GenericMemberIterator;
204 //! non-const GenericMemberIterator
205 template <typename Encoding, typename Allocator>
206 struct GenericMemberIterator<false,Encoding,Allocator> {
207 //! use plain pointer as iterator type
208 typedef GenericMember<Encoding,Allocator>* Iterator;
210 //! const GenericMemberIterator
211 template <typename Encoding, typename Allocator>
212 struct GenericMemberIterator<true,Encoding,Allocator> {
213 //! use plain const pointer as iterator type
214 typedef const GenericMember<Encoding,Allocator>* Iterator;
217 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
219 ///////////////////////////////////////////////////////////////////////////////
222 //! Reference to a constant string (not taking a copy)
224 \tparam CharType character type of the string
226 This helper class is used to automatically infer constant string
227 references for string literals, especially from \c const \b (!)
230 The main use is for creating JSON string values without copying the
231 source string via an \ref Allocator. This requires that the referenced
232 string pointers have a sufficient lifetime, which exceeds the lifetime
233 of the associated GenericValue.
237 Value v("foo"); // ok, no need to copy & calculate length
238 const char foo[] = "foo";
239 v.SetString(foo); // ok
241 const char* bar = foo;
242 // Value x(bar); // not ok, can't rely on bar's lifetime
243 Value x(StringRef(bar)); // lifetime explicitly guaranteed by user
244 Value y(StringRef(bar, 3)); // ok, explicitly pass length
247 \see StringRef, GenericValue::SetString
249 template<typename CharType>
250 struct GenericStringRef {
251 typedef CharType Ch; //!< character type of the string
253 //! Create string reference from \c const character array
254 #ifndef __clang__ // -Wdocumentation
256 This constructor implicitly creates a constant string reference from
257 a \c const character array. It has better performance than
258 \ref StringRef(const CharType*) by inferring the string \ref length
259 from the array length, and also supports strings containing null
262 \tparam N length of the string, automatically inferred
264 \param str Constant character array, lifetime assumed to be longer
265 than the use of the string in e.g. a GenericValue
269 \note Constant complexity.
270 \note There is a hidden, private overload to disallow references to
271 non-const character arrays to be created via this constructor.
272 By this, e.g. function-scope arrays used to be filled via
273 \c snprintf are excluded from consideration.
274 In such cases, the referenced string should be \b copied to the
275 GenericValue instead.
279 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
280 : s(str), length(N-1) {}
282 //! Explicitly create string reference from \c const character pointer
283 #ifndef __clang__ // -Wdocumentation
285 This constructor can be used to \b explicitly create a reference to
286 a constant string pointer.
288 \see StringRef(const CharType*)
290 \param str Constant character pointer, lifetime assumed to be longer
291 than the use of the string in e.g. a GenericValue
295 \note There is a hidden, private overload to disallow references to
296 non-const character arrays to be created via this constructor.
297 By this, e.g. function-scope arrays used to be filled via
298 \c snprintf are excluded from consideration.
299 In such cases, the referenced string should be \b copied to the
300 GenericValue instead.
303 explicit GenericStringRef(const CharType* str)
304 : s(str), length(NotNullStrLen(str)) {}
306 //! Create constant string reference from pointer and length
307 #ifndef __clang__ // -Wdocumentation
308 /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
309 \param len length of the string, excluding the trailing NULL terminator
311 \post \ref s == str && \ref length == len
312 \note Constant complexity.
315 GenericStringRef(const CharType* str, SizeType len)
316 : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
318 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
320 //! implicit conversion to plain CharType pointer
321 operator const Ch *() const { return s; }
323 const Ch* const s; //!< plain CharType pointer
324 const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
327 SizeType NotNullStrLen(const CharType* str) {
328 RAPIDJSON_ASSERT(str != 0);
329 return internal::StrLen(str);
332 /// Empty string - used when passing in a NULL pointer
333 static const Ch emptyString[];
335 //! Disallow construction from non-const array
337 GenericStringRef(CharType (&str)[N]) /* = delete */;
338 //! Copy assignment operator not permitted - immutable type
339 GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
342 template<typename CharType>
343 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
345 //! Mark a character pointer as constant string
346 /*! Mark a plain character pointer as a "string literal". This function
347 can be used to avoid copying a character string to be referenced as a
348 value in a JSON GenericValue object, if the string's lifetime is known
349 to be valid long enough.
350 \tparam CharType Character type of the string
351 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
352 \return GenericStringRef string reference object
353 \relatesalso GenericStringRef
355 \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember
357 template<typename CharType>
358 inline GenericStringRef<CharType> StringRef(const CharType* str) {
359 return GenericStringRef<CharType>(str);
362 //! Mark a character pointer as constant string
363 /*! Mark a plain character pointer as a "string literal". This function
364 can be used to avoid copying a character string to be referenced as a
365 value in a JSON GenericValue object, if the string's lifetime is known
366 to be valid long enough.
368 This version has better performance with supplied length, and also
369 supports string containing null characters.
371 \tparam CharType character type of the string
372 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
373 \param length The length of source string.
374 \return GenericStringRef string reference object
375 \relatesalso GenericStringRef
377 template<typename CharType>
378 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
379 return GenericStringRef<CharType>(str, SizeType(length));
382 #if RAPIDJSON_HAS_STDSTRING
383 //! Mark a string object as constant string
384 /*! Mark a string object (e.g. \c std::string) as a "string literal".
385 This function can be used to avoid copying a string to be referenced as a
386 value in a JSON GenericValue object, if the string's lifetime is known
387 to be valid long enough.
389 \tparam CharType character type of the string
390 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
391 \return GenericStringRef string reference object
392 \relatesalso GenericStringRef
393 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
395 template<typename CharType>
396 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
397 return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
401 ///////////////////////////////////////////////////////////////////////////////
402 // GenericValue type traits
405 template <typename T, typename Encoding = void, typename Allocator = void>
406 struct IsGenericValueImpl : FalseType {};
408 // select candidates according to nested encoding and allocator types
409 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
410 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
412 // helper to match arbitrary GenericValue instantiations, including derived classes
413 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
415 } // namespace internal
417 ///////////////////////////////////////////////////////////////////////////////
422 template <typename ValueType, typename T>
423 struct TypeHelper {};
425 template<typename ValueType>
426 struct TypeHelper<ValueType, bool> {
427 static bool Is(const ValueType& v) { return v.IsBool(); }
428 static bool Get(const ValueType& v) { return v.GetBool(); }
429 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
430 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
433 template<typename ValueType>
434 struct TypeHelper<ValueType, int> {
435 static bool Is(const ValueType& v) { return v.IsInt(); }
436 static int Get(const ValueType& v) { return v.GetInt(); }
437 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
438 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
441 template<typename ValueType>
442 struct TypeHelper<ValueType, unsigned> {
443 static bool Is(const ValueType& v) { return v.IsUint(); }
444 static unsigned Get(const ValueType& v) { return v.GetUint(); }
445 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
446 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
450 RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
451 template<typename ValueType>
452 struct TypeHelper<ValueType, long> {
453 static bool Is(const ValueType& v) { return v.IsInt(); }
454 static long Get(const ValueType& v) { return v.GetInt(); }
455 static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
456 static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
459 RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
460 template<typename ValueType>
461 struct TypeHelper<ValueType, unsigned long> {
462 static bool Is(const ValueType& v) { return v.IsUint(); }
463 static unsigned long Get(const ValueType& v) { return v.GetUint(); }
464 static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
465 static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
469 template<typename ValueType>
470 struct TypeHelper<ValueType, int64_t> {
471 static bool Is(const ValueType& v) { return v.IsInt64(); }
472 static int64_t Get(const ValueType& v) { return v.GetInt64(); }
473 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
474 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
477 template<typename ValueType>
478 struct TypeHelper<ValueType, uint64_t> {
479 static bool Is(const ValueType& v) { return v.IsUint64(); }
480 static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
481 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
482 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
485 template<typename ValueType>
486 struct TypeHelper<ValueType, double> {
487 static bool Is(const ValueType& v) { return v.IsDouble(); }
488 static double Get(const ValueType& v) { return v.GetDouble(); }
489 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
490 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
493 template<typename ValueType>
494 struct TypeHelper<ValueType, float> {
495 static bool Is(const ValueType& v) { return v.IsFloat(); }
496 static float Get(const ValueType& v) { return v.GetFloat(); }
497 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
498 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
501 template<typename ValueType>
502 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
503 typedef const typename ValueType::Ch* StringType;
504 static bool Is(const ValueType& v) { return v.IsString(); }
505 static StringType Get(const ValueType& v) { return v.GetString(); }
506 static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
507 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
510 #if RAPIDJSON_HAS_STDSTRING
511 template<typename ValueType>
512 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
513 typedef std::basic_string<typename ValueType::Ch> StringType;
514 static bool Is(const ValueType& v) { return v.IsString(); }
515 static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
516 static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
520 template<typename ValueType>
521 struct TypeHelper<ValueType, typename ValueType::Array> {
522 typedef typename ValueType::Array ArrayType;
523 static bool Is(const ValueType& v) { return v.IsArray(); }
524 static ArrayType Get(ValueType& v) { return v.GetArray(); }
525 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
526 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
529 template<typename ValueType>
530 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
531 typedef typename ValueType::ConstArray ArrayType;
532 static bool Is(const ValueType& v) { return v.IsArray(); }
533 static ArrayType Get(const ValueType& v) { return v.GetArray(); }
536 template<typename ValueType>
537 struct TypeHelper<ValueType, typename ValueType::Object> {
538 typedef typename ValueType::Object ObjectType;
539 static bool Is(const ValueType& v) { return v.IsObject(); }
540 static ObjectType Get(ValueType& v) { return v.GetObject(); }
541 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
542 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
545 template<typename ValueType>
546 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
547 typedef typename ValueType::ConstObject ObjectType;
548 static bool Is(const ValueType& v) { return v.IsObject(); }
549 static ObjectType Get(const ValueType& v) { return v.GetObject(); }
552 } // namespace internal
554 // Forward declarations
555 template <bool, typename> class GenericArray;
556 template <bool, typename> class GenericObject;
558 ///////////////////////////////////////////////////////////////////////////////
561 //! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
563 A JSON value can be one of 7 types. This class is a variant type supporting
566 Use the Value if UTF8 and default allocator
568 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
569 \tparam Allocator Allocator type for allocating memory of object, array and string.
571 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
574 //! Name-value pair in an object.
575 typedef GenericMember<Encoding, Allocator> Member;
576 typedef Encoding EncodingType; //!< Encoding type from template parameter.
577 typedef Allocator AllocatorType; //!< Allocator type from template parameter.
578 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
579 typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string
580 typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object.
581 typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object.
582 typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
583 typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
584 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself.
585 typedef GenericArray<false, ValueType> Array;
586 typedef GenericArray<true, ValueType> ConstArray;
587 typedef GenericObject<false, ValueType> Object;
588 typedef GenericObject<true, ValueType> ConstObject;
590 //!@name Constructors and destructor.
593 //! Default constructor creates a null value.
594 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
596 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
597 //! Move constructor in C++11
598 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
599 rhs.data_.f.flags = kNullFlag; // give up contents
604 //! Copy constructor is not permitted.
605 GenericValue(const GenericValue& rhs);
607 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
608 //! Moving from a GenericDocument is not permitted.
609 template <typename StackAllocator>
610 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
612 //! Move assignment from a GenericDocument is not permitted.
613 template <typename StackAllocator>
614 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
619 //! Constructor with JSON value type.
620 /*! This creates a Value of specified type with default content.
621 \param type Type of the value.
622 \note Default content for number is zero.
624 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
625 static const uint16_t defaultFlags[] = {
626 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
629 RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
630 data_.f.flags = defaultFlags[type];
632 // Use ShortString to store empty string.
633 if (type == kStringType)
634 data_.ss.SetLength(0);
637 //! Explicit copy constructor (with allocator)
638 /*! Creates a copy of a Value by using the given Allocator
639 \tparam SourceAllocator allocator of \c rhs
640 \param rhs Value to copy from (read-only)
641 \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
642 \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
645 template <typename SourceAllocator>
646 GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
647 switch (rhs.GetType()) {
649 SizeType count = rhs.data_.o.size;
650 Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
651 const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
652 for (SizeType i = 0; i < count; i++) {
653 new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
654 new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
656 data_.f.flags = kObjectFlag;
657 data_.o.size = data_.o.capacity = count;
658 SetMembersPointer(lm);
662 SizeType count = rhs.data_.a.size;
663 GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
664 const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
665 for (SizeType i = 0; i < count; i++)
666 new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
667 data_.f.flags = kArrayFlag;
668 data_.a.size = data_.a.capacity = count;
669 SetElementsPointer(le);
673 if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
674 data_.f.flags = rhs.data_.f.flags;
675 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
678 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
681 data_.f.flags = rhs.data_.f.flags;
682 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
687 //! Constructor for boolean value.
688 /*! \param b Boolean value
689 \note This constructor is limited to \em real boolean values and rejects
690 implicitly converted types like arbitrary pointers. Use an explicit cast
691 to \c bool, if you want to construct a boolean JSON value in such cases.
693 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
694 template <typename T>
695 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
697 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
700 // safe-guard against failing SFINAE
701 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
702 data_.f.flags = b ? kTrueFlag : kFalseFlag;
705 //! Constructor for int value.
706 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
708 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
711 //! Constructor for unsigned value.
712 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
714 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
717 //! Constructor for int64_t value.
718 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
720 data_.f.flags = kNumberInt64Flag;
722 data_.f.flags |= kNumberUint64Flag;
723 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
724 data_.f.flags |= kUintFlag;
725 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
726 data_.f.flags |= kIntFlag;
728 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
729 data_.f.flags |= kIntFlag;
732 //! Constructor for uint64_t value.
733 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
735 data_.f.flags = kNumberUint64Flag;
736 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
737 data_.f.flags |= kInt64Flag;
738 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
739 data_.f.flags |= kUintFlag;
740 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
741 data_.f.flags |= kIntFlag;
744 //! Constructor for double value.
745 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
747 //! Constructor for float value.
748 explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
750 //! Constructor for constant string (i.e. do not make a copy of string)
751 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
753 //! Constructor for constant string (i.e. do not make a copy of string)
754 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
756 //! Constructor for copy-string (i.e. do make a copy of string)
757 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
759 //! Constructor for copy-string (i.e. do make a copy of string)
760 GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
762 #if RAPIDJSON_HAS_STDSTRING
763 //! Constructor for copy-string from a string object (i.e. do make a copy of string)
764 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
766 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
769 //! Constructor for Array.
771 \param a An array obtained by \c GetArray().
772 \note \c Array is always pass-by-value.
773 \note the source array is moved into this value and the sourec array becomes empty.
775 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
776 a.value_.data_ = Data();
777 a.value_.data_.f.flags = kArrayFlag;
780 //! Constructor for Object.
782 \param o An object obtained by \c GetObject().
783 \note \c Object is always pass-by-value.
784 \note the source object is moved into this value and the sourec object becomes empty.
786 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
787 o.value_.data_ = Data();
788 o.value_.data_.f.flags = kObjectFlag;
792 /*! Need to destruct elements of array, members of object, or copy-string.
795 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
796 switch(data_.f.flags) {
799 GenericValue* e = GetElementsPointer();
800 for (GenericValue* v = e; v != e + data_.a.size; ++v)
807 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
809 Allocator::Free(GetMembersPointer());
812 case kCopyStringFlag:
813 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
817 break; // Do nothing for other types.
824 //!@name Assignment operators
827 //! Assignment with move semantics.
828 /*! \param rhs Source of the assignment. It will become a null value after assignment.
830 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
831 if (RAPIDJSON_LIKELY(this != &rhs)) {
832 this->~GenericValue();
838 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
839 //! Move assignment in C++11
840 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
841 return *this = rhs.Move();
845 //! Assignment of constant string reference (no copy)
846 /*! \param str Constant string reference to be assigned
847 \note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
848 \see GenericStringRef, operator=(T)
850 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
855 //! Assignment with primitive types.
856 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
857 \param value The value to be assigned.
859 \note The source type \c T explicitly disallows all pointer types,
860 especially (\c const) \ref Ch*. This helps avoiding implicitly
861 referencing character strings with insufficient lifetime, use
862 \ref SetString(const Ch*, Allocator&) (for copying) or
863 \ref StringRef() (to explicitly mark the pointer as constant) instead.
864 All other pointer types would implicitly convert to \c bool,
865 use \ref SetBool() instead.
867 template <typename T>
868 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
870 GenericValue v(value);
874 //! Deep-copy assignment from Value
875 /*! Assigns a \b copy of the Value to the current Value object
876 \tparam SourceAllocator Allocator type of \c rhs
877 \param rhs Value to copy from (read-only)
878 \param allocator Allocator to use for copying
879 \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
881 template <typename SourceAllocator>
882 GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
883 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
884 this->~GenericValue();
885 new (this) GenericValue(rhs, allocator, copyConstStrings);
889 //! Exchange the contents of this value with those of other.
891 \param other Another value.
892 \note Constant complexity.
894 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
896 temp.RawAssign(*this);
898 other.RawAssign(temp);
902 //! free-standing swap function helper
904 Helper function to enable support for common swap implementation pattern based on \c std::swap:
906 void swap(MyClass& a, MyClass& b) {
908 swap(a.value, b.value);
914 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
916 //! Prepare Value for move semantics
918 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
921 //!@name Equal-to and not-equal-to operators
923 //! Equal-to operator
925 \note If an object contains duplicated named member, comparing equality with any object is always \c false.
926 \note Linear time complexity (number of all values in the subtree and total lengths of all strings).
928 template <typename SourceAllocator>
929 bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
930 typedef GenericValue<Encoding, SourceAllocator> RhsType;
931 if (GetType() != rhs.GetType())
935 case kObjectType: // Warning: O(n^2) inner-loop
936 if (data_.o.size != rhs.data_.o.size)
938 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
939 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
940 if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
946 if (data_.a.size != rhs.data_.a.size)
948 for (SizeType i = 0; i < data_.a.size; i++)
949 if ((*this)[i] != rhs[i])
954 return StringEqual(rhs);
957 if (IsDouble() || rhs.IsDouble()) {
958 double a = GetDouble(); // May convert from integer to double.
959 double b = rhs.GetDouble(); // Ditto
960 return a >= b && a <= b; // Prevent -Wfloat-equal
963 return data_.n.u64 == rhs.data_.n.u64;
970 //! Equal-to operator with const C-string pointer
971 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
973 #if RAPIDJSON_HAS_STDSTRING
974 //! Equal-to operator with string object
975 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
977 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
980 //! Equal-to operator with primitive types
981 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
983 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
985 //! Not-equal-to operator
986 /*! \return !(*this == rhs)
988 template <typename SourceAllocator>
989 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
991 //! Not-equal-to operator with const C-string pointer
992 bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
994 //! Not-equal-to operator with arbitrary types
995 /*! \return !(*this == rhs)
997 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
999 //! Equal-to operator with arbitrary types (symmetric version)
1000 /*! \return (rhs == lhs)
1002 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1004 //! Not-Equal-to operator with arbitrary types (symmetric version)
1005 /*! \return !(rhs == lhs)
1007 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1013 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1014 bool IsNull() const { return data_.f.flags == kNullFlag; }
1015 bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1016 bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1017 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1018 bool IsObject() const { return data_.f.flags == kObjectFlag; }
1019 bool IsArray() const { return data_.f.flags == kArrayFlag; }
1020 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1021 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1022 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1023 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1024 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1025 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1026 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1028 // Checks whether a number can be losslessly converted to a double.
1029 bool IsLosslessDouble() const {
1030 if (!IsNumber()) return false;
1032 uint64_t u = GetUint64();
1033 volatile double d = static_cast<double>(u);
1035 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1036 && (u == static_cast<uint64_t>(d));
1039 int64_t i = GetInt64();
1040 volatile double d = static_cast<double>(i);
1041 return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1042 && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1043 && (i == static_cast<int64_t>(d));
1045 return true; // double, int, uint are always lossless
1048 // Checks whether a number is a float (possible lossy).
1049 bool IsFloat() const {
1050 if ((data_.f.flags & kDoubleFlag) == 0)
1052 double d = GetDouble();
1053 return d >= -3.4028234e38 && d <= 3.4028234e38;
1055 // Checks whether a number can be losslessly converted to a float.
1056 bool IsLosslessFloat() const {
1057 if (!IsNumber()) return false;
1058 double a = GetDouble();
1059 if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1060 || a > static_cast<double>((std::numeric_limits<float>::max)()))
1062 double b = static_cast<double>(static_cast<float>(a));
1063 return a >= b && a <= b; // Prevent -Wfloat-equal
1071 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1078 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1079 //!< Set boolean value
1080 /*! \post IsBool() == true */
1081 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1088 //! Set this value as an empty object.
1089 /*! \post IsObject() == true */
1090 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1092 //! Get the number of members in the object.
1093 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1095 //! Get the capacity of object.
1096 SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1098 //! Check whether the object is empty.
1099 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1101 //! Get a value from an object associated with the name.
1102 /*! \pre IsObject() == true
1103 \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType))
1104 \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
1105 Since 0.2, if the name is not correct, it will assert.
1106 If user is unsure whether a member exists, user should use HasMember() first.
1107 A better approach is to use FindMember().
1108 \note Linear time complexity.
1110 template <typename T>
1111 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1112 GenericValue n(StringRef(name));
1115 template <typename T>
1116 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]; }
1118 //! Get a value from an object associated with the name.
1119 /*! \pre IsObject() == true
1120 \tparam SourceAllocator Allocator of the \c name value
1122 \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen().
1123 And it can also handle strings with embedded null characters.
1125 \note Linear time complexity.
1127 template <typename SourceAllocator>
1128 GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1129 MemberIterator member = FindMember(name);
1130 if (member != MemberEnd())
1131 return member->value;
1133 RAPIDJSON_ASSERT(false); // see above note
1135 // This will generate -Wexit-time-destructors in clang
1136 // static GenericValue NullValue;
1137 // return NullValue;
1139 // Use static buffer and placement-new to prevent destruction
1140 static char buffer[sizeof(GenericValue)];
1141 return *new (buffer) GenericValue();
1144 template <typename SourceAllocator>
1145 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1147 #if RAPIDJSON_HAS_STDSTRING
1148 //! Get a value from an object associated with name (string object).
1149 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1150 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1153 //! Const member iterator
1154 /*! \pre IsObject() == true */
1155 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1156 //! Const \em past-the-end member iterator
1157 /*! \pre IsObject() == true */
1158 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1160 /*! \pre IsObject() == true */
1161 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1162 //! \em Past-the-end member iterator
1163 /*! \pre IsObject() == true */
1164 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1166 //! Request the object to have enough capacity to store members.
1167 /*! \param newCapacity The capacity that the object at least need to have.
1168 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1169 \return The value itself for fluent API.
1170 \note Linear time complexity.
1172 GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1173 RAPIDJSON_ASSERT(IsObject());
1174 if (newCapacity > data_.o.capacity) {
1175 SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
1176 data_.o.capacity = newCapacity;
1181 //! Check whether a member exists in the object.
1183 \param name Member name to be searched.
1184 \pre IsObject() == true
1185 \return Whether a member with that name exists.
1186 \note It is better to use FindMember() directly if you need the obtain the value as well.
1187 \note Linear time complexity.
1189 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1191 #if RAPIDJSON_HAS_STDSTRING
1192 //! Check whether a member exists in the object with string object.
1194 \param name Member name to be searched.
1195 \pre IsObject() == true
1196 \return Whether a member with that name exists.
1197 \note It is better to use FindMember() directly if you need the obtain the value as well.
1198 \note Linear time complexity.
1200 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1203 //! Check whether a member exists in the object with GenericValue name.
1205 This version is faster because it does not need a StrLen(). It can also handle string with null character.
1206 \param name Member name to be searched.
1207 \pre IsObject() == true
1208 \return Whether a member with that name exists.
1209 \note It is better to use FindMember() directly if you need the obtain the value as well.
1210 \note Linear time complexity.
1212 template <typename SourceAllocator>
1213 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1215 //! Find member by name.
1217 \param name Member name to be searched.
1218 \pre IsObject() == true
1219 \return Iterator to member, if it exists.
1220 Otherwise returns \ref MemberEnd().
1222 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
1223 the requested member doesn't exist. For consistency with e.g.
1224 \c std::map, this has been changed to MemberEnd() now.
1225 \note Linear time complexity.
1227 MemberIterator FindMember(const Ch* name) {
1228 GenericValue n(StringRef(name));
1229 return FindMember(n);
1232 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1234 //! Find member by name.
1236 This version is faster because it does not need a StrLen(). It can also handle string with null character.
1237 \param name Member name to be searched.
1238 \pre IsObject() == true
1239 \return Iterator to member, if it exists.
1240 Otherwise returns \ref MemberEnd().
1242 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
1243 the requested member doesn't exist. For consistency with e.g.
1244 \c std::map, this has been changed to MemberEnd() now.
1245 \note Linear time complexity.
1247 template <typename SourceAllocator>
1248 MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
1249 RAPIDJSON_ASSERT(IsObject());
1250 RAPIDJSON_ASSERT(name.IsString());
1251 MemberIterator member = MemberBegin();
1252 for ( ; member != MemberEnd(); ++member)
1253 if (name.StringEqual(member->name))
1257 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1259 #if RAPIDJSON_HAS_STDSTRING
1260 //! Find member by string object name.
1262 \param name Member name to be searched.
1263 \pre IsObject() == true
1264 \return Iterator to member, if it exists.
1265 Otherwise returns \ref MemberEnd().
1267 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1268 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1271 //! Add a member (name-value pair) to the object.
1272 /*! \param name A string value as name of member.
1273 \param value Value of any type.
1274 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1275 \return The value itself for fluent API.
1276 \note The ownership of \c name and \c value will be transferred to this object on success.
1277 \pre IsObject() && name.IsString()
1278 \post name.IsNull() && value.IsNull()
1279 \note Amortized Constant time complexity.
1281 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1282 RAPIDJSON_ASSERT(IsObject());
1283 RAPIDJSON_ASSERT(name.IsString());
1285 ObjectData& o = data_.o;
1286 if (o.size >= o.capacity)
1287 MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1288 Member* members = GetMembersPointer();
1289 members[o.size].name.RawAssign(name);
1290 members[o.size].value.RawAssign(value);
1295 //! Add a constant string value as member (name-value pair) to the object.
1296 /*! \param name A string value as name of member.
1297 \param value constant string reference as value of member.
1298 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1299 \return The value itself for fluent API.
1301 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
1302 \note Amortized Constant time complexity.
1304 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1305 GenericValue v(value);
1306 return AddMember(name, v, allocator);
1309 #if RAPIDJSON_HAS_STDSTRING
1310 //! Add a string object as member (name-value pair) to the object.
1311 /*! \param name A string value as name of member.
1312 \param value constant string reference as value of member.
1313 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1314 \return The value itself for fluent API.
1316 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
1317 \note Amortized Constant time complexity.
1319 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1320 GenericValue v(value, allocator);
1321 return AddMember(name, v, allocator);
1325 //! Add any primitive value as member (name-value pair) to the object.
1326 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1327 \param name A string value as name of member.
1328 \param value Value of primitive type \c T as value of member
1329 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1330 \return The value itself for fluent API.
1333 \note The source type \c T explicitly disallows all pointer types,
1334 especially (\c const) \ref Ch*. This helps avoiding implicitly
1335 referencing character strings with insufficient lifetime, use
1336 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1337 AddMember(StringRefType, StringRefType, Allocator&).
1338 All other pointer types would implicitly convert to \c bool,
1339 use an explicit cast instead, if needed.
1340 \note Amortized Constant time complexity.
1342 template <typename T>
1343 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1344 AddMember(GenericValue& name, T value, Allocator& allocator) {
1345 GenericValue v(value);
1346 return AddMember(name, v, allocator);
1349 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1350 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1351 return AddMember(name, value, allocator);
1353 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1354 return AddMember(name, value, allocator);
1356 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1357 return AddMember(name, value, allocator);
1359 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1360 GenericValue n(name);
1361 return AddMember(n, value, allocator);
1363 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1366 //! Add a member (name-value pair) to the object.
1367 /*! \param name A constant string reference as name of member.
1368 \param value Value of any type.
1369 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1370 \return The value itself for fluent API.
1371 \note The ownership of \c value will be transferred to this object on success.
1373 \post value.IsNull()
1374 \note Amortized Constant time complexity.
1376 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1377 GenericValue n(name);
1378 return AddMember(n, value, allocator);
1381 //! Add a constant string value as member (name-value pair) to the object.
1382 /*! \param name A constant string reference as name of member.
1383 \param value constant string reference as value of member.
1384 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1385 \return The value itself for fluent API.
1387 \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.
1388 \note Amortized Constant time complexity.
1390 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1391 GenericValue v(value);
1392 return AddMember(name, v, allocator);
1395 //! Add any primitive value as member (name-value pair) to the object.
1396 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1397 \param name A constant string reference as name of member.
1398 \param value Value of primitive type \c T as value of member
1399 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1400 \return The value itself for fluent API.
1403 \note The source type \c T explicitly disallows all pointer types,
1404 especially (\c const) \ref Ch*. This helps avoiding implicitly
1405 referencing character strings with insufficient lifetime, use
1406 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1407 AddMember(StringRefType, StringRefType, Allocator&).
1408 All other pointer types would implicitly convert to \c bool,
1409 use an explicit cast instead, if needed.
1410 \note Amortized Constant time complexity.
1412 template <typename T>
1413 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1414 AddMember(StringRefType name, T value, Allocator& allocator) {
1415 GenericValue n(name);
1416 return AddMember(n, value, allocator);
1419 //! Remove all members in the object.
1420 /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.
1421 \note Linear time complexity.
1423 void RemoveAllMembers() {
1424 RAPIDJSON_ASSERT(IsObject());
1425 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1430 //! Remove a member in object by its name.
1431 /*! \param name Name of member to be removed.
1432 \return Whether the member existed.
1433 \note This function may reorder the object members. Use \ref
1434 EraseMember(ConstMemberIterator) if you need to preserve the
1435 relative order of the remaining members.
1436 \note Linear time complexity.
1438 bool RemoveMember(const Ch* name) {
1439 GenericValue n(StringRef(name));
1440 return RemoveMember(n);
1443 #if RAPIDJSON_HAS_STDSTRING
1444 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1447 template <typename SourceAllocator>
1448 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1449 MemberIterator m = FindMember(name);
1450 if (m != MemberEnd()) {
1458 //! Remove a member in object by iterator.
1459 /*! \param m member iterator (obtained by FindMember() or MemberBegin()).
1460 \return the new iterator after removal.
1461 \note This function may reorder the object members. Use \ref
1462 EraseMember(ConstMemberIterator) if you need to preserve the
1463 relative order of the remaining members.
1464 \note Constant time complexity.
1466 MemberIterator RemoveMember(MemberIterator m) {
1467 RAPIDJSON_ASSERT(IsObject());
1468 RAPIDJSON_ASSERT(data_.o.size > 0);
1469 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1470 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1472 MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1473 if (data_.o.size > 1 && m != last)
1474 *m = *last; // Move the last one to this place
1476 m->~Member(); // Only one left, just destroy
1481 //! Remove a member from an object by iterator.
1482 /*! \param pos iterator to the member to remove
1483 \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd()
1484 \return Iterator following the removed element.
1485 If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned.
1486 \note This function preserves the relative order of the remaining object
1487 members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator).
1488 \note Linear time complexity.
1490 MemberIterator EraseMember(ConstMemberIterator pos) {
1491 return EraseMember(pos, pos +1);
1494 //! Remove members in the range [first, last) from an object.
1495 /*! \param first iterator to the first member to remove
1496 \param last iterator following the last member to remove
1497 \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd()
1498 \return Iterator following the last removed element.
1499 \note This function preserves the relative order of the remaining object
1501 \note Linear time complexity.
1503 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1504 RAPIDJSON_ASSERT(IsObject());
1505 RAPIDJSON_ASSERT(data_.o.size > 0);
1506 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1507 RAPIDJSON_ASSERT(first >= MemberBegin());
1508 RAPIDJSON_ASSERT(first <= last);
1509 RAPIDJSON_ASSERT(last <= MemberEnd());
1511 MemberIterator pos = MemberBegin() + (first - MemberBegin());
1512 for (MemberIterator itr = pos; itr != last; ++itr)
1514 std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1515 data_.o.size -= static_cast<SizeType>(last - first);
1519 //! Erase a member in object by its name.
1520 /*! \param name Name of member to be removed.
1521 \return Whether the member existed.
1522 \note Linear time complexity.
1524 bool EraseMember(const Ch* name) {
1525 GenericValue n(StringRef(name));
1526 return EraseMember(n);
1529 #if RAPIDJSON_HAS_STDSTRING
1530 bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1533 template <typename SourceAllocator>
1534 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1535 MemberIterator m = FindMember(name);
1536 if (m != MemberEnd()) {
1544 Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1545 ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1552 //! Set this value as an empty array.
1553 /*! \post IsArray == true */
1554 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1556 //! Get the number of elements in array.
1557 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1559 //! Get the capacity of array.
1560 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1562 //! Check whether the array is empty.
1563 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1565 //! Remove all elements in the array.
1566 /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
1567 \note Linear time complexity.
1570 RAPIDJSON_ASSERT(IsArray());
1571 GenericValue* e = GetElementsPointer();
1572 for (GenericValue* v = e; v != e + data_.a.size; ++v)
1577 //! Get an element from array by index.
1578 /*! \pre IsArray() == true
1579 \param index Zero-based index of element.
1582 GenericValue& operator[](SizeType index) {
1583 RAPIDJSON_ASSERT(IsArray());
1584 RAPIDJSON_ASSERT(index < data_.a.size);
1585 return GetElementsPointer()[index];
1587 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1589 //! Element iterator
1590 /*! \pre IsArray() == true */
1591 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1592 //! \em Past-the-end element iterator
1593 /*! \pre IsArray() == true */
1594 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1595 //! Constant element iterator
1596 /*! \pre IsArray() == true */
1597 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1598 //! Constant \em past-the-end element iterator
1599 /*! \pre IsArray() == true */
1600 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1602 //! Request the array to have enough capacity to store elements.
1603 /*! \param newCapacity The capacity that the array at least need to have.
1604 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1605 \return The value itself for fluent API.
1606 \note Linear time complexity.
1608 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1609 RAPIDJSON_ASSERT(IsArray());
1610 if (newCapacity > data_.a.capacity) {
1611 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1612 data_.a.capacity = newCapacity;
1617 //! Append a GenericValue at the end of the array.
1618 /*! \param value Value to be appended.
1619 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1620 \pre IsArray() == true
1621 \post value.IsNull() == true
1622 \return The value itself for fluent API.
1623 \note The ownership of \c value will be transferred to this array on success.
1624 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1625 \note Amortized constant time complexity.
1627 GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1628 RAPIDJSON_ASSERT(IsArray());
1629 if (data_.a.size >= data_.a.capacity)
1630 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1631 GetElementsPointer()[data_.a.size++].RawAssign(value);
1635 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1636 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1637 return PushBack(value, allocator);
1639 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1641 //! Append a constant string reference at the end of the array.
1642 /*! \param value Constant string reference to be appended.
1643 \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().
1644 \pre IsArray() == true
1645 \return The value itself for fluent API.
1646 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1647 \note Amortized constant time complexity.
1648 \see GenericStringRef
1650 GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1651 return (*this).template PushBack<StringRefType>(value, allocator);
1654 //! Append a primitive value at the end of the array.
1655 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1656 \param value Value of primitive type T to be appended.
1657 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1658 \pre IsArray() == true
1659 \return The value itself for fluent API.
1660 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1662 \note The source type \c T explicitly disallows all pointer types,
1663 especially (\c const) \ref Ch*. This helps avoiding implicitly
1664 referencing character strings with insufficient lifetime, use
1665 \ref PushBack(GenericValue&, Allocator&) or \ref
1666 PushBack(StringRefType, Allocator&).
1667 All other pointer types would implicitly convert to \c bool,
1668 use an explicit cast instead, if needed.
1669 \note Amortized constant time complexity.
1671 template <typename T>
1672 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1673 PushBack(T value, Allocator& allocator) {
1674 GenericValue v(value);
1675 return PushBack(v, allocator);
1678 //! Remove the last element in the array.
1680 \note Constant time complexity.
1682 GenericValue& PopBack() {
1683 RAPIDJSON_ASSERT(IsArray());
1684 RAPIDJSON_ASSERT(!Empty());
1685 GetElementsPointer()[--data_.a.size].~GenericValue();
1689 //! Remove an element of array by iterator.
1691 \param pos iterator to the element to remove
1692 \pre IsArray() == true && \ref Begin() <= \c pos < \ref End()
1693 \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.
1694 \note Linear time complexity.
1696 ValueIterator Erase(ConstValueIterator pos) {
1697 return Erase(pos, pos + 1);
1700 //! Remove elements in the range [first, last) of the array.
1702 \param first iterator to the first element to remove
1703 \param last iterator following the last element to remove
1704 \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End()
1705 \return Iterator following the last removed element.
1706 \note Linear time complexity.
1708 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1709 RAPIDJSON_ASSERT(IsArray());
1710 RAPIDJSON_ASSERT(data_.a.size > 0);
1711 RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1712 RAPIDJSON_ASSERT(first >= Begin());
1713 RAPIDJSON_ASSERT(first <= last);
1714 RAPIDJSON_ASSERT(last <= End());
1715 ValueIterator pos = Begin() + (first - Begin());
1716 for (ValueIterator itr = pos; itr != last; ++itr)
1717 itr->~GenericValue();
1718 std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1719 data_.a.size -= static_cast<SizeType>(last - first);
1723 Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1724 ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1731 int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1732 unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1733 int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1734 uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1736 //! Get the value as double type.
1737 /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless.
1739 double GetDouble() const {
1740 RAPIDJSON_ASSERT(IsNumber());
1741 if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1742 if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1743 if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1744 if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1745 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1748 //! Get the value as float type.
1749 /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless.
1751 float GetFloat() const {
1752 return static_cast<float>(GetDouble());
1755 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1756 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1757 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1758 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1759 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1760 GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1767 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1769 //! Get the length of string.
1770 /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
1772 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1774 //! Set this value as a string without copying source string.
1775 /*! This version has better performance with supplied length, and also support string containing null character.
1776 \param s source string pointer.
1777 \param length The length of source string, excluding the trailing null terminator.
1778 \return The value itself for fluent API.
1779 \post IsString() == true && GetString() == s && GetStringLength() == length
1780 \see SetString(StringRefType)
1782 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1784 //! Set this value as a string without copying source string.
1785 /*! \param s source string reference
1786 \return The value itself for fluent API.
1787 \post IsString() == true && GetString() == s && GetStringLength() == s.length
1789 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1791 //! Set this value as a string by copying from source string.
1792 /*! This version has better performance with supplied length, and also support string containing null character.
1793 \param s source string.
1794 \param length The length of source string, excluding the trailing null terminator.
1795 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1796 \return The value itself for fluent API.
1797 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1799 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1801 //! Set this value as a string by copying from source string.
1802 /*! \param s source string.
1803 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1804 \return The value itself for fluent API.
1805 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1807 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1809 //! Set this value as a string by copying from source string.
1810 /*! \param s source string reference
1811 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1812 \return The value itself for fluent API.
1813 \post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1815 GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1817 #if RAPIDJSON_HAS_STDSTRING
1818 //! Set this value as a string by copying from source string.
1819 /*! \param s source string.
1820 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1821 \return The value itself for fluent API.
1822 \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()
1823 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
1825 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1833 //! Templated version for checking whether this value is type T.
1835 \tparam T Either \c bool, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c float, \c const \c char*, \c std::basic_string<Ch>
1837 template <typename T>
1838 bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1840 template <typename T>
1841 T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1843 template <typename T>
1844 T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1846 template<typename T>
1847 ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1851 //! Generate events of this value to a Handler.
1852 /*! This function adopts the GoF visitor pattern.
1853 Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.
1854 It can also be used to deep clone this value via GenericDocument, which is also a Handler.
1855 \tparam Handler type of handler.
1856 \param handler An object implementing concept Handler.
1858 template <typename Handler>
1859 bool Accept(Handler& handler) const {
1861 case kNullType: return handler.Null();
1862 case kFalseType: return handler.Bool(false);
1863 case kTrueType: return handler.Bool(true);
1866 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1868 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1869 RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1870 if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1872 if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1875 return handler.EndObject(data_.o.size);
1878 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1880 for (const GenericValue* v = Begin(); v != End(); ++v)
1881 if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1883 return handler.EndArray(data_.a.size);
1886 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1889 RAPIDJSON_ASSERT(GetType() == kNumberType);
1890 if (IsDouble()) return handler.Double(data_.n.d);
1891 else if (IsInt()) return handler.Int(data_.n.i.i);
1892 else if (IsUint()) return handler.Uint(data_.n.u.u);
1893 else if (IsInt64()) return handler.Int64(data_.n.i64);
1894 else return handler.Uint64(data_.n.u64);
1899 template <typename, typename> friend class GenericValue;
1900 template <typename, typename, typename> friend class GenericDocument;
1904 kNumberFlag = 0x0010,
1907 kInt64Flag = 0x0080,
1908 kUint64Flag = 0x0100,
1909 kDoubleFlag = 0x0200,
1910 kStringFlag = 0x0400,
1912 kInlineStrFlag = 0x1000,
1914 // Initial flags of different types.
1915 kNullFlag = kNullType,
1916 kTrueFlag = kTrueType | kBoolFlag,
1917 kFalseFlag = kFalseType | kBoolFlag,
1918 kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
1919 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
1920 kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
1921 kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
1922 kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
1923 kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
1924 kConstStringFlag = kStringType | kStringFlag,
1925 kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
1926 kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
1927 kObjectFlag = kObjectType,
1928 kArrayFlag = kArrayType,
1933 static const SizeType kDefaultArrayCapacity = 16;
1934 static const SizeType kDefaultObjectCapacity = 16;
1937 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
1938 char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
1939 #elif RAPIDJSON_64BIT
1940 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
1942 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
1949 SizeType hashcode; //!< reserved
1951 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1953 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1954 // (excluding the terminating zero) and store a value to determine the length of the contained
1955 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1956 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1957 // the string terminator as well. For getting the string length back from that value just use
1958 // "MaxSize - str[LenPos]".
1959 // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
1960 // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
1961 struct ShortString {
1962 enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
1965 inline static bool Usable(SizeType len) { return (MaxSize >= len); }
1966 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
1967 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
1968 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1970 // By using proper binary layout, retrieval of different integer types do not need conversions.
1972 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2000 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2005 GenericValue* elements;
2006 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2015 }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2017 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2018 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2019 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2020 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2021 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2022 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2024 // Initialize this value as array with initial data, without calling destructor.
2025 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2026 data_.f.flags = kArrayFlag;
2028 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2029 SetElementsPointer(e);
2030 std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2033 SetElementsPointer(0);
2034 data_.a.size = data_.a.capacity = count;
2037 //! Initialize this value as object with initial data, without calling destructor.
2038 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2039 data_.f.flags = kObjectFlag;
2041 Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2042 SetMembersPointer(m);
2043 std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2046 SetMembersPointer(0);
2047 data_.o.size = data_.o.capacity = count;
2050 //! Initialize this value as constant string, without calling destructor.
2051 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2052 data_.f.flags = kConstStringFlag;
2053 SetStringPointer(s);
2054 data_.s.length = s.length;
2057 //! Initialize this value as copy string with initial data, without calling destructor.
2058 void SetStringRaw(StringRefType s, Allocator& allocator) {
2060 if (ShortString::Usable(s.length)) {
2061 data_.f.flags = kShortStringFlag;
2062 data_.ss.SetLength(s.length);
2065 data_.f.flags = kCopyStringFlag;
2066 data_.s.length = s.length;
2067 str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2068 SetStringPointer(str);
2070 std::memcpy(str, s, s.length * sizeof(Ch));
2071 str[s.length] = '\0';
2074 //! Assignment without calling destructor
2075 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2077 // data_.f.flags = rhs.data_.f.flags;
2078 rhs.data_.f.flags = kNullFlag;
2081 template <typename SourceAllocator>
2082 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2083 RAPIDJSON_ASSERT(IsString());
2084 RAPIDJSON_ASSERT(rhs.IsString());
2086 const SizeType len1 = GetStringLength();
2087 const SizeType len2 = rhs.GetStringLength();
2088 if(len1 != len2) { return false; }
2090 const Ch* const str1 = GetString();
2091 const Ch* const str2 = rhs.GetString();
2092 if(str1 == str2) { return true; } // fast path for constant string
2094 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2100 //! GenericValue with UTF8 encoding
2101 typedef GenericValue<UTF8<> > Value;
2103 ///////////////////////////////////////////////////////////////////////////////
2106 //! A document for parsing JSON text as DOM.
2108 \note implements Handler concept
2109 \tparam Encoding Encoding for both parsing and string storage.
2110 \tparam Allocator Allocator for allocating memory for the DOM
2111 \tparam StackAllocator Allocator for allocating memory for stack during parsing.
2112 \warning Although GenericDocument inherits from GenericValue, the API does \b not provide any virtual functions, especially no virtual destructor. To avoid memory leaks, do not \c delete a GenericDocument object via a pointer to a GenericValue.
2114 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
2115 class GenericDocument : public GenericValue<Encoding, Allocator> {
2117 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
2118 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
2119 typedef Allocator AllocatorType; //!< Allocator type from template parameter.
2122 /*! Creates an empty document of specified type.
2123 \param type Mandatory type of object to create.
2124 \param allocator Optional allocator for allocating memory.
2125 \param stackCapacity Optional initial capacity of stack in bytes.
2126 \param stackAllocator Optional allocator for allocating memory for stack.
2128 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2129 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2132 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2136 /*! Creates an empty document which type is Null.
2137 \param allocator Optional allocator for allocating memory.
2138 \param stackCapacity Optional initial capacity of stack in bytes.
2139 \param stackAllocator Optional allocator for allocating memory for stack.
2141 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2142 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2145 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2148 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2149 //! Move constructor in C++11
2150 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2151 : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2152 allocator_(rhs.allocator_),
2153 ownAllocator_(rhs.ownAllocator_),
2154 stack_(std::move(rhs.stack_)),
2155 parseResult_(rhs.parseResult_)
2158 rhs.ownAllocator_ = 0;
2159 rhs.parseResult_ = ParseResult();
2163 ~GenericDocument() {
2167 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2168 //! Move assignment in C++11
2169 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2171 // The cast to ValueType is necessary here, because otherwise it would
2172 // attempt to call GenericValue's templated assignment operator.
2173 ValueType::operator=(std::forward<ValueType>(rhs));
2175 // Calling the destructor here would prematurely call stack_'s destructor
2178 allocator_ = rhs.allocator_;
2179 ownAllocator_ = rhs.ownAllocator_;
2180 stack_ = std::move(rhs.stack_);
2181 parseResult_ = rhs.parseResult_;
2184 rhs.ownAllocator_ = 0;
2185 rhs.parseResult_ = ParseResult();
2191 //! Exchange the contents of this document with those of another.
2193 \param rhs Another document.
2194 \note Constant complexity.
2195 \see GenericValue::Swap
2197 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2198 ValueType::Swap(rhs);
2199 stack_.Swap(rhs.stack_);
2200 internal::Swap(allocator_, rhs.allocator_);
2201 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2202 internal::Swap(parseResult_, rhs.parseResult_);
2206 // Allow Swap with ValueType.
2207 // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2208 using ValueType::Swap;
2210 //! free-standing swap function helper
2212 Helper function to enable support for common swap implementation pattern based on \c std::swap:
2214 void swap(MyClass& a, MyClass& b) {
2222 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2224 //! Populate this document by a generator which produces SAX events.
2225 /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.
2226 \param g Generator functor which sends SAX events to the parameter.
2227 \return The document itself for fluent API.
2229 template <typename Generator>
2230 GenericDocument& Populate(Generator& g) {
2231 ClearStackOnExit scope(*this);
2233 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2234 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2239 //!@name Parse from stream
2242 //! Parse JSON text from an input stream (with Encoding conversion)
2243 /*! \tparam parseFlags Combination of \ref ParseFlag.
2244 \tparam SourceEncoding Encoding of input stream
2245 \tparam InputStream Type of input stream, implementing Stream concept
2246 \param is Input stream to be parsed.
2247 \return The document itself for fluent API.
2249 template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2250 GenericDocument& ParseStream(InputStream& is) {
2251 GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2252 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2253 ClearStackOnExit scope(*this);
2254 parseResult_ = reader.template Parse<parseFlags>(is, *this);
2256 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2257 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2262 //! Parse JSON text from an input stream
2263 /*! \tparam parseFlags Combination of \ref ParseFlag.
2264 \tparam InputStream Type of input stream, implementing Stream concept
2265 \param is Input stream to be parsed.
2266 \return The document itself for fluent API.
2268 template <unsigned parseFlags, typename InputStream>
2269 GenericDocument& ParseStream(InputStream& is) {
2270 return ParseStream<parseFlags, Encoding, InputStream>(is);
2273 //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
2274 /*! \tparam InputStream Type of input stream, implementing Stream concept
2275 \param is Input stream to be parsed.
2276 \return The document itself for fluent API.
2278 template <typename InputStream>
2279 GenericDocument& ParseStream(InputStream& is) {
2280 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2284 //!@name Parse in-place from mutable string
2287 //! Parse JSON text from a mutable string
2288 /*! \tparam parseFlags Combination of \ref ParseFlag.
2289 \param str Mutable zero-terminated string to be parsed.
2290 \return The document itself for fluent API.
2292 template <unsigned parseFlags>
2293 GenericDocument& ParseInsitu(Ch* str) {
2294 GenericInsituStringStream<Encoding> s(str);
2295 return ParseStream<parseFlags | kParseInsituFlag>(s);
2298 //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
2299 /*! \param str Mutable zero-terminated string to be parsed.
2300 \return The document itself for fluent API.
2302 GenericDocument& ParseInsitu(Ch* str) {
2303 return ParseInsitu<kParseDefaultFlags>(str);
2307 //!@name Parse from read-only string
2310 //! Parse JSON text from a read-only string (with Encoding conversion)
2311 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2312 \tparam SourceEncoding Transcoding from input Encoding
2313 \param str Read-only zero-terminated string to be parsed.
2315 template <unsigned parseFlags, typename SourceEncoding>
2316 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2317 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2318 GenericStringStream<SourceEncoding> s(str);
2319 return ParseStream<parseFlags, SourceEncoding>(s);
2322 //! Parse JSON text from a read-only string
2323 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2324 \param str Read-only zero-terminated string to be parsed.
2326 template <unsigned parseFlags>
2327 GenericDocument& Parse(const Ch* str) {
2328 return Parse<parseFlags, Encoding>(str);
2331 //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
2332 /*! \param str Read-only zero-terminated string to be parsed.
2334 GenericDocument& Parse(const Ch* str) {
2335 return Parse<kParseDefaultFlags>(str);
2338 template <unsigned parseFlags, typename SourceEncoding>
2339 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2340 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2341 MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2342 EncodedInputStream<SourceEncoding, MemoryStream> is(ms);
2343 ParseStream<parseFlags, SourceEncoding>(is);
2347 template <unsigned parseFlags>
2348 GenericDocument& Parse(const Ch* str, size_t length) {
2349 return Parse<parseFlags, Encoding>(str, length);
2352 GenericDocument& Parse(const Ch* str, size_t length) {
2353 return Parse<kParseDefaultFlags>(str, length);
2356 #if RAPIDJSON_HAS_STDSTRING
2357 template <unsigned parseFlags, typename SourceEncoding>
2358 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2359 // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2360 return Parse<parseFlags, SourceEncoding>(str.c_str());
2363 template <unsigned parseFlags>
2364 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2365 return Parse<parseFlags, Encoding>(str.c_str());
2368 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2369 return Parse<kParseDefaultFlags>(str);
2371 #endif // RAPIDJSON_HAS_STDSTRING
2375 //!@name Handling parse errors
2378 //! Whether a parse error has occurred in the last parsing.
2379 bool HasParseError() const { return parseResult_.IsError(); }
2381 //! Get the \ref ParseErrorCode of last parsing.
2382 ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2384 //! Get the position of last parsing error in input, 0 otherwise.
2385 size_t GetErrorOffset() const { return parseResult_.Offset(); }
2387 //! Implicit conversion to get the last parse result
2388 #ifndef __clang // -Wdocumentation
2389 /*! \return \ref ParseResult of the last parse operation
2393 ParseResult ok = doc.Parse(json);
2395 printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
2399 operator ParseResult() const { return parseResult_; }
2402 //! Get the allocator of this document.
2403 Allocator& GetAllocator() {
2404 RAPIDJSON_ASSERT(allocator_);
2408 //! Get the capacity of stack in bytes.
2409 size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2412 // clear stack on any exit from ParseStream, e.g. due to exception
2413 struct ClearStackOnExit {
2414 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2415 ~ClearStackOnExit() { d_.ClearStack(); }
2417 ClearStackOnExit(const ClearStackOnExit&);
2418 ClearStackOnExit& operator=(const ClearStackOnExit&);
2419 GenericDocument& d_;
2422 // callers of the following private Handler functions
2423 // template <typename,typename,typename> friend class GenericReader; // for parsing
2424 template <typename, typename> friend class GenericValue; // for deep copying
2427 // Implementation of Handler
2428 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2429 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2430 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2431 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2432 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2433 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2434 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2436 bool RawNumber(const Ch* str, SizeType length, bool copy) {
2438 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2440 new (stack_.template Push<ValueType>()) ValueType(str, length);
2444 bool String(const Ch* str, SizeType length, bool copy) {
2446 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2448 new (stack_.template Push<ValueType>()) ValueType(str, length);
2452 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2454 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2456 bool EndObject(SizeType memberCount) {
2457 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2458 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2462 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2464 bool EndArray(SizeType elementCount) {
2465 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2466 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2471 //! Prohibit copying
2472 GenericDocument(const GenericDocument&);
2473 //! Prohibit assignment
2474 GenericDocument& operator=(const GenericDocument&);
2477 if (Allocator::kNeedFree)
2478 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2479 (stack_.template Pop<ValueType>(1))->~ValueType();
2482 stack_.ShrinkToFit();
2486 RAPIDJSON_DELETE(ownAllocator_);
2489 static const size_t kDefaultStackCapacity = 1024;
2490 Allocator* allocator_;
2491 Allocator* ownAllocator_;
2492 internal::Stack<StackAllocator> stack_;
2493 ParseResult parseResult_;
2496 //! GenericDocument with UTF8 encoding
2497 typedef GenericDocument<UTF8<> > Document;
2499 //! Helper class for accessing Value of array type.
2501 Instance of this helper class is obtained by \c GenericValue::GetArray().
2502 In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2504 template <bool Const, typename ValueT>
2505 class GenericArray {
2507 typedef GenericArray<true, ValueT> ConstArray;
2508 typedef GenericArray<false, ValueT> Array;
2509 typedef ValueT PlainType;
2510 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2511 typedef ValueType* ValueIterator; // This may be const or non-const iterator
2512 typedef const ValueT* ConstValueIterator;
2513 typedef typename ValueType::AllocatorType AllocatorType;
2514 typedef typename ValueType::StringRefType StringRefType;
2516 template <typename, typename>
2517 friend class GenericValue;
2519 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2520 GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2523 SizeType Size() const { return value_.Size(); }
2524 SizeType Capacity() const { return value_.Capacity(); }
2525 bool Empty() const { return value_.Empty(); }
2526 void Clear() const { value_.Clear(); }
2527 ValueType& operator[](SizeType index) const { return value_[index]; }
2528 ValueIterator Begin() const { return value_.Begin(); }
2529 ValueIterator End() const { return value_.End(); }
2530 GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2531 GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2532 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2533 GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2534 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2535 GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2536 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (const GenericArray&)) PushBack(T value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2537 GenericArray PopBack() const { value_.PopBack(); return *this; }
2538 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2539 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2541 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2542 ValueIterator begin() const { return value_.Begin(); }
2543 ValueIterator end() const { return value_.End(); }
2548 GenericArray(ValueType& value) : value_(value) {}
2552 //! Helper class for accessing Value of object type.
2554 Instance of this helper class is obtained by \c GenericValue::GetObject().
2555 In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2557 template <bool Const, typename ValueT>
2558 class GenericObject {
2560 typedef GenericObject<true, ValueT> ConstObject;
2561 typedef GenericObject<false, ValueT> Object;
2562 typedef ValueT PlainType;
2563 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2564 typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
2565 typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;
2566 typedef typename ValueType::AllocatorType AllocatorType;
2567 typedef typename ValueType::StringRefType StringRefType;
2568 typedef typename ValueType::EncodingType EncodingType;
2569 typedef typename ValueType::Ch Ch;
2571 template <typename, typename>
2572 friend class GenericValue;
2574 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2575 GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2578 SizeType MemberCount() const { return value_.MemberCount(); }
2579 SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2580 bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2581 template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2582 template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2583 #if RAPIDJSON_HAS_STDSTRING
2584 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2586 MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2587 MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2588 GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2589 bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2590 #if RAPIDJSON_HAS_STDSTRING
2591 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2593 template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2594 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2595 template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2596 #if RAPIDJSON_HAS_STDSTRING
2597 MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2599 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2600 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2601 #if RAPIDJSON_HAS_STDSTRING
2602 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2604 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&)) AddMember(ValueType& name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2605 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2606 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2607 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2608 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2609 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2610 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2611 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2612 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2613 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericObject)) AddMember(StringRefType name, T value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2614 void RemoveAllMembers() { value_.RemoveAllMembers(); }
2615 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2616 #if RAPIDJSON_HAS_STDSTRING
2617 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2619 template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2620 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2621 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
2622 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2623 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2624 #if RAPIDJSON_HAS_STDSTRING
2625 bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2627 template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2629 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2630 MemberIterator begin() const { return value_.MemberBegin(); }
2631 MemberIterator end() const { return value_.MemberEnd(); }
2636 GenericObject(ValueType& value) : value_(value) {}
2640 RAPIDJSON_NAMESPACE_END
2643 #endif // RAPIDJSON_DOCUMENT_H_