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