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