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