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