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