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