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
27 #ifdef __cpp_lib_three_way_comparison
33 RAPIDJSON_DIAG_OFF(padded)
34 RAPIDJSON_DIAG_OFF(switch-enum)
35 RAPIDJSON_DIAG_OFF(c++98-compat)
36 #elif defined(_MSC_VER)
37 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
38 RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
42 RAPIDJSON_DIAG_OFF(effc++)
45 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
46 #include <iterator> // std::random_access_iterator_tag
49 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
50 #include <utility> // std::move
53 RAPIDJSON_NAMESPACE_BEGIN
55 // Forward declaration.
56 template <typename Encoding, typename Allocator>
59 template <typename Encoding, typename Allocator, typename StackAllocator>
60 class GenericDocument;
62 /*! \def RAPIDJSON_DEFAULT_ALLOCATOR
63 \ingroup RAPIDJSON_CONFIG
64 \brief Allows to choose default allocator.
66 User can define this to use CrtAllocator or MemoryPoolAllocator.
68 #ifndef RAPIDJSON_DEFAULT_ALLOCATOR
69 #define RAPIDJSON_DEFAULT_ALLOCATOR MemoryPoolAllocator<CrtAllocator>
72 /*! \def RAPIDJSON_DEFAULT_STACK_ALLOCATOR
73 \ingroup RAPIDJSON_CONFIG
74 \brief Allows to choose default stack allocator for Document.
76 User can define this to use CrtAllocator or MemoryPoolAllocator.
78 #ifndef RAPIDJSON_DEFAULT_STACK_ALLOCATOR
79 #define RAPIDJSON_DEFAULT_STACK_ALLOCATOR CrtAllocator
82 /*! \def RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
83 \ingroup RAPIDJSON_CONFIG
84 \brief User defined kDefaultObjectCapacity value.
86 User can define this as any natural number.
88 #ifndef RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY
89 // number of objects that rapidjson::Value allocates memory for by default
90 #define RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY 16
93 /*! \def RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
94 \ingroup RAPIDJSON_CONFIG
95 \brief User defined kDefaultArrayCapacity value.
97 User can define this as any natural number.
99 #ifndef RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY
100 // number of array elements that rapidjson::Value allocates memory for by default
101 #define RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY 16
104 //! Name-value pair in a JSON object value.
106 This class was internal to GenericValue. It used to be a inner struct.
107 But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
108 https://code.google.com/p/rapidjson/issues/detail?id=64
110 template <typename Encoding, typename Allocator>
111 class GenericMember {
113 GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
114 GenericValue<Encoding, Allocator> value; //!< value of member.
116 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
117 //! Move constructor in C++11
118 GenericMember(GenericMember&& rhs) RAPIDJSON_NOEXCEPT
119 : name(std::move(rhs.name)),
120 value(std::move(rhs.value))
124 //! Move assignment in C++11
125 GenericMember& operator=(GenericMember&& rhs) RAPIDJSON_NOEXCEPT {
126 return *this = static_cast<GenericMember&>(rhs);
130 //! Assignment with move semantics.
131 /*! \param rhs Source of the assignment. Its name and value will become a null value after assignment.
133 GenericMember& operator=(GenericMember& rhs) RAPIDJSON_NOEXCEPT {
134 if (RAPIDJSON_LIKELY(this != &rhs)) {
141 // swap() for std::sort() and other potential use in STL.
142 friend inline void swap(GenericMember& a, GenericMember& b) RAPIDJSON_NOEXCEPT {
144 a.value.Swap(b.value);
148 //! Copy constructor is not permitted.
149 GenericMember(const GenericMember& rhs);
152 ///////////////////////////////////////////////////////////////////////////////
153 // GenericMemberIterator
155 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
157 //! (Constant) member iterator for a JSON object value
159 \tparam Const Is this a constant iterator?
160 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
161 \tparam Allocator Allocator type for allocating memory of object, array and string.
163 This class implements a Random Access Iterator for GenericMember elements
164 of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
166 \note This iterator implementation is mainly intended to avoid implicit
167 conversions from iterator values to \c NULL,
168 e.g. from GenericValue::FindMember.
170 \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
171 pointer-based implementation, if your platform doesn't provide
172 the C++ <iterator> header.
174 \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
176 template <bool Const, typename Encoding, typename Allocator>
177 class GenericMemberIterator {
179 friend class GenericValue<Encoding,Allocator>;
180 template <bool, typename, typename> friend class GenericMemberIterator;
182 typedef GenericMember<Encoding,Allocator> PlainType;
183 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
186 //! Iterator type itself
187 typedef GenericMemberIterator Iterator;
188 //! Constant iterator type
189 typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator;
190 //! Non-constant iterator type
191 typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator;
193 /** \name std::iterator_traits support */
195 typedef ValueType value_type;
196 typedef ValueType * pointer;
197 typedef ValueType & reference;
198 typedef std::ptrdiff_t difference_type;
199 typedef std::random_access_iterator_tag iterator_category;
202 //! Pointer to (const) GenericMember
203 typedef pointer Pointer;
204 //! Reference to (const) GenericMember
205 typedef reference Reference;
206 //! Signed integer type (e.g. \c ptrdiff_t)
207 typedef difference_type DifferenceType;
209 //! Default constructor (singular value)
210 /*! Creates an iterator pointing to no element.
211 \note All operations, except for comparisons, are undefined on such values.
213 GenericMemberIterator() : ptr_() {}
215 //! Iterator conversions to more const
217 \param it (Non-const) iterator to copy from
219 Allows the creation of an iterator from another GenericMemberIterator
220 that is "less const". Especially, creating a non-constant iterator
221 from a constant iterator are disabled:
222 \li const -> non-const (not ok)
223 \li const -> const (ok)
224 \li non-const -> const (ok)
225 \li non-const -> non-const (ok)
227 \note If the \c Const template parameter is already \c false, this
228 constructor effectively defines a regular copy-constructor.
229 Otherwise, the copy constructor is implicitly defined.
231 GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
232 Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
236 Iterator& operator++(){ ++ptr_; return *this; }
237 Iterator& operator--(){ --ptr_; return *this; }
238 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
239 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
242 //! @name increment/decrement
244 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
245 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
247 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
248 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
253 template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
254 template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
255 template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
256 template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
257 template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
258 template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
260 #ifdef __cpp_lib_three_way_comparison
261 template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
265 //! @name dereference
267 Reference operator*() const { return *ptr_; }
268 Pointer operator->() const { return ptr_; }
269 Reference operator[](DifferenceType n) const { return ptr_[n]; }
273 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
276 //! Internal constructor from plain pointer
277 explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
279 Pointer ptr_; //!< raw pointer
282 #else // RAPIDJSON_NOMEMBERITERATORCLASS
284 // class-based member iterator implementation disabled, use plain pointers
286 template <bool Const, typename Encoding, typename Allocator>
287 class GenericMemberIterator;
289 //! non-const GenericMemberIterator
290 template <typename Encoding, typename Allocator>
291 class GenericMemberIterator<false,Encoding,Allocator> {
292 //! use plain pointer as iterator type
293 typedef GenericMember<Encoding,Allocator>* Iterator;
295 //! const GenericMemberIterator
296 template <typename Encoding, typename Allocator>
297 class GenericMemberIterator<true,Encoding,Allocator> {
298 //! use plain const pointer as iterator type
299 typedef const GenericMember<Encoding,Allocator>* Iterator;
302 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
304 ///////////////////////////////////////////////////////////////////////////////
307 //! Reference to a constant string (not taking a copy)
309 \tparam CharType character type of the string
311 This helper class is used to automatically infer constant string
312 references for string literals, especially from \c const \b (!)
315 The main use is for creating JSON string values without copying the
316 source string via an \ref Allocator. This requires that the referenced
317 string pointers have a sufficient lifetime, which exceeds the lifetime
318 of the associated GenericValue.
322 Value v("foo"); // ok, no need to copy & calculate length
323 const char foo[] = "foo";
324 v.SetString(foo); // ok
326 const char* bar = foo;
327 // Value x(bar); // not ok, can't rely on bar's lifetime
328 Value x(StringRef(bar)); // lifetime explicitly guaranteed by user
329 Value y(StringRef(bar, 3)); // ok, explicitly pass length
332 \see StringRef, GenericValue::SetString
334 template<typename CharType>
335 struct GenericStringRef {
336 typedef CharType Ch; //!< character type of the string
338 //! Create string reference from \c const character array
339 #ifndef __clang__ // -Wdocumentation
341 This constructor implicitly creates a constant string reference from
342 a \c const character array. It has better performance than
343 \ref StringRef(const CharType*) by inferring the string \ref length
344 from the array length, and also supports strings containing null
347 \tparam N length of the string, automatically inferred
349 \param str Constant character array, lifetime assumed to be longer
350 than the use of the string in e.g. a GenericValue
354 \note Constant complexity.
355 \note There is a hidden, private overload to disallow references to
356 non-const character arrays to be created via this constructor.
357 By this, e.g. function-scope arrays used to be filled via
358 \c snprintf are excluded from consideration.
359 In such cases, the referenced string should be \b copied to the
360 GenericValue instead.
364 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
365 : s(str), length(N-1) {}
367 //! Explicitly create string reference from \c const character pointer
368 #ifndef __clang__ // -Wdocumentation
370 This constructor can be used to \b explicitly create a reference to
371 a constant string pointer.
373 \see StringRef(const CharType*)
375 \param str Constant character pointer, lifetime assumed to be longer
376 than the use of the string in e.g. a GenericValue
380 \note There is a hidden, private overload to disallow references to
381 non-const character arrays to be created via this constructor.
382 By this, e.g. function-scope arrays used to be filled via
383 \c snprintf are excluded from consideration.
384 In such cases, the referenced string should be \b copied to the
385 GenericValue instead.
388 explicit GenericStringRef(const CharType* str)
389 : s(str), length(NotNullStrLen(str)) {}
391 //! Create constant string reference from pointer and length
392 #ifndef __clang__ // -Wdocumentation
393 /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
394 \param len length of the string, excluding the trailing NULL terminator
396 \post \ref s == str && \ref length == len
397 \note Constant complexity.
400 GenericStringRef(const CharType* str, SizeType len)
401 : s(RAPIDJSON_LIKELY(str) ? str : emptyString), length(len) { RAPIDJSON_ASSERT(str != 0 || len == 0u); }
403 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
405 //! implicit conversion to plain CharType pointer
406 operator const Ch *() const { return s; }
408 const Ch* const s; //!< plain CharType pointer
409 const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
412 SizeType NotNullStrLen(const CharType* str) {
413 RAPIDJSON_ASSERT(str != 0);
414 return internal::StrLen(str);
417 /// Empty string - used when passing in a NULL pointer
418 static const Ch emptyString[];
420 //! Disallow construction from non-const array
422 GenericStringRef(CharType (&str)[N]) /* = delete */;
423 //! Copy assignment operator not permitted - immutable type
424 GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
427 template<typename CharType>
428 const CharType GenericStringRef<CharType>::emptyString[] = { CharType() };
430 //! Mark a character pointer as constant string
431 /*! Mark a plain character pointer as a "string literal". This function
432 can be used to avoid copying a character string to be referenced as a
433 value in a JSON GenericValue object, if the string's lifetime is known
434 to be valid long enough.
435 \tparam CharType Character type of the string
436 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
437 \return GenericStringRef string reference object
438 \relatesalso GenericStringRef
440 \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember
442 template<typename CharType>
443 inline GenericStringRef<CharType> StringRef(const CharType* str) {
444 return GenericStringRef<CharType>(str);
447 //! Mark a character pointer as constant string
448 /*! Mark a plain character pointer as a "string literal". This function
449 can be used to avoid copying a character string to be referenced as a
450 value in a JSON GenericValue object, if the string's lifetime is known
451 to be valid long enough.
453 This version has better performance with supplied length, and also
454 supports string containing null characters.
456 \tparam CharType character type of the string
457 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
458 \param length The length of source string.
459 \return GenericStringRef string reference object
460 \relatesalso GenericStringRef
462 template<typename CharType>
463 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
464 return GenericStringRef<CharType>(str, SizeType(length));
467 #if RAPIDJSON_HAS_STDSTRING
468 //! Mark a string object as constant string
469 /*! Mark a string object (e.g. \c std::string) as a "string literal".
470 This function can be used to avoid copying a string to be referenced as a
471 value in a JSON GenericValue object, if the string's lifetime is known
472 to be valid long enough.
474 \tparam CharType character type of the string
475 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
476 \return GenericStringRef string reference object
477 \relatesalso GenericStringRef
478 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
480 template<typename CharType>
481 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
482 return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
486 ///////////////////////////////////////////////////////////////////////////////
487 // GenericValue type traits
490 template <typename T, typename Encoding = void, typename Allocator = void>
491 struct IsGenericValueImpl : FalseType {};
493 // select candidates according to nested encoding and allocator types
494 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
495 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
497 // helper to match arbitrary GenericValue instantiations, including derived classes
498 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
500 } // namespace internal
502 ///////////////////////////////////////////////////////////////////////////////
507 template <typename ValueType, typename T>
508 struct TypeHelper {};
510 template<typename ValueType>
511 struct TypeHelper<ValueType, bool> {
512 static bool Is(const ValueType& v) { return v.IsBool(); }
513 static bool Get(const ValueType& v) { return v.GetBool(); }
514 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
515 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
518 template<typename ValueType>
519 struct TypeHelper<ValueType, int> {
520 static bool Is(const ValueType& v) { return v.IsInt(); }
521 static int Get(const ValueType& v) { return v.GetInt(); }
522 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
523 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
526 template<typename ValueType>
527 struct TypeHelper<ValueType, unsigned> {
528 static bool Is(const ValueType& v) { return v.IsUint(); }
529 static unsigned Get(const ValueType& v) { return v.GetUint(); }
530 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
531 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
535 RAPIDJSON_STATIC_ASSERT(sizeof(long) == sizeof(int));
536 template<typename ValueType>
537 struct TypeHelper<ValueType, long> {
538 static bool Is(const ValueType& v) { return v.IsInt(); }
539 static long Get(const ValueType& v) { return v.GetInt(); }
540 static ValueType& Set(ValueType& v, long data) { return v.SetInt(data); }
541 static ValueType& Set(ValueType& v, long data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
544 RAPIDJSON_STATIC_ASSERT(sizeof(unsigned long) == sizeof(unsigned));
545 template<typename ValueType>
546 struct TypeHelper<ValueType, unsigned long> {
547 static bool Is(const ValueType& v) { return v.IsUint(); }
548 static unsigned long Get(const ValueType& v) { return v.GetUint(); }
549 static ValueType& Set(ValueType& v, unsigned long data) { return v.SetUint(data); }
550 static ValueType& Set(ValueType& v, unsigned long data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
554 template<typename ValueType>
555 struct TypeHelper<ValueType, int64_t> {
556 static bool Is(const ValueType& v) { return v.IsInt64(); }
557 static int64_t Get(const ValueType& v) { return v.GetInt64(); }
558 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
559 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
562 template<typename ValueType>
563 struct TypeHelper<ValueType, uint64_t> {
564 static bool Is(const ValueType& v) { return v.IsUint64(); }
565 static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
566 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
567 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
570 template<typename ValueType>
571 struct TypeHelper<ValueType, double> {
572 static bool Is(const ValueType& v) { return v.IsDouble(); }
573 static double Get(const ValueType& v) { return v.GetDouble(); }
574 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
575 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
578 template<typename ValueType>
579 struct TypeHelper<ValueType, float> {
580 static bool Is(const ValueType& v) { return v.IsFloat(); }
581 static float Get(const ValueType& v) { return v.GetFloat(); }
582 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
583 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
586 template<typename ValueType>
587 struct TypeHelper<ValueType, const typename ValueType::Ch*> {
588 typedef const typename ValueType::Ch* StringType;
589 static bool Is(const ValueType& v) { return v.IsString(); }
590 static StringType Get(const ValueType& v) { return v.GetString(); }
591 static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
592 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
595 #if RAPIDJSON_HAS_STDSTRING
596 template<typename ValueType>
597 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
598 typedef std::basic_string<typename ValueType::Ch> StringType;
599 static bool Is(const ValueType& v) { return v.IsString(); }
600 static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
601 static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
605 template<typename ValueType>
606 struct TypeHelper<ValueType, typename ValueType::Array> {
607 typedef typename ValueType::Array ArrayType;
608 static bool Is(const ValueType& v) { return v.IsArray(); }
609 static ArrayType Get(ValueType& v) { return v.GetArray(); }
610 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
611 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
614 template<typename ValueType>
615 struct TypeHelper<ValueType, typename ValueType::ConstArray> {
616 typedef typename ValueType::ConstArray ArrayType;
617 static bool Is(const ValueType& v) { return v.IsArray(); }
618 static ArrayType Get(const ValueType& v) { return v.GetArray(); }
621 template<typename ValueType>
622 struct TypeHelper<ValueType, typename ValueType::Object> {
623 typedef typename ValueType::Object ObjectType;
624 static bool Is(const ValueType& v) { return v.IsObject(); }
625 static ObjectType Get(ValueType& v) { return v.GetObject(); }
626 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
627 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { return v = data; }
630 template<typename ValueType>
631 struct TypeHelper<ValueType, typename ValueType::ConstObject> {
632 typedef typename ValueType::ConstObject ObjectType;
633 static bool Is(const ValueType& v) { return v.IsObject(); }
634 static ObjectType Get(const ValueType& v) { return v.GetObject(); }
637 } // namespace internal
639 // Forward declarations
640 template <bool, typename> class GenericArray;
641 template <bool, typename> class GenericObject;
643 ///////////////////////////////////////////////////////////////////////////////
646 //! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
648 A JSON value can be one of 7 types. This class is a variant type supporting
651 Use the Value if UTF8 and default allocator
653 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
654 \tparam Allocator Allocator type for allocating memory of object, array and string.
656 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR >
659 //! Name-value pair in an object.
660 typedef GenericMember<Encoding, Allocator> Member;
661 typedef Encoding EncodingType; //!< Encoding type from template parameter.
662 typedef Allocator AllocatorType; //!< Allocator type from template parameter.
663 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
664 typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string
665 typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object.
666 typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object.
667 typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
668 typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
669 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself.
670 typedef GenericArray<false, ValueType> Array;
671 typedef GenericArray<true, ValueType> ConstArray;
672 typedef GenericObject<false, ValueType> Object;
673 typedef GenericObject<true, ValueType> ConstObject;
675 //!@name Constructors and destructor.
678 //! Default constructor creates a null value.
679 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
681 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
682 //! Move constructor in C++11
683 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
684 rhs.data_.f.flags = kNullFlag; // give up contents
689 //! Copy constructor is not permitted.
690 GenericValue(const GenericValue& rhs);
692 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
693 //! Moving from a GenericDocument is not permitted.
694 template <typename StackAllocator>
695 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
697 //! Move assignment from a GenericDocument is not permitted.
698 template <typename StackAllocator>
699 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
704 //! Constructor with JSON value type.
705 /*! This creates a Value of specified type with default content.
706 \param type Type of the value.
707 \note Default content for number is zero.
709 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
710 static const uint16_t defaultFlags[] = {
711 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
714 RAPIDJSON_NOEXCEPT_ASSERT(type >= kNullType && type <= kNumberType);
715 data_.f.flags = defaultFlags[type];
717 // Use ShortString to store empty string.
718 if (type == kStringType)
719 data_.ss.SetLength(0);
722 //! Explicit copy constructor (with allocator)
723 /*! Creates a copy of a Value by using the given Allocator
724 \tparam SourceAllocator allocator of \c rhs
725 \param rhs Value to copy from (read-only)
726 \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
727 \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
730 template <typename SourceAllocator>
731 GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
732 switch (rhs.GetType()) {
734 SizeType count = rhs.data_.o.size;
735 Member* lm = reinterpret_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
736 const typename GenericValue<Encoding,SourceAllocator>::Member* rm = rhs.GetMembersPointer();
737 for (SizeType i = 0; i < count; i++) {
738 new (&lm[i].name) GenericValue(rm[i].name, allocator, copyConstStrings);
739 new (&lm[i].value) GenericValue(rm[i].value, allocator, copyConstStrings);
741 data_.f.flags = kObjectFlag;
742 data_.o.size = data_.o.capacity = count;
743 SetMembersPointer(lm);
747 SizeType count = rhs.data_.a.size;
748 GenericValue* le = reinterpret_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
749 const GenericValue<Encoding,SourceAllocator>* re = rhs.GetElementsPointer();
750 for (SizeType i = 0; i < count; i++)
751 new (&le[i]) GenericValue(re[i], allocator, copyConstStrings);
752 data_.f.flags = kArrayFlag;
753 data_.a.size = data_.a.capacity = count;
754 SetElementsPointer(le);
758 if (rhs.data_.f.flags == kConstStringFlag && !copyConstStrings) {
759 data_.f.flags = rhs.data_.f.flags;
760 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
763 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
766 data_.f.flags = rhs.data_.f.flags;
767 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
772 //! Constructor for boolean value.
773 /*! \param b Boolean value
774 \note This constructor is limited to \em real boolean values and rejects
775 implicitly converted types like arbitrary pointers. Use an explicit cast
776 to \c bool, if you want to construct a boolean JSON value in such cases.
778 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
779 template <typename T>
780 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
782 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
785 // safe-guard against failing SFINAE
786 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value));
787 data_.f.flags = b ? kTrueFlag : kFalseFlag;
790 //! Constructor for int value.
791 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
793 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
796 //! Constructor for unsigned value.
797 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
799 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
802 //! Constructor for int64_t value.
803 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
805 data_.f.flags = kNumberInt64Flag;
807 data_.f.flags |= kNumberUint64Flag;
808 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
809 data_.f.flags |= kUintFlag;
810 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
811 data_.f.flags |= kIntFlag;
813 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
814 data_.f.flags |= kIntFlag;
817 //! Constructor for uint64_t value.
818 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
820 data_.f.flags = kNumberUint64Flag;
821 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
822 data_.f.flags |= kInt64Flag;
823 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
824 data_.f.flags |= kUintFlag;
825 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
826 data_.f.flags |= kIntFlag;
829 //! Constructor for double value.
830 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
832 //! Constructor for float value.
833 explicit GenericValue(float f) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = static_cast<double>(f); data_.f.flags = kNumberDoubleFlag; }
835 //! Constructor for constant string (i.e. do not make a copy of string)
836 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
838 //! Constructor for constant string (i.e. do not make a copy of string)
839 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
841 //! Constructor for copy-string (i.e. do make a copy of string)
842 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
844 //! Constructor for copy-string (i.e. do make a copy of string)
845 GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
847 #if RAPIDJSON_HAS_STDSTRING
848 //! Constructor for copy-string from a string object (i.e. do make a copy of string)
849 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
851 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
854 //! Constructor for Array.
856 \param a An array obtained by \c GetArray().
857 \note \c Array is always pass-by-value.
858 \note the source array is moved into this value and the sourec array becomes empty.
860 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
861 a.value_.data_ = Data();
862 a.value_.data_.f.flags = kArrayFlag;
865 //! Constructor for Object.
867 \param o An object obtained by \c GetObject().
868 \note \c Object is always pass-by-value.
869 \note the source object is moved into this value and the sourec object becomes empty.
871 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
872 o.value_.data_ = Data();
873 o.value_.data_.f.flags = kObjectFlag;
877 /*! Need to destruct elements of array, members of object, or copy-string.
880 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
881 switch(data_.f.flags) {
884 GenericValue* e = GetElementsPointer();
885 for (GenericValue* v = e; v != e + data_.a.size; ++v)
892 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
894 Allocator::Free(GetMembersPointer());
897 case kCopyStringFlag:
898 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
902 break; // Do nothing for other types.
909 //!@name Assignment operators
912 //! Assignment with move semantics.
913 /*! \param rhs Source of the assignment. It will become a null value after assignment.
915 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
916 if (RAPIDJSON_LIKELY(this != &rhs)) {
917 this->~GenericValue();
923 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
924 //! Move assignment in C++11
925 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
926 return *this = rhs.Move();
930 //! Assignment of constant string reference (no copy)
931 /*! \param str Constant string reference to be assigned
932 \note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
933 \see GenericStringRef, operator=(T)
935 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
940 //! Assignment with primitive types.
941 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
942 \param value The value to be assigned.
944 \note The source type \c T explicitly disallows all pointer types,
945 especially (\c const) \ref Ch*. This helps avoiding implicitly
946 referencing character strings with insufficient lifetime, use
947 \ref SetString(const Ch*, Allocator&) (for copying) or
948 \ref StringRef() (to explicitly mark the pointer as constant) instead.
949 All other pointer types would implicitly convert to \c bool,
950 use \ref SetBool() instead.
952 template <typename T>
953 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
955 GenericValue v(value);
959 //! Deep-copy assignment from Value
960 /*! Assigns a \b copy of the Value to the current Value object
961 \tparam SourceAllocator Allocator type of \c rhs
962 \param rhs Value to copy from (read-only)
963 \param allocator Allocator to use for copying
964 \param copyConstStrings Force copying of constant strings (e.g. referencing an in-situ buffer)
966 template <typename SourceAllocator>
967 GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator, bool copyConstStrings = false) {
968 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
969 this->~GenericValue();
970 new (this) GenericValue(rhs, allocator, copyConstStrings);
974 //! Exchange the contents of this value with those of other.
976 \param other Another value.
977 \note Constant complexity.
979 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
981 temp.RawAssign(*this);
983 other.RawAssign(temp);
987 //! free-standing swap function helper
989 Helper function to enable support for common swap implementation pattern based on \c std::swap:
991 void swap(MyClass& a, MyClass& b) {
993 swap(a.value, b.value);
999 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
1001 //! Prepare Value for move semantics
1002 /*! \return *this */
1003 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
1006 //!@name Equal-to and not-equal-to operators
1008 //! Equal-to operator
1010 \note If an object contains duplicated named member, comparing equality with any object is always \c false.
1011 \note Complexity is quadratic in Object's member number and linear for the rest (number of all values in the subtree and total lengths of all strings).
1013 template <typename SourceAllocator>
1014 bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const {
1015 typedef GenericValue<Encoding, SourceAllocator> RhsType;
1016 if (GetType() != rhs.GetType())
1019 switch (GetType()) {
1020 case kObjectType: // Warning: O(n^2) inner-loop
1021 if (data_.o.size != rhs.data_.o.size)
1023 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
1024 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
1025 if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
1031 if (data_.a.size != rhs.data_.a.size)
1033 for (SizeType i = 0; i < data_.a.size; i++)
1034 if ((*this)[i] != rhs[i])
1039 return StringEqual(rhs);
1042 if (IsDouble() || rhs.IsDouble()) {
1043 double a = GetDouble(); // May convert from integer to double.
1044 double b = rhs.GetDouble(); // Ditto
1045 return a >= b && a <= b; // Prevent -Wfloat-equal
1048 return data_.n.u64 == rhs.data_.n.u64;
1055 //! Equal-to operator with const C-string pointer
1056 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
1058 #if RAPIDJSON_HAS_STDSTRING
1059 //! Equal-to operator with string object
1060 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
1062 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
1065 //! Equal-to operator with primitive types
1066 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
1068 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
1070 //! Not-equal-to operator
1071 /*! \return !(*this == rhs)
1073 template <typename SourceAllocator>
1074 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
1076 //! Not-equal-to operator with const C-string pointer
1077 bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
1079 //! Not-equal-to operator with arbitrary types
1080 /*! \return !(*this == rhs)
1082 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
1084 //! Equal-to operator with arbitrary types (symmetric version)
1085 /*! \return (rhs == lhs)
1087 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
1089 //! Not-Equal-to operator with arbitrary types (symmetric version)
1090 /*! \return !(rhs == lhs)
1092 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
1098 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
1099 bool IsNull() const { return data_.f.flags == kNullFlag; }
1100 bool IsFalse() const { return data_.f.flags == kFalseFlag; }
1101 bool IsTrue() const { return data_.f.flags == kTrueFlag; }
1102 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
1103 bool IsObject() const { return data_.f.flags == kObjectFlag; }
1104 bool IsArray() const { return data_.f.flags == kArrayFlag; }
1105 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
1106 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
1107 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
1108 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
1109 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
1110 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
1111 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
1113 // Checks whether a number can be losslessly converted to a double.
1114 bool IsLosslessDouble() const {
1115 if (!IsNumber()) return false;
1117 uint64_t u = GetUint64();
1118 volatile double d = static_cast<double>(u);
1120 && (d < static_cast<double>((std::numeric_limits<uint64_t>::max)()))
1121 && (u == static_cast<uint64_t>(d));
1124 int64_t i = GetInt64();
1125 volatile double d = static_cast<double>(i);
1126 return (d >= static_cast<double>((std::numeric_limits<int64_t>::min)()))
1127 && (d < static_cast<double>((std::numeric_limits<int64_t>::max)()))
1128 && (i == static_cast<int64_t>(d));
1130 return true; // double, int, uint are always lossless
1133 // Checks whether a number is a float (possible lossy).
1134 bool IsFloat() const {
1135 if ((data_.f.flags & kDoubleFlag) == 0)
1137 double d = GetDouble();
1138 return d >= -3.4028234e38 && d <= 3.4028234e38;
1140 // Checks whether a number can be losslessly converted to a float.
1141 bool IsLosslessFloat() const {
1142 if (!IsNumber()) return false;
1143 double a = GetDouble();
1144 if (a < static_cast<double>(-(std::numeric_limits<float>::max)())
1145 || a > static_cast<double>((std::numeric_limits<float>::max)()))
1147 double b = static_cast<double>(static_cast<float>(a));
1148 return a >= b && a <= b; // Prevent -Wfloat-equal
1156 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1163 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1164 //!< Set boolean value
1165 /*! \post IsBool() == true */
1166 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1173 //! Set this value as an empty object.
1174 /*! \post IsObject() == true */
1175 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1177 //! Get the number of members in the object.
1178 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1180 //! Get the capacity of object.
1181 SizeType MemberCapacity() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.capacity; }
1183 //! Check whether the object is empty.
1184 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1186 //! Get a value from an object associated with the name.
1187 /*! \pre IsObject() == true
1188 \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType))
1189 \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
1190 Since 0.2, if the name is not correct, it will assert.
1191 If user is unsure whether a member exists, user should use HasMember() first.
1192 A better approach is to use FindMember().
1193 \note Linear time complexity.
1195 template <typename T>
1196 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1197 GenericValue n(StringRef(name));
1200 template <typename T>
1201 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]; }
1203 //! Get a value from an object associated with the name.
1204 /*! \pre IsObject() == true
1205 \tparam SourceAllocator Allocator of the \c name value
1207 \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen().
1208 And it can also handle strings with embedded null characters.
1210 \note Linear time complexity.
1212 template <typename SourceAllocator>
1213 GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) {
1214 MemberIterator member = FindMember(name);
1215 if (member != MemberEnd())
1216 return member->value;
1218 RAPIDJSON_ASSERT(false); // see above note
1220 // This will generate -Wexit-time-destructors in clang
1221 // static GenericValue NullValue;
1222 // return NullValue;
1224 // Use static buffer and placement-new to prevent destruction
1225 static char buffer[sizeof(GenericValue)];
1226 return *new (buffer) GenericValue();
1229 template <typename SourceAllocator>
1230 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1232 #if RAPIDJSON_HAS_STDSTRING
1233 //! Get a value from an object associated with name (string object).
1234 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1235 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1238 //! Const member iterator
1239 /*! \pre IsObject() == true */
1240 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1241 //! Const \em past-the-end member iterator
1242 /*! \pre IsObject() == true */
1243 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1245 /*! \pre IsObject() == true */
1246 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1247 //! \em Past-the-end member iterator
1248 /*! \pre IsObject() == true */
1249 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1251 //! Request the object to have enough capacity to store members.
1252 /*! \param newCapacity The capacity that the object at least need to have.
1253 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1254 \return The value itself for fluent API.
1255 \note Linear time complexity.
1257 GenericValue& MemberReserve(SizeType newCapacity, Allocator &allocator) {
1258 RAPIDJSON_ASSERT(IsObject());
1259 if (newCapacity > data_.o.capacity) {
1260 SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), data_.o.capacity * sizeof(Member), newCapacity * sizeof(Member))));
1261 data_.o.capacity = newCapacity;
1266 //! Check whether a member exists in the object.
1268 \param name Member name to be searched.
1269 \pre IsObject() == true
1270 \return Whether a member with that name exists.
1271 \note It is better to use FindMember() directly if you need the obtain the value as well.
1272 \note Linear time complexity.
1274 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1276 #if RAPIDJSON_HAS_STDSTRING
1277 //! Check whether a member exists in the object with string object.
1279 \param name Member name to be searched.
1280 \pre IsObject() == true
1281 \return Whether a member with that name exists.
1282 \note It is better to use FindMember() directly if you need the obtain the value as well.
1283 \note Linear time complexity.
1285 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1288 //! Check whether a member exists in the object with GenericValue name.
1290 This version is faster because it does not need a StrLen(). It can also handle string with null character.
1291 \param name Member name to be searched.
1292 \pre IsObject() == true
1293 \return Whether a member with that name exists.
1294 \note It is better to use FindMember() directly if you need the obtain the value as well.
1295 \note Linear time complexity.
1297 template <typename SourceAllocator>
1298 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1300 //! Find member by name.
1302 \param name Member name to be searched.
1303 \pre IsObject() == true
1304 \return Iterator to member, if it exists.
1305 Otherwise returns \ref MemberEnd().
1307 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
1308 the requested member doesn't exist. For consistency with e.g.
1309 \c std::map, this has been changed to MemberEnd() now.
1310 \note Linear time complexity.
1312 MemberIterator FindMember(const Ch* name) {
1313 GenericValue n(StringRef(name));
1314 return FindMember(n);
1317 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1319 //! Find member by name.
1321 This version is faster because it does not need a StrLen(). It can also handle string with null character.
1322 \param name Member name to be searched.
1323 \pre IsObject() == true
1324 \return Iterator to member, if it exists.
1325 Otherwise returns \ref MemberEnd().
1327 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
1328 the requested member doesn't exist. For consistency with e.g.
1329 \c std::map, this has been changed to MemberEnd() now.
1330 \note Linear time complexity.
1332 template <typename SourceAllocator>
1333 MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) {
1334 RAPIDJSON_ASSERT(IsObject());
1335 RAPIDJSON_ASSERT(name.IsString());
1336 MemberIterator member = MemberBegin();
1337 for ( ; member != MemberEnd(); ++member)
1338 if (name.StringEqual(member->name))
1342 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1344 #if RAPIDJSON_HAS_STDSTRING
1345 //! Find member by string object name.
1347 \param name Member name to be searched.
1348 \pre IsObject() == true
1349 \return Iterator to member, if it exists.
1350 Otherwise returns \ref MemberEnd().
1352 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1353 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1356 //! Add a member (name-value pair) to the object.
1357 /*! \param name A string value as name of member.
1358 \param value Value of any type.
1359 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1360 \return The value itself for fluent API.
1361 \note The ownership of \c name and \c value will be transferred to this object on success.
1362 \pre IsObject() && name.IsString()
1363 \post name.IsNull() && value.IsNull()
1364 \note Amortized Constant time complexity.
1366 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) {
1367 RAPIDJSON_ASSERT(IsObject());
1368 RAPIDJSON_ASSERT(name.IsString());
1370 ObjectData& o = data_.o;
1371 if (o.size >= o.capacity)
1372 MemberReserve(o.capacity == 0 ? kDefaultObjectCapacity : (o.capacity + (o.capacity + 1) / 2), allocator);
1373 Member* members = GetMembersPointer();
1374 members[o.size].name.RawAssign(name);
1375 members[o.size].value.RawAssign(value);
1380 //! Add a constant string value as member (name-value pair) to the object.
1381 /*! \param name A string value as name of member.
1382 \param value constant string reference as value of member.
1383 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1384 \return The value itself for fluent API.
1386 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
1387 \note Amortized Constant time complexity.
1389 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) {
1390 GenericValue v(value);
1391 return AddMember(name, v, allocator);
1394 #if RAPIDJSON_HAS_STDSTRING
1395 //! Add a string object as member (name-value pair) to the object.
1396 /*! \param name A string value as name of member.
1397 \param value constant string reference as value of member.
1398 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1399 \return The value itself for fluent API.
1401 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
1402 \note Amortized Constant time complexity.
1404 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1405 GenericValue v(value, allocator);
1406 return AddMember(name, v, allocator);
1410 //! Add any primitive value as member (name-value pair) to the object.
1411 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1412 \param name A string value as name of member.
1413 \param value Value of primitive type \c T as value of member
1414 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1415 \return The value itself for fluent API.
1418 \note The source type \c T explicitly disallows all pointer types,
1419 especially (\c const) \ref Ch*. This helps avoiding implicitly
1420 referencing character strings with insufficient lifetime, use
1421 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1422 AddMember(StringRefType, StringRefType, Allocator&).
1423 All other pointer types would implicitly convert to \c bool,
1424 use an explicit cast instead, if needed.
1425 \note Amortized Constant time complexity.
1427 template <typename T>
1428 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1429 AddMember(GenericValue& name, T value, Allocator& allocator) {
1430 GenericValue v(value);
1431 return AddMember(name, v, allocator);
1434 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1435 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1436 return AddMember(name, value, allocator);
1438 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1439 return AddMember(name, value, allocator);
1441 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1442 return AddMember(name, value, allocator);
1444 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1445 GenericValue n(name);
1446 return AddMember(n, value, allocator);
1448 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1451 //! Add a member (name-value pair) to the object.
1452 /*! \param name A constant string reference as name of member.
1453 \param value Value of any type.
1454 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1455 \return The value itself for fluent API.
1456 \note The ownership of \c value will be transferred to this object on success.
1458 \post value.IsNull()
1459 \note Amortized Constant time complexity.
1461 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) {
1462 GenericValue n(name);
1463 return AddMember(n, value, allocator);
1466 //! Add a constant string value as member (name-value pair) to the object.
1467 /*! \param name A constant string reference as name of member.
1468 \param value constant string reference as value of member.
1469 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1470 \return The value itself for fluent API.
1472 \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.
1473 \note Amortized Constant time complexity.
1475 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) {
1476 GenericValue v(value);
1477 return AddMember(name, v, allocator);
1480 //! Add any primitive value as member (name-value pair) to the object.
1481 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1482 \param name A constant string reference as name of member.
1483 \param value Value of primitive type \c T as value of member
1484 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1485 \return The value itself for fluent API.
1488 \note The source type \c T explicitly disallows all pointer types,
1489 especially (\c const) \ref Ch*. This helps avoiding implicitly
1490 referencing character strings with insufficient lifetime, use
1491 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1492 AddMember(StringRefType, StringRefType, Allocator&).
1493 All other pointer types would implicitly convert to \c bool,
1494 use an explicit cast instead, if needed.
1495 \note Amortized Constant time complexity.
1497 template <typename T>
1498 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1499 AddMember(StringRefType name, T value, Allocator& allocator) {
1500 GenericValue n(name);
1501 return AddMember(n, value, allocator);
1504 //! Remove all members in the object.
1505 /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.
1506 \note Linear time complexity.
1508 void RemoveAllMembers() {
1509 RAPIDJSON_ASSERT(IsObject());
1510 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1515 //! Remove a member in object by its name.
1516 /*! \param name Name of member to be removed.
1517 \return Whether the member existed.
1518 \note This function may reorder the object members. Use \ref
1519 EraseMember(ConstMemberIterator) if you need to preserve the
1520 relative order of the remaining members.
1521 \note Linear time complexity.
1523 bool RemoveMember(const Ch* name) {
1524 GenericValue n(StringRef(name));
1525 return RemoveMember(n);
1528 #if RAPIDJSON_HAS_STDSTRING
1529 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1532 template <typename SourceAllocator>
1533 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1534 MemberIterator m = FindMember(name);
1535 if (m != MemberEnd()) {
1543 //! Remove a member in object by iterator.
1544 /*! \param m member iterator (obtained by FindMember() or MemberBegin()).
1545 \return the new iterator after removal.
1546 \note This function may reorder the object members. Use \ref
1547 EraseMember(ConstMemberIterator) if you need to preserve the
1548 relative order of the remaining members.
1549 \note Constant time complexity.
1551 MemberIterator RemoveMember(MemberIterator m) {
1552 RAPIDJSON_ASSERT(IsObject());
1553 RAPIDJSON_ASSERT(data_.o.size > 0);
1554 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1555 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1557 MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1558 if (data_.o.size > 1 && m != last)
1559 *m = *last; // Move the last one to this place
1561 m->~Member(); // Only one left, just destroy
1566 //! Remove a member from an object by iterator.
1567 /*! \param pos iterator to the member to remove
1568 \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd()
1569 \return Iterator following the removed element.
1570 If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned.
1571 \note This function preserves the relative order of the remaining object
1572 members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator).
1573 \note Linear time complexity.
1575 MemberIterator EraseMember(ConstMemberIterator pos) {
1576 return EraseMember(pos, pos +1);
1579 //! Remove members in the range [first, last) from an object.
1580 /*! \param first iterator to the first member to remove
1581 \param last iterator following the last member to remove
1582 \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd()
1583 \return Iterator following the last removed element.
1584 \note This function preserves the relative order of the remaining object
1586 \note Linear time complexity.
1588 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) {
1589 RAPIDJSON_ASSERT(IsObject());
1590 RAPIDJSON_ASSERT(data_.o.size > 0);
1591 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1592 RAPIDJSON_ASSERT(first >= MemberBegin());
1593 RAPIDJSON_ASSERT(first <= last);
1594 RAPIDJSON_ASSERT(last <= MemberEnd());
1596 MemberIterator pos = MemberBegin() + (first - MemberBegin());
1597 for (MemberIterator itr = pos; itr != last; ++itr)
1599 std::memmove(static_cast<void*>(&*pos), &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1600 data_.o.size -= static_cast<SizeType>(last - first);
1604 //! Erase a member in object by its name.
1605 /*! \param name Name of member to be removed.
1606 \return Whether the member existed.
1607 \note Linear time complexity.
1609 bool EraseMember(const Ch* name) {
1610 GenericValue n(StringRef(name));
1611 return EraseMember(n);
1614 #if RAPIDJSON_HAS_STDSTRING
1615 bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1618 template <typename SourceAllocator>
1619 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1620 MemberIterator m = FindMember(name);
1621 if (m != MemberEnd()) {
1629 Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1630 ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1637 //! Set this value as an empty array.
1638 /*! \post IsArray == true */
1639 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1641 //! Get the number of elements in array.
1642 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1644 //! Get the capacity of array.
1645 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1647 //! Check whether the array is empty.
1648 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1650 //! Remove all elements in the array.
1651 /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
1652 \note Linear time complexity.
1655 RAPIDJSON_ASSERT(IsArray());
1656 GenericValue* e = GetElementsPointer();
1657 for (GenericValue* v = e; v != e + data_.a.size; ++v)
1662 //! Get an element from array by index.
1663 /*! \pre IsArray() == true
1664 \param index Zero-based index of element.
1667 GenericValue& operator[](SizeType index) {
1668 RAPIDJSON_ASSERT(IsArray());
1669 RAPIDJSON_ASSERT(index < data_.a.size);
1670 return GetElementsPointer()[index];
1672 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1674 //! Element iterator
1675 /*! \pre IsArray() == true */
1676 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1677 //! \em Past-the-end element iterator
1678 /*! \pre IsArray() == true */
1679 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1680 //! Constant element iterator
1681 /*! \pre IsArray() == true */
1682 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1683 //! Constant \em past-the-end element iterator
1684 /*! \pre IsArray() == true */
1685 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1687 //! Request the array to have enough capacity to store elements.
1688 /*! \param newCapacity The capacity that the array at least need to have.
1689 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1690 \return The value itself for fluent API.
1691 \note Linear time complexity.
1693 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1694 RAPIDJSON_ASSERT(IsArray());
1695 if (newCapacity > data_.a.capacity) {
1696 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1697 data_.a.capacity = newCapacity;
1702 //! Append a GenericValue at the end of the array.
1703 /*! \param value Value to be appended.
1704 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1705 \pre IsArray() == true
1706 \post value.IsNull() == true
1707 \return The value itself for fluent API.
1708 \note The ownership of \c value will be transferred to this array on success.
1709 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1710 \note Amortized constant time complexity.
1712 GenericValue& PushBack(GenericValue& value, Allocator& allocator) {
1713 RAPIDJSON_ASSERT(IsArray());
1714 if (data_.a.size >= data_.a.capacity)
1715 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1716 GetElementsPointer()[data_.a.size++].RawAssign(value);
1720 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1721 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1722 return PushBack(value, allocator);
1724 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1726 //! Append a constant string reference at the end of the array.
1727 /*! \param value Constant string reference to be appended.
1728 \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().
1729 \pre IsArray() == true
1730 \return The value itself for fluent API.
1731 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1732 \note Amortized constant time complexity.
1733 \see GenericStringRef
1735 GenericValue& PushBack(StringRefType value, Allocator& allocator) {
1736 return (*this).template PushBack<StringRefType>(value, allocator);
1739 //! Append a primitive value at the end of the array.
1740 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1741 \param value Value of primitive type T to be appended.
1742 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1743 \pre IsArray() == true
1744 \return The value itself for fluent API.
1745 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1747 \note The source type \c T explicitly disallows all pointer types,
1748 especially (\c const) \ref Ch*. This helps avoiding implicitly
1749 referencing character strings with insufficient lifetime, use
1750 \ref PushBack(GenericValue&, Allocator&) or \ref
1751 PushBack(StringRefType, Allocator&).
1752 All other pointer types would implicitly convert to \c bool,
1753 use an explicit cast instead, if needed.
1754 \note Amortized constant time complexity.
1756 template <typename T>
1757 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1758 PushBack(T value, Allocator& allocator) {
1759 GenericValue v(value);
1760 return PushBack(v, allocator);
1763 //! Remove the last element in the array.
1765 \note Constant time complexity.
1767 GenericValue& PopBack() {
1768 RAPIDJSON_ASSERT(IsArray());
1769 RAPIDJSON_ASSERT(!Empty());
1770 GetElementsPointer()[--data_.a.size].~GenericValue();
1774 //! Remove an element of array by iterator.
1776 \param pos iterator to the element to remove
1777 \pre IsArray() == true && \ref Begin() <= \c pos < \ref End()
1778 \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.
1779 \note Linear time complexity.
1781 ValueIterator Erase(ConstValueIterator pos) {
1782 return Erase(pos, pos + 1);
1785 //! Remove elements in the range [first, last) of the array.
1787 \param first iterator to the first element to remove
1788 \param last iterator following the last element to remove
1789 \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End()
1790 \return Iterator following the last removed element.
1791 \note Linear time complexity.
1793 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) {
1794 RAPIDJSON_ASSERT(IsArray());
1795 RAPIDJSON_ASSERT(data_.a.size > 0);
1796 RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1797 RAPIDJSON_ASSERT(first >= Begin());
1798 RAPIDJSON_ASSERT(first <= last);
1799 RAPIDJSON_ASSERT(last <= End());
1800 ValueIterator pos = Begin() + (first - Begin());
1801 for (ValueIterator itr = pos; itr != last; ++itr)
1802 itr->~GenericValue();
1803 std::memmove(static_cast<void*>(pos), last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1804 data_.a.size -= static_cast<SizeType>(last - first);
1808 Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1809 ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1816 int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1817 unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1818 int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1819 uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1821 //! Get the value as double type.
1822 /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless.
1824 double GetDouble() const {
1825 RAPIDJSON_ASSERT(IsNumber());
1826 if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1827 if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1828 if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1829 if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1830 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1833 //! Get the value as float type.
1834 /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless.
1836 float GetFloat() const {
1837 return static_cast<float>(GetDouble());
1840 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1841 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1842 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1843 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1844 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1845 GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(static_cast<double>(f)); return *this; }
1852 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1854 //! Get the length of string.
1855 /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
1857 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1859 //! Set this value as a string without copying source string.
1860 /*! This version has better performance with supplied length, and also support string containing null character.
1861 \param s source string pointer.
1862 \param length The length of source string, excluding the trailing null terminator.
1863 \return The value itself for fluent API.
1864 \post IsString() == true && GetString() == s && GetStringLength() == length
1865 \see SetString(StringRefType)
1867 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1869 //! Set this value as a string without copying source string.
1870 /*! \param s source string reference
1871 \return The value itself for fluent API.
1872 \post IsString() == true && GetString() == s && GetStringLength() == s.length
1874 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1876 //! Set this value as a string by copying from source string.
1877 /*! This version has better performance with supplied length, and also support string containing null character.
1878 \param s source string.
1879 \param length The length of source string, excluding the trailing null terminator.
1880 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1881 \return The value itself for fluent API.
1882 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1884 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { return SetString(StringRef(s, length), allocator); }
1886 //! Set this value as a string by copying from source string.
1887 /*! \param s source string.
1888 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1889 \return The value itself for fluent API.
1890 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1892 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1894 //! Set this value as a string by copying from source string.
1895 /*! \param s source string reference
1896 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1897 \return The value itself for fluent API.
1898 \post IsString() == true && GetString() != s.s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1900 GenericValue& SetString(StringRefType s, Allocator& allocator) { this->~GenericValue(); SetStringRaw(s, allocator); return *this; }
1902 #if RAPIDJSON_HAS_STDSTRING
1903 //! Set this value as a string by copying from source string.
1904 /*! \param s source string.
1905 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1906 \return The value itself for fluent API.
1907 \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()
1908 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
1910 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(StringRef(s), allocator); }
1918 //! Templated version for checking whether this value is type T.
1920 \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>
1922 template <typename T>
1923 bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1925 template <typename T>
1926 T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1928 template <typename T>
1929 T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1931 template<typename T>
1932 ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1934 template<typename T>
1935 ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1939 //! Generate events of this value to a Handler.
1940 /*! This function adopts the GoF visitor pattern.
1941 Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.
1942 It can also be used to deep clone this value via GenericDocument, which is also a Handler.
1943 \tparam Handler type of handler.
1944 \param handler An object implementing concept Handler.
1946 template <typename Handler>
1947 bool Accept(Handler& handler) const {
1949 case kNullType: return handler.Null();
1950 case kFalseType: return handler.Bool(false);
1951 case kTrueType: return handler.Bool(true);
1954 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1956 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1957 RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1958 if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1960 if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1963 return handler.EndObject(data_.o.size);
1966 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1968 for (const GenericValue* v = Begin(); v != End(); ++v)
1969 if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1971 return handler.EndArray(data_.a.size);
1974 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1977 RAPIDJSON_ASSERT(GetType() == kNumberType);
1978 if (IsDouble()) return handler.Double(data_.n.d);
1979 else if (IsInt()) return handler.Int(data_.n.i.i);
1980 else if (IsUint()) return handler.Uint(data_.n.u.u);
1981 else if (IsInt64()) return handler.Int64(data_.n.i64);
1982 else return handler.Uint64(data_.n.u64);
1987 template <typename, typename> friend class GenericValue;
1988 template <typename, typename, typename> friend class GenericDocument;
1992 kNumberFlag = 0x0010,
1995 kInt64Flag = 0x0080,
1996 kUint64Flag = 0x0100,
1997 kDoubleFlag = 0x0200,
1998 kStringFlag = 0x0400,
2000 kInlineStrFlag = 0x1000,
2002 // Initial flags of different types.
2003 kNullFlag = kNullType,
2004 kTrueFlag = kTrueType | kBoolFlag,
2005 kFalseFlag = kFalseType | kBoolFlag,
2006 kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
2007 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
2008 kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
2009 kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
2010 kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
2011 kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
2012 kConstStringFlag = kStringType | kStringFlag,
2013 kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
2014 kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
2015 kObjectFlag = kObjectType,
2016 kArrayFlag = kArrayType,
2021 static const SizeType kDefaultArrayCapacity = RAPIDJSON_VALUE_DEFAULT_ARRAY_CAPACITY;
2022 static const SizeType kDefaultObjectCapacity = RAPIDJSON_VALUE_DEFAULT_OBJECT_CAPACITY;
2025 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION
2026 char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
2027 #elif RAPIDJSON_64BIT
2028 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
2030 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
2037 SizeType hashcode; //!< reserved
2039 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2041 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
2042 // (excluding the terminating zero) and store a value to determine the length of the contained
2043 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
2044 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
2045 // the string terminator as well. For getting the string length back from that value just use
2046 // "MaxSize - str[LenPos]".
2047 // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
2048 // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
2049 struct ShortString {
2050 enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
2053 inline static bool Usable(SizeType len) { return (MaxSize >= len); }
2054 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
2055 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
2056 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2058 // By using proper binary layout, retrieval of different integer types do not need conversions.
2060 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
2088 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2093 GenericValue* elements;
2094 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
2103 }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
2105 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
2106 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
2107 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
2108 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
2109 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
2110 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
2112 // Initialize this value as array with initial data, without calling destructor.
2113 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
2114 data_.f.flags = kArrayFlag;
2116 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
2117 SetElementsPointer(e);
2118 std::memcpy(static_cast<void*>(e), values, count * sizeof(GenericValue));
2121 SetElementsPointer(0);
2122 data_.a.size = data_.a.capacity = count;
2125 //! Initialize this value as object with initial data, without calling destructor.
2126 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
2127 data_.f.flags = kObjectFlag;
2129 Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
2130 SetMembersPointer(m);
2131 std::memcpy(static_cast<void*>(m), members, count * sizeof(Member));
2134 SetMembersPointer(0);
2135 data_.o.size = data_.o.capacity = count;
2138 //! Initialize this value as constant string, without calling destructor.
2139 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
2140 data_.f.flags = kConstStringFlag;
2141 SetStringPointer(s);
2142 data_.s.length = s.length;
2145 //! Initialize this value as copy string with initial data, without calling destructor.
2146 void SetStringRaw(StringRefType s, Allocator& allocator) {
2148 if (ShortString::Usable(s.length)) {
2149 data_.f.flags = kShortStringFlag;
2150 data_.ss.SetLength(s.length);
2153 data_.f.flags = kCopyStringFlag;
2154 data_.s.length = s.length;
2155 str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
2156 SetStringPointer(str);
2158 std::memcpy(str, s, s.length * sizeof(Ch));
2159 str[s.length] = '\0';
2162 //! Assignment without calling destructor
2163 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
2165 // data_.f.flags = rhs.data_.f.flags;
2166 rhs.data_.f.flags = kNullFlag;
2169 template <typename SourceAllocator>
2170 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2171 RAPIDJSON_ASSERT(IsString());
2172 RAPIDJSON_ASSERT(rhs.IsString());
2174 const SizeType len1 = GetStringLength();
2175 const SizeType len2 = rhs.GetStringLength();
2176 if(len1 != len2) { return false; }
2178 const Ch* const str1 = GetString();
2179 const Ch* const str2 = rhs.GetString();
2180 if(str1 == str2) { return true; } // fast path for constant string
2182 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2188 //! GenericValue with UTF8 encoding
2189 typedef GenericValue<UTF8<> > Value;
2191 ///////////////////////////////////////////////////////////////////////////////
2194 //! A document for parsing JSON text as DOM.
2196 \note implements Handler concept
2197 \tparam Encoding Encoding for both parsing and string storage.
2198 \tparam Allocator Allocator for allocating memory for the DOM
2199 \tparam StackAllocator Allocator for allocating memory for stack during parsing.
2200 \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.
2202 template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR, typename StackAllocator = RAPIDJSON_DEFAULT_STACK_ALLOCATOR >
2203 class GenericDocument : public GenericValue<Encoding, Allocator> {
2205 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
2206 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
2207 typedef Allocator AllocatorType; //!< Allocator type from template parameter.
2210 /*! Creates an empty document of specified type.
2211 \param type Mandatory type of object to create.
2212 \param allocator Optional allocator for allocating memory.
2213 \param stackCapacity Optional initial capacity of stack in bytes.
2214 \param stackAllocator Optional allocator for allocating memory for stack.
2216 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2217 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2220 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2224 /*! Creates an empty document which type is Null.
2225 \param allocator Optional allocator for allocating memory.
2226 \param stackCapacity Optional initial capacity of stack in bytes.
2227 \param stackAllocator Optional allocator for allocating memory for stack.
2229 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2230 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2233 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
2236 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2237 //! Move constructor in C++11
2238 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2239 : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2240 allocator_(rhs.allocator_),
2241 ownAllocator_(rhs.ownAllocator_),
2242 stack_(std::move(rhs.stack_)),
2243 parseResult_(rhs.parseResult_)
2246 rhs.ownAllocator_ = 0;
2247 rhs.parseResult_ = ParseResult();
2251 ~GenericDocument() {
2255 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2256 //! Move assignment in C++11
2257 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2259 // The cast to ValueType is necessary here, because otherwise it would
2260 // attempt to call GenericValue's templated assignment operator.
2261 ValueType::operator=(std::forward<ValueType>(rhs));
2263 // Calling the destructor here would prematurely call stack_'s destructor
2266 allocator_ = rhs.allocator_;
2267 ownAllocator_ = rhs.ownAllocator_;
2268 stack_ = std::move(rhs.stack_);
2269 parseResult_ = rhs.parseResult_;
2272 rhs.ownAllocator_ = 0;
2273 rhs.parseResult_ = ParseResult();
2279 //! Exchange the contents of this document with those of another.
2281 \param rhs Another document.
2282 \note Constant complexity.
2283 \see GenericValue::Swap
2285 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2286 ValueType::Swap(rhs);
2287 stack_.Swap(rhs.stack_);
2288 internal::Swap(allocator_, rhs.allocator_);
2289 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2290 internal::Swap(parseResult_, rhs.parseResult_);
2294 // Allow Swap with ValueType.
2295 // Refer to Effective C++ 3rd Edition/Item 33: Avoid hiding inherited names.
2296 using ValueType::Swap;
2298 //! free-standing swap function helper
2300 Helper function to enable support for common swap implementation pattern based on \c std::swap:
2302 void swap(MyClass& a, MyClass& b) {
2310 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2312 //! Populate this document by a generator which produces SAX events.
2313 /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.
2314 \param g Generator functor which sends SAX events to the parameter.
2315 \return The document itself for fluent API.
2317 template <typename Generator>
2318 GenericDocument& Populate(Generator& g) {
2319 ClearStackOnExit scope(*this);
2321 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2322 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2327 //!@name Parse from stream
2330 //! Parse JSON text from an input stream (with Encoding conversion)
2331 /*! \tparam parseFlags Combination of \ref ParseFlag.
2332 \tparam SourceEncoding Encoding of input stream
2333 \tparam InputStream Type of input stream, implementing Stream concept
2334 \param is Input stream to be parsed.
2335 \return The document itself for fluent API.
2337 template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2338 GenericDocument& ParseStream(InputStream& is) {
2339 GenericReader<SourceEncoding, Encoding, StackAllocator> reader(
2340 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2341 ClearStackOnExit scope(*this);
2342 parseResult_ = reader.template Parse<parseFlags>(is, *this);
2344 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2345 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2350 //! Parse JSON text from an input stream
2351 /*! \tparam parseFlags Combination of \ref ParseFlag.
2352 \tparam InputStream Type of input stream, implementing Stream concept
2353 \param is Input stream to be parsed.
2354 \return The document itself for fluent API.
2356 template <unsigned parseFlags, typename InputStream>
2357 GenericDocument& ParseStream(InputStream& is) {
2358 return ParseStream<parseFlags, Encoding, InputStream>(is);
2361 //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
2362 /*! \tparam InputStream Type of input stream, implementing Stream concept
2363 \param is Input stream to be parsed.
2364 \return The document itself for fluent API.
2366 template <typename InputStream>
2367 GenericDocument& ParseStream(InputStream& is) {
2368 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2372 //!@name Parse in-place from mutable string
2375 //! Parse JSON text from a mutable string
2376 /*! \tparam parseFlags Combination of \ref ParseFlag.
2377 \param str Mutable zero-terminated string to be parsed.
2378 \return The document itself for fluent API.
2380 template <unsigned parseFlags>
2381 GenericDocument& ParseInsitu(Ch* str) {
2382 GenericInsituStringStream<Encoding> s(str);
2383 return ParseStream<parseFlags | kParseInsituFlag>(s);
2386 //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
2387 /*! \param str Mutable zero-terminated string to be parsed.
2388 \return The document itself for fluent API.
2390 GenericDocument& ParseInsitu(Ch* str) {
2391 return ParseInsitu<kParseDefaultFlags>(str);
2395 //!@name Parse from read-only string
2398 //! Parse JSON text from a read-only string (with Encoding conversion)
2399 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2400 \tparam SourceEncoding Transcoding from input Encoding
2401 \param str Read-only zero-terminated string to be parsed.
2403 template <unsigned parseFlags, typename SourceEncoding>
2404 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2405 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2406 GenericStringStream<SourceEncoding> s(str);
2407 return ParseStream<parseFlags, SourceEncoding>(s);
2410 //! Parse JSON text from a read-only string
2411 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2412 \param str Read-only zero-terminated string to be parsed.
2414 template <unsigned parseFlags>
2415 GenericDocument& Parse(const Ch* str) {
2416 return Parse<parseFlags, Encoding>(str);
2419 //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
2420 /*! \param str Read-only zero-terminated string to be parsed.
2422 GenericDocument& Parse(const Ch* str) {
2423 return Parse<kParseDefaultFlags>(str);
2426 template <unsigned parseFlags, typename SourceEncoding>
2427 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2428 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2429 MemoryStream ms(reinterpret_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2430 EncodedInputStream<SourceEncoding, MemoryStream> is(ms);
2431 ParseStream<parseFlags, SourceEncoding>(is);
2435 template <unsigned parseFlags>
2436 GenericDocument& Parse(const Ch* str, size_t length) {
2437 return Parse<parseFlags, Encoding>(str, length);
2440 GenericDocument& Parse(const Ch* str, size_t length) {
2441 return Parse<kParseDefaultFlags>(str, length);
2444 #if RAPIDJSON_HAS_STDSTRING
2445 template <unsigned parseFlags, typename SourceEncoding>
2446 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2447 // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2448 return Parse<parseFlags, SourceEncoding>(str.c_str());
2451 template <unsigned parseFlags>
2452 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2453 return Parse<parseFlags, Encoding>(str.c_str());
2456 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2457 return Parse<kParseDefaultFlags>(str);
2459 #endif // RAPIDJSON_HAS_STDSTRING
2463 //!@name Handling parse errors
2466 //! Whether a parse error has occurred in the last parsing.
2467 bool HasParseError() const { return parseResult_.IsError(); }
2469 //! Get the \ref ParseErrorCode of last parsing.
2470 ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2472 //! Get the position of last parsing error in input, 0 otherwise.
2473 size_t GetErrorOffset() const { return parseResult_.Offset(); }
2475 //! Implicit conversion to get the last parse result
2476 #ifndef __clang // -Wdocumentation
2477 /*! \return \ref ParseResult of the last parse operation
2481 ParseResult ok = doc.Parse(json);
2483 printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
2487 operator ParseResult() const { return parseResult_; }
2490 //! Get the allocator of this document.
2491 Allocator& GetAllocator() {
2492 RAPIDJSON_ASSERT(allocator_);
2496 //! Get the capacity of stack in bytes.
2497 size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2500 // clear stack on any exit from ParseStream, e.g. due to exception
2501 struct ClearStackOnExit {
2502 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2503 ~ClearStackOnExit() { d_.ClearStack(); }
2505 ClearStackOnExit(const ClearStackOnExit&);
2506 ClearStackOnExit& operator=(const ClearStackOnExit&);
2507 GenericDocument& d_;
2510 // callers of the following private Handler functions
2511 // template <typename,typename,typename> friend class GenericReader; // for parsing
2512 template <typename, typename> friend class GenericValue; // for deep copying
2515 // Implementation of Handler
2516 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2517 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2518 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2519 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2520 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2521 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2522 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2524 bool RawNumber(const Ch* str, SizeType length, bool copy) {
2526 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2528 new (stack_.template Push<ValueType>()) ValueType(str, length);
2532 bool String(const Ch* str, SizeType length, bool copy) {
2534 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2536 new (stack_.template Push<ValueType>()) ValueType(str, length);
2540 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2542 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2544 bool EndObject(SizeType memberCount) {
2545 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2546 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2550 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2552 bool EndArray(SizeType elementCount) {
2553 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2554 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2559 //! Prohibit copying
2560 GenericDocument(const GenericDocument&);
2561 //! Prohibit assignment
2562 GenericDocument& operator=(const GenericDocument&);
2565 if (Allocator::kNeedFree)
2566 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2567 (stack_.template Pop<ValueType>(1))->~ValueType();
2570 stack_.ShrinkToFit();
2574 RAPIDJSON_DELETE(ownAllocator_);
2577 static const size_t kDefaultStackCapacity = 1024;
2578 Allocator* allocator_;
2579 Allocator* ownAllocator_;
2580 internal::Stack<StackAllocator> stack_;
2581 ParseResult parseResult_;
2584 //! GenericDocument with UTF8 encoding
2585 typedef GenericDocument<UTF8<> > Document;
2588 //! Helper class for accessing Value of array type.
2590 Instance of this helper class is obtained by \c GenericValue::GetArray().
2591 In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2593 template <bool Const, typename ValueT>
2594 class GenericArray {
2596 typedef GenericArray<true, ValueT> ConstArray;
2597 typedef GenericArray<false, ValueT> Array;
2598 typedef ValueT PlainType;
2599 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2600 typedef ValueType* ValueIterator; // This may be const or non-const iterator
2601 typedef const ValueT* ConstValueIterator;
2602 typedef typename ValueType::AllocatorType AllocatorType;
2603 typedef typename ValueType::StringRefType StringRefType;
2605 template <typename, typename>
2606 friend class GenericValue;
2608 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2609 GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2612 SizeType Size() const { return value_.Size(); }
2613 SizeType Capacity() const { return value_.Capacity(); }
2614 bool Empty() const { return value_.Empty(); }
2615 void Clear() const { value_.Clear(); }
2616 ValueType& operator[](SizeType index) const { return value_[index]; }
2617 ValueIterator Begin() const { return value_.Begin(); }
2618 ValueIterator End() const { return value_.End(); }
2619 GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2620 GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2621 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2622 GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2623 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2624 GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2625 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; }
2626 GenericArray PopBack() const { value_.PopBack(); return *this; }
2627 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2628 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2630 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2631 ValueIterator begin() const { return value_.Begin(); }
2632 ValueIterator end() const { return value_.End(); }
2637 GenericArray(ValueType& value) : value_(value) {}
2641 //! Helper class for accessing Value of object type.
2643 Instance of this helper class is obtained by \c GenericValue::GetObject().
2644 In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2646 template <bool Const, typename ValueT>
2647 class GenericObject {
2649 typedef GenericObject<true, ValueT> ConstObject;
2650 typedef GenericObject<false, ValueT> Object;
2651 typedef ValueT PlainType;
2652 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2653 typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator
2654 typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator;
2655 typedef typename ValueType::AllocatorType AllocatorType;
2656 typedef typename ValueType::StringRefType StringRefType;
2657 typedef typename ValueType::EncodingType EncodingType;
2658 typedef typename ValueType::Ch Ch;
2660 template <typename, typename>
2661 friend class GenericValue;
2663 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2664 GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2667 SizeType MemberCount() const { return value_.MemberCount(); }
2668 SizeType MemberCapacity() const { return value_.MemberCapacity(); }
2669 bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2670 template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2671 template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2672 #if RAPIDJSON_HAS_STDSTRING
2673 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2675 MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2676 MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2677 GenericObject MemberReserve(SizeType newCapacity, AllocatorType &allocator) const { value_.MemberReserve(newCapacity, allocator); return *this; }
2678 bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2679 #if RAPIDJSON_HAS_STDSTRING
2680 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2682 template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2683 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2684 template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2685 #if RAPIDJSON_HAS_STDSTRING
2686 MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2688 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2689 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2690 #if RAPIDJSON_HAS_STDSTRING
2691 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2693 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; }
2694 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2695 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2696 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2697 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2698 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2699 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2700 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2701 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2702 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; }
2703 void RemoveAllMembers() { value_.RemoveAllMembers(); }
2704 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2705 #if RAPIDJSON_HAS_STDSTRING
2706 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2708 template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2709 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2710 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
2711 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2712 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2713 #if RAPIDJSON_HAS_STDSTRING
2714 bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2716 template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2718 #if RAPIDJSON_HAS_CXX11_RANGE_FOR
2719 MemberIterator begin() const { return value_.MemberBegin(); }
2720 MemberIterator end() const { return value_.MemberEnd(); }
2725 GenericObject(ValueType& value) : value_(value) {}
2729 RAPIDJSON_NAMESPACE_END
2732 #endif // RAPIDJSON_DOCUMENT_H_