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