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