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