RapidJSON: include/rapidjson/document.h Source File

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