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