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