document.h
Go to the documentation of this file.
1// Tencent is pleased to support the open source community by making RapidJSON available.
2//
3// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4//
5// Licensed under the MIT License (the "License"); you may not use this file except
6// in compliance with the License. You may obtain a copy of the License at
7//
8// http://opensource.org/licenses/MIT
9//
10// Unless required by applicable law or agreed to in writing, software distributed
11// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13// specific language governing permissions and limitations under the License.
14
15#ifndef RAPIDJSON_DOCUMENT_H_
16#define RAPIDJSON_DOCUMENT_H_
17
18/*! \file document.h */
19
20#include "reader.h"
21#include "internal/meta.h"
22#include "internal/strfunc.h"
23#include "memorystream.h"
24#include "encodedstream.h"
25#include <new> // placement new
26#include <limits>
27#ifdef __cpp_lib_three_way_comparison
28#include <compare>
29#endif
30
31RAPIDJSON_DIAG_PUSH
32#ifdef _MSC_VER
33RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
34RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
35#endif
36
37#ifdef __clang__
38RAPIDJSON_DIAG_OFF(padded)
39RAPIDJSON_DIAG_OFF(switch-enum)
40RAPIDJSON_DIAG_OFF(c++98-compat)
41#endif
42
43#ifdef __GNUC__
44RAPIDJSON_DIAG_OFF(effc++)
45#if __GNUC__ >= 6
46RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions
47#endif
48#endif // __GNUC__
49
50#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
51#include <iterator> // std::iterator, std::random_access_iterator_tag
52#endif
53
54#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
55#include <utility> // std::move
56#endif
57
58RAPIDJSON_NAMESPACE_BEGIN
59
60// Forward declaration.
61template <typename Encoding, typename Allocator>
62class GenericValue;
63
64template <typename Encoding, typename Allocator, typename StackAllocator>
65class GenericDocument;
66
67//! Name-value pair in a JSON object value.
68/*!
69 This class was internal to GenericValue. It used to be a inner struct.
70 But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
71 https://code.google.com/p/rapidjson/issues/detail?id=64
72*/
73template <typename Encoding, typename Allocator>
75 GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
77};
78
79///////////////////////////////////////////////////////////////////////////////
80// GenericMemberIterator
81
82#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
83
84//! (Constant) member iterator for a JSON object value
85/*!
86 \tparam Const Is this a constant iterator?
87 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
88 \tparam Allocator Allocator type for allocating memory of object, array and string.
89
90 This class implements a Random Access Iterator for GenericMember elements
91 of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
92
93 \note This iterator implementation is mainly intended to avoid implicit
94 conversions from iterator values to \c NULL,
95 e.g. from GenericValue::FindMember.
96
97 \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
98 pointer-based implementation, if your platform doesn't provide
99 the C++ <iterator> header.
100
101 \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
102 */
103template <bool Const, typename Encoding, typename Allocator>
105 : public std::iterator<std::random_access_iterator_tag
106 , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
107
108 friend class GenericValue<Encoding,Allocator>;
109 template <bool, typename, typename> friend class GenericMemberIterator;
110
112 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
113 typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
114
115public:
116 //! Iterator type itself
118 //! Constant iterator type
120 //! Non-constant iterator type
122
123 //! Pointer to (const) GenericMember
124 typedef typename BaseType::pointer Pointer;
125 //! Reference to (const) GenericMember
126 typedef typename BaseType::reference Reference;
127 //! Signed integer type (e.g. \c ptrdiff_t)
128 typedef typename BaseType::difference_type DifferenceType;
129
130 //! Default constructor (singular value)
131 /*! Creates an iterator pointing to no element.
132 \note All operations, except for comparisons, are undefined on such values.
133 */
135
136 //! Iterator conversions to more const
137 /*!
138 \param it (Non-const) iterator to copy from
139
140 Allows the creation of an iterator from another GenericMemberIterator
141 that is "less const". Especially, creating a non-constant iterator
142 from a constant iterator are disabled:
143 \li const -> non-const (not ok)
144 \li const -> const (ok)
145 \li non-const -> const (ok)
146 \li non-const -> non-const (ok)
147
148 \note If the \c Const template parameter is already \c false, this
149 constructor effectively defines a regular copy-constructor.
150 Otherwise, the copy constructor is implicitly defined.
151 */
152 GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
153 Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
154
155 //! @name stepping
156 //@{
157 Iterator& operator++(){ ++ptr_; return *this; }
158 Iterator& operator--(){ --ptr_; return *this; }
159 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
160 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
161 //@}
162
163 //! @name increment/decrement
164 //@{
165 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
166 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
167
168 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
169 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
170 //@}
171
172 //! @name relations
173 //@{
174 template <bool Const_> bool operator==(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ == that.ptr_; }
175 template <bool Const_> bool operator!=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ != that.ptr_; }
176 template <bool Const_> bool operator<=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <= that.ptr_; }
177 template <bool Const_> bool operator>=(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ >= that.ptr_; }
178 template <bool Const_> bool operator< (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ < that.ptr_; }
179 template <bool Const_> bool operator> (const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ > that.ptr_; }
180
181#ifdef __cpp_lib_three_way_comparison
182 template <bool Const_> std::strong_ordering operator<=>(const GenericMemberIterator<Const_, Encoding, Allocator>& that) const { return ptr_ <=> that.ptr_; }
183#endif
184 //@}
185
186 //! @name dereference
187 //@{
188 Reference operator*() const { return *ptr_; }
189 Pointer operator->() const { return ptr_; }
190 Reference operator[](DifferenceType n) const { return ptr_[n]; }
191 //@}
192
193 //! Distance
194 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
195
196private:
197 //! Internal constructor from plain pointer
198 explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
199
200 Pointer ptr_; //!< raw pointer
201};
202
203#else // RAPIDJSON_NOMEMBERITERATORCLASS
204
205// class-based member iterator implementation disabled, use plain pointers
206
207template <bool Const, typename Encoding, typename Allocator>
208struct GenericMemberIterator;
209
210//! non-const GenericMemberIterator
211template <typename Encoding, typename Allocator>
212struct GenericMemberIterator<false,Encoding,Allocator> {
213 //! use plain pointer as iterator type
214 typedef GenericMember<Encoding,Allocator>* Iterator;
215};
216//! const GenericMemberIterator
217template <typename Encoding, typename Allocator>
218struct GenericMemberIterator<true,Encoding,Allocator> {
219 //! use plain const pointer as iterator type
220 typedef const GenericMember<Encoding,Allocator>* Iterator;
221};
222
223#endif // RAPIDJSON_NOMEMBERITERATORCLASS
224
225///////////////////////////////////////////////////////////////////////////////
226// GenericStringRef
227
228//! Reference to a constant string (not taking a copy)
229/*!
230 \tparam CharType character type of the string
231
232 This helper class is used to automatically infer constant string
233 references for string literals, especially from \c const \b (!)
234 character arrays.
235
236 The main use is for creating JSON string values without copying the
237 source string via an \ref Allocator. This requires that the referenced
238 string pointers have a sufficient lifetime, which exceeds the lifetime
239 of the associated GenericValue.
240
241 \b Example
242 \code
243 Value v("foo"); // ok, no need to copy & calculate length
244 const char foo[] = "foo";
245 v.SetString(foo); // ok
246
247 const char* bar = foo;
248 // Value x(bar); // not ok, can't rely on bar's lifetime
249 Value x(StringRef(bar)); // lifetime explicitly guaranteed by user
250 Value y(StringRef(bar, 3)); // ok, explicitly pass length
251 \endcode
252
253 \see StringRef, GenericValue::SetString
254*/
255template<typename CharType>
257 typedef CharType Ch; //!< character type of the string
258
259 //! Create string reference from \c const character array
260#ifndef __clang__ // -Wdocumentation
261 /*!
262 This constructor implicitly creates a constant string reference from
263 a \c const character array. It has better performance than
264 \ref StringRef(const CharType*) by inferring the string \ref length
265 from the array length, and also supports strings containing null
266 characters.
267
268 \tparam N length of the string, automatically inferred
269
270 \param str Constant character array, lifetime assumed to be longer
271 than the use of the string in e.g. a GenericValue
272
273 \post \ref s == str
274
275 \note Constant complexity.
276 \note There is a hidden, private overload to disallow references to
277 non-const character arrays to be created via this constructor.
278 By this, e.g. function-scope arrays used to be filled via
279 \c snprintf are excluded from consideration.
280 In such cases, the referenced string should be \b copied to the
281 GenericValue instead.
282 */
283#endif
284 template<SizeType N>
285 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
286 : s(str), length(N-1) {}
287
288 //! Explicitly create string reference from \c const character pointer
289#ifndef __clang__ // -Wdocumentation
290 /*!
291 This constructor can be used to \b explicitly create a reference to
292 a constant string pointer.
293
294 \see StringRef(const CharType*)
295
296 \param str Constant character pointer, lifetime assumed to be longer
297 than the use of the string in e.g. a GenericValue
298
299 \post \ref s == str
300
301 \note There is a hidden, private overload to disallow references to
302 non-const character arrays to be created via this constructor.
303 By this, e.g. function-scope arrays used to be filled via
304 \c snprintf are excluded from consideration.
305 In such cases, the referenced string should be \b copied to the
306 GenericValue instead.
307 */
308#endif
309 explicit GenericStringRef(const CharType* str)
310 : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); }
311
312 //! Create constant string reference from pointer and length
313#ifndef __clang__ // -Wdocumentation
314 /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
315 \param len length of the string, excluding the trailing NULL terminator
316
317 \post \ref s == str && \ref length == len
318 \note Constant complexity.
319 */
320#endif
321 GenericStringRef(const CharType* str, SizeType len)
322 : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); }
323
324 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
325
326 //! implicit conversion to plain CharType pointer
327 operator const Ch *() const { return s; }
328
329 const Ch* const s; //!< plain CharType pointer
330 const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
331
332private:
333 //! Disallow construction from non-const array
334 template<SizeType N>
335 GenericStringRef(CharType (&str)[N]) /* = delete */;
336 //! Copy assignment operator not permitted - immutable type
337 GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */;
338};
339
340//! Mark a character pointer as constant string
341/*! Mark a plain character pointer as a "string literal". This function
342 can be used to avoid copying a character string to be referenced as a
343 value in a JSON GenericValue object, if the string's lifetime is known
344 to be valid long enough.
345 \tparam CharType Character type of the string
346 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
347 \return GenericStringRef string reference object
348 \relatesalso GenericStringRef
349
350 \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember
351*/
352template<typename CharType>
353inline GenericStringRef<CharType> StringRef(const CharType* str) {
354 return GenericStringRef<CharType>(str, internal::StrLen(str));
355}
356
357//! Mark a character pointer as constant string
358/*! Mark a plain character pointer as a "string literal". This function
359 can be used to avoid copying a character string to be referenced as a
360 value in a JSON GenericValue object, if the string's lifetime is known
361 to be valid long enough.
362
363 This version has better performance with supplied length, and also
364 supports string containing null characters.
365
366 \tparam CharType character type of the string
367 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
368 \param length The length of source string.
369 \return GenericStringRef string reference object
370 \relatesalso GenericStringRef
371*/
372template<typename CharType>
373inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
374 return GenericStringRef<CharType>(str, SizeType(length));
375}
376
377#if RAPIDJSON_HAS_STDSTRING
378//! Mark a string object as constant string
379/*! Mark a string object (e.g. \c std::string) as a "string literal".
380 This function can be used to avoid copying a string to be referenced as a
381 value in a JSON GenericValue object, if the string's lifetime is known
382 to be valid long enough.
383
384 \tparam CharType character type of the string
385 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
386 \return GenericStringRef string reference object
387 \relatesalso GenericStringRef
388 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
389*/
390template<typename CharType>
391inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
392 return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
393}
394#endif
395
396///////////////////////////////////////////////////////////////////////////////
397// GenericValue type traits
398namespace internal {
399
400template <typename T, typename Encoding = void, typename Allocator = void>
401struct IsGenericValueImpl : FalseType {};
402
403// select candidates according to nested encoding and allocator types
404template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
405 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
406
407// helper to match arbitrary GenericValue instantiations, including derived classes
408template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
409
410} // namespace internal
411
412///////////////////////////////////////////////////////////////////////////////
413// TypeHelper
414
415namespace internal {
416
417template <typename ValueType, typename T>
418struct TypeHelper {};
419
420template<typename ValueType>
421struct TypeHelper<ValueType, bool> {
422 static bool Is(const ValueType& v) { return v.IsBool(); }
423 static bool Get(const ValueType& v) { return v.GetBool(); }
424 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
425 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
426};
427
428template<typename ValueType>
429struct TypeHelper<ValueType, int> {
430 static bool Is(const ValueType& v) { return v.IsInt(); }
431 static int Get(const ValueType& v) { return v.GetInt(); }
432 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
433 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
434};
435
436template<typename ValueType>
437struct TypeHelper<ValueType, unsigned> {
438 static bool Is(const ValueType& v) { return v.IsUint(); }
439 static unsigned Get(const ValueType& v) { return v.GetUint(); }
440 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
441 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
442};
443
444template<typename ValueType>
445struct TypeHelper<ValueType, int64_t> {
446 static bool Is(const ValueType& v) { return v.IsInt64(); }
447 static int64_t Get(const ValueType& v) { return v.GetInt64(); }
448 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
449 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
450};
451
452template<typename ValueType>
453struct TypeHelper<ValueType, uint64_t> {
454 static bool Is(const ValueType& v) { return v.IsUint64(); }
455 static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
456 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
457 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
458};
459
460template<typename ValueType>
461struct TypeHelper<ValueType, double> {
462 static bool Is(const ValueType& v) { return v.IsDouble(); }
463 static double Get(const ValueType& v) { return v.GetDouble(); }
464 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
465 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
466};
467
468template<typename ValueType>
469struct TypeHelper<ValueType, float> {
470 static bool Is(const ValueType& v) { return v.IsFloat(); }
471 static float Get(const ValueType& v) { return v.GetFloat(); }
472 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
473 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
474};
475
476template<typename ValueType>
477struct TypeHelper<ValueType, const typename ValueType::Ch*> {
478 typedef const typename ValueType::Ch* StringType;
479 static bool Is(const ValueType& v) { return v.IsString(); }
480 static StringType Get(const ValueType& v) { return v.GetString(); }
481 static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
482 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
483};
484
485#if RAPIDJSON_HAS_STDSTRING
486template<typename ValueType>
487struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > {
488 typedef std::basic_string<typename ValueType::Ch> StringType;
489 static bool Is(const ValueType& v) { return v.IsString(); }
490 static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
491 static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
492};
493#endif
494
495template<typename ValueType>
496struct TypeHelper<ValueType, typename ValueType::Array> {
497 typedef typename ValueType::Array ArrayType;
498 static bool Is(const ValueType& v) { return v.IsArray(); }
499 static ArrayType Get(ValueType& v) { return v.GetArray(); }
500 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
501 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
502};
503
504template<typename ValueType>
505struct TypeHelper<ValueType, typename ValueType::ConstArray> {
506 typedef typename ValueType::ConstArray ArrayType;
507 static bool Is(const ValueType& v) { return v.IsArray(); }
508 static ArrayType Get(const ValueType& v) { return v.GetArray(); }
509};
510
511template<typename ValueType>
512struct TypeHelper<ValueType, typename ValueType::Object> {
513 typedef typename ValueType::Object ObjectType;
514 static bool Is(const ValueType& v) { return v.IsObject(); }
515 static ObjectType Get(ValueType& v) { return v.GetObject(); }
516 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
517 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; }
518};
519
520template<typename ValueType>
521struct TypeHelper<ValueType, typename ValueType::ConstObject> {
522 typedef typename ValueType::ConstObject ObjectType;
523 static bool Is(const ValueType& v) { return v.IsObject(); }
524 static ObjectType Get(const ValueType& v) { return v.GetObject(); }
525};
526
527} // namespace internal
528
529// Forward declarations
530template <bool, typename> class GenericArray;
531template <bool, typename> class GenericObject;
532
533///////////////////////////////////////////////////////////////////////////////
534// GenericValue
535
536//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
537/*!
538 A JSON value can be one of 7 types. This class is a variant type supporting
539 these types.
540
541 Use the Value if UTF8 and default allocator
542
543 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
544 \tparam Allocator Allocator type for allocating memory of object, array and string.
545*/
546template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
548public:
549 //! Name-value pair in an object.
551 typedef Encoding EncodingType; //!< Encoding type from template parameter.
552 typedef Allocator AllocatorType; //!< Allocator type from template parameter.
553 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
554 typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string
555 typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object.
556 typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object.
557 typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
558 typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
559 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself.
564
565 //!@name Constructors and destructor.
566 //@{
567
568 //! Default constructor creates a null value.
569 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
570
571#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
572 //! Move constructor in C++11
573 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
574 rhs.data_.f.flags = kNullFlag; // give up contents
575 }
576#endif
577
578private:
579 //! Copy constructor is not permitted.
580 GenericValue(const GenericValue& rhs);
581
582#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
583 //! Moving from a GenericDocument is not permitted.
584 template <typename StackAllocator>
585 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
586
587 //! Move assignment from a GenericDocument is not permitted.
588 template <typename StackAllocator>
589 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs);
590#endif
591
592public:
593
594 //! Constructor with JSON value type.
595 /*! This creates a Value of specified type with default content.
596 \param type Type of the value.
597 \note Default content for number is zero.
598 */
599 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
600 static const uint16_t defaultFlags[7] = {
601 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
602 kNumberAnyFlag
603 };
605 data_.f.flags = defaultFlags[type];
606
607 // Use ShortString to store empty string.
608 if (type == kStringType)
609 data_.ss.SetLength(0);
610 }
611
612 //! Explicit copy constructor (with allocator)
613 /*! Creates a copy of a Value by using the given Allocator
614 \tparam SourceAllocator allocator of \c rhs
615 \param rhs Value to copy from (read-only)
616 \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
617 \see CopyFrom()
618 */
619 template< typename SourceAllocator >
621
622 //! Constructor for boolean value.
623 /*! \param b Boolean value
624 \note This constructor is limited to \em real boolean values and rejects
625 implicitly converted types like arbitrary pointers. Use an explicit cast
626 to \c bool, if you want to construct a boolean JSON value in such cases.
627 */
628#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
629 template <typename T>
630 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472
631#else
632 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
633#endif
634 : data_() {
635 // safe-guard against failing SFINAE
637 data_.f.flags = b ? kTrueFlag : kFalseFlag;
638 }
639
640 //! Constructor for int value.
641 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
642 data_.n.i64 = i;
643 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
644 }
645
646 //! Constructor for unsigned value.
647 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
648 data_.n.u64 = u;
649 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
650 }
651
652 //! Constructor for int64_t value.
653 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
654 data_.n.i64 = i64;
655 data_.f.flags = kNumberInt64Flag;
656 if (i64 >= 0) {
657 data_.f.flags |= kNumberUint64Flag;
658 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
659 data_.f.flags |= kUintFlag;
660 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
661 data_.f.flags |= kIntFlag;
662 }
663 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
664 data_.f.flags |= kIntFlag;
665 }
666
667 //! Constructor for uint64_t value.
668 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() {
669 data_.n.u64 = u64;
670 data_.f.flags = kNumberUint64Flag;
671 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
672 data_.f.flags |= kInt64Flag;
673 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
674 data_.f.flags |= kUintFlag;
675 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
676 data_.f.flags |= kIntFlag;
677 }
678
679 //! Constructor for double value.
680 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; }
681
682 //! Constructor for constant string (i.e. do not make a copy of string)
683 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); }
684
685 //! Constructor for constant string (i.e. do not make a copy of string)
686 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); }
687
688 //! Constructor for copy-string (i.e. do make a copy of string)
689 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); }
690
691 //! Constructor for copy-string (i.e. do make a copy of string)
692 GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
693
694#if RAPIDJSON_HAS_STDSTRING
695 //! Constructor for copy-string from a string object (i.e. do make a copy of string)
696 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
697 */
698 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); }
699#endif
700
701 //! Constructor for Array.
702 /*!
703 \param a An array obtained by \c GetArray().
704 \note \c Array is always pass-by-value.
705 \note the source array is moved into this value and the sourec array becomes empty.
706 */
707 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) {
708 a.value_.data_ = Data();
709 a.value_.data_.f.flags = kArrayFlag;
710 }
711
712 //! Constructor for Object.
713 /*!
714 \param o An object obtained by \c GetObject().
715 \note \c Object is always pass-by-value.
716 \note the source object is moved into this value and the sourec object becomes empty.
717 */
718 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) {
719 o.value_.data_ = Data();
720 o.value_.data_.f.flags = kObjectFlag;
721 }
722
723 //! Destructor.
724 /*! Need to destruct elements of array, members of object, or copy-string.
725 */
727 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
728 switch(data_.f.flags) {
729 case kArrayFlag:
730 {
731 GenericValue* e = GetElementsPointer();
732 for (GenericValue* v = e; v != e + data_.a.size; ++v)
733 v->~GenericValue();
734 Allocator::Free(e);
735 }
736 break;
737
738 case kObjectFlag:
739 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
740 m->~Member();
741 Allocator::Free(GetMembersPointer());
742 break;
743
744 case kCopyStringFlag:
745 Allocator::Free(const_cast<Ch*>(GetStringPointer()));
746 break;
747
748 default:
749 break; // Do nothing for other types.
750 }
751 }
752 }
753
754 //@}
755
756 //!@name Assignment operators
757 //@{
758
759 //! Assignment with move semantics.
760 /*! \param rhs Source of the assignment. It will become a null value after assignment.
761 */
762 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
763 RAPIDJSON_ASSERT(this != &rhs);
764 this->~GenericValue();
765 RawAssign(rhs);
766 return *this;
767 }
768
769#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
770 //! Move assignment in C++11
771 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
772 return *this = rhs.Move();
773 }
774#endif
775
776 //! Assignment of constant string reference (no copy)
777 /*! \param str Constant string reference to be assigned
778 \note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
779 \see GenericStringRef, operator=(T)
780 */
781 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
782 GenericValue s(str);
783 return *this = s;
784 }
785
786 //! Assignment with primitive types.
787 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
788 \param value The value to be assigned.
789
790 \note The source type \c T explicitly disallows all pointer types,
791 especially (\c const) \ref Ch*. This helps avoiding implicitly
792 referencing character strings with insufficient lifetime, use
793 \ref SetString(const Ch*, Allocator&) (for copying) or
794 \ref StringRef() (to explicitly mark the pointer as constant) instead.
795 All other pointer types would implicitly convert to \c bool,
796 use \ref SetBool() instead.
797 */
798 template <typename T>
799 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
800 operator=(T value) {
801 GenericValue v(value);
802 return *this = v;
803 }
804
805 //! Deep-copy assignment from Value
806 /*! Assigns a \b copy of the Value to the current Value object
807 \tparam SourceAllocator Allocator type of \c rhs
808 \param rhs Value to copy from (read-only)
809 \param allocator Allocator to use for copying
810 */
811 template <typename SourceAllocator>
813 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs));
814 this->~GenericValue();
815 new (this) GenericValue(rhs, allocator);
816 return *this;
817 }
818
819 //! Exchange the contents of this value with those of other.
820 /*!
821 \param other Another value.
822 \note Constant complexity.
823 */
824 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
825 GenericValue temp;
826 temp.RawAssign(*this);
827 RawAssign(other);
828 other.RawAssign(temp);
829 return *this;
830 }
831
832 //! free-standing swap function helper
833 /*!
834 Helper function to enable support for common swap implementation pattern based on \c std::swap:
835 \code
836 void swap(MyClass& a, MyClass& b) {
837 using std::swap;
838 swap(a.value, b.value);
839 // ...
840 }
841 \endcode
842 \see Swap()
843 */
844 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
845
846 //! Prepare Value for move semantics
847 /*! \return *this */
848 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
849 //@}
850
851 //!@name Equal-to and not-equal-to operators
852 //@{
853 //! Equal-to operator
854 /*!
855 \note If an object contains duplicated named member, comparing equality with any object is always \c false.
856 \note Linear time complexity (number of all values in the subtree and total lengths of all strings).
857 */
858 template <typename SourceAllocator>
861 if (GetType() != rhs.GetType())
862 return false;
863
864 switch (GetType()) {
865 case kObjectType: // Warning: O(n^2) inner-loop
866 if (data_.o.size != rhs.data_.o.size)
867 return false;
868 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
869 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
870 if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
871 return false;
872 }
873 return true;
874
875 case kArrayType:
876 if (data_.a.size != rhs.data_.a.size)
877 return false;
878 for (SizeType i = 0; i < data_.a.size; i++)
879 if ((*this)[i] != rhs[i])
880 return false;
881 return true;
882
883 case kStringType:
884 return StringEqual(rhs);
885
886 case kNumberType:
887 if (IsDouble() || rhs.IsDouble()) {
888 double a = GetDouble(); // May convert from integer to double.
889 double b = rhs.GetDouble(); // Ditto
890 return a >= b && a <= b; // Prevent -Wfloat-equal
891 }
892 else
893 return data_.n.u64 == rhs.data_.n.u64;
894
895 default:
896 return true;
897 }
898 }
899
900 //! Equal-to operator with const C-string pointer
901 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
902
903#if RAPIDJSON_HAS_STDSTRING
904 //! Equal-to operator with string object
905 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
906 */
907 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
908#endif
909
910 //! Equal-to operator with primitive types
911 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
912 */
913 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
914
915#ifndef __cpp_impl_three_way_comparison
916 //! Not-equal-to operator
917 /*! \return !(*this == rhs)
918 */
919 template <typename SourceAllocator>
920 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
921
922 //! Not-equal-to operator with const C-string pointer
923 bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
924
925 //! Not-equal-to operator with arbitrary types
926 /*! \return !(*this == rhs)
927 */
928 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
929
930 //! Equal-to operator with arbitrary types (symmetric version)
931 /*! \return (rhs == lhs)
932 */
933 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
934
935 //! Not-Equal-to operator with arbitrary types (symmetric version)
936 /*! \return !(rhs == lhs)
937 */
938 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
939 //@}
940#endif
941
942 //!@name Type
943 //@{
944
945 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); }
946 bool IsNull() const { return data_.f.flags == kNullFlag; }
947 bool IsFalse() const { return data_.f.flags == kFalseFlag; }
948 bool IsTrue() const { return data_.f.flags == kTrueFlag; }
949 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; }
950 bool IsObject() const { return data_.f.flags == kObjectFlag; }
951 bool IsArray() const { return data_.f.flags == kArrayFlag; }
952 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; }
953 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; }
954 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; }
955 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; }
956 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; }
957 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; }
958 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; }
959
960 // Checks whether a number can be losslessly converted to a double.
961 bool IsLosslessDouble() const {
962 if (!IsNumber()) return false;
963 if (IsUint64()) {
964 uint64_t u = GetUint64();
965 volatile double d = static_cast<double>(u);
966 return (d >= 0.0)
967 && (d < static_cast<double>(std::numeric_limits<uint64_t>::max()))
968 && (u == static_cast<uint64_t>(d));
969 }
970 if (IsInt64()) {
971 int64_t i = GetInt64();
972 volatile double d = static_cast<double>(i);
973 return (d >= static_cast<double>(std::numeric_limits<int64_t>::min()))
974 && (d < static_cast<double>(std::numeric_limits<int64_t>::max()))
975 && (i == static_cast<int64_t>(d));
976 }
977 return true; // double, int, uint are always lossless
978 }
979
980 // Checks whether a number is a float (possible lossy).
981 bool IsFloat() const {
982 if ((data_.f.flags & kDoubleFlag) == 0)
983 return false;
984 double d = GetDouble();
985 return d >= -3.4028234e38 && d <= 3.4028234e38;
986 }
987 // Checks whether a number can be losslessly converted to a float.
988 bool IsLosslessFloat() const {
989 if (!IsNumber()) return false;
990 double a = GetDouble();
991 if (a < static_cast<double>(-std::numeric_limits<float>::max())
992 || a > static_cast<double>(std::numeric_limits<float>::max()))
993 return false;
994 double b = static_cast<double>(static_cast<float>(a));
995 return a >= b && a <= b; // Prevent -Wfloat-equal
996 }
997
998 //@}
999
1000 //!@name Null
1001 //@{
1002
1003 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
1004
1005 //@}
1006
1007 //!@name Bool
1008 //@{
1009
1010 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; }
1011 //!< Set boolean value
1012 /*! \post IsBool() == true */
1013 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
1014
1015 //@}
1016
1017 //!@name Object
1018 //@{
1019
1020 //! Set this value as an empty object.
1021 /*! \post IsObject() == true */
1022 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
1023
1024 //! Get the number of members in the object.
1025 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
1026
1027 //! Check whether the object is empty.
1028 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
1029
1030 //! Get a value from an object associated with the name.
1031 /*! \pre IsObject() == true
1032 \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType))
1033 \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
1034 Since 0.2, if the name is not correct, it will assert.
1035 If user is unsure whether a member exists, user should use HasMember() first.
1036 A better approach is to use FindMember().
1037 \note Linear time complexity.
1038 */
1039 template <typename T>
1040 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
1041 GenericValue n(StringRef(name));
1042 return (*this)[n];
1043 }
1044 template <typename T>
1045 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]; }
1046
1047 //! Get a value from an object associated with the name.
1048 /*! \pre IsObject() == true
1049 \tparam SourceAllocator Allocator of the \c name value
1050
1051 \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen().
1052 And it can also handle strings with embedded null characters.
1053
1054 \note Linear time complexity.
1055 */
1056 template <typename SourceAllocator>
1058 MemberIterator member = FindMember(name);
1059 if (member != MemberEnd())
1060 return member->value;
1061 else {
1062 RAPIDJSON_ASSERT(false); // see above note
1063
1064 // This will generate -Wexit-time-destructors in clang
1065 // static GenericValue NullValue;
1066 // return NullValue;
1067
1068 // Use static buffer and placement-new to prevent destruction
1069 static char buffer[sizeof(GenericValue)];
1070 return *new (buffer) GenericValue();
1071 }
1072 }
1073 template <typename SourceAllocator>
1074 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
1075
1076#if RAPIDJSON_HAS_STDSTRING
1077 //! Get a value from an object associated with name (string object).
1078 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; }
1079 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; }
1080#endif
1081
1082 //! Const member iterator
1083 /*! \pre IsObject() == true */
1084 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); }
1085 //! Const \em past-the-end member iterator
1086 /*! \pre IsObject() == true */
1087 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); }
1088 //! Member iterator
1089 /*! \pre IsObject() == true */
1090 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); }
1091 //! \em Past-the-end member iterator
1092 /*! \pre IsObject() == true */
1093 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); }
1094
1095 //! Check whether a member exists in the object.
1096 /*!
1097 \param name Member name to be searched.
1098 \pre IsObject() == true
1099 \return Whether a member with that name exists.
1100 \note It is better to use FindMember() directly if you need the obtain the value as well.
1101 \note Linear time complexity.
1102 */
1103 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
1104
1105#if RAPIDJSON_HAS_STDSTRING
1106 //! Check whether a member exists in the object with string object.
1107 /*!
1108 \param name Member name to be searched.
1109 \pre IsObject() == true
1110 \return Whether a member with that name exists.
1111 \note It is better to use FindMember() directly if you need the obtain the value as well.
1112 \note Linear time complexity.
1113 */
1114 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); }
1115#endif
1116
1117 //! Check whether a member exists in the object with GenericValue name.
1118 /*!
1119 This version is faster because it does not need a StrLen(). It can also handle string with null character.
1120 \param name Member name to be searched.
1121 \pre IsObject() == true
1122 \return Whether a member with that name exists.
1123 \note It is better to use FindMember() directly if you need the obtain the value as well.
1124 \note Linear time complexity.
1125 */
1126 template <typename SourceAllocator>
1127 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
1128
1129 //! Find member by name.
1130 /*!
1131 \param name Member name to be searched.
1132 \pre IsObject() == true
1133 \return Iterator to member, if it exists.
1134 Otherwise returns \ref MemberEnd().
1135
1136 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
1137 the requested member doesn't exist. For consistency with e.g.
1138 \c std::map, this has been changed to MemberEnd() now.
1139 \note Linear time complexity.
1140 */
1142 GenericValue n(StringRef(name));
1143 return FindMember(n);
1144 }
1145
1146 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1147
1148 //! Find member by name.
1149 /*!
1150 This version is faster because it does not need a StrLen(). It can also handle string with null character.
1151 \param name Member name to be searched.
1152 \pre IsObject() == true
1153 \return Iterator to member, if it exists.
1154 Otherwise returns \ref MemberEnd().
1155
1156 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
1157 the requested member doesn't exist. For consistency with e.g.
1158 \c std::map, this has been changed to MemberEnd() now.
1159 \note Linear time complexity.
1160 */
1161 template <typename SourceAllocator>
1163 RAPIDJSON_ASSERT(IsObject());
1164 RAPIDJSON_ASSERT(name.IsString());
1165 MemberIterator member = MemberBegin();
1166 for ( ; member != MemberEnd(); ++member)
1167 if (name.StringEqual(member->name))
1168 break;
1169 return member;
1170 }
1171 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
1172
1173#if RAPIDJSON_HAS_STDSTRING
1174 //! Find member by string object name.
1175 /*!
1176 \param name Member name to be searched.
1177 \pre IsObject() == true
1178 \return Iterator to member, if it exists.
1179 Otherwise returns \ref MemberEnd().
1180 */
1181 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); }
1182 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); }
1183#endif
1184
1185 //! Add a member (name-value pair) to the object.
1186 /*! \param name A string value as name of member.
1187 \param value Value of any type.
1188 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1189 \return The value itself for fluent API.
1190 \note The ownership of \c name and \c value will be transferred to this object on success.
1191 \pre IsObject() && name.IsString()
1192 \post name.IsNull() && value.IsNull()
1193 \note Amortized Constant time complexity.
1194 */
1196 RAPIDJSON_ASSERT(IsObject());
1197 RAPIDJSON_ASSERT(name.IsString());
1198
1199 ObjectData& o = data_.o;
1200 if (o.size >= o.capacity) {
1201 if (o.capacity == 0) {
1202 o.capacity = kDefaultObjectCapacity;
1203 SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member))));
1204 }
1205 else {
1206 SizeType oldCapacity = o.capacity;
1207 o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
1208 SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member))));
1209 }
1210 }
1211 Member* members = GetMembersPointer();
1212 members[o.size].name.RawAssign(name);
1213 members[o.size].value.RawAssign(value);
1214 o.size++;
1215 return *this;
1216 }
1217
1218 //! Add a constant string value as member (name-value pair) to the object.
1219 /*! \param name A string value as name of member.
1220 \param value constant string reference as value of member.
1221 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1222 \return The value itself for fluent API.
1223 \pre IsObject()
1224 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
1225 \note Amortized Constant time complexity.
1226 */
1228 GenericValue v(value);
1229 return AddMember(name, v, allocator);
1230 }
1231
1232#if RAPIDJSON_HAS_STDSTRING
1233 //! Add a string object as member (name-value pair) to the object.
1234 /*! \param name A string value as name of member.
1235 \param value constant string reference as value of member.
1236 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1237 \return The value itself for fluent API.
1238 \pre IsObject()
1239 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below.
1240 \note Amortized Constant time complexity.
1241 */
1242 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) {
1243 GenericValue v(value, allocator);
1244 return AddMember(name, v, allocator);
1245 }
1246#endif
1247
1248 //! Add any primitive value as member (name-value pair) to the object.
1249 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1250 \param name A string value as name of member.
1251 \param value Value of primitive type \c T as value of member
1252 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1253 \return The value itself for fluent API.
1254 \pre IsObject()
1255
1256 \note The source type \c T explicitly disallows all pointer types,
1257 especially (\c const) \ref Ch*. This helps avoiding implicitly
1258 referencing character strings with insufficient lifetime, use
1259 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1260 AddMember(StringRefType, StringRefType, Allocator&).
1261 All other pointer types would implicitly convert to \c bool,
1262 use an explicit cast instead, if needed.
1263 \note Amortized Constant time complexity.
1264 */
1265 template <typename T>
1266 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1267 AddMember(GenericValue& name, T value, Allocator& allocator) {
1268 GenericValue v(value);
1269 return AddMember(name, v, allocator);
1270 }
1271
1272#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1273 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
1274 return AddMember(name, value, allocator);
1275 }
1276 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
1277 return AddMember(name, value, allocator);
1278 }
1279 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
1280 return AddMember(name, value, allocator);
1281 }
1282 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
1283 GenericValue n(name);
1284 return AddMember(n, value, allocator);
1285 }
1286#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1287
1288
1289 //! Add a member (name-value pair) to the object.
1290 /*! \param name A constant string reference as name of member.
1291 \param value Value of any type.
1292 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1293 \return The value itself for fluent API.
1294 \note The ownership of \c value will be transferred to this object on success.
1295 \pre IsObject()
1296 \post value.IsNull()
1297 \note Amortized Constant time complexity.
1298 */
1300 GenericValue n(name);
1301 return AddMember(n, value, allocator);
1302 }
1303
1304 //! Add a constant string value as member (name-value pair) to the object.
1305 /*! \param name A constant string reference as name of member.
1306 \param value constant string reference as value of member.
1307 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1308 \return The value itself for fluent API.
1309 \pre IsObject()
1310 \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.
1311 \note Amortized Constant time complexity.
1312 */
1314 GenericValue v(value);
1315 return AddMember(name, v, allocator);
1316 }
1317
1318 //! Add any primitive value as member (name-value pair) to the object.
1319 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1320 \param name A constant string reference as name of member.
1321 \param value Value of primitive type \c T as value of member
1322 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1323 \return The value itself for fluent API.
1324 \pre IsObject()
1325
1326 \note The source type \c T explicitly disallows all pointer types,
1327 especially (\c const) \ref Ch*. This helps avoiding implicitly
1328 referencing character strings with insufficient lifetime, use
1329 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1330 AddMember(StringRefType, StringRefType, Allocator&).
1331 All other pointer types would implicitly convert to \c bool,
1332 use an explicit cast instead, if needed.
1333 \note Amortized Constant time complexity.
1334 */
1335 template <typename T>
1336 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1337 AddMember(StringRefType name, T value, Allocator& allocator) {
1338 GenericValue n(name);
1339 return AddMember(n, value, allocator);
1340 }
1341
1342 //! Remove all members in the object.
1343 /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.
1344 \note Linear time complexity.
1345 */
1347 RAPIDJSON_ASSERT(IsObject());
1348 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1349 m->~Member();
1350 data_.o.size = 0;
1351 }
1352
1353 //! Remove a member in object by its name.
1354 /*! \param name Name of member to be removed.
1355 \return Whether the member existed.
1356 \note This function may reorder the object members. Use \ref
1357 EraseMember(ConstMemberIterator) if you need to preserve the
1358 relative order of the remaining members.
1359 \note Linear time complexity.
1360 */
1361 bool RemoveMember(const Ch* name) {
1362 GenericValue n(StringRef(name));
1363 return RemoveMember(n);
1364 }
1365
1366#if RAPIDJSON_HAS_STDSTRING
1367 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); }
1368#endif
1369
1370 template <typename SourceAllocator>
1371 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) {
1372 MemberIterator m = FindMember(name);
1373 if (m != MemberEnd()) {
1374 RemoveMember(m);
1375 return true;
1376 }
1377 else
1378 return false;
1379 }
1380
1381 //! Remove a member in object by iterator.
1382 /*! \param m member iterator (obtained by FindMember() or MemberBegin()).
1383 \return the new iterator after removal.
1384 \note This function may reorder the object members. Use \ref
1385 EraseMember(ConstMemberIterator) if you need to preserve the
1386 relative order of the remaining members.
1387 \note Constant time complexity.
1388 */
1390 RAPIDJSON_ASSERT(IsObject());
1391 RAPIDJSON_ASSERT(data_.o.size > 0);
1392 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1393 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1394
1395 MemberIterator last(GetMembersPointer() + (data_.o.size - 1));
1396 if (data_.o.size > 1 && m != last)
1397 *m = *last; // Move the last one to this place
1398 else
1399 m->~Member(); // Only one left, just destroy
1400 --data_.o.size;
1401 return m;
1402 }
1403
1404 //! Remove a member from an object by iterator.
1405 /*! \param pos iterator to the member to remove
1406 \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd()
1407 \return Iterator following the removed element.
1408 If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned.
1409 \note This function preserves the relative order of the remaining object
1410 members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator).
1411 \note Linear time complexity.
1412 */
1414 return EraseMember(pos, pos +1);
1415 }
1416
1417 //! Remove members in the range [first, last) from an object.
1418 /*! \param first iterator to the first member to remove
1419 \param last iterator following the last member to remove
1420 \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd()
1421 \return Iterator following the last removed element.
1422 \note This function preserves the relative order of the remaining object
1423 members.
1424 \note Linear time complexity.
1425 */
1427 RAPIDJSON_ASSERT(IsObject());
1428 RAPIDJSON_ASSERT(data_.o.size > 0);
1429 RAPIDJSON_ASSERT(GetMembersPointer() != 0);
1430 RAPIDJSON_ASSERT(first >= MemberBegin());
1431 RAPIDJSON_ASSERT(first <= last);
1432 RAPIDJSON_ASSERT(last <= MemberEnd());
1433
1434 MemberIterator pos = MemberBegin() + (first - MemberBegin());
1435 for (MemberIterator itr = pos; itr != last; ++itr)
1436 itr->~Member();
1437 std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member));
1438 data_.o.size -= static_cast<SizeType>(last - first);
1439 return pos;
1440 }
1441
1442 //! Erase a member in object by its name.
1443 /*! \param name Name of member to be removed.
1444 \return Whether the member existed.
1445 \note Linear time complexity.
1446 */
1447 bool EraseMember(const Ch* name) {
1448 GenericValue n(StringRef(name));
1449 return EraseMember(n);
1450 }
1451
1452#if RAPIDJSON_HAS_STDSTRING
1453 bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); }
1454#endif
1455
1456 template <typename SourceAllocator>
1457 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) {
1458 MemberIterator m = FindMember(name);
1459 if (m != MemberEnd()) {
1460 EraseMember(m);
1461 return true;
1462 }
1463 else
1464 return false;
1465 }
1466
1467 Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
1468 ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); }
1469
1470 //@}
1471
1472 //!@name Array
1473 //@{
1474
1475 //! Set this value as an empty array.
1476 /*! \post IsArray == true */
1477 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1478
1479 //! Get the number of elements in array.
1480 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1481
1482 //! Get the capacity of array.
1483 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1484
1485 //! Check whether the array is empty.
1486 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1487
1488 //! Remove all elements in the array.
1489 /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
1490 \note Linear time complexity.
1491 */
1492 void Clear() {
1493 RAPIDJSON_ASSERT(IsArray());
1494 GenericValue* e = GetElementsPointer();
1495 for (GenericValue* v = e; v != e + data_.a.size; ++v)
1496 v->~GenericValue();
1497 data_.a.size = 0;
1498 }
1499
1500 //! Get an element from array by index.
1501 /*! \pre IsArray() == true
1502 \param index Zero-based index of element.
1503 \see operator[](T*)
1504 */
1506 RAPIDJSON_ASSERT(IsArray());
1507 RAPIDJSON_ASSERT(index < data_.a.size);
1508 return GetElementsPointer()[index];
1509 }
1510 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1511
1512 //! Element iterator
1513 /*! \pre IsArray() == true */
1514 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); }
1515 //! \em Past-the-end element iterator
1516 /*! \pre IsArray() == true */
1517 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; }
1518 //! Constant element iterator
1519 /*! \pre IsArray() == true */
1520 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1521 //! Constant \em past-the-end element iterator
1522 /*! \pre IsArray() == true */
1523 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1524
1525 //! Request the array to have enough capacity to store elements.
1526 /*! \param newCapacity The capacity that the array at least need to have.
1527 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1528 \return The value itself for fluent API.
1529 \note Linear time complexity.
1530 */
1531 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1532 RAPIDJSON_ASSERT(IsArray());
1533 if (newCapacity > data_.a.capacity) {
1534 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue))));
1535 data_.a.capacity = newCapacity;
1536 }
1537 return *this;
1538 }
1539
1540 //! Append a GenericValue at the end of the array.
1541 /*! \param value Value to be appended.
1542 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1543 \pre IsArray() == true
1544 \post value.IsNull() == true
1545 \return The value itself for fluent API.
1546 \note The ownership of \c value will be transferred to this array on success.
1547 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1548 \note Amortized constant time complexity.
1549 */
1551 RAPIDJSON_ASSERT(IsArray());
1552 if (data_.a.size >= data_.a.capacity)
1553 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1554 GetElementsPointer()[data_.a.size++].RawAssign(value);
1555 return *this;
1556 }
1557
1558#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1559 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1560 return PushBack(value, allocator);
1561 }
1562#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1563
1564 //! Append a constant string reference at the end of the array.
1565 /*! \param value Constant string reference to be appended.
1566 \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().
1567 \pre IsArray() == true
1568 \return The value itself for fluent API.
1569 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1570 \note Amortized constant time complexity.
1571 \see GenericStringRef
1572 */
1574 return (*this).template PushBack<StringRefType>(value, allocator);
1575 }
1576
1577 //! Append a primitive value at the end of the array.
1578 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1579 \param value Value of primitive type T to be appended.
1580 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1581 \pre IsArray() == true
1582 \return The value itself for fluent API.
1583 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1584
1585 \note The source type \c T explicitly disallows all pointer types,
1586 especially (\c const) \ref Ch*. This helps avoiding implicitly
1587 referencing character strings with insufficient lifetime, use
1588 \ref PushBack(GenericValue&, Allocator&) or \ref
1589 PushBack(StringRefType, Allocator&).
1590 All other pointer types would implicitly convert to \c bool,
1591 use an explicit cast instead, if needed.
1592 \note Amortized constant time complexity.
1593 */
1594 template <typename T>
1595 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1596 PushBack(T value, Allocator& allocator) {
1597 GenericValue v(value);
1598 return PushBack(v, allocator);
1599 }
1600
1601 //! Remove the last element in the array.
1602 /*!
1603 \note Constant time complexity.
1604 */
1606 RAPIDJSON_ASSERT(IsArray());
1607 RAPIDJSON_ASSERT(!Empty());
1608 GetElementsPointer()[--data_.a.size].~GenericValue();
1609 return *this;
1610 }
1611
1612 //! Remove an element of array by iterator.
1613 /*!
1614 \param pos iterator to the element to remove
1615 \pre IsArray() == true && \ref Begin() <= \c pos < \ref End()
1616 \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.
1617 \note Linear time complexity.
1618 */
1620 return Erase(pos, pos + 1);
1621 }
1622
1623 //! Remove elements in the range [first, last) of the array.
1624 /*!
1625 \param first iterator to the first element to remove
1626 \param last iterator following the last element to remove
1627 \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End()
1628 \return Iterator following the last removed element.
1629 \note Linear time complexity.
1630 */
1632 RAPIDJSON_ASSERT(IsArray());
1633 RAPIDJSON_ASSERT(data_.a.size > 0);
1634 RAPIDJSON_ASSERT(GetElementsPointer() != 0);
1635 RAPIDJSON_ASSERT(first >= Begin());
1636 RAPIDJSON_ASSERT(first <= last);
1637 RAPIDJSON_ASSERT(last <= End());
1638 ValueIterator pos = Begin() + (first - Begin());
1639 for (ValueIterator itr = pos; itr != last; ++itr)
1640 itr->~GenericValue();
1641 std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue));
1642 data_.a.size -= static_cast<SizeType>(last - first);
1643 return pos;
1644 }
1645
1646 Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); }
1647 ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); }
1648
1649 //@}
1650
1651 //!@name Number
1652 //@{
1653
1654 int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; }
1655 unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; }
1656 int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; }
1657 uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; }
1658
1659 //! Get the value as double type.
1660 /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless.
1661 */
1662 double GetDouble() const {
1663 RAPIDJSON_ASSERT(IsNumber());
1664 if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1665 if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double
1666 if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1667 if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision)
1668 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision)
1669 }
1670
1671 //! Get the value as float type.
1672 /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless.
1673 */
1674 float GetFloat() const {
1675 return static_cast<float>(GetDouble());
1676 }
1677
1678 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1679 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1680 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1681 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1682 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1683 GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(f); return *this; }
1684
1685 //@}
1686
1687 //!@name String
1688 //@{
1689
1690 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); }
1691
1692 //! Get the length of string.
1693 /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
1694 */
1695 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1696
1697 //! Set this value as a string without copying source string.
1698 /*! This version has better performance with supplied length, and also support string containing null character.
1699 \param s source string pointer.
1700 \param length The length of source string, excluding the trailing null terminator.
1701 \return The value itself for fluent API.
1702 \post IsString() == true && GetString() == s && GetStringLength() == length
1703 \see SetString(StringRefType)
1704 */
1705 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1706
1707 //! Set this value as a string without copying source string.
1708 /*! \param s source string reference
1709 \return The value itself for fluent API.
1710 \post IsString() == true && GetString() == s && GetStringLength() == s.length
1711 */
1712 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1713
1714 //! Set this value as a string by copying from source string.
1715 /*! This version has better performance with supplied length, and also support string containing null character.
1716 \param s source string.
1717 \param length The length of source string, excluding the trailing null terminator.
1718 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1719 \return The value itself for fluent API.
1720 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1721 */
1722 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }
1723
1724 //! Set this value as a string by copying from source string.
1725 /*! \param s source string.
1726 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1727 \return The value itself for fluent API.
1728 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1729 */
1730 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }
1731
1732#if RAPIDJSON_HAS_STDSTRING
1733 //! Set this value as a string by copying from source string.
1734 /*! \param s source string.
1735 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1736 \return The value itself for fluent API.
1737 \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()
1738 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
1739 */
1740 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); }
1741#endif
1742
1743 //@}
1744
1745 //!@name Array
1746 //@{
1747
1748 //! Templated version for checking whether this value is type T.
1749 /*!
1750 \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>
1751 */
1752 template <typename T>
1753 bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); }
1754
1755 template <typename T>
1756 T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); }
1757
1758 template <typename T>
1759 T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); }
1760
1761 template<typename T>
1762 ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); }
1763
1764 template<typename T>
1765 ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); }
1766
1767 //@}
1768
1769 //! Generate events of this value to a Handler.
1770 /*! This function adopts the GoF visitor pattern.
1771 Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.
1772 It can also be used to deep clone this value via GenericDocument, which is also a Handler.
1773 \tparam Handler type of handler.
1774 \param handler An object implementing concept Handler.
1775 */
1776 template <typename Handler>
1777 bool Accept(Handler& handler) const {
1778 switch(GetType()) {
1779 case kNullType: return handler.Null();
1780 case kFalseType: return handler.Bool(false);
1781 case kTrueType: return handler.Bool(true);
1782
1783 case kObjectType:
1784 if (RAPIDJSON_UNLIKELY(!handler.StartObject()))
1785 return false;
1786 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1787 RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator.
1788 if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0)))
1789 return false;
1790 if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler)))
1791 return false;
1792 }
1793 return handler.EndObject(data_.o.size);
1794
1795 case kArrayType:
1796 if (RAPIDJSON_UNLIKELY(!handler.StartArray()))
1797 return false;
1798 for (const GenericValue* v = Begin(); v != End(); ++v)
1799 if (RAPIDJSON_UNLIKELY(!v->Accept(handler)))
1800 return false;
1801 return handler.EndArray(data_.a.size);
1802
1803 case kStringType:
1804 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0);
1805
1806 default:
1807 RAPIDJSON_ASSERT(GetType() == kNumberType);
1808 if (IsDouble()) return handler.Double(data_.n.d);
1809 else if (IsInt()) return handler.Int(data_.n.i.i);
1810 else if (IsUint()) return handler.Uint(data_.n.u.u);
1811 else if (IsInt64()) return handler.Int64(data_.n.i64);
1812 else return handler.Uint64(data_.n.u64);
1813 }
1814 }
1815
1816private:
1817 template <typename, typename> friend class GenericValue;
1818 template <typename, typename, typename> friend class GenericDocument;
1819
1820 enum {
1821 kBoolFlag = 0x0008,
1822 kNumberFlag = 0x0010,
1823 kIntFlag = 0x0020,
1824 kUintFlag = 0x0040,
1825 kInt64Flag = 0x0080,
1826 kUint64Flag = 0x0100,
1827 kDoubleFlag = 0x0200,
1828 kStringFlag = 0x0400,
1829 kCopyFlag = 0x0800,
1830 kInlineStrFlag = 0x1000,
1831
1832 // Initial flags of different types.
1833 kNullFlag = kNullType,
1834 kTrueFlag = kTrueType | kBoolFlag,
1835 kFalseFlag = kFalseType | kBoolFlag,
1836 kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
1837 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
1838 kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
1839 kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
1840 kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
1841 kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
1842 kConstStringFlag = kStringType | kStringFlag,
1843 kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
1844 kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
1845 kObjectFlag = kObjectType,
1846 kArrayFlag = kArrayType,
1847
1848 kTypeMask = 0x07
1849 };
1850
1851 static const SizeType kDefaultArrayCapacity = 16;
1852 static const SizeType kDefaultObjectCapacity = 16;
1853
1854 struct Flag {
1855#if RAPIDJSON_48BITPOINTER_OPTIMIZATION
1856 char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer
1857#elif RAPIDJSON_64BIT
1858 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes
1859#else
1860 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes
1861#endif
1862 uint16_t flags;
1863 };
1864
1865 struct String {
1866 SizeType length;
1867 SizeType hashcode; //!< reserved
1868 const Ch* str;
1869 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1870
1871 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1872 // (excluding the terminating zero) and store a value to determine the length of the contained
1873 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1874 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1875 // the string terminator as well. For getting the string length back from that value just use
1876 // "MaxSize - str[LenPos]".
1877 // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode,
1878 // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings).
1879 struct ShortString {
1880 enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
1881 Ch str[MaxChars];
1882
1883 inline static bool Usable(SizeType len) { return (MaxSize >= len); }
1884 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); }
1885 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); }
1886 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1887
1888 // By using proper binary layout, retrieval of different integer types do not need conversions.
1889 union Number {
1890#if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
1891 struct I {
1892 int i;
1893 char padding[4];
1894 }i;
1895 struct U {
1896 unsigned u;
1897 char padding2[4];
1898 }u;
1899#else
1900 struct I {
1901 char padding[4];
1902 int i;
1903 }i;
1904 struct U {
1905 char padding2[4];
1906 unsigned u;
1907 }u;
1908#endif
1909 int64_t i64;
1910 uint64_t u64;
1911 double d;
1912 }; // 8 bytes
1913
1914 struct ObjectData {
1915 SizeType size;
1916 SizeType capacity;
1917 Member* members;
1918 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1919
1920 struct ArrayData {
1921 SizeType size;
1922 SizeType capacity;
1923 GenericValue* elements;
1924 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1925
1926 union Data {
1927 String s;
1928 ShortString ss;
1929 Number n;
1930 ObjectData o;
1931 ArrayData a;
1932 Flag f;
1933 }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION
1934
1935 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); }
1936 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); }
1937 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); }
1938 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); }
1939 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); }
1940 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); }
1941
1942 // Initialize this value as array with initial data, without calling destructor.
1943 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
1944 data_.f.flags = kArrayFlag;
1945 if (count) {
1946 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue)));
1947 SetElementsPointer(e);
1948 std::memcpy(e, values, count * sizeof(GenericValue));
1949 }
1950 else
1951 SetElementsPointer(0);
1952 data_.a.size = data_.a.capacity = count;
1953 }
1954
1955 //! Initialize this value as object with initial data, without calling destructor.
1956 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
1957 data_.f.flags = kObjectFlag;
1958 if (count) {
1959 Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member)));
1960 SetMembersPointer(m);
1961 std::memcpy(m, members, count * sizeof(Member));
1962 }
1963 else
1964 SetMembersPointer(0);
1965 data_.o.size = data_.o.capacity = count;
1966 }
1967
1968 //! Initialize this value as constant string, without calling destructor.
1969 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
1970 data_.f.flags = kConstStringFlag;
1971 SetStringPointer(s);
1972 data_.s.length = s.length;
1973 }
1974
1975 //! Initialize this value as copy string with initial data, without calling destructor.
1976 void SetStringRaw(StringRefType s, Allocator& allocator) {
1977 Ch* str = 0;
1978 if (ShortString::Usable(s.length)) {
1979 data_.f.flags = kShortStringFlag;
1980 data_.ss.SetLength(s.length);
1981 str = data_.ss.str;
1982 } else {
1983 data_.f.flags = kCopyStringFlag;
1984 data_.s.length = s.length;
1985 str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch)));
1986 SetStringPointer(str);
1987 }
1988 std::memcpy(str, s, s.length * sizeof(Ch));
1989 str[s.length] = '\0';
1990 }
1991
1992 //! Assignment without calling destructor
1993 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
1994 data_ = rhs.data_;
1995 // data_.f.flags = rhs.data_.f.flags;
1996 rhs.data_.f.flags = kNullFlag;
1997 }
1998
1999 template <typename SourceAllocator>
2000 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
2001 RAPIDJSON_ASSERT(IsString());
2002 RAPIDJSON_ASSERT(rhs.IsString());
2003
2004 const SizeType len1 = GetStringLength();
2005 const SizeType len2 = rhs.GetStringLength();
2006 if(len1 != len2) { return false; }
2007
2008 const Ch* const str1 = GetString();
2009 const Ch* const str2 = rhs.GetString();
2010 if(str1 == str2) { return true; } // fast path for constant string
2011
2012 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
2013 }
2014
2015 Data data_;
2016};
2017
2018//! GenericValue with UTF8 encoding
2020
2021///////////////////////////////////////////////////////////////////////////////
2022// GenericDocument
2023
2024//! A document for parsing JSON text as DOM.
2025/*!
2026 \note implements Handler concept
2027 \tparam Encoding Encoding for both parsing and string storage.
2028 \tparam Allocator Allocator for allocating memory for the DOM
2029 \tparam StackAllocator Allocator for allocating memory for stack during parsing.
2030 \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.
2031*/
2032template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
2033class GenericDocument : public GenericValue<Encoding, Allocator> {
2034public:
2035 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
2036 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
2037 typedef Allocator AllocatorType; //!< Allocator type from template parameter.
2038
2039 //! Constructor
2040 /*! Creates an empty document of specified type.
2041 \param type Mandatory type of object to create.
2042 \param allocator Optional allocator for allocating memory.
2043 \param stackCapacity Optional initial capacity of stack in bytes.
2044 \param stackAllocator Optional allocator for allocating memory for stack.
2045 */
2046 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2047 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2048 {
2049 if (!allocator_)
2050 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
2051 }
2052
2053 //! Constructor
2054 /*! Creates an empty document which type is Null.
2055 \param allocator Optional allocator for allocating memory.
2056 \param stackCapacity Optional initial capacity of stack in bytes.
2057 \param stackAllocator Optional allocator for allocating memory for stack.
2058 */
2059 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
2060 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
2061 {
2062 if (!allocator_)
2063 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
2064 }
2065
2066#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2067 //! Move constructor in C++11
2068 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2069 : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document
2070 allocator_(rhs.allocator_),
2071 ownAllocator_(rhs.ownAllocator_),
2072 stack_(std::move(rhs.stack_)),
2073 parseResult_(rhs.parseResult_)
2074 {
2075 rhs.allocator_ = 0;
2076 rhs.ownAllocator_ = 0;
2077 rhs.parseResult_ = ParseResult();
2078 }
2079#endif
2080
2081 ~GenericDocument() {
2082 Destroy();
2083 }
2084
2085#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2086 //! Move assignment in C++11
2087 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
2088 {
2089 // The cast to ValueType is necessary here, because otherwise it would
2090 // attempt to call GenericValue's templated assignment operator.
2091 ValueType::operator=(std::forward<ValueType>(rhs));
2092
2093 // Calling the destructor here would prematurely call stack_'s destructor
2094 Destroy();
2095
2096 allocator_ = rhs.allocator_;
2097 ownAllocator_ = rhs.ownAllocator_;
2098 stack_ = std::move(rhs.stack_);
2099 parseResult_ = rhs.parseResult_;
2100
2101 rhs.allocator_ = 0;
2102 rhs.ownAllocator_ = 0;
2103 rhs.parseResult_ = ParseResult();
2104
2105 return *this;
2106 }
2107#endif
2108
2109 //! Exchange the contents of this document with those of another.
2110 /*!
2111 \param rhs Another document.
2112 \note Constant complexity.
2113 \see GenericValue::Swap
2114 */
2115 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT {
2116 ValueType::Swap(rhs);
2117 stack_.Swap(rhs.stack_);
2118 internal::Swap(allocator_, rhs.allocator_);
2119 internal::Swap(ownAllocator_, rhs.ownAllocator_);
2120 internal::Swap(parseResult_, rhs.parseResult_);
2121 return *this;
2122 }
2123
2124 //! free-standing swap function helper
2125 /*!
2126 Helper function to enable support for common swap implementation pattern based on \c std::swap:
2127 \code
2128 void swap(MyClass& a, MyClass& b) {
2129 using std::swap;
2130 swap(a.doc, b.doc);
2131 // ...
2132 }
2133 \endcode
2134 \see Swap()
2135 */
2136 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); }
2137
2138 //! Populate this document by a generator which produces SAX events.
2139 /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype.
2140 \param g Generator functor which sends SAX events to the parameter.
2141 \return The document itself for fluent API.
2142 */
2143 template <typename Generator>
2144 GenericDocument& Populate(Generator& g) {
2145 ClearStackOnExit scope(*this);
2146 if (g(*this)) {
2147 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2148 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2149 }
2150 return *this;
2151 }
2152
2153 //!@name Parse from stream
2154 //!@{
2155
2156 //! Parse JSON text from an input stream (with Encoding conversion)
2157 /*! \tparam parseFlags Combination of \ref ParseFlag.
2158 \tparam SourceEncoding Encoding of input stream
2159 \tparam InputStream Type of input stream, implementing Stream concept
2160 \param is Input stream to be parsed.
2161 \return The document itself for fluent API.
2162 */
2163 template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
2164 GenericDocument& ParseStream(InputStream& is) {
2166 stack_.HasAllocator() ? &stack_.GetAllocator() : 0);
2167 ClearStackOnExit scope(*this);
2168 parseResult_ = reader.template Parse<parseFlags>(is, *this);
2169 if (parseResult_) {
2170 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
2171 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document
2172 }
2173 return *this;
2174 }
2175
2176 //! Parse JSON text from an input stream
2177 /*! \tparam parseFlags Combination of \ref ParseFlag.
2178 \tparam InputStream Type of input stream, implementing Stream concept
2179 \param is Input stream to be parsed.
2180 \return The document itself for fluent API.
2181 */
2182 template <unsigned parseFlags, typename InputStream>
2183 GenericDocument& ParseStream(InputStream& is) {
2184 return ParseStream<parseFlags, Encoding, InputStream>(is);
2185 }
2186
2187 //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
2188 /*! \tparam InputStream Type of input stream, implementing Stream concept
2189 \param is Input stream to be parsed.
2190 \return The document itself for fluent API.
2191 */
2192 template <typename InputStream>
2193 GenericDocument& ParseStream(InputStream& is) {
2194 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
2195 }
2196 //!@}
2197
2198 //!@name Parse in-place from mutable string
2199 //!@{
2200
2201 //! Parse JSON text from a mutable string
2202 /*! \tparam parseFlags Combination of \ref ParseFlag.
2203 \param str Mutable zero-terminated string to be parsed.
2204 \return The document itself for fluent API.
2205 */
2206 template <unsigned parseFlags>
2209 return ParseStream<parseFlags | kParseInsituFlag>(s);
2210 }
2211
2212 //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
2213 /*! \param str Mutable zero-terminated string to be parsed.
2214 \return The document itself for fluent API.
2215 */
2217 return ParseInsitu<kParseDefaultFlags>(str);
2218 }
2219 //!@}
2220
2221 //!@name Parse from read-only string
2222 //!@{
2223
2224 //! Parse JSON text from a read-only string (with Encoding conversion)
2225 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2226 \tparam SourceEncoding Transcoding from input Encoding
2227 \param str Read-only zero-terminated string to be parsed.
2228 */
2229 template <unsigned parseFlags, typename SourceEncoding>
2230 GenericDocument& Parse(const typename SourceEncoding::Ch* str) {
2231 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2233 return ParseStream<parseFlags, SourceEncoding>(s);
2234 }
2235
2236 //! Parse JSON text from a read-only string
2237 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
2238 \param str Read-only zero-terminated string to be parsed.
2239 */
2240 template <unsigned parseFlags>
2241 GenericDocument& Parse(const Ch* str) {
2242 return Parse<parseFlags, Encoding>(str);
2243 }
2244
2245 //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
2246 /*! \param str Read-only zero-terminated string to be parsed.
2247 */
2248 GenericDocument& Parse(const Ch* str) {
2249 return Parse<kParseDefaultFlags>(str);
2250 }
2251
2252 template <unsigned parseFlags, typename SourceEncoding>
2253 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) {
2254 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
2255 MemoryStream ms(static_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch));
2257 ParseStream<parseFlags, SourceEncoding>(is);
2258 return *this;
2259 }
2260
2261 template <unsigned parseFlags>
2262 GenericDocument& Parse(const Ch* str, size_t length) {
2263 return Parse<parseFlags, Encoding>(str, length);
2264 }
2265
2266 GenericDocument& Parse(const Ch* str, size_t length) {
2267 return Parse<kParseDefaultFlags>(str, length);
2268 }
2269
2270#if RAPIDJSON_HAS_STDSTRING
2271 template <unsigned parseFlags, typename SourceEncoding>
2272 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) {
2273 // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t)
2274 return Parse<parseFlags, SourceEncoding>(str.c_str());
2275 }
2276
2277 template <unsigned parseFlags>
2278 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2279 return Parse<parseFlags, Encoding>(str.c_str());
2280 }
2281
2282 GenericDocument& Parse(const std::basic_string<Ch>& str) {
2283 return Parse<kParseDefaultFlags>(str);
2284 }
2285#endif // RAPIDJSON_HAS_STDSTRING
2286
2287 //!@}
2288
2289 //!@name Handling parse errors
2290 //!@{
2291
2292 //! Whether a parse error has occured in the last parsing.
2293 bool HasParseError() const { return parseResult_.IsError(); }
2294
2295 //! Get the \ref ParseErrorCode of last parsing.
2296 ParseErrorCode GetParseError() const { return parseResult_.Code(); }
2297
2298 //! Get the position of last parsing error in input, 0 otherwise.
2299 size_t GetErrorOffset() const { return parseResult_.Offset(); }
2300
2301 //! Implicit conversion to get the last parse result
2302#ifndef __clang // -Wdocumentation
2303 /*! \return \ref ParseResult of the last parse operation
2304
2305 \code
2306 Document doc;
2307 ParseResult ok = doc.Parse(json);
2308 if (!ok)
2309 printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset());
2310 \endcode
2311 */
2312#endif
2313 operator ParseResult() const { return parseResult_; }
2314 //!@}
2315
2316 //! Get the allocator of this document.
2318 RAPIDJSON_ASSERT(allocator_);
2319 return *allocator_;
2320 }
2321
2322 //! Get the capacity of stack in bytes.
2323 size_t GetStackCapacity() const { return stack_.GetCapacity(); }
2324
2325private:
2326 // clear stack on any exit from ParseStream, e.g. due to exception
2327 struct ClearStackOnExit {
2328 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
2329 ~ClearStackOnExit() { d_.ClearStack(); }
2330 private:
2331 ClearStackOnExit(const ClearStackOnExit&);
2332 ClearStackOnExit& operator=(const ClearStackOnExit&);
2333 GenericDocument& d_;
2334 };
2335
2336 // callers of the following private Handler functions
2337 // template <typename,typename,typename> friend class GenericReader; // for parsing
2338 template <typename, typename> friend class GenericValue; // for deep copying
2339
2340public:
2341 // Implementation of Handler
2342 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
2343 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
2344 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2345 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2346 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2347 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
2348 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
2349
2350 bool RawNumber(const Ch* str, SizeType length, bool copy) {
2351 if (copy)
2352 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2353 else
2354 new (stack_.template Push<ValueType>()) ValueType(str, length);
2355 return true;
2356 }
2357
2358 bool String(const Ch* str, SizeType length, bool copy) {
2359 if (copy)
2360 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
2361 else
2362 new (stack_.template Push<ValueType>()) ValueType(str, length);
2363 return true;
2364 }
2365
2366 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
2367
2368 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
2369
2370 bool EndObject(SizeType memberCount) {
2371 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
2372 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator());
2373 return true;
2374 }
2375
2376 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
2377
2378 bool EndArray(SizeType elementCount) {
2379 ValueType* elements = stack_.template Pop<ValueType>(elementCount);
2380 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
2381 return true;
2382 }
2383
2384private:
2385 //! Prohibit copying
2386 GenericDocument(const GenericDocument&);
2387 //! Prohibit assignment
2388 GenericDocument& operator=(const GenericDocument&);
2389
2390 void ClearStack() {
2391 if (Allocator::kNeedFree)
2392 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
2393 (stack_.template Pop<ValueType>(1))->~ValueType();
2394 else
2395 stack_.Clear();
2396 stack_.ShrinkToFit();
2397 }
2398
2399 void Destroy() {
2400 RAPIDJSON_DELETE(ownAllocator_);
2401 }
2402
2403 static const size_t kDefaultStackCapacity = 1024;
2404 Allocator* allocator_;
2405 Allocator* ownAllocator_;
2406 internal::Stack<StackAllocator> stack_;
2407 ParseResult parseResult_;
2408};
2409
2410//! GenericDocument with UTF8 encoding
2412
2413// defined here due to the dependency on GenericDocument
2414template <typename Encoding, typename Allocator>
2415template <typename SourceAllocator>
2416inline
2418{
2419 switch (rhs.GetType()) {
2420 case kObjectType:
2421 case kArrayType: { // perform deep copy via SAX Handler
2423 rhs.Accept(d);
2424 RawAssign(*d.stack_.template Pop<GenericValue>(1));
2425 }
2426 break;
2427 case kStringType:
2428 if (rhs.data_.f.flags == kConstStringFlag) {
2429 data_.f.flags = rhs.data_.f.flags;
2430 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
2431 } else {
2432 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator);
2433 }
2434 break;
2435 default:
2436 data_.f.flags = rhs.data_.f.flags;
2437 data_ = *reinterpret_cast<const Data*>(&rhs.data_);
2438 break;
2439 }
2440}
2441
2442//! Helper class for accessing Value of array type.
2443/*!
2444 Instance of this helper class is obtained by \c GenericValue::GetArray().
2445 In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2446*/
2447template <bool Const, typename ValueT>
2449public:
2452 typedef ValueT PlainType;
2453 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2454 typedef ValueType* ValueIterator; // This may be const or non-const iterator
2455 typedef const ValueT* ConstValueIterator;
2456 typedef typename ValueType::AllocatorType AllocatorType;
2457 typedef typename ValueType::StringRefType StringRefType;
2458
2459 template <typename, typename>
2460 friend class GenericValue;
2461
2462 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {}
2463 GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; }
2464 ~GenericArray() {}
2465
2466 SizeType Size() const { return value_.Size(); }
2467 SizeType Capacity() const { return value_.Capacity(); }
2468 bool Empty() const { return value_.Empty(); }
2469 void Clear() const { value_.Clear(); }
2470 ValueType& operator[](SizeType index) const { return value_[index]; }
2471 ValueIterator Begin() const { return value_.Begin(); }
2472 ValueIterator End() const { return value_.End(); }
2473 GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; }
2474 GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2475#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2476 GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2477#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2478 GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; }
2479 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; }
2480 GenericArray PopBack() const { value_.PopBack(); return *this; }
2481 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); }
2482 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); }
2483
2484#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2485 ValueIterator begin() const { return value_.Begin(); }
2486 ValueIterator end() const { return value_.End(); }
2487#endif
2488
2489private:
2490 GenericArray();
2491 GenericArray(ValueType& value) : value_(value) {}
2492 ValueType& value_;
2493};
2494
2495//! Helper class for accessing Value of object type.
2496/*!
2497 Instance of this helper class is obtained by \c GenericValue::GetObject().
2498 In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1.
2499*/
2500template <bool Const, typename ValueT>
2502public:
2505 typedef ValueT PlainType;
2506 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
2509 typedef typename ValueType::AllocatorType AllocatorType;
2510 typedef typename ValueType::StringRefType StringRefType;
2511 typedef typename ValueType::EncodingType EncodingType;
2512 typedef typename ValueType::Ch Ch;
2513
2514 template <typename, typename>
2515 friend class GenericValue;
2516
2517 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {}
2518 GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; }
2519 ~GenericObject() {}
2520
2521 SizeType MemberCount() const { return value_.MemberCount(); }
2522 bool ObjectEmpty() const { return value_.ObjectEmpty(); }
2523 template <typename T> ValueType& operator[](T* name) const { return value_[name]; }
2524 template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; }
2525#if RAPIDJSON_HAS_STDSTRING
2526 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; }
2527#endif
2528 MemberIterator MemberBegin() const { return value_.MemberBegin(); }
2529 MemberIterator MemberEnd() const { return value_.MemberEnd(); }
2530 bool HasMember(const Ch* name) const { return value_.HasMember(name); }
2531#if RAPIDJSON_HAS_STDSTRING
2532 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); }
2533#endif
2534 template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); }
2535 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); }
2536 template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); }
2537#if RAPIDJSON_HAS_STDSTRING
2538 MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); }
2539#endif
2540 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2541 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2542#if RAPIDJSON_HAS_STDSTRING
2543 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2544#endif
2545 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; }
2546#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
2547 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2548 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2549 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2550 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2551#endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
2552 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2553 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; }
2554 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; }
2555 void RemoveAllMembers() { return value_.RemoveAllMembers(); }
2556 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); }
2557#if RAPIDJSON_HAS_STDSTRING
2558 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); }
2559#endif
2560 template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); }
2561 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); }
2562 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); }
2563 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); }
2564 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); }
2565#if RAPIDJSON_HAS_STDSTRING
2566 bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); }
2567#endif
2568 template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); }
2569
2570#if RAPIDJSON_HAS_CXX11_RANGE_FOR
2571 MemberIterator begin() const { return value_.MemberBegin(); }
2572 MemberIterator end() const { return value_.MemberEnd(); }
2573#endif
2574
2575private:
2576 GenericObject();
2577 GenericObject(ValueType& value) : value_(value) {}
2578 ValueType& value_;
2579};
2580
2581RAPIDJSON_NAMESPACE_END
2582RAPIDJSON_DIAG_POP
2583
2584#endif // RAPIDJSON_DOCUMENT_H_
Concept for allocating, resizing and freeing memory block.
Input byte stream wrapper with a statically bound encoding.
Definition: encodedstream.h:39
Concept for encoding of Unicode characters.
Helper class for accessing Value of array type.
Definition: document.h:2448
A document for parsing JSON text as DOM.
Definition: document.h:2033
GenericDocument & Populate(Generator &g)
Populate this document by a generator which produces SAX events.
Definition: document.h:2144
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:2317
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:2216
friend void swap(GenericDocument &a, GenericDocument &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:2136
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:2323
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:2183
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:2036
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:2037
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:2164
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: document.h:2293
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2059
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:2035
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:2193
GenericDocument(Type type, Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:2046
GenericDocument & Parse(const typename SourceEncoding::Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:2230
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:2296
GenericDocument & Swap(GenericDocument &rhs) RAPIDJSON_NOEXCEPT
Exchange the contents of this document with those of another.
Definition: document.h:2115
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:2207
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:2248
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:2299
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:2241
(Constant) member iterator for a JSON object value
Definition: document.h:106
BaseType::pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:124
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:121
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:117
BaseType::difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:128
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:119
BaseType::reference Reference
Reference to (const) GenericMember.
Definition: document.h:126
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:152
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:194
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:134
Helper class for accessing Value of object type.
Definition: document.h:2501
Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
Definition: pointer.h:81
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:466
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:547
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:550
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:551
GenericValue & SetString(const Ch *s, Allocator &allocator)
Set this value as a string by copying from source string.
Definition: document.h:1730
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:557
ConstValueIterator Begin() const
Constant element iterator.
Definition: document.h:1520
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:781
MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last)
Remove members in the range [first, last) from an object.
Definition: document.h:1426
MemberIterator EraseMember(ConstMemberIterator pos)
Remove a member from an object by iterator.
Definition: document.h:1413
GenericValue & SetObject()
Set this value as an empty object.
Definition: document.h:1022
SizeType GetStringLength() const
Get the length of string.
Definition: document.h:1695
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:668
bool ObjectEmpty() const
Check whether the object is empty.
Definition: document.h:1028
GenericValue & SetString(StringRefType s)
Set this value as a string without copying source string.
Definition: document.h:1712
MemberIterator FindMember(const std::basic_string< Ch > &name)
Find member by string object name.
Definition: document.h:1181
ConstMemberIterator MemberEnd() const
Const past-the-end member iterator.
Definition: document.h:1087
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:762
GenericValue & Move() RAPIDJSON_NOEXCEPT
Prepare Value for move semantics.
Definition: document.h:848
GenericValue & PushBack(GenericValue &value, Allocator &allocator)
Append a GenericValue at the end of the array.
Definition: document.h:1550
~GenericValue()
Destructor.
Definition: document.h:726
GenericValue & AddMember(GenericValue &name, GenericValue &value, Allocator &allocator)
Add a member (name-value pair) to the object.
Definition: document.h:1195
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:647
GenericValue & CopyFrom(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator)
Deep-copy assignment from Value.
Definition: document.h:812
GenericValue & Reserve(SizeType newCapacity, Allocator &allocator)
Request the array to have enough capacity to store elements.
Definition: document.h:1531
GenericValue & SetArray()
Set this value as an empty array.
Definition: document.h:1477
GenericValue & PopBack()
Remove the last element in the array.
Definition: document.h:1605
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:683
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:554
float GetFloat() const
Get the value as float type.
Definition: document.h:1674
friend void swap(GenericValue &a, GenericValue &b) RAPIDJSON_NOEXCEPT
free-standing swap function helper
Definition: document.h:844
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:552
GenericValue & SetBool(bool b)
Definition: document.h:1013
GenericValue & Swap(GenericValue &other) RAPIDJSON_NOEXCEPT
Exchange the contents of this value with those of other.
Definition: document.h:824
GenericValue & AddMember(StringRefType name, StringRefType value, Allocator &allocator)
Add a constant string value as member (name-value pair) to the object.
Definition: document.h:1313
GenericValue(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator)
Explicit copy constructor (with allocator)
Definition: document.h:2417
bool operator!=(const Ch *rhs) const
Not-equal-to operator with const C-string pointer.
Definition: document.h:923
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:599
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:686
ValueIterator Erase(ConstValueIterator pos)
Remove an element of array by iterator.
Definition: document.h:1619
void RemoveAllMembers()
Remove all members in the object.
Definition: document.h:1346
GenericValue & AddMember(StringRefType name, GenericValue &value, Allocator &allocator)
Add a member (name-value pair) to the object.
Definition: document.h:1299
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:556
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:680
GenericValue(Array a) RAPIDJSON_NOEXCEPT
Constructor for Array.
Definition: document.h:707
bool GetBool() const
Set boolean value.
Definition: document.h:1010
bool HasMember(const GenericValue< Encoding, SourceAllocator > &name) const
Check whether a member exists in the object with GenericValue name.
Definition: document.h:1127
SizeType Size() const
Get the number of elements in array.
Definition: document.h:1480
SizeType Capacity() const
Get the capacity of array.
Definition: document.h:1483
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:692
GenericValue(const std::basic_string< Ch > &s, Allocator &allocator)
Constructor for copy-string from a string object (i.e. do make a copy of string)
Definition: document.h:698
GenericValue(Object o) RAPIDJSON_NOEXCEPT
Constructor for Object.
Definition: document.h:718
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:558
GenericValue & operator[](const GenericValue< Encoding, SourceAllocator > &name)
Get a value from an object associated with the name.
Definition: document.h:1057
GenericValue & PushBack(StringRefType value, Allocator &allocator)
Append a constant string reference at the end of the array.
Definition: document.h:1573
SizeType MemberCount() const
Get the number of members in the object.
Definition: document.h:1025
ValueIterator Begin()
Element iterator.
Definition: document.h:1514
MemberIterator FindMember(const GenericValue< Encoding, SourceAllocator > &name)
Find member by name.
Definition: document.h:1162
ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)
Remove elements in the range [first, last) of the array.
Definition: document.h:1631
MemberIterator MemberBegin()
Member iterator.
Definition: document.h:1090
bool HasMember(const std::basic_string< Ch > &name) const
Check whether a member exists in the object with string object.
Definition: document.h:1114
double GetDouble() const
Get the value as double type.
Definition: document.h:1662
GenericValue & operator[](const std::basic_string< Ch > &name)
Get a value from an object associated with name (string object).
Definition: document.h:1078
void Clear()
Remove all elements in the array.
Definition: document.h:1492
bool RemoveMember(const Ch *name)
Remove a member in object by its name.
Definition: document.h:1361
bool HasMember(const Ch *name) const
Check whether a member exists in the object.
Definition: document.h:1103
friend bool operator==(const T &lhs, const GenericValue &rhs)
Equal-to operator with arbitrary types (symmetric version)
Definition: document.h:933
bool operator==(const T &rhs) const
Equal-to operator with primitive types.
Definition: document.h:913
ValueIterator End()
Past-the-end element iterator
Definition: document.h:1517
GenericValue & AddMember(GenericValue &name, std::basic_string< Ch > &value, Allocator &allocator)
Add a string object as member (name-value pair) to the object.
Definition: document.h:1242
bool operator==(const GenericValue< Encoding, SourceAllocator > &rhs) const
Equal-to operator.
Definition: document.h:859
GenericValue & SetString(const Ch *s, SizeType length)
Set this value as a string without copying source string.
Definition: document.h:1705
GenericValue(bool b) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:632
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:641
ConstValueIterator End() const
Constant past-the-end element iterator.
Definition: document.h:1523
bool EraseMember(const Ch *name)
Erase a member in object by its name.
Definition: document.h:1447
GenericValue & operator[](T *name)
Get a value from an object associated with the name.
Definition: document.h:1040
GenericValue & operator[](SizeType index)
Get an element from array by index.
Definition: document.h:1505
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:555
bool Is() const
Templated version for checking whether this value is type T.
Definition: document.h:1753
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:653
bool Empty() const
Check whether the array is empty.
Definition: document.h:1486
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:569
MemberIterator FindMember(const Ch *name)
Find member by name.
Definition: document.h:1141
GenericValue< Encoding, Allocator > ValueType
Value type of itself.
Definition: document.h:559
bool Accept(Handler &handler) const
Generate events of this value to a Handler.
Definition: document.h:1777
bool operator!=(const GenericValue< Encoding, SourceAllocator > &rhs) const
Not-equal-to operator.
Definition: document.h:920
GenericValue & SetString(const Ch *s, SizeType length, Allocator &allocator)
Set this value as a string by copying from source string.
Definition: document.h:1722
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:689
MemberIterator MemberEnd()
Past-the-end member iterator
Definition: document.h:1093
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:553
friend bool operator!=(const T &lhs, const GenericValue &rhs)
Not-Equal-to operator with arbitrary types (symmetric version)
Definition: document.h:938
bool operator!=(const T &rhs) const
Not-equal-to operator with arbitrary types.
Definition: document.h:928
GenericValue & SetString(const std::basic_string< Ch > &s, Allocator &allocator)
Set this value as a string by copying from source string.
Definition: document.h:1740
ConstMemberIterator MemberBegin() const
Const member iterator.
Definition: document.h:1084
GenericValue & AddMember(GenericValue &name, StringRefType value, Allocator &allocator)
Add a constant string value as member (name-value pair) to the object.
Definition: document.h:1227
bool operator==(const Ch *rhs) const
Equal-to operator with const C-string pointer.
Definition: document.h:901
bool operator==(const std::basic_string< Ch > &rhs) const
Equal-to operator with string object.
Definition: document.h:907
MemberIterator RemoveMember(MemberIterator m)
Remove a member in object by iterator.
Definition: document.h:1389
Concept for receiving events from GenericReader upon parsing. The functions return true if no error o...
#define RAPIDJSON_UNLIKELY(x)
Compiler branching hint for expression with low probability to be true.
Definition: rapidjson.h:468
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:402
ParseErrorCode
Error code of parsing.
Definition: error.h:64
Result of parsing (wraps ParseErrorCode)
Definition: error.h:106
GenericPointer< Value, CrtAllocator > Pointer
GenericPointer for Value (UTF-8, default allocator).
Definition: fwd.h:128
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:380
@ kParseInsituFlag
In-situ(destructive) parsing.
Definition: reader.h:147
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2019
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2411
Type
Type of JSON value.
Definition: rapidjson.h:603
@ kArrayType
array
Definition: rapidjson.h:608
@ kTrueType
true
Definition: rapidjson.h:606
@ kNullType
null
Definition: rapidjson.h:604
@ kFalseType
false
Definition: rapidjson.h:605
@ kNumberType
number
Definition: rapidjson.h:610
@ kObjectType
object
Definition: rapidjson.h:607
@ kStringType
string
Definition: rapidjson.h:609
GenericStringRef< CharType > StringRef(const std::basic_string< CharType > &str)
Mark a string object as constant string.
Definition: document.h:391
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:590
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:289
#define RAPIDJSON_NEW(x)
! customization point for global new
Definition: rapidjson.h:586
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:437
A read-write string stream.
Definition: stream.h:144
Name-value pair in a JSON object value.
Definition: document.h:74
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:76
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:75
Reference to a constant string (not taking a copy)
Definition: document.h:256
const Ch *const s
plain CharType pointer
Definition: document.h:329
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:309
GenericStringRef< CharType > StringRef(const CharType *str, size_t length)
Mark a character pointer as constant string.
Definition: document.h:373
CharType Ch
character type of the string
Definition: document.h:257
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:353
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:285
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:321
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:330
GenericStringRef< CharType > StringRef(const std::basic_string< CharType > &str)
Mark a string object as constant string.
Definition: document.h:391
Read-only string stream.
Definition: stream.h:110
Definition: document.h:1900
Definition: document.h:1904
Represents an in-memory input byte stream.
Definition: memorystream.h:40