All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
document.h
Go to the documentation of this file.
1 // Copyright (C) 2011 Milo Yip
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 #ifndef RAPIDJSON_DOCUMENT_H_
22 #define RAPIDJSON_DOCUMENT_H_
23 
24 /*! \file document.h */
25 
26 #include "reader.h"
27 #include "internal/meta.h"
28 #include "internal/strfunc.h"
29 #include <new> // placement new
30 
31 #ifdef _MSC_VER
32 RAPIDJSON_DIAG_PUSH
33 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
34 #elif defined(__GNUC__)
35 RAPIDJSON_DIAG_PUSH
36 RAPIDJSON_DIAG_OFF(effc++)
37 #endif
38 
39 ///////////////////////////////////////////////////////////////////////////////
40 // RAPIDJSON_HAS_STDSTRING
41 
42 #ifndef RAPIDJSON_HAS_STDSTRING
43 #ifdef RAPIDJSON_DOXYGEN_RUNNING
44 #define RAPIDJSON_HAS_STDSTRING 1 // force generation of documentation
45 #else
46 #define RAPIDJSON_HAS_STDSTRING 0 // no std::string support by default
47 #endif
48 /*! \def RAPIDJSON_HAS_STDSTRING
49  \ingroup RAPIDJSON_CONFIG
50  \brief Enable RapidJSON support for \c std::string
51 
52  By defining this preprocessor symbol to \c 1, several convenience functions for using
53  \ref rapidjson::GenericValue with \c std::string are enabled, especially
54  for construction and comparison.
55 
56  \hideinitializer
57 */
58 #include <string>
59 #endif // RAPIDJSON_HAS_STDSTRING
60 
61 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
62 #include <iterator> // std::iterator, std::random_access_iterator_tag
63 #endif
64 
65 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
66 #include <utility> // std::move
67 #endif
68 
69 namespace rapidjson {
70 
71 // Forward declaration.
72 template <typename Encoding, typename Allocator>
74 
75 //! Name-value pair in a JSON object value.
76 /*!
77  This class was internal to GenericValue. It used to be a inner struct.
78  But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
79  https://code.google.com/p/rapidjson/issues/detail?id=64
80 */
81 template <typename Encoding, typename Allocator>
82 struct GenericMember {
83  GenericValue<Encoding, Allocator> name; //!< name of member (must be a string)
85 };
86 
87 ///////////////////////////////////////////////////////////////////////////////
88 // GenericMemberIterator
89 
90 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS
91 
92 //! (Constant) member iterator for a JSON object value
93 /*!
94  \tparam Const Is this a constant iterator?
95  \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
96  \tparam Allocator Allocator type for allocating memory of object, array and string.
97 
98  This class implements a Random Access Iterator for GenericMember elements
99  of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
100 
101  \note This iterator implementation is mainly intended to avoid implicit
102  conversions from iterator values to \c NULL,
103  e.g. from GenericValue::FindMember.
104 
105  \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
106  pointer-based implementation, if your platform doesn't provide
107  the C++ <iterator> header.
108 
109  \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
110  */
111 template <bool Const, typename Encoding, typename Allocator>
113  : public std::iterator<std::random_access_iterator_tag
114  , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> {
115 
116  friend class GenericValue<Encoding,Allocator>;
117  template <bool, typename, typename> friend class GenericMemberIterator;
118 
120  typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType;
121  typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType;
122 
123 public:
124  //! Iterator type itself
126  //! Constant iterator type
128  //! Non-constant iterator type
130 
131  //! Pointer to (const) GenericMember
132  typedef typename BaseType::pointer Pointer;
133  //! Reference to (const) GenericMember
134  typedef typename BaseType::reference Reference;
135  //! Signed integer type (e.g. \c ptrdiff_t)
136  typedef typename BaseType::difference_type DifferenceType;
137 
138  //! Default constructor (singular value)
139  /*! Creates an iterator pointing to no element.
140  \note All operations, except for comparisons, are undefined on such values.
141  */
142  GenericMemberIterator() : ptr_() {}
143 
144  //! Iterator conversions to more const
145  /*!
146  \param it (Non-const) iterator to copy from
147 
148  Allows the creation of an iterator from another GenericMemberIterator
149  that is "less const". Especially, creating a non-constant iterator
150  from a constant iterator are disabled:
151  \li const -> non-const (not ok)
152  \li const -> const (ok)
153  \li non-const -> const (ok)
154  \li non-const -> non-const (ok)
155 
156  \note If the \c Const template parameter is already \c false, this
157  constructor effectively defines a regular copy-constructor.
158  Otherwise, the copy constructor is implicitly defined.
159  */
160  GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
161 
162  //! @name stepping
163  //@{
164  Iterator& operator++(){ ++ptr_; return *this; }
165  Iterator& operator--(){ --ptr_; return *this; }
166  Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
167  Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
168  //@}
169 
170  //! @name increment/decrement
171  //@{
172  Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
173  Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
174 
175  Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
176  Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
177  //@}
178 
179  //! @name relations
180  //@{
181  bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
182  bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
183  bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
184  bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
185  bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
186  bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
187  //@}
188 
189  //! @name dereference
190  //@{
191  Reference operator*() const { return *ptr_; }
192  Pointer operator->() const { return ptr_; }
193  Reference operator[](DifferenceType n) const { return ptr_[n]; }
194  //@}
195 
196  //! Distance
197  DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
198 
199 private:
200  //! Internal constructor from plain pointer
201  explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
202 
203  Pointer ptr_; //!< raw pointer
204 };
205 
206 #else // RAPIDJSON_NOMEMBERITERATORCLASS
207 
208 // class-based member iterator implementation disabled, use plain pointers
209 
210 template <bool Const, typename Encoding, typename Allocator>
211 struct GenericMemberIterator;
212 
213 //! non-const GenericMemberIterator
214 template <typename Encoding, typename Allocator>
215 struct GenericMemberIterator<false,Encoding,Allocator> {
216  //! use plain pointer as iterator type
217  typedef GenericMember<Encoding,Allocator>* Iterator;
218 };
219 //! const GenericMemberIterator
220 template <typename Encoding, typename Allocator>
221 struct GenericMemberIterator<true,Encoding,Allocator> {
222  //! use plain const pointer as iterator type
223  typedef const GenericMember<Encoding,Allocator>* Iterator;
224 };
225 
226 #endif // RAPIDJSON_NOMEMBERITERATORCLASS
227 
228 ///////////////////////////////////////////////////////////////////////////////
229 // GenericStringRef
230 
231 //! Reference to a constant string (not taking a copy)
232 /*!
233  \tparam CharType character type of the string
234 
235  This helper class is used to automatically infer constant string
236  references for string literals, especially from \c const \b (!)
237  character arrays.
238 
239  The main use is for creating JSON string values without copying the
240  source string via an \ref Allocator. This requires that the referenced
241  string pointers have a sufficient lifetime, which exceeds the lifetime
242  of the associated GenericValue.
243 
244  \b Example
245  \code
246  Value v("foo"); // ok, no need to copy & calculate length
247  const char foo[] = "foo";
248  v.SetString(foo); // ok
249 
250  const char* bar = foo;
251  // Value x(bar); // not ok, can't rely on bar's lifetime
252  Value x(StringRef(bar)); // lifetime explicitly guaranteed by user
253  Value y(StringRef(bar, 3)); // ok, explicitly pass length
254  \endcode
255 
256  \see StringRef, GenericValue::SetString
257 */
258 template<typename CharType>
260  typedef CharType Ch; //!< character type of the string
261 
262  //! Create string reference from \c const character array
263  /*!
264  This constructor implicitly creates a constant string reference from
265  a \c const character array. It has better performance than
266  \ref StringRef(const CharType*) by inferring the string \ref length
267  from the array length, and also supports strings containing null
268  characters.
269 
270  \tparam N length of the string, automatically inferred
271 
272  \param str Constant character array, lifetime assumed to be longer
273  than the use of the string in e.g. a GenericValue
274 
275  \post \ref s == str
276 
277  \note Constant complexity.
278  \note There is a hidden, private overload to disallow references to
279  non-const character arrays to be created via this constructor.
280  By this, e.g. function-scope arrays used to be filled via
281  \c snprintf are excluded from consideration.
282  In such cases, the referenced string should be \b copied to the
283  GenericValue instead.
284  */
285  template<SizeType N>
286  GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
287  : s(str), length(N-1) {}
288 
289  //! Explicitly create string reference from \c const character pointer
290  /*!
291  This constructor can be used to \b explicitly create a reference to
292  a constant string pointer.
293 
294  \see StringRef(const CharType*)
295 
296  \param str Constant character pointer, lifetime assumed to be longer
297  than the use of the string in e.g. a GenericValue
298 
299  \post \ref s == str
300 
301  \note There is a hidden, private overload to disallow references to
302  non-const character arrays to be created via this constructor.
303  By this, e.g. function-scope arrays used to be filled via
304  \c snprintf are excluded from consideration.
305  In such cases, the referenced string should be \b copied to the
306  GenericValue instead.
307  */
308  explicit GenericStringRef(const CharType* str)
309  : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != NULL); }
310 
311  //! Create constant string reference from pointer and length
312  /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
313  \param len length of the string, excluding the trailing NULL terminator
314 
315  \post \ref s == str && \ref length == len
316  \note Constant complexity.
317  */
318  GenericStringRef(const CharType* str, SizeType len)
319  : s(str), length(len) { RAPIDJSON_ASSERT(s != NULL); }
320 
321  //! implicit conversion to plain CharType pointer
322  operator const Ch *() const { return s; }
323 
324  const Ch* const s; //!< plain CharType pointer
325  const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
326 
327 private:
328  //! Disallow copy-assignment
329  GenericStringRef operator=(const GenericStringRef&);
330  //! Disallow construction from non-const array
331  template<SizeType N>
332  GenericStringRef(CharType (&str)[N]) /* = delete */;
333 };
334 
335 //! Mark a character pointer as constant string
336 /*! Mark a plain character pointer as a "string literal". This function
337  can be used to avoid copying a character string to be referenced as a
338  value in a JSON GenericValue object, if the string's lifetime is known
339  to be valid long enough.
340  \tparam CharType Character type of the string
341  \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
342  \return GenericStringRef string reference object
343  \relatesalso GenericStringRef
344 
345  \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember
346 */
347 template<typename CharType>
348 inline GenericStringRef<CharType> StringRef(const CharType* str) {
349  return GenericStringRef<CharType>(str, internal::StrLen(str));
350 }
351 
352 //! Mark a character pointer as constant string
353 /*! Mark a plain character pointer as a "string literal". This function
354  can be used to avoid copying a character string to be referenced as a
355  value in a JSON GenericValue object, if the string's lifetime is known
356  to be valid long enough.
357 
358  This version has better performance with supplied length, and also
359  supports string containing null characters.
360 
361  \tparam CharType character type of the string
362  \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
363  \param length The length of source string.
364  \return GenericStringRef string reference object
365  \relatesalso GenericStringRef
366 */
367 template<typename CharType>
368 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) {
369  return GenericStringRef<CharType>(str, SizeType(length));
370 }
371 
372 #if RAPIDJSON_HAS_STDSTRING
373 //! Mark a string object as constant string
374 /*! Mark a string object (e.g. \c std::string) as a "string literal".
375  This function can be used to avoid copying a string to be referenced as a
376  value in a JSON GenericValue object, if the string's lifetime is known
377  to be valid long enough.
378 
379  \tparam CharType character type of the string
380  \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
381  \return GenericStringRef string reference object
382  \relatesalso GenericStringRef
383  \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
384 */
385 template<typename CharType>
386 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) {
387  return GenericStringRef<CharType>(str.data(), SizeType(str.size()));
388 }
389 #endif
390 
391 ///////////////////////////////////////////////////////////////////////////////
392 // GenericValue type traits
393 namespace internal {
394 
395 template <typename T, typename Encoding = void, typename Allocator = void>
396 struct IsGenericValueImpl : FalseType {};
397 
398 // select candidates according to nested encoding and allocator types
399 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type>
400  : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {};
401 
402 // helper to match arbitrary GenericValue instantiations, including derived classes
403 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {};
404 
405 } // namespace internal
406 
407 ///////////////////////////////////////////////////////////////////////////////
408 // GenericValue
409 
410 //! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
411 /*!
412  A JSON value can be one of 7 types. This class is a variant type supporting
413  these types.
414 
415  Use the Value if UTF8 and default allocator
416 
417  \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
418  \tparam Allocator Allocator type for allocating memory of object, array and string.
419 */
420 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> >
421 class GenericValue {
422 public:
423  //! Name-value pair in an object.
425  typedef Encoding EncodingType; //!< Encoding type from template parameter.
426  typedef Allocator AllocatorType; //!< Allocator type from template parameter.
427  typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
428  typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string
429  typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object.
430  typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object.
431  typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
432  typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
433 
434  //!@name Constructors and destructor.
435  //@{
436 
437  //! Default constructor creates a null value.
438  GenericValue() RAPIDJSON_NOEXCEPT : data_(), flags_(kNullFlag) {}
439 
440 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
441  //! Move constructor in C++11
442  GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_), flags_(rhs.flags_) {
443  rhs.flags_ = kNullFlag; // give up contents
444  }
445 #endif
446 
447 private:
448  //! Copy constructor is not permitted.
449  GenericValue(const GenericValue& rhs);
450 
451 public:
452 
453  //! Constructor with JSON value type.
454  /*! This creates a Value of specified type with default content.
455  \param type Type of the value.
456  \note Default content for number is zero.
457  */
458  explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_(), flags_() {
459  static const unsigned defaultFlags[7] = {
460  kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kConstStringFlag,
461  kNumberAnyFlag
462  };
463  RAPIDJSON_ASSERT(type <= kNumberType);
464  flags_ = defaultFlags[type];
465  }
466 
467  //! Explicit copy constructor (with allocator)
468  /*! Creates a copy of a Value by using the given Allocator
469  \tparam SourceAllocator allocator of \c rhs
470  \param rhs Value to copy from (read-only)
471  \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
472  \see CopyFrom()
473  */
474  template< typename SourceAllocator >
476 
477  //! Constructor for boolean value.
478  /*! \param b Boolean value
479  \note This constructor is limited to \em real boolean values and rejects
480  implicitly converted types like arbitrary pointers. Use an explicit cast
481  to \c bool, if you want to construct a boolean JSON value in such cases.
482  */
483 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
484  template <typename T>
485  explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<T,bool>))) RAPIDJSON_NOEXCEPT
486 #else
487  explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
488 #endif
489  : data_(), flags_(b ? kTrueFlag : kFalseFlag) {
490  // safe-guard against failing SFINAE
492  }
493 
494  //! Constructor for int value.
495  explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberIntFlag) {
496  data_.n.i64 = i;
497  if (i >= 0)
498  flags_ |= kUintFlag | kUint64Flag;
499  }
500 
501  //! Constructor for unsigned value.
502  explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUintFlag) {
503  data_.n.u64 = u;
504  if (!(u & 0x80000000))
505  flags_ |= kIntFlag | kInt64Flag;
506  }
507 
508  //! Constructor for int64_t value.
509  explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberInt64Flag) {
510  data_.n.i64 = i64;
511  if (i64 >= 0) {
512  flags_ |= kNumberUint64Flag;
513  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
514  flags_ |= kUintFlag;
515  if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
516  flags_ |= kIntFlag;
517  }
518  else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
519  flags_ |= kIntFlag;
520  }
521 
522  //! Constructor for uint64_t value.
523  explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberUint64Flag) {
524  data_.n.u64 = u64;
525  if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000)))
526  flags_ |= kInt64Flag;
527  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
528  flags_ |= kUintFlag;
529  if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
530  flags_ |= kIntFlag;
531  }
532 
533  //! Constructor for double value.
534  explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_(), flags_(kNumberDoubleFlag) { data_.n.d = d; }
535 
536  //! Constructor for constant string (i.e. do not make a copy of string)
537  GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(StringRef(s, length)); }
538 
539  //! Constructor for constant string (i.e. do not make a copy of string)
540  explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_(), flags_() { SetStringRaw(s); }
541 
542  //! Constructor for copy-string (i.e. do make a copy of string)
543  GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s, length), allocator); }
544 
545  //! Constructor for copy-string (i.e. do make a copy of string)
546  GenericValue(const Ch*s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); }
547 
548 #if RAPIDJSON_HAS_STDSTRING
549  //! Constructor for copy-string from a string object (i.e. do make a copy of string)
550  /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
551  */
552  GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_(), flags_() { SetStringRaw(StringRef(s), allocator); }
553 #endif
554 
555  //! Destructor.
556  /*! Need to destruct elements of array, members of object, or copy-string.
557  */
559  if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
560  switch(flags_) {
561  case kArrayFlag:
562  for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
563  v->~GenericValue();
564  Allocator::Free(data_.a.elements);
565  break;
566 
567  case kObjectFlag:
568  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
569  m->~Member();
570  Allocator::Free(data_.o.members);
571  break;
572 
573  case kCopyStringFlag:
574  Allocator::Free(const_cast<Ch*>(data_.s.str));
575  break;
576 
577  default:
578  break; // Do nothing for other types.
579  }
580  }
581  }
582 
583  //@}
584 
585  //!@name Assignment operators
586  //@{
587 
588  //! Assignment with move semantics.
589  /*! \param rhs Source of the assignment. It will become a null value after assignment.
590  */
591  GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
592  RAPIDJSON_ASSERT(this != &rhs);
593  this->~GenericValue();
594  RawAssign(rhs);
595  return *this;
596  }
597 
598 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
599  //! Move assignment in C++11
600  GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT {
601  return *this = rhs.Move();
602  }
603 #endif
604 
605  //! Assignment of constant string reference (no copy)
606  /*! \param str Constant string reference to be assigned
607  \note This overload is needed to avoid clashes with the generic primitive type assignment overload below.
608  \see GenericStringRef, operator=(T)
609  */
610  GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT {
611  GenericValue s(str);
612  return *this = s;
613  }
614 
615  //! Assignment with primitive types.
616  /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
617  \param value The value to be assigned.
618 
619  \note The source type \c T explicitly disallows all pointer types,
620  especially (\c const) \ref Ch*. This helps avoiding implicitly
621  referencing character strings with insufficient lifetime, use
622  \ref SetString(const Ch*, Allocator&) (for copying) or
623  \ref StringRef() (to explicitly mark the pointer as constant) instead.
624  All other pointer types would implicitly convert to \c bool,
625  use \ref SetBool() instead.
626  */
627  template <typename T>
628  RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&))
629  operator=(T value) {
630  GenericValue v(value);
631  return *this = v;
632  }
633 
634  //! Deep-copy assignment from Value
635  /*! Assigns a \b copy of the Value to the current Value object
636  \tparam SourceAllocator Allocator type of \c rhs
637  \param rhs Value to copy from (read-only)
638  \param allocator Allocator to use for copying
639  */
640  template <typename SourceAllocator>
642  RAPIDJSON_ASSERT((void*)this != (void const*)&rhs);
643  this->~GenericValue();
644  new (this) GenericValue(rhs, allocator);
645  return *this;
646  }
647 
648  //! Exchange the contents of this value with those of other.
649  /*!
650  \param other Another value.
651  \note Constant complexity.
652  */
653  GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT {
654  GenericValue temp;
655  temp.RawAssign(*this);
656  RawAssign(other);
657  other.RawAssign(temp);
658  return *this;
659  }
660 
661  //! Prepare Value for move semantics
662  /*! \return *this */
663  GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; }
664  //@}
665 
666  //!@name Equal-to and not-equal-to operators
667  //@{
668  //! Equal-to operator
669  /*!
670  \note If an object contains duplicated named member, comparing equality with any object is always \c false.
671  \note Linear time complexity (number of all values in the subtree and total lengths of all strings).
672  */
673  template <typename SourceAllocator>
676  if (GetType() != rhs.GetType())
677  return false;
678 
679  switch (GetType()) {
680  case kObjectType: // Warning: O(n^2) inner-loop
681  if (data_.o.size != rhs.data_.o.size)
682  return false;
683  for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) {
684  typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name);
685  if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value)
686  return false;
687  }
688  return true;
689 
690  case kArrayType:
691  if (data_.a.size != rhs.data_.a.size)
692  return false;
693  for (SizeType i = 0; i < data_.a.size; i++)
694  if ((*this)[i] != rhs[i])
695  return false;
696  return true;
697 
698  case kStringType:
699  return StringEqual(rhs);
700 
701  case kNumberType:
702  if (IsDouble() || rhs.IsDouble())
703  return GetDouble() == rhs.GetDouble(); // May convert one operand from integer to double.
704  else
705  return data_.n.u64 == rhs.data_.n.u64;
706 
707  default: // kTrueType, kFalseType, kNullType
708  return true;
709  }
710  }
711 
712  //! Equal-to operator with const C-string pointer
713  bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); }
714 
715 #if RAPIDJSON_HAS_STDSTRING
716  //! Equal-to operator with string object
717  /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
718  */
719  bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); }
720 #endif
721 
722  //! Equal-to operator with primitive types
723  /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false
724  */
725  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); }
726 
727  //! Not-equal-to operator
728  /*! \return !(*this == rhs)
729  */
730  template <typename SourceAllocator>
731  bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); }
732 
733  //! Not-equal-to operator with const C-string pointer
734  bool operator!=(const Ch* rhs) const { return !(*this == rhs); }
735 
736  //! Not-equal-to operator with arbitrary types
737  /*! \return !(*this == rhs)
738  */
739  template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); }
740 
741  //! Equal-to operator with arbitrary types (symmetric version)
742  /*! \return (rhs == lhs)
743  */
744  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; }
745 
746  //! Not-Equal-to operator with arbitrary types (symmetric version)
747  /*! \return !(rhs == lhs)
748  */
749  template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); }
750  //@}
751 
752  //!@name Type
753  //@{
754 
755  Type GetType() const { return static_cast<Type>(flags_ & kTypeMask); }
756  bool IsNull() const { return flags_ == kNullFlag; }
757  bool IsFalse() const { return flags_ == kFalseFlag; }
758  bool IsTrue() const { return flags_ == kTrueFlag; }
759  bool IsBool() const { return (flags_ & kBoolFlag) != 0; }
760  bool IsObject() const { return flags_ == kObjectFlag; }
761  bool IsArray() const { return flags_ == kArrayFlag; }
762  bool IsNumber() const { return (flags_ & kNumberFlag) != 0; }
763  bool IsInt() const { return (flags_ & kIntFlag) != 0; }
764  bool IsUint() const { return (flags_ & kUintFlag) != 0; }
765  bool IsInt64() const { return (flags_ & kInt64Flag) != 0; }
766  bool IsUint64() const { return (flags_ & kUint64Flag) != 0; }
767  bool IsDouble() const { return (flags_ & kDoubleFlag) != 0; }
768  bool IsString() const { return (flags_ & kStringFlag) != 0; }
769 
770  //@}
771 
772  //!@name Null
773  //@{
774 
775  GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; }
776 
777  //@}
778 
779  //!@name Bool
780  //@{
781 
782  bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return flags_ == kTrueFlag; }
783  //!< Set boolean value
784  /*! \post IsBool() == true */
785  GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; }
786 
787  //@}
788 
789  //!@name Object
790  //@{
791 
792  //! Set this value as an empty object.
793  /*! \post IsObject() == true */
794  GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; }
795 
796  //! Get the number of members in the object.
797  SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; }
798 
799  //! Check whether the object is empty.
800  bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; }
801 
802  //! Get a value from an object associated with the name.
803  /*! \pre IsObject() == true
804  \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType))
805  \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7.
806  Since 0.2, if the name is not correct, it will assert.
807  If user is unsure whether a member exists, user should use HasMember() first.
808  A better approach is to use FindMember().
809  \note Linear time complexity.
810  */
811  template <typename T>
812  RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) {
813  GenericValue n(StringRef(name));
814  return (*this)[n];
815  }
816  template <typename T>
817  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]; }
818 
819  //! Get a value from an object associated with the name.
820  /*! \pre IsObject() == true
821  \tparam SourceAllocator Allocator of the \c name value
822 
823  \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen().
824  And it can also handle strings with embedded null characters.
825 
826  \note Linear time complexity.
827  */
828  template <typename SourceAllocator>
830  MemberIterator member = FindMember(name);
831  if (member != MemberEnd())
832  return member->value;
833  else {
834  RAPIDJSON_ASSERT(false); // see above note
835  static GenericValue NullValue;
836  return NullValue;
837  }
838  }
839  template <typename SourceAllocator>
840  const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; }
841 
842  //! Const member iterator
843  /*! \pre IsObject() == true */
844  ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members); }
845  //! Const \em past-the-end member iterator
846  /*! \pre IsObject() == true */
847  ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(data_.o.members + data_.o.size); }
848  //! Member iterator
849  /*! \pre IsObject() == true */
850  MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members); }
851  //! \em Past-the-end member iterator
852  /*! \pre IsObject() == true */
853  MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(data_.o.members + data_.o.size); }
854 
855  //! Check whether a member exists in the object.
856  /*!
857  \param name Member name to be searched.
858  \pre IsObject() == true
859  \return Whether a member with that name exists.
860  \note It is better to use FindMember() directly if you need the obtain the value as well.
861  \note Linear time complexity.
862  */
863  bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); }
864 
865  //! Check whether a member exists in the object with GenericValue name.
866  /*!
867  This version is faster because it does not need a StrLen(). It can also handle string with null character.
868  \param name Member name to be searched.
869  \pre IsObject() == true
870  \return Whether a member with that name exists.
871  \note It is better to use FindMember() directly if you need the obtain the value as well.
872  \note Linear time complexity.
873  */
874  template <typename SourceAllocator>
875  bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); }
876 
877  //! Find member by name.
878  /*!
879  \param name Member name to be searched.
880  \pre IsObject() == true
881  \return Iterator to member, if it exists.
882  Otherwise returns \ref MemberEnd().
883 
884  \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
885  the requested member doesn't exist. For consistency with e.g.
886  \c std::map, this has been changed to MemberEnd() now.
887  \note Linear time complexity.
888  */
889  MemberIterator FindMember(const Ch* name) {
890  GenericValue n(StringRef(name));
891  return FindMember(n);
892  }
893 
894  ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
895 
896  //! Find member by name.
897  /*!
898  This version is faster because it does not need a StrLen(). It can also handle string with null character.
899  \param name Member name to be searched.
900  \pre IsObject() == true
901  \return Iterator to member, if it exists.
902  Otherwise returns \ref MemberEnd().
903 
904  \note Earlier versions of Rapidjson returned a \c NULL pointer, in case
905  the requested member doesn't exist. For consistency with e.g.
906  \c std::map, this has been changed to MemberEnd() now.
907  \note Linear time complexity.
908  */
909  template <typename SourceAllocator>
911  RAPIDJSON_ASSERT(IsObject());
912  RAPIDJSON_ASSERT(name.IsString());
913  MemberIterator member = MemberBegin();
914  for ( ; member != MemberEnd(); ++member)
915  if (name.StringEqual(member->name))
916  break;
917  return member;
918  }
919  template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); }
920 
921  //! Add a member (name-value pair) to the object.
922  /*! \param name A string value as name of member.
923  \param value Value of any type.
924  \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
925  \return The value itself for fluent API.
926  \note The ownership of \c name and \c value will be transferred to this object on success.
927  \pre IsObject() && name.IsString()
928  \post name.IsNull() && value.IsNull()
929  \note Amortized Constant time complexity.
930  */
932  RAPIDJSON_ASSERT(IsObject());
933  RAPIDJSON_ASSERT(name.IsString());
934 
935  Object& o = data_.o;
936  if (o.size >= o.capacity) {
937  if (o.capacity == 0) {
938  o.capacity = kDefaultObjectCapacity;
939  o.members = reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member)));
940  }
941  else {
942  SizeType oldCapacity = o.capacity;
943  o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5
944  o.members = reinterpret_cast<Member*>(allocator.Realloc(o.members, oldCapacity * sizeof(Member), o.capacity * sizeof(Member)));
945  }
946  }
947  o.members[o.size].name.RawAssign(name);
948  o.members[o.size].value.RawAssign(value);
949  o.size++;
950  return *this;
951  }
952 
953 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
954  GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) {
955  return AddMember(name, value, allocator);
956  }
957  GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) {
958  return AddMember(name, value, allocator);
959  }
960  GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) {
961  return AddMember(name, value, allocator);
962  }
963  GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) {
964  GenericValue n(name);
965  return AddMember(n, value, allocator);
966  }
967 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
968 
969 
970  //! Add a member (name-value pair) to the object.
971  /*! \param name A constant string reference as name of member.
972  \param value Value of any type.
973  \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
974  \return The value itself for fluent API.
975  \note The ownership of \c value will be transferred to this object on success.
976  \pre IsObject()
977  \post value.IsNull()
978  \note Amortized Constant time complexity.
979  */
981  GenericValue n(name);
982  return AddMember(n, value, allocator);
983  }
984 
985  //! Add a constant string value as member (name-value pair) to the object.
986  /*! \param name A constant string reference as name of member.
987  \param value constant string reference as value of member.
988  \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
989  \return The value itself for fluent API.
990  \pre IsObject()
991  \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below.
992  \note Amortized Constant time complexity.
993  */
995  GenericValue v(value);
996  return AddMember(name, v, allocator);
997  }
998 
999  //! Add any primitive value as member (name-value pair) to the object.
1000  /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1001  \param name A constant string reference as name of member.
1002  \param value Value of primitive type \c T as value of member
1003  \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator().
1004  \return The value itself for fluent API.
1005  \pre IsObject()
1006 
1007  \note The source type \c T explicitly disallows all pointer types,
1008  especially (\c const) \ref Ch*. This helps avoiding implicitly
1009  referencing character strings with insufficient lifetime, use
1010  \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref
1011  AddMember(StringRefType, StringRefType, Allocator&).
1012  All other pointer types would implicitly convert to \c bool,
1013  use an explicit cast instead, if needed.
1014  \note Amortized Constant time complexity.
1015  */
1016  template <typename T>
1017  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1018  AddMember(StringRefType name, T value, Allocator& allocator) {
1019  GenericValue n(name);
1020  GenericValue v(value);
1021  return AddMember(n, v, allocator);
1022  }
1023 
1024  //! Remove all members in the object.
1025  /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged.
1026  \note Linear time complexity.
1027  */
1029  RAPIDJSON_ASSERT(IsObject());
1030  for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
1031  m->~Member();
1032  data_.o.size = 0;
1033  }
1034 
1035  //! Remove a member in object by its name.
1036  /*! \param name Name of member to be removed.
1037  \return Whether the member existed.
1038  \note This function may reorder the object members. Use \ref
1039  EraseMember(ConstMemberIterator) if you need to preserve the
1040  relative order of the remaining members.
1041  \note Linear time complexity.
1042  */
1043  bool RemoveMember(const Ch* name) {
1044  GenericValue n(StringRef(name));
1045  return RemoveMember(n);
1046  }
1047 
1048  template <typename SourceAllocator>
1050  MemberIterator m = FindMember(name);
1051  if (m != MemberEnd()) {
1052  RemoveMember(m);
1053  return true;
1054  }
1055  else
1056  return false;
1057  }
1058 
1059  //! Remove a member in object by iterator.
1060  /*! \param m member iterator (obtained by FindMember() or MemberBegin()).
1061  \return the new iterator after removal.
1062  \note This function may reorder the object members. Use \ref
1063  EraseMember(ConstMemberIterator) if you need to preserve the
1064  relative order of the remaining members.
1065  \note Constant time complexity.
1066  */
1068  RAPIDJSON_ASSERT(IsObject());
1069  RAPIDJSON_ASSERT(data_.o.size > 0);
1070  RAPIDJSON_ASSERT(data_.o.members != 0);
1071  RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd());
1072 
1073  MemberIterator last(data_.o.members + (data_.o.size - 1));
1074  if (data_.o.size > 1 && m != last) {
1075  // Move the last one to this place
1076  *m = *last;
1077  }
1078  else {
1079  // Only one left, just destroy
1080  m->~Member();
1081  }
1082  --data_.o.size;
1083  return m;
1084  }
1085 
1086  //! Remove a member from an object by iterator.
1087  /*! \param pos iterator to the member to remove
1088  \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd()
1089  \return Iterator following the removed element.
1090  If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned.
1091  \note This function preserves the relative order of the remaining object
1092  members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator).
1093  \note Linear time complexity.
1094  */
1096  return EraseMember(pos, pos +1);
1097  }
1098 
1099  //! Remove members in the range [first, last) from an object.
1100  /*! \param first iterator to the first member to remove
1101  \param last iterator following the last member to remove
1102  \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd()
1103  \return Iterator following the last removed element.
1104  \note This function preserves the relative order of the remaining object
1105  members.
1106  \note Linear time complexity.
1107  */
1109  RAPIDJSON_ASSERT(IsObject());
1110  RAPIDJSON_ASSERT(data_.o.size > 0);
1111  RAPIDJSON_ASSERT(data_.o.members != 0);
1112  RAPIDJSON_ASSERT(first >= MemberBegin());
1113  RAPIDJSON_ASSERT(first <= last);
1114  RAPIDJSON_ASSERT(last <= MemberEnd());
1115 
1116  MemberIterator pos = MemberBegin() + (first - MemberBegin());
1117  for (MemberIterator itr = pos; itr != last; ++itr)
1118  itr->~Member();
1119  std::memmove(&*pos, &*last, (MemberEnd() - last) * sizeof(Member));
1120  data_.o.size -= (last - first);
1121  return pos;
1122  }
1123 
1124  //@}
1125 
1126  //!@name Array
1127  //@{
1128 
1129  //! Set this value as an empty array.
1130  /*! \post IsArray == true */
1131  GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; }
1132 
1133  //! Get the number of elements in array.
1134  SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; }
1135 
1136  //! Get the capacity of array.
1137  SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; }
1138 
1139  //! Check whether the array is empty.
1140  bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; }
1141 
1142  //! Remove all elements in the array.
1143  /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged.
1144  \note Linear time complexity.
1145  */
1146  void Clear() {
1147  RAPIDJSON_ASSERT(IsArray());
1148  for (SizeType i = 0; i < data_.a.size; ++i)
1149  data_.a.elements[i].~GenericValue();
1150  data_.a.size = 0;
1151  }
1152 
1153  //! Get an element from array by index.
1154  /*! \pre IsArray() == true
1155  \param index Zero-based index of element.
1156  \see operator[](T*)
1157  */
1159  RAPIDJSON_ASSERT(IsArray());
1160  RAPIDJSON_ASSERT(index < data_.a.size);
1161  return data_.a.elements[index];
1162  }
1163  const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; }
1164 
1165  //! Element iterator
1166  /*! \pre IsArray() == true */
1167  ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements; }
1168  //! \em Past-the-end element iterator
1169  /*! \pre IsArray() == true */
1170  ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return data_.a.elements + data_.a.size; }
1171  //! Constant element iterator
1172  /*! \pre IsArray() == true */
1173  ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); }
1174  //! Constant \em past-the-end element iterator
1175  /*! \pre IsArray() == true */
1176  ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); }
1177 
1178  //! Request the array to have enough capacity to store elements.
1179  /*! \param newCapacity The capacity that the array at least need to have.
1180  \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1181  \return The value itself for fluent API.
1182  \note Linear time complexity.
1183  */
1184  GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) {
1185  RAPIDJSON_ASSERT(IsArray());
1186  if (newCapacity > data_.a.capacity) {
1187  data_.a.elements = (GenericValue*)allocator.Realloc(data_.a.elements, data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue));
1188  data_.a.capacity = newCapacity;
1189  }
1190  return *this;
1191  }
1192 
1193  //! Append a GenericValue at the end of the array.
1194  /*! \param value Value to be appended.
1195  \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1196  \pre IsArray() == true
1197  \post value.IsNull() == true
1198  \return The value itself for fluent API.
1199  \note The ownership of \c value will be transferred to this array on success.
1200  \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1201  \note Amortized constant time complexity.
1202  */
1204  RAPIDJSON_ASSERT(IsArray());
1205  if (data_.a.size >= data_.a.capacity)
1206  Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator);
1207  data_.a.elements[data_.a.size++].RawAssign(value);
1208  return *this;
1209  }
1210 
1211 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1212  GenericValue& PushBack(GenericValue&& value, Allocator& allocator) {
1213  return PushBack(value, allocator);
1214  }
1215 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS
1216 
1217  //! Append a constant string reference at the end of the array.
1218  /*! \param value Constant string reference to be appended.
1219  \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator().
1220  \pre IsArray() == true
1221  \return The value itself for fluent API.
1222  \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1223  \note Amortized constant time complexity.
1224  \see GenericStringRef
1225  */
1227  return (*this).template PushBack<StringRefType>(value, allocator);
1228  }
1229 
1230  //! Append a primitive value at the end of the array.
1231  /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t
1232  \param value Value of primitive type T to be appended.
1233  \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator().
1234  \pre IsArray() == true
1235  \return The value itself for fluent API.
1236  \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient.
1237 
1238  \note The source type \c T explicitly disallows all pointer types,
1239  especially (\c const) \ref Ch*. This helps avoiding implicitly
1240  referencing character strings with insufficient lifetime, use
1241  \ref PushBack(GenericValue&, Allocator&) or \ref
1242  PushBack(StringRefType, Allocator&).
1243  All other pointer types would implicitly convert to \c bool,
1244  use an explicit cast instead, if needed.
1245  \note Amortized constant time complexity.
1246  */
1247  template <typename T>
1248  RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&))
1249  PushBack(T value, Allocator& allocator) {
1250  GenericValue v(value);
1251  return PushBack(v, allocator);
1252  }
1253 
1254  //! Remove the last element in the array.
1255  /*!
1256  \note Constant time complexity.
1257  */
1259  RAPIDJSON_ASSERT(IsArray());
1260  RAPIDJSON_ASSERT(!Empty());
1261  data_.a.elements[--data_.a.size].~GenericValue();
1262  return *this;
1263  }
1264 
1265  //! Remove an element of array by iterator.
1266  /*!
1267  \param pos iterator to the element to remove
1268  \pre IsArray() == true && \ref Begin() <= \c pos < \ref End()
1269  \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned.
1270  \note Linear time complexity.
1271  */
1273  return Erase(pos, pos + 1);
1274  }
1275 
1276  //! Remove elements in the range [first, last) of the array.
1277  /*!
1278  \param first iterator to the first element to remove
1279  \param last iterator following the last element to remove
1280  \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End()
1281  \return Iterator following the last removed element.
1282  \note Linear time complexity.
1283  */
1285  RAPIDJSON_ASSERT(IsArray());
1286  RAPIDJSON_ASSERT(data_.a.size > 0);
1287  RAPIDJSON_ASSERT(data_.a.elements != 0);
1288  RAPIDJSON_ASSERT(first >= Begin());
1289  RAPIDJSON_ASSERT(first <= last);
1290  RAPIDJSON_ASSERT(last <= End());
1291  ValueIterator pos = Begin() + (first - Begin());
1292  for (ValueIterator itr = pos; itr != last; ++itr)
1293  itr->~GenericValue();
1294  std::memmove(pos, last, (End() - last) * sizeof(GenericValue));
1295  data_.a.size -= (last - first);
1296  return pos;
1297  }
1298 
1299  //@}
1300 
1301  //!@name Number
1302  //@{
1303 
1304  int GetInt() const { RAPIDJSON_ASSERT(flags_ & kIntFlag); return data_.n.i.i; }
1305  unsigned GetUint() const { RAPIDJSON_ASSERT(flags_ & kUintFlag); return data_.n.u.u; }
1306  int64_t GetInt64() const { RAPIDJSON_ASSERT(flags_ & kInt64Flag); return data_.n.i64; }
1307  uint64_t GetUint64() const { RAPIDJSON_ASSERT(flags_ & kUint64Flag); return data_.n.u64; }
1308 
1309  double GetDouble() const {
1310  RAPIDJSON_ASSERT(IsNumber());
1311  if ((flags_ & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion.
1312  if ((flags_ & kIntFlag) != 0) return data_.n.i.i; // int -> double
1313  if ((flags_ & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double
1314  if ((flags_ & kInt64Flag) != 0) return (double)data_.n.i64; // int64_t -> double (may lose precision)
1315  RAPIDJSON_ASSERT((flags_ & kUint64Flag) != 0); return (double)data_.n.u64; // uint64_t -> double (may lose precision)
1316  }
1317 
1318  GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; }
1319  GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; }
1320  GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; }
1321  GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; }
1322  GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; }
1323 
1324  //@}
1325 
1326  //!@name String
1327  //@{
1328 
1329  const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? data_.ss.str : data_.s.str); }
1330 
1331  //! Get the length of string.
1332  /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength().
1333  */
1334  SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((flags_ & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); }
1335 
1336  //! Set this value as a string without copying source string.
1337  /*! This version has better performance with supplied length, and also support string containing null character.
1338  \param s source string pointer.
1339  \param length The length of source string, excluding the trailing null terminator.
1340  \return The value itself for fluent API.
1341  \post IsString() == true && GetString() == s && GetStringLength() == length
1342  \see SetString(StringRefType)
1343  */
1344  GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); }
1345 
1346  //! Set this value as a string without copying source string.
1347  /*! \param s source string reference
1348  \return The value itself for fluent API.
1349  \post IsString() == true && GetString() == s && GetStringLength() == s.length
1350  */
1351  GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; }
1352 
1353  //! Set this value as a string by copying from source string.
1354  /*! This version has better performance with supplied length, and also support string containing null character.
1355  \param s source string.
1356  \param length The length of source string, excluding the trailing null terminator.
1357  \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1358  \return The value itself for fluent API.
1359  \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1360  */
1361  GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; }
1362 
1363  //! Set this value as a string by copying from source string.
1364  /*! \param s source string.
1365  \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1366  \return The value itself for fluent API.
1367  \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length
1368  */
1369  GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); }
1370 
1371 #if RAPIDJSON_HAS_STDSTRING
1372  //! Set this value as a string by copying from source string.
1373  /*! \param s source string.
1374  \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator().
1375  \return The value itself for fluent API.
1376  \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size()
1377  \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
1378  */
1379  GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), s.size(), allocator); }
1380 #endif
1381 
1382  //@}
1383 
1384  //! Generate events of this value to a Handler.
1385  /*! This function adopts the GoF visitor pattern.
1386  Typical usage is to output this JSON value as JSON text via Writer, which is a Handler.
1387  It can also be used to deep clone this value via GenericDocument, which is also a Handler.
1388  \tparam Handler type of handler.
1389  \param handler An object implementing concept Handler.
1390  */
1391  template <typename Handler>
1392  bool Accept(Handler& handler) const {
1393  switch(GetType()) {
1394  case kNullType: return handler.Null();
1395  case kFalseType: return handler.Bool(false);
1396  case kTrueType: return handler.Bool(true);
1397 
1398  case kObjectType:
1399  if (!handler.StartObject())
1400  return false;
1401  for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
1402  if (!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.flags_ & kCopyFlag) != 0))
1403  return false;
1404  if (!m->value.Accept(handler))
1405  return false;
1406  }
1407  return handler.EndObject(data_.o.size);
1408 
1409  case kArrayType:
1410  if (!handler.StartArray())
1411  return false;
1412  for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
1413  if (!v->Accept(handler))
1414  return false;
1415  return handler.EndArray(data_.a.size);
1416 
1417  case kStringType:
1418  return handler.String(GetString(), GetStringLength(), (flags_ & kCopyFlag) != 0);
1419 
1420  case kNumberType:
1421  if (IsInt()) return handler.Int(data_.n.i.i);
1422  else if (IsUint()) return handler.Uint(data_.n.u.u);
1423  else if (IsInt64()) return handler.Int64(data_.n.i64);
1424  else if (IsUint64()) return handler.Uint64(data_.n.u64);
1425  else return handler.Double(data_.n.d);
1426 
1427  default:
1428  RAPIDJSON_ASSERT(false);
1429  }
1430  return false;
1431  }
1432 
1433 private:
1434  template <typename, typename> friend class GenericValue;
1435  template <typename, typename, typename> friend class GenericDocument;
1436 
1437  enum {
1438  kBoolFlag = 0x100,
1439  kNumberFlag = 0x200,
1440  kIntFlag = 0x400,
1441  kUintFlag = 0x800,
1442  kInt64Flag = 0x1000,
1443  kUint64Flag = 0x2000,
1444  kDoubleFlag = 0x4000,
1445  kStringFlag = 0x100000,
1446  kCopyFlag = 0x200000,
1447  kInlineStrFlag = 0x400000,
1448 
1449  // Initial flags of different types.
1450  kNullFlag = kNullType,
1451  kTrueFlag = kTrueType | kBoolFlag,
1452  kFalseFlag = kFalseType | kBoolFlag,
1453  kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag,
1454  kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag,
1455  kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag,
1456  kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag,
1457  kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag,
1458  kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag,
1459  kConstStringFlag = kStringType | kStringFlag,
1460  kCopyStringFlag = kStringType | kStringFlag | kCopyFlag,
1461  kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag,
1462  kObjectFlag = kObjectType,
1463  kArrayFlag = kArrayType,
1464 
1465  kTypeMask = 0xFF // bitwise-and with mask of 0xFF can be optimized by compiler
1466  };
1467 
1468  static const SizeType kDefaultArrayCapacity = 16;
1469  static const SizeType kDefaultObjectCapacity = 16;
1470 
1471  struct String {
1472  const Ch* str;
1473  SizeType length;
1474  unsigned hashcode; //!< reserved
1475  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1476 
1477  // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars
1478  // (excluding the terminating zero) and store a value to determine the length of the contained
1479  // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string
1480  // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as
1481  // the string terminator as well. For getting the string length back from that value just use
1482  // "MaxSize - str[LenPos]".
1483  // This allows to store 11-chars strings in 32-bit mode and 15-chars strings in 64-bit mode
1484  // inline (for `UTF8`-encoded strings).
1485  struct ShortString {
1486  enum { MaxChars = sizeof(String) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize };
1487  Ch str[MaxChars];
1488 
1489  inline static bool Usable(SizeType len) { return (MaxSize >= len); }
1490  inline void SetLength(SizeType len) { str[LenPos] = (Ch)(MaxSize - len); }
1491  inline SizeType GetLength() const { return (SizeType)(MaxSize - str[LenPos]); }
1492  }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1493 
1494  // By using proper binary layout, retrieval of different integer types do not need conversions.
1495  union Number {
1496 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN
1497  struct I {
1498  int i;
1499  char padding[4];
1500  }i;
1501  struct U {
1502  unsigned u;
1503  char padding2[4];
1504  }u;
1505 #else
1506  struct I {
1507  char padding[4];
1508  int i;
1509  }i;
1510  struct U {
1511  char padding2[4];
1512  unsigned u;
1513  }u;
1514 #endif
1515  int64_t i64;
1516  uint64_t u64;
1517  double d;
1518  }; // 8 bytes
1519 
1520  struct Object {
1521  Member* members;
1522  SizeType size;
1523  SizeType capacity;
1524  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1525 
1526  struct Array {
1527  GenericValue* elements;
1528  SizeType size;
1529  SizeType capacity;
1530  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1531 
1532  union Data {
1533  String s;
1534  ShortString ss;
1535  Number n;
1536  Object o;
1537  Array a;
1538  }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode
1539 
1540  // Initialize this value as array with initial data, without calling destructor.
1541  void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
1542  flags_ = kArrayFlag;
1543  data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue));
1544  std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
1545  data_.a.size = data_.a.capacity = count;
1546  }
1547 
1548  //! Initialize this value as object with initial data, without calling destructor.
1549  void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
1550  flags_ = kObjectFlag;
1551  data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member));
1552  std::memcpy(data_.o.members, members, count * sizeof(Member));
1553  data_.o.size = data_.o.capacity = count;
1554  }
1555 
1556  //! Initialize this value as constant string, without calling destructor.
1557  void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT {
1558  flags_ = kConstStringFlag;
1559  data_.s.str = s;
1560  data_.s.length = s.length;
1561  }
1562 
1563  //! Initialize this value as copy string with initial data, without calling destructor.
1564  void SetStringRaw(StringRefType s, Allocator& allocator) {
1565  Ch* str = NULL;
1566  if(ShortString::Usable(s.length)) {
1567  flags_ = kShortStringFlag;
1568  data_.ss.SetLength(s.length);
1569  str = data_.ss.str;
1570  } else {
1571  flags_ = kCopyStringFlag;
1572  data_.s.length = s.length;
1573  str = (Ch *)allocator.Malloc((s.length + 1) * sizeof(Ch));
1574  data_.s.str = str;
1575  }
1576  std::memcpy(str, s, s.length * sizeof(Ch));
1577  str[s.length] = '\0';
1578  }
1579 
1580  //! Assignment without calling destructor
1581  void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT {
1582  data_ = rhs.data_;
1583  flags_ = rhs.flags_;
1584  rhs.flags_ = kNullFlag;
1585  }
1586 
1587  template <typename SourceAllocator>
1588  bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const {
1589  RAPIDJSON_ASSERT(IsString());
1590  RAPIDJSON_ASSERT(rhs.IsString());
1591 
1592  const SizeType len1 = GetStringLength();
1593  const SizeType len2 = rhs.GetStringLength();
1594  if(len1 != len2) { return false; }
1595 
1596  const Ch* const str1 = GetString();
1597  const Ch* const str2 = rhs.GetString();
1598  if(str1 == str2) { return true; } // fast path for constant string
1599 
1600  return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0);
1601  }
1602 
1603  Data data_;
1604  unsigned flags_;
1605 };
1606 
1607 //! GenericValue with UTF8 encoding
1609 
1610 ///////////////////////////////////////////////////////////////////////////////
1611 // GenericDocument
1612 
1613 //! A document for parsing JSON text as DOM.
1614 /*!
1615  \note implements Handler concept
1616  \tparam Encoding Encoding for both parsing and string storage.
1617  \tparam Allocator Allocator for allocating memory for the DOM
1618  \tparam StackAllocator Allocator for allocating memory for stack during parsing.
1619  \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.
1620 */
1621 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator>
1622 class GenericDocument : public GenericValue<Encoding, Allocator> {
1623 public:
1624  typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
1625  typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document.
1626  typedef Allocator AllocatorType; //!< Allocator type from template parameter.
1627 
1628  //! Constructor
1629  /*! \param allocator Optional allocator for allocating memory.
1630  \param stackCapacity Optional initial capacity of stack in bytes.
1631  \param stackAllocator Optional allocator for allocating memory for stack.
1632  */
1633  GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) :
1634  allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_()
1635  {
1636  if (!allocator_)
1637  ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator());
1638  }
1639 
1640 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1641  //! Move constructor in C++11
1642  GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
1643  : ValueType(std::move(rhs)),
1644  allocator_(rhs.allocator_),
1645  ownAllocator_(rhs.ownAllocator_),
1646  stack_(std::move(rhs.stack_)),
1647  parseResult_(rhs.parseResult_)
1648  {
1649  rhs.allocator_ = 0;
1650  rhs.ownAllocator_ = 0;
1651  rhs.parseResult_ = ParseResult();
1652  }
1653 #endif
1654 
1655  ~GenericDocument() {
1656  Destroy();
1657  }
1658 
1659 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS
1660  //! Move assignment in C++11
1661  GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT
1662  {
1663  // The cast to ValueType is necessary here, because otherwise it would
1664  // attempt to call GenericValue's templated assignment operator.
1665  ValueType::operator=(std::forward<ValueType>(rhs));
1666 
1667  // Calling the destructor here would prematurely call stack_'s destructor
1668  Destroy();
1669 
1670  allocator_ = rhs.allocator_;
1671  ownAllocator_ = rhs.ownAllocator_;
1672  stack_ = std::move(rhs.stack_);
1673  parseResult_ = rhs.parseResult_;
1674 
1675  rhs.allocator_ = 0;
1676  rhs.ownAllocator_ = 0;
1677  rhs.parseResult_ = ParseResult();
1678 
1679  return *this;
1680  }
1681 #endif
1682 
1683  //!@name Parse from stream
1684  //!@{
1685 
1686  //! Parse JSON text from an input stream (with Encoding conversion)
1687  /*! \tparam parseFlags Combination of \ref ParseFlag.
1688  \tparam SourceEncoding Encoding of input stream
1689  \tparam InputStream Type of input stream, implementing Stream concept
1690  \param is Input stream to be parsed.
1691  \return The document itself for fluent API.
1692  */
1693  template <unsigned parseFlags, typename SourceEncoding, typename InputStream>
1694  GenericDocument& ParseStream(InputStream& is) {
1695  ValueType::SetNull(); // Remove existing root if exist
1697  ClearStackOnExit scope(*this);
1698  parseResult_ = reader.template Parse<parseFlags>(is, *this);
1699  if (parseResult_) {
1700  RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object
1701  this->RawAssign(*stack_.template Pop<ValueType>(1)); // Add this-> to prevent issue 13.
1702  }
1703  return *this;
1704  }
1705 
1706  //! Parse JSON text from an input stream
1707  /*! \tparam parseFlags Combination of \ref ParseFlag.
1708  \tparam InputStream Type of input stream, implementing Stream concept
1709  \param is Input stream to be parsed.
1710  \return The document itself for fluent API.
1711  */
1712  template <unsigned parseFlags, typename InputStream>
1713  GenericDocument& ParseStream(InputStream& is) {
1714  return ParseStream<parseFlags,Encoding,InputStream>(is);
1715  }
1716 
1717  //! Parse JSON text from an input stream (with \ref kParseDefaultFlags)
1718  /*! \tparam InputStream Type of input stream, implementing Stream concept
1719  \param is Input stream to be parsed.
1720  \return The document itself for fluent API.
1721  */
1722  template <typename InputStream>
1723  GenericDocument& ParseStream(InputStream& is) {
1724  return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is);
1725  }
1726  //!@}
1727 
1728  //!@name Parse in-place from mutable string
1729  //!@{
1730 
1731  //! Parse JSON text from a mutable string (with Encoding conversion)
1732  /*! \tparam parseFlags Combination of \ref ParseFlag.
1733  \tparam SourceEncoding Transcoding from input Encoding
1734  \param str Mutable zero-terminated string to be parsed.
1735  \return The document itself for fluent API.
1736  */
1737  template <unsigned parseFlags, typename SourceEncoding>
1740  return ParseStream<parseFlags | kParseInsituFlag, SourceEncoding>(s);
1741  }
1742 
1743  //! Parse JSON text from a mutable string
1744  /*! \tparam parseFlags Combination of \ref ParseFlag.
1745  \param str Mutable zero-terminated string to be parsed.
1746  \return The document itself for fluent API.
1747  */
1748  template <unsigned parseFlags>
1750  return ParseInsitu<parseFlags, Encoding>(str);
1751  }
1752 
1753  //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags)
1754  /*! \param str Mutable zero-terminated string to be parsed.
1755  \return The document itself for fluent API.
1756  */
1758  return ParseInsitu<kParseDefaultFlags, Encoding>(str);
1759  }
1760  //!@}
1761 
1762  //!@name Parse from read-only string
1763  //!@{
1764 
1765  //! Parse JSON text from a read-only string (with Encoding conversion)
1766  /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
1767  \tparam SourceEncoding Transcoding from input Encoding
1768  \param str Read-only zero-terminated string to be parsed.
1769  */
1770  template <unsigned parseFlags, typename SourceEncoding>
1771  GenericDocument& Parse(const Ch* str) {
1772  RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag));
1774  return ParseStream<parseFlags, SourceEncoding>(s);
1775  }
1776 
1777  //! Parse JSON text from a read-only string
1778  /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag).
1779  \param str Read-only zero-terminated string to be parsed.
1780  */
1781  template <unsigned parseFlags>
1782  GenericDocument& Parse(const Ch* str) {
1783  return Parse<parseFlags, Encoding>(str);
1784  }
1785 
1786  //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags)
1787  /*! \param str Read-only zero-terminated string to be parsed.
1788  */
1789  GenericDocument& Parse(const Ch* str) {
1790  return Parse<kParseDefaultFlags>(str);
1791  }
1792  //!@}
1793 
1794  //!@name Handling parse errors
1795  //!@{
1796 
1797  //! Whether a parse error has occured in the last parsing.
1798  bool HasParseError() const { return parseResult_.IsError(); }
1799 
1800  //! Get the \ref ParseErrorCode of last parsing.
1801  ParseErrorCode GetParseError() const { return parseResult_.Code(); }
1802 
1803  //! Get the position of last parsing error in input, 0 otherwise.
1804  size_t GetErrorOffset() const { return parseResult_.Offset(); }
1805 
1806  //!@}
1807 
1808  //! Get the allocator of this document.
1809  Allocator& GetAllocator() { return *allocator_; }
1810 
1811  //! Get the capacity of stack in bytes.
1812  size_t GetStackCapacity() const { return stack_.GetCapacity(); }
1813 
1814 private:
1815  // clear stack on any exit from ParseStream, e.g. due to exception
1816  struct ClearStackOnExit {
1817  explicit ClearStackOnExit(GenericDocument& d) : d_(d) {}
1818  ~ClearStackOnExit() { d_.ClearStack(); }
1819  private:
1820  ClearStackOnExit(const ClearStackOnExit&);
1821  ClearStackOnExit& operator=(const ClearStackOnExit&);
1822  GenericDocument& d_;
1823  };
1824 
1825  // callers of the following private Handler functions
1826  template <typename,typename,typename> friend class GenericReader; // for parsing
1827  template <typename, typename> friend class GenericValue; // for deep copying
1828 
1829  // Implementation of Handler
1830  bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; }
1831  bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; }
1832  bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
1833  bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
1834  bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
1835  bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; }
1836  bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; }
1837 
1838  bool String(const Ch* str, SizeType length, bool copy) {
1839  if (copy)
1840  new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator());
1841  else
1842  new (stack_.template Push<ValueType>()) ValueType(str, length);
1843  return true;
1844  }
1845 
1846  bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
1847 
1848  bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
1849 
1850  bool EndObject(SizeType memberCount) {
1851  typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
1852  stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
1853  return true;
1854  }
1855 
1856  bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; }
1857 
1858  bool EndArray(SizeType elementCount) {
1859  ValueType* elements = stack_.template Pop<ValueType>(elementCount);
1860  stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator());
1861  return true;
1862  }
1863 
1864 private:
1865  //! Prohibit assignment
1866  GenericDocument& operator=(const GenericDocument&);
1867 
1868  void ClearStack() {
1869  if (Allocator::kNeedFree)
1870  while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects)
1871  (stack_.template Pop<ValueType>(1))->~ValueType();
1872  else
1873  stack_.Clear();
1874  stack_.ShrinkToFit();
1875  }
1876 
1877  void Destroy() {
1878  RAPIDJSON_DELETE(ownAllocator_);
1879  }
1880 
1881  static const size_t kDefaultStackCapacity = 1024;
1882  Allocator* allocator_;
1883  Allocator* ownAllocator_;
1884  internal::Stack<StackAllocator> stack_;
1885  ParseResult parseResult_;
1886 };
1887 
1888 //! GenericDocument with UTF8 encoding
1890 
1891 // defined here due to the dependency on GenericDocument
1892 template <typename Encoding, typename Allocator>
1893 template <typename SourceAllocator>
1894 inline
1896 {
1898  rhs.Accept(d);
1899  RawAssign(*d.stack_.template Pop<GenericValue>(1));
1900 }
1901 
1902 } // namespace rapidjson
1903 
1904 #if defined(_MSC_VER) || defined(__GNUC__)
1905 RAPIDJSON_DIAG_POP
1906 #endif
1907 
1908 #endif // RAPIDJSON_DOCUMENT_H_
BaseType::difference_type DifferenceType
Signed integer type (e.g. ptrdiff_t)
Definition: document.h:136
GenericValue< Encoding, Allocator > ValueType
Value type of the document.
Definition: document.h:1625
GenericValue(unsigned u) RAPIDJSON_NOEXCEPT
Constructor for unsigned value.
Definition: document.h:502
true
Definition: rapidjson.h:570
ValueIterator Erase(ConstValueIterator first, ConstValueIterator last)
Remove elements in the range [first, last) of the array.
Definition: document.h:1284
Definition: document.h:1497
Read-only string stream.
Definition: rapidjson.h:496
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:663
ValueIterator Begin()
Element iterator.
Definition: document.h:1167
GenericMemberIterator< true, Encoding, Allocator > ConstIterator
Constant iterator type.
Definition: document.h:127
DifferenceType operator-(ConstIterator that) const
Distance.
Definition: document.h:197
GenericValue(const Ch *s, SizeType length, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:543
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with Encoding conversion)
Definition: document.h:1738
GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT
Constructor for int64_t value.
Definition: document.h:509
~GenericValue()
Destructor.
Definition: document.h:558
#define RAPIDJSON_UINT64_C2(high32, low32)
Construct a 64-bit literal by a pair of 32-bit integer.
Definition: rapidjson.h:186
SAX-style JSON parser. Use Reader for UTF8 encoding and default allocator.
Definition: reader.h:363
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with kParseDefaultFlags)
Definition: document.h:1723
GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:540
GenericValue & SetString(const std::basic_string< Ch > &s, Allocator &allocator)
Set this value as a string by copying from source string.
Definition: document.h:1379
GenericValue & SetObject()
Set this value as an empty object.
Definition: document.h:794
GenericStringRef< Ch > StringRefType
Reference to a constant string.
Definition: document.h:428
GenericMemberIterator Iterator
Iterator type itself.
Definition: document.h:125
ConstMemberIterator MemberBegin() const
Const member iterator.
Definition: document.h:844
GenericValue & operator=(GenericValue &rhs) RAPIDJSON_NOEXCEPT
Assignment with move semantics.
Definition: document.h:591
ConstMemberIterator MemberEnd() const
Const past-the-end member iterator.
Definition: document.h:847
unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:247
GenericMemberIterator< false, Encoding, Allocator > NonConstIterator
Non-constant iterator type.
Definition: document.h:129
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:1626
MemberIterator FindMember(const GenericValue< Encoding, SourceAllocator > &name)
Find member by name.
Definition: document.h:910
bool ObjectEmpty() const
Check whether the object is empty.
Definition: document.h:800
false
Definition: rapidjson.h:569
ParseErrorCode
Error code of parsing.
Definition: error.h:63
bool operator!=(const GenericValue< Encoding, SourceAllocator > &rhs) const
Not-equal-to operator.
Definition: document.h:731
#define RAPIDJSON_STATIC_ASSERT(x)
(Internal) macro to check for conditions at compile-time
Definition: rapidjson.h:301
GenericValue(const Ch *s, Allocator &allocator)
Constructor for copy-string (i.e. do make a copy of string)
Definition: document.h:546
bool RemoveMember(const Ch *name)
Remove a member in object by its name.
Definition: document.h:1043
bool Accept(Handler &handler) const
Generate events of this value to a Handler.
Definition: document.h:1392
GenericValue & PopBack()
Remove the last element in the array.
Definition: document.h:1258
GenericValue & Reserve(SizeType newCapacity, Allocator &allocator)
Request the array to have enough capacity to store elements.
Definition: document.h:1184
ValueIterator End()
Past-the-end element iterator
Definition: document.h:1170
bool IsError() const
Whether the result is an error.
Definition: error.h:120
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with kParseDefaultFlags)
Definition: document.h:1789
bool GetBool() const
Set boolean value.
Definition: document.h:782
MemberIterator RemoveMember(MemberIterator m)
Remove a member in object by iterator.
Definition: document.h:1067
MemberIterator MemberBegin()
Member iterator.
Definition: document.h:850
Allocator AllocatorType
Allocator type from template parameter.
Definition: document.h:426
GenericValue & AddMember(StringRefType name, StringRefType value, Allocator &allocator)
Add a constant string value as member (name-value pair) to the object.
Definition: document.h:994
GenericValue(const Ch *s, SizeType length) RAPIDJSON_NOEXCEPT
Constructor for constant string (i.e. do not make a copy of string)
Definition: document.h:537
GenericValue & operator[](const GenericValue< Encoding, SourceAllocator > &name)
Get a value from an object associated with the name.
Definition: document.h:829
GenericValue & SetString(const Ch *s, SizeType length, Allocator &allocator)
Set this value as a string by copying from source string.
Definition: document.h:1361
MemberIterator EraseMember(ConstMemberIterator pos)
Remove a member from an object by iterator.
Definition: document.h:1095
GenericStringRef(const CharType *str, SizeType len)
Create constant string reference from pointer and length.
Definition: document.h:318
bool operator==(const std::basic_string< Ch > &rhs) const
Equal-to operator with string object.
Definition: document.h:719
Name-value pair in a JSON object value.
Definition: document.h:82
GenericValue & SetString(const Ch *s, SizeType length)
Set this value as a string without copying source string.
Definition: document.h:1344
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string (with kParseDefaultFlags)
Definition: document.h:1757
SizeType Size() const
Get the number of elements in array.
Definition: document.h:1134
const SizeType length
length of the string (excluding the trailing NULL terminator)
Definition: document.h:325
BaseType::reference Reference
Reference to (const) GenericMember.
Definition: document.h:134
const GenericValue * ConstValueIterator
Constant value iterator for iterating in array.
Definition: document.h:432
size_t GetErrorOffset() const
Get the position of last parsing error in input, 0 otherwise.
Definition: document.h:1804
Concept for encoding of Unicode characters.
GenericValue & AddMember(GenericValue &name, GenericValue &value, Allocator &allocator)
Add a member (name-value pair) to the object.
Definition: document.h:931
Result of parsing (wraps ParseErrorCode)
Definition: error.h:105
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream (with Encoding conversion)
Definition: document.h:1694
MemberIterator FindMember(const Ch *name)
Find member by name.
Definition: document.h:889
ConstValueIterator Begin() const
Constant element iterator.
Definition: document.h:1173
void Clear()
Remove all elements in the array.
Definition: document.h:1146
GenericStringRef< CharType > StringRef(const CharType *str)
Mark a character pointer as constant string.
Definition: document.h:348
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string.
Definition: document.h:1782
Type
Type of JSON value.
Definition: rapidjson.h:567
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:1624
GenericValue & operator[](SizeType index)
Get an element from array by index.
Definition: document.h:1158
BaseType::pointer Pointer
Pointer to (const) GenericMember.
Definition: document.h:132
ParseErrorCode GetParseError() const
Get the ParseErrorCode of last parsing.
Definition: document.h:1801
object
Definition: rapidjson.h:571
GenericValue & PushBack(GenericValue &value, Allocator &allocator)
Append a GenericValue at the end of the array.
Definition: document.h:1203
GenericValue & operator[](T *name)
Get a value from an object associated with the name.
Definition: document.h:812
GenericValue & Swap(GenericValue &other) RAPIDJSON_NOEXCEPT
Exchange the contents of this value with those of other.
Definition: document.h:653
MemberIterator MemberEnd()
Past-the-end member iterator
Definition: document.h:853
GenericStringRef(const CharType(&str)[N]) RAPIDJSON_NOEXCEPT
Create string reference from const character array.
Definition: document.h:286
bool operator!=(const Ch *rhs) const
Not-equal-to operator with const C-string pointer.
Definition: document.h:734
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:552
#define RAPIDJSON_NEW(x)
! customization point for global new
Definition: rapidjson.h:408
GenericValue(Type type) RAPIDJSON_NOEXCEPT
Constructor with JSON value type.
Definition: document.h:458
A document for parsing JSON text as DOM.
Definition: document.h:1622
array
Definition: rapidjson.h:572
GenericValue * ValueIterator
Value iterator for iterating in array.
Definition: document.h:431
bool operator==(const GenericValue< Encoding, SourceAllocator > &rhs) const
Equal-to operator.
Definition: document.h:674
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition: rapidjson.h:412
Encoding::Ch Ch
Character type derived from Encoding.
Definition: document.h:427
Definition: document.h:1501
GenericMemberIterator< false, Encoding, Allocator >::Iterator MemberIterator
Member iterator for iterating in object.
Definition: document.h:429
size_t GetStackCapacity() const
Get the capacity of stack in bytes.
Definition: document.h:1812
GenericValue(bool b) RAPIDJSON_NOEXCEPT
Constructor for boolean value.
Definition: document.h:487
GenericValue(int i) RAPIDJSON_NOEXCEPT
Constructor for int value.
Definition: document.h:495
GenericValue< Encoding, Allocator > value
value of member.
Definition: document.h:84
GenericValue() RAPIDJSON_NOEXCEPT
Default constructor creates a null value.
Definition: document.h:438
ParseErrorCode Code() const
Get the error code.
Definition: error.h:113
GenericStringRef(const CharType *str)
Explicitly create string reference from const character pointer.
Definition: document.h:308
null
Definition: rapidjson.h:568
GenericDocument(Allocator *allocator=0, size_t stackCapacity=kDefaultStackCapacity, StackAllocator *stackAllocator=0)
Constructor.
Definition: document.h:1633
GenericValue< Encoding, Allocator > name
name of member (must be a string)
Definition: document.h:83
string
Definition: rapidjson.h:573
Allocator & GetAllocator()
Get the allocator of this document.
Definition: document.h:1809
GenericMember< Encoding, Allocator > Member
Name-value pair in an object.
Definition: document.h:424
GenericDocument & ParseStream(InputStream &is)
Parse JSON text from an input stream.
Definition: document.h:1713
SizeType MemberCount() const
Get the number of members in the object.
Definition: document.h:797
CharType Ch
character type of the string
Definition: document.h:260
Encoding EncodingType
Encoding type from template parameter.
Definition: document.h:425
bool HasMember(const GenericValue< Encoding, SourceAllocator > &name) const
Check whether a member exists in the object with GenericValue name.
Definition: document.h:875
GenericValue & SetString(StringRefType s)
Set this value as a string without copying source string.
Definition: document.h:1351
void RemoveAllMembers()
Remove all members in the object.
Definition: document.h:1028
GenericMemberIterator(const NonConstIterator &it)
Iterator conversions to more const.
Definition: document.h:160
GenericValue & operator=(StringRefType str) RAPIDJSON_NOEXCEPT
Assignment of constant string reference (no copy)
Definition: document.h:610
bool operator==(const Ch *rhs) const
Equal-to operator with const C-string pointer.
Definition: document.h:713
In-situ(destructive) parsing.
Definition: reader.h:129
bool HasMember(const Ch *name) const
Check whether a member exists in the object.
Definition: document.h:863
bool Empty() const
Check whether the array is empty.
Definition: document.h:1140
Reference to a constant string (not taking a copy)
Definition: document.h:259
GenericValue(double d) RAPIDJSON_NOEXCEPT
Constructor for double value.
Definition: document.h:534
GenericValue & SetBool(bool b)
Definition: document.h:785
Concept for allocating, resizing and freeing memory block.
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:73
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:1608
GenericValue & CopyFrom(const GenericValue< Encoding, SourceAllocator > &rhs, Allocator &allocator)
Deep-copy assignment from Value.
Definition: document.h:641
size_t Offset() const
Get the error offset, if IsError(), 0 otherwise.
Definition: error.h:115
GenericValue & SetArray()
Set this value as an empty array.
Definition: document.h:1131
(Constant) member iterator for a JSON object value
Definition: document.h:112
GenericValue & SetString(const Ch *s, Allocator &allocator)
Set this value as a string by copying from source string.
Definition: document.h:1369
MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last)
Remove members in the range [first, last) from an object.
Definition: document.h:1108
const Ch *const s
plain CharType pointer
Definition: document.h:324
GenericMemberIterator< true, Encoding, Allocator >::Iterator ConstMemberIterator
Constant member iterator for iterating in object.
Definition: document.h:430
ConstValueIterator End() const
Constant past-the-end element iterator.
Definition: document.h:1176
GenericMemberIterator()
Default constructor (singular value)
Definition: document.h:142
SizeType Capacity() const
Get the capacity of array.
Definition: document.h:1137
GenericValue & PushBack(StringRefType value, Allocator &allocator)
Append a constant string reference at the end of the array.
Definition: document.h:1226
bool HasParseError() const
Whether a parse error has occured in the last parsing.
Definition: document.h:1798
GenericValue & AddMember(StringRefType name, GenericValue &value, Allocator &allocator)
Add a member (name-value pair) to the object.
Definition: document.h:980
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition: rapidjson.h:269
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:1889
GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT
Constructor for uint64_t value.
Definition: document.h:523
number
Definition: rapidjson.h:574
GenericDocument & ParseInsitu(Ch *str)
Parse JSON text from a mutable string.
Definition: document.h:1749
ValueIterator Erase(ConstValueIterator pos)
Remove an element of array by iterator.
Definition: document.h:1272
GenericDocument & Parse(const Ch *str)
Parse JSON text from a read-only string (with Encoding conversion)
Definition: document.h:1771
SizeType GetStringLength() const
Get the length of string.
Definition: document.h:1334
A read-write string stream.
Definition: rapidjson.h:530