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