DeepCover Embedded Security in IoT: Public-key Secured Data Paths
Dependencies: MaximInterface
document.h
00001 // Tencent is pleased to support the open source community by making RapidJSON available. 00002 // 00003 // Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. 00004 // 00005 // Licensed under the MIT License (the "License"); you may not use this file except 00006 // in compliance with the License. You may obtain a copy of the License at 00007 // 00008 // http://opensource.org/licenses/MIT 00009 // 00010 // Unless required by applicable law or agreed to in writing, software distributed 00011 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00012 // CONDITIONS OF ANY KIND, either express or implied. See the License for the 00013 // specific language governing permissions and limitations under the License. 00014 00015 #ifndef RAPIDJSON_DOCUMENT_H_ 00016 #define RAPIDJSON_DOCUMENT_H_ 00017 00018 /*! \file document.h */ 00019 00020 #include "reader.h " 00021 #include "internal/meta.h" 00022 #include "internal/strfunc.h" 00023 #include "memorystream.h" 00024 #include "encodedstream.h" 00025 #include <new> // placement new 00026 #include <limits> 00027 00028 RAPIDJSON_DIAG_PUSH 00029 #ifdef _MSC_VER 00030 RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant 00031 RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data 00032 #endif 00033 00034 #ifdef __clang__ 00035 RAPIDJSON_DIAG_OFF(padded) 00036 RAPIDJSON_DIAG_OFF(switch-enum) 00037 RAPIDJSON_DIAG_OFF(c++98-compat) 00038 #endif 00039 00040 #ifdef __GNUC__ 00041 RAPIDJSON_DIAG_OFF(effc++) 00042 #if __GNUC__ >= 6 00043 RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions 00044 #endif 00045 #endif // __GNUC__ 00046 00047 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS 00048 #include <iterator> // std::iterator, std::random_access_iterator_tag 00049 #endif 00050 00051 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 00052 #include <utility> // std::move 00053 #endif 00054 00055 RAPIDJSON_NAMESPACE_BEGIN 00056 00057 // Forward declaration. 00058 template <typename Encoding, typename Allocator> 00059 class GenericValue; 00060 00061 template <typename Encoding, typename Allocator, typename StackAllocator> 00062 class GenericDocument; 00063 00064 //! Name-value pair in a JSON object value. 00065 /*! 00066 This class was internal to GenericValue. It used to be a inner struct. 00067 But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct. 00068 https://code.google.com/p/rapidjson/issues/detail?id=64 00069 */ 00070 template <typename Encoding, typename Allocator> 00071 struct GenericMember { 00072 GenericValue<Encoding, Allocator> name; //!< name of member (must be a string) 00073 GenericValue<Encoding, Allocator> value; //!< value of member. 00074 }; 00075 00076 /////////////////////////////////////////////////////////////////////////////// 00077 // GenericMemberIterator 00078 00079 #ifndef RAPIDJSON_NOMEMBERITERATORCLASS 00080 00081 //! (Constant) member iterator for a JSON object value 00082 /*! 00083 \tparam Const Is this a constant iterator? 00084 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) 00085 \tparam Allocator Allocator type for allocating memory of object, array and string. 00086 00087 This class implements a Random Access Iterator for GenericMember elements 00088 of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements]. 00089 00090 \note This iterator implementation is mainly intended to avoid implicit 00091 conversions from iterator values to \c NULL, 00092 e.g. from GenericValue::FindMember. 00093 00094 \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a 00095 pointer-based implementation, if your platform doesn't provide 00096 the C++ <iterator> header. 00097 00098 \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator 00099 */ 00100 template <bool Const, typename Encoding, typename Allocator> 00101 class GenericMemberIterator 00102 : public std::iterator<std::random_access_iterator_tag 00103 , typename internal::MaybeAddConst<Const,GenericMember<Encoding,Allocator> >::Type> { 00104 00105 friend class GenericValue<Encoding,Allocator>; 00106 template <bool, typename, typename> friend class GenericMemberIterator; 00107 00108 typedef GenericMember<Encoding,Allocator> PlainType; 00109 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType; 00110 typedef std::iterator<std::random_access_iterator_tag,ValueType> BaseType; 00111 00112 public: 00113 //! Iterator type itself 00114 typedef GenericMemberIterator Iterator; 00115 //! Constant iterator type 00116 typedef GenericMemberIterator<true,Encoding,Allocator> ConstIterator; 00117 //! Non-constant iterator type 00118 typedef GenericMemberIterator<false,Encoding,Allocator> NonConstIterator; 00119 00120 //! Pointer to (const) GenericMember 00121 typedef typename BaseType::pointer Pointer; 00122 //! Reference to (const) GenericMember 00123 typedef typename BaseType::reference Reference; 00124 //! Signed integer type (e.g. \c ptrdiff_t) 00125 typedef typename BaseType::difference_type DifferenceType; 00126 00127 //! Default constructor (singular value) 00128 /*! Creates an iterator pointing to no element. 00129 \note All operations, except for comparisons, are undefined on such values. 00130 */ 00131 GenericMemberIterator() : ptr_() {} 00132 00133 //! Iterator conversions to more const 00134 /*! 00135 \param it (Non-const) iterator to copy from 00136 00137 Allows the creation of an iterator from another GenericMemberIterator 00138 that is "less const". Especially, creating a non-constant iterator 00139 from a constant iterator are disabled: 00140 \li const -> non-const (not ok) 00141 \li const -> const (ok) 00142 \li non-const -> const (ok) 00143 \li non-const -> non-const (ok) 00144 00145 \note If the \c Const template parameter is already \c false, this 00146 constructor effectively defines a regular copy-constructor. 00147 Otherwise, the copy constructor is implicitly defined. 00148 */ 00149 GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {} 00150 Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; } 00151 00152 //! @name stepping 00153 //@{ 00154 Iterator& operator++(){ ++ptr_; return *this; } 00155 Iterator& operator--(){ --ptr_; return *this; } 00156 Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; } 00157 Iterator operator--(int){ Iterator old(*this); --ptr_; return old; } 00158 //@} 00159 00160 //! @name increment/decrement 00161 //@{ 00162 Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); } 00163 Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); } 00164 00165 Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; } 00166 Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; } 00167 //@} 00168 00169 //! @name relations 00170 //@{ 00171 bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; } 00172 bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; } 00173 bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; } 00174 bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; } 00175 bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; } 00176 bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; } 00177 //@} 00178 00179 //! @name dereference 00180 //@{ 00181 Reference operator*() const { return *ptr_; } 00182 Pointer operator->() const { return ptr_; } 00183 Reference operator[](DifferenceType n) const { return ptr_[n]; } 00184 //@} 00185 00186 //! Distance 00187 DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; } 00188 00189 private: 00190 //! Internal constructor from plain pointer 00191 explicit GenericMemberIterator(Pointer p) : ptr_(p) {} 00192 00193 Pointer ptr_; //!< raw pointer 00194 }; 00195 00196 #else // RAPIDJSON_NOMEMBERITERATORCLASS 00197 00198 // class-based member iterator implementation disabled, use plain pointers 00199 00200 template <bool Const, typename Encoding, typename Allocator> 00201 struct GenericMemberIterator; 00202 00203 //! non-const GenericMemberIterator 00204 template <typename Encoding, typename Allocator> 00205 struct GenericMemberIterator<false,Encoding,Allocator> { 00206 //! use plain pointer as iterator type 00207 typedef GenericMember<Encoding,Allocator>* Iterator; 00208 }; 00209 //! const GenericMemberIterator 00210 template <typename Encoding, typename Allocator> 00211 struct GenericMemberIterator<true,Encoding,Allocator> { 00212 //! use plain const pointer as iterator type 00213 typedef const GenericMember<Encoding,Allocator>* Iterator; 00214 }; 00215 00216 #endif // RAPIDJSON_NOMEMBERITERATORCLASS 00217 00218 /////////////////////////////////////////////////////////////////////////////// 00219 // GenericStringRef 00220 00221 //! Reference to a constant string (not taking a copy) 00222 /*! 00223 \tparam CharType character type of the string 00224 00225 This helper class is used to automatically infer constant string 00226 references for string literals, especially from \c const \b (!) 00227 character arrays. 00228 00229 The main use is for creating JSON string values without copying the 00230 source string via an \ref Allocator. This requires that the referenced 00231 string pointers have a sufficient lifetime, which exceeds the lifetime 00232 of the associated GenericValue. 00233 00234 \b Example 00235 \code 00236 Value v("foo"); // ok, no need to copy & calculate length 00237 const char foo[] = "foo"; 00238 v.SetString(foo); // ok 00239 00240 const char* bar = foo; 00241 // Value x(bar); // not ok, can't rely on bar's lifetime 00242 Value x(StringRef(bar)); // lifetime explicitly guaranteed by user 00243 Value y(StringRef(bar, 3)); // ok, explicitly pass length 00244 \endcode 00245 00246 \see StringRef, GenericValue::SetString 00247 */ 00248 template<typename CharType> 00249 struct GenericStringRef { 00250 typedef CharType Ch; //!< character type of the string 00251 00252 //! Create string reference from \c const character array 00253 #ifndef __clang__ // -Wdocumentation 00254 /*! 00255 This constructor implicitly creates a constant string reference from 00256 a \c const character array. It has better performance than 00257 \ref StringRef(const CharType*) by inferring the string \ref length 00258 from the array length, and also supports strings containing null 00259 characters. 00260 00261 \tparam N length of the string, automatically inferred 00262 00263 \param str Constant character array, lifetime assumed to be longer 00264 than the use of the string in e.g. a GenericValue 00265 00266 \post \ref s == str 00267 00268 \note Constant complexity. 00269 \note There is a hidden, private overload to disallow references to 00270 non-const character arrays to be created via this constructor. 00271 By this, e.g. function-scope arrays used to be filled via 00272 \c snprintf are excluded from consideration. 00273 In such cases, the referenced string should be \b copied to the 00274 GenericValue instead. 00275 */ 00276 #endif 00277 template<SizeType N> 00278 GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT 00279 : s(str), length(N-1) {} 00280 00281 //! Explicitly create string reference from \c const character pointer 00282 #ifndef __clang__ // -Wdocumentation 00283 /*! 00284 This constructor can be used to \b explicitly create a reference to 00285 a constant string pointer. 00286 00287 \see StringRef(const CharType*) 00288 00289 \param str Constant character pointer, lifetime assumed to be longer 00290 than the use of the string in e.g. a GenericValue 00291 00292 \post \ref s == str 00293 00294 \note There is a hidden, private overload to disallow references to 00295 non-const character arrays to be created via this constructor. 00296 By this, e.g. function-scope arrays used to be filled via 00297 \c snprintf are excluded from consideration. 00298 In such cases, the referenced string should be \b copied to the 00299 GenericValue instead. 00300 */ 00301 #endif 00302 explicit GenericStringRef(const CharType* str) 00303 : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); } 00304 00305 //! Create constant string reference from pointer and length 00306 #ifndef __clang__ // -Wdocumentation 00307 /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue 00308 \param len length of the string, excluding the trailing NULL terminator 00309 00310 \post \ref s == str && \ref length == len 00311 \note Constant complexity. 00312 */ 00313 #endif 00314 GenericStringRef(const CharType* str, SizeType len) 00315 : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); } 00316 00317 GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {} 00318 00319 //! implicit conversion to plain CharType pointer 00320 operator const Ch *() const { return s; } 00321 00322 const Ch* const s; //!< plain CharType pointer 00323 const SizeType length; //!< length of the string (excluding the trailing NULL terminator) 00324 00325 private: 00326 //! Disallow construction from non-const array 00327 template<SizeType N> 00328 GenericStringRef(CharType (&str)[N]) /* = delete */; 00329 //! Copy assignment operator not permitted - immutable type 00330 GenericStringRef& operator=(const GenericStringRef& rhs) /* = delete */; 00331 }; 00332 00333 //! Mark a character pointer as constant string 00334 /*! Mark a plain character pointer as a "string literal". This function 00335 can be used to avoid copying a character string to be referenced as a 00336 value in a JSON GenericValue object, if the string's lifetime is known 00337 to be valid long enough. 00338 \tparam CharType Character type of the string 00339 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue 00340 \return GenericStringRef string reference object 00341 \relatesalso GenericStringRef 00342 00343 \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember 00344 */ 00345 template<typename CharType> 00346 inline GenericStringRef<CharType> StringRef(const CharType* str) { 00347 return GenericStringRef<CharType>(str, internal::StrLen(str)); 00348 } 00349 00350 //! Mark a character pointer as constant string 00351 /*! Mark a plain character pointer as a "string literal". This function 00352 can be used to avoid copying a character string to be referenced as a 00353 value in a JSON GenericValue object, if the string's lifetime is known 00354 to be valid long enough. 00355 00356 This version has better performance with supplied length, and also 00357 supports string containing null characters. 00358 00359 \tparam CharType character type of the string 00360 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue 00361 \param length The length of source string. 00362 \return GenericStringRef string reference object 00363 \relatesalso GenericStringRef 00364 */ 00365 template<typename CharType> 00366 inline GenericStringRef<CharType> StringRef(const CharType* str, size_t length) { 00367 return GenericStringRef<CharType>(str, SizeType(length)); 00368 } 00369 00370 #if RAPIDJSON_HAS_STDSTRING 00371 //! Mark a string object as constant string 00372 /*! Mark a string object (e.g. \c std::string) as a "string literal". 00373 This function can be used to avoid copying a string to be referenced as a 00374 value in a JSON GenericValue object, if the string's lifetime is known 00375 to be valid long enough. 00376 00377 \tparam CharType character type of the string 00378 \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue 00379 \return GenericStringRef string reference object 00380 \relatesalso GenericStringRef 00381 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. 00382 */ 00383 template<typename CharType> 00384 inline GenericStringRef<CharType> StringRef(const std::basic_string<CharType>& str) { 00385 return GenericStringRef<CharType>(str.data(), SizeType(str.size())); 00386 } 00387 #endif 00388 00389 /////////////////////////////////////////////////////////////////////////////// 00390 // GenericValue type traits 00391 namespace internal { 00392 00393 template <typename T, typename Encoding = void, typename Allocator = void> 00394 struct IsGenericValueImpl : FalseType {}; 00395 00396 // select candidates according to nested encoding and allocator types 00397 template <typename T> struct IsGenericValueImpl<T, typename Void<typename T::EncodingType>::Type, typename Void<typename T::AllocatorType>::Type> 00398 : IsBaseOf<GenericValue<typename T::EncodingType, typename T::AllocatorType>, T>::Type {}; 00399 00400 // helper to match arbitrary GenericValue instantiations, including derived classes 00401 template <typename T> struct IsGenericValue : IsGenericValueImpl<T>::Type {}; 00402 00403 } // namespace internal 00404 00405 /////////////////////////////////////////////////////////////////////////////// 00406 // TypeHelper 00407 00408 namespace internal { 00409 00410 template <typename ValueType, typename T> 00411 struct TypeHelper {}; 00412 00413 template<typename ValueType> 00414 struct TypeHelper<ValueType, bool> { 00415 static bool Is(const ValueType& v) { return v.IsBool(); } 00416 static bool Get(const ValueType& v) { return v.GetBool(); } 00417 static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); } 00418 static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); } 00419 }; 00420 00421 template<typename ValueType> 00422 struct TypeHelper<ValueType, int> { 00423 static bool Is(const ValueType& v) { return v.IsInt(); } 00424 static int Get(const ValueType& v) { return v.GetInt(); } 00425 static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); } 00426 static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); } 00427 }; 00428 00429 template<typename ValueType> 00430 struct TypeHelper<ValueType, unsigned> { 00431 static bool Is(const ValueType& v) { return v.IsUint(); } 00432 static unsigned Get(const ValueType& v) { return v.GetUint(); } 00433 static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); } 00434 static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); } 00435 }; 00436 00437 template<typename ValueType> 00438 struct TypeHelper<ValueType, int64_t> { 00439 static bool Is(const ValueType& v) { return v.IsInt64(); } 00440 static int64_t Get(const ValueType& v) { return v.GetInt64(); } 00441 static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); } 00442 static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); } 00443 }; 00444 00445 template<typename ValueType> 00446 struct TypeHelper<ValueType, uint64_t> { 00447 static bool Is(const ValueType& v) { return v.IsUint64(); } 00448 static uint64_t Get(const ValueType& v) { return v.GetUint64(); } 00449 static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); } 00450 static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); } 00451 }; 00452 00453 template<typename ValueType> 00454 struct TypeHelper<ValueType, double> { 00455 static bool Is(const ValueType& v) { return v.IsDouble(); } 00456 static double Get(const ValueType& v) { return v.GetDouble(); } 00457 static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); } 00458 static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); } 00459 }; 00460 00461 template<typename ValueType> 00462 struct TypeHelper<ValueType, float> { 00463 static bool Is(const ValueType& v) { return v.IsFloat(); } 00464 static float Get(const ValueType& v) { return v.GetFloat(); } 00465 static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); } 00466 static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); } 00467 }; 00468 00469 template<typename ValueType> 00470 struct TypeHelper<ValueType, const typename ValueType::Ch*> { 00471 typedef const typename ValueType::Ch* StringType; 00472 static bool Is(const ValueType& v) { return v.IsString(); } 00473 static StringType Get(const ValueType& v) { return v.GetString(); } 00474 static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); } 00475 static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } 00476 }; 00477 00478 #if RAPIDJSON_HAS_STDSTRING 00479 template<typename ValueType> 00480 struct TypeHelper<ValueType, std::basic_string<typename ValueType::Ch> > { 00481 typedef std::basic_string<typename ValueType::Ch> StringType; 00482 static bool Is(const ValueType& v) { return v.IsString(); } 00483 static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); } 00484 static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); } 00485 }; 00486 #endif 00487 00488 template<typename ValueType> 00489 struct TypeHelper<ValueType, typename ValueType::Array> { 00490 typedef typename ValueType::Array ArrayType; 00491 static bool Is(const ValueType& v) { return v.IsArray(); } 00492 static ArrayType Get(ValueType& v) { return v.GetArray(); } 00493 static ValueType& Set(ValueType& v, ArrayType data) { return v = data; } 00494 static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; } 00495 }; 00496 00497 template<typename ValueType> 00498 struct TypeHelper<ValueType, typename ValueType::ConstArray> { 00499 typedef typename ValueType::ConstArray ArrayType; 00500 static bool Is(const ValueType& v) { return v.IsArray(); } 00501 static ArrayType Get(const ValueType& v) { return v.GetArray(); } 00502 }; 00503 00504 template<typename ValueType> 00505 struct TypeHelper<ValueType, typename ValueType::Object> { 00506 typedef typename ValueType::Object ObjectType; 00507 static bool Is(const ValueType& v) { return v.IsObject(); } 00508 static ObjectType Get(ValueType& v) { return v.GetObject(); } 00509 static ValueType& Set(ValueType& v, ObjectType data) { return v = data; } 00510 static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; } 00511 }; 00512 00513 template<typename ValueType> 00514 struct TypeHelper<ValueType, typename ValueType::ConstObject> { 00515 typedef typename ValueType::ConstObject ObjectType; 00516 static bool Is(const ValueType& v) { return v.IsObject(); } 00517 static ObjectType Get(const ValueType& v) { return v.GetObject(); } 00518 }; 00519 00520 } // namespace internal 00521 00522 // Forward declarations 00523 template <bool, typename> class GenericArray; 00524 template <bool, typename> class GenericObject; 00525 00526 /////////////////////////////////////////////////////////////////////////////// 00527 // GenericValue 00528 00529 //! Represents a JSON value. Use Value for UTF8 encoding and default allocator. 00530 /*! 00531 A JSON value can be one of 7 types. This class is a variant type supporting 00532 these types. 00533 00534 Use the Value if UTF8 and default allocator 00535 00536 \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document) 00537 \tparam Allocator Allocator type for allocating memory of object, array and string. 00538 */ 00539 template <typename Encoding, typename Allocator = MemoryPoolAllocator<> > 00540 class GenericValue { 00541 public: 00542 //! Name-value pair in an object. 00543 typedef GenericMember<Encoding, Allocator> Member; 00544 typedef Encoding EncodingType; //!< Encoding type from template parameter. 00545 typedef Allocator AllocatorType; //!< Allocator type from template parameter. 00546 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. 00547 typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string 00548 typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object. 00549 typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. 00550 typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. 00551 typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. 00552 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself. 00553 typedef GenericArray<false, ValueType> Array; 00554 typedef GenericArray<true, ValueType> ConstArray; 00555 typedef GenericObject<false, ValueType> Object; 00556 typedef GenericObject<true, ValueType> ConstObject; 00557 00558 //!@name Constructors and destructor. 00559 //@{ 00560 00561 //! Default constructor creates a null value. 00562 GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; } 00563 00564 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 00565 //! Move constructor in C++11 00566 GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) { 00567 rhs.data_.f.flags = kNullFlag; // give up contents 00568 } 00569 #endif 00570 00571 private: 00572 //! Copy constructor is not permitted. 00573 GenericValue(const GenericValue& rhs); 00574 00575 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 00576 //! Moving from a GenericDocument is not permitted. 00577 template <typename StackAllocator> 00578 GenericValue(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs); 00579 00580 //! Move assignment from a GenericDocument is not permitted. 00581 template <typename StackAllocator> 00582 GenericValue& operator=(GenericDocument<Encoding,Allocator,StackAllocator>&& rhs); 00583 #endif 00584 00585 public: 00586 00587 //! Constructor with JSON value type. 00588 /*! This creates a Value of specified type with default content. 00589 \param type Type of the value. 00590 \note Default content for number is zero. 00591 */ 00592 explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() { 00593 static const uint16_t defaultFlags[7] = { 00594 kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag, 00595 kNumberAnyFlag 00596 }; 00597 RAPIDJSON_ASSERT(type <= kNumberType); 00598 data_.f.flags = defaultFlags[type]; 00599 00600 // Use ShortString to store empty string. 00601 if (type == kStringType) 00602 data_.ss.SetLength(0); 00603 } 00604 00605 //! Explicit copy constructor (with allocator) 00606 /*! Creates a copy of a Value by using the given Allocator 00607 \tparam SourceAllocator allocator of \c rhs 00608 \param rhs Value to copy from (read-only) 00609 \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator(). 00610 \see CopyFrom() 00611 */ 00612 template< typename SourceAllocator > 00613 GenericValue(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator & allocator); 00614 00615 //! Constructor for boolean value. 00616 /*! \param b Boolean value 00617 \note This constructor is limited to \em real boolean values and rejects 00618 implicitly converted types like arbitrary pointers. Use an explicit cast 00619 to \c bool, if you want to construct a boolean JSON value in such cases. 00620 */ 00621 #ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen 00622 template <typename T> 00623 explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame<bool, T>))) RAPIDJSON_NOEXCEPT // See #472 00624 #else 00625 explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT 00626 #endif 00627 : data_() { 00628 // safe-guard against failing SFINAE 00629 RAPIDJSON_STATIC_ASSERT((internal::IsSame<bool,T>::Value)); 00630 data_.f.flags = b ? kTrueFlag : kFalseFlag; 00631 } 00632 00633 //! Constructor for int value. 00634 explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() { 00635 data_.n.i64 = i; 00636 data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag; 00637 } 00638 00639 //! Constructor for unsigned value. 00640 explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() { 00641 data_.n.u64 = u; 00642 data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag); 00643 } 00644 00645 //! Constructor for int64_t value. 00646 explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() { 00647 data_.n.i64 = i64; 00648 data_.f.flags = kNumberInt64Flag; 00649 if (i64 >= 0) { 00650 data_.f.flags |= kNumberUint64Flag; 00651 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) 00652 data_.f.flags |= kUintFlag; 00653 if (!(static_cast<uint64_t>(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) 00654 data_.f.flags |= kIntFlag; 00655 } 00656 else if (i64 >= static_cast<int64_t>(RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) 00657 data_.f.flags |= kIntFlag; 00658 } 00659 00660 //! Constructor for uint64_t value. 00661 explicit GenericValue(uint64_t u64) RAPIDJSON_NOEXCEPT : data_() { 00662 data_.n.u64 = u64; 00663 data_.f.flags = kNumberUint64Flag; 00664 if (!(u64 & RAPIDJSON_UINT64_C2(0x80000000, 0x00000000))) 00665 data_.f.flags |= kInt64Flag; 00666 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000))) 00667 data_.f.flags |= kUintFlag; 00668 if (!(u64 & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000))) 00669 data_.f.flags |= kIntFlag; 00670 } 00671 00672 //! Constructor for double value. 00673 explicit GenericValue(double d) RAPIDJSON_NOEXCEPT : data_() { data_.n.d = d; data_.f.flags = kNumberDoubleFlag; } 00674 00675 //! Constructor for constant string (i.e. do not make a copy of string) 00676 GenericValue(const Ch* s, SizeType length) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(StringRef(s, length)); } 00677 00678 //! Constructor for constant string (i.e. do not make a copy of string) 00679 explicit GenericValue(StringRefType s) RAPIDJSON_NOEXCEPT : data_() { SetStringRaw(s); } 00680 00681 //! Constructor for copy-string (i.e. do make a copy of string) 00682 GenericValue(const Ch* s, SizeType length, Allocator& allocator) : data_() { SetStringRaw(StringRef(s, length), allocator); } 00683 00684 //! Constructor for copy-string (i.e. do make a copy of string) 00685 GenericValue(const Ch*s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } 00686 00687 #if RAPIDJSON_HAS_STDSTRING 00688 //! Constructor for copy-string from a string object (i.e. do make a copy of string) 00689 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. 00690 */ 00691 GenericValue(const std::basic_string<Ch>& s, Allocator& allocator) : data_() { SetStringRaw(StringRef(s), allocator); } 00692 #endif 00693 00694 //! Constructor for Array. 00695 /*! 00696 \param a An array obtained by \c GetArray(). 00697 \note \c Array is always pass-by-value. 00698 \note the source array is moved into this value and the sourec array becomes empty. 00699 */ 00700 GenericValue(Array a) RAPIDJSON_NOEXCEPT : data_(a.value_.data_) { 00701 a.value_.data_ = Data(); 00702 a.value_.data_.f.flags = kArrayFlag; 00703 } 00704 00705 //! Constructor for Object. 00706 /*! 00707 \param o An object obtained by \c GetObject(). 00708 \note \c Object is always pass-by-value. 00709 \note the source object is moved into this value and the sourec object becomes empty. 00710 */ 00711 GenericValue(Object o) RAPIDJSON_NOEXCEPT : data_(o.value_.data_) { 00712 o.value_.data_ = Data(); 00713 o.value_.data_.f.flags = kObjectFlag; 00714 } 00715 00716 //! Destructor. 00717 /*! Need to destruct elements of array, members of object, or copy-string. 00718 */ 00719 ~GenericValue() { 00720 if (Allocator::kNeedFree) { // Shortcut by Allocator's trait 00721 switch(data_.f.flags) { 00722 case kArrayFlag: 00723 { 00724 GenericValue* e = GetElementsPointer(); 00725 for (GenericValue* v = e; v != e + data_.a.size; ++v) 00726 v->~GenericValue(); 00727 Allocator::Free(e); 00728 } 00729 break; 00730 00731 case kObjectFlag: 00732 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) 00733 m->~Member(); 00734 Allocator::Free(GetMembersPointer()); 00735 break; 00736 00737 case kCopyStringFlag: 00738 Allocator::Free(const_cast<Ch*>(GetStringPointer())); 00739 break; 00740 00741 default: 00742 break; // Do nothing for other types. 00743 } 00744 } 00745 } 00746 00747 //@} 00748 00749 //!@name Assignment operators 00750 //@{ 00751 00752 //! Assignment with move semantics. 00753 /*! \param rhs Source of the assignment. It will become a null value after assignment. 00754 */ 00755 GenericValue& operator=(GenericValue& rhs) RAPIDJSON_NOEXCEPT { 00756 RAPIDJSON_ASSERT(this != &rhs); 00757 this->~GenericValue(); 00758 RawAssign(rhs); 00759 return *this; 00760 } 00761 00762 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 00763 //! Move assignment in C++11 00764 GenericValue& operator=(GenericValue&& rhs) RAPIDJSON_NOEXCEPT { 00765 return *this = rhs.Move(); 00766 } 00767 #endif 00768 00769 //! Assignment of constant string reference (no copy) 00770 /*! \param str Constant string reference to be assigned 00771 \note This overload is needed to avoid clashes with the generic primitive type assignment overload below. 00772 \see GenericStringRef, operator=(T) 00773 */ 00774 GenericValue& operator=(StringRefType str) RAPIDJSON_NOEXCEPT { 00775 GenericValue s(str); 00776 return *this = s; 00777 } 00778 00779 //! Assignment with primitive types. 00780 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t 00781 \param value The value to be assigned. 00782 00783 \note The source type \c T explicitly disallows all pointer types, 00784 especially (\c const) \ref Ch*. This helps avoiding implicitly 00785 referencing character strings with insufficient lifetime, use 00786 \ref SetString(const Ch*, Allocator&) (for copying) or 00787 \ref StringRef() (to explicitly mark the pointer as constant) instead. 00788 All other pointer types would implicitly convert to \c bool, 00789 use \ref SetBool() instead. 00790 */ 00791 template <typename T> 00792 RAPIDJSON_DISABLEIF_RETURN((internal::IsPointer<T>), (GenericValue&)) 00793 operator=(T value) { 00794 GenericValue v(value); 00795 return *this = v; 00796 } 00797 00798 //! Deep-copy assignment from Value 00799 /*! Assigns a \b copy of the Value to the current Value object 00800 \tparam SourceAllocator Allocator type of \c rhs 00801 \param rhs Value to copy from (read-only) 00802 \param allocator Allocator to use for copying 00803 */ 00804 template <typename SourceAllocator> 00805 GenericValue& CopyFrom(const GenericValue<Encoding, SourceAllocator>& rhs, Allocator& allocator) { 00806 RAPIDJSON_ASSERT(static_cast<void*>(this) != static_cast<void const*>(&rhs)); 00807 this->~GenericValue(); 00808 new (this) GenericValue(rhs, allocator); 00809 return *this; 00810 } 00811 00812 //! Exchange the contents of this value with those of other. 00813 /*! 00814 \param other Another value. 00815 \note Constant complexity. 00816 */ 00817 GenericValue& Swap(GenericValue& other) RAPIDJSON_NOEXCEPT { 00818 GenericValue temp; 00819 temp.RawAssign(*this); 00820 RawAssign(other); 00821 other.RawAssign(temp); 00822 return *this; 00823 } 00824 00825 //! free-standing swap function helper 00826 /*! 00827 Helper function to enable support for common swap implementation pattern based on \c std::swap: 00828 \code 00829 void swap(MyClass& a, MyClass& b) { 00830 using std::swap; 00831 swap(a.value, b.value); 00832 // ... 00833 } 00834 \endcode 00835 \see Swap() 00836 */ 00837 friend inline void swap(GenericValue& a, GenericValue& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } 00838 00839 //! Prepare Value for move semantics 00840 /*! \return *this */ 00841 GenericValue& Move() RAPIDJSON_NOEXCEPT { return *this; } 00842 //@} 00843 00844 //!@name Equal-to and not-equal-to operators 00845 //@{ 00846 //! Equal-to operator 00847 /*! 00848 \note If an object contains duplicated named member, comparing equality with any object is always \c false. 00849 \note Linear time complexity (number of all values in the subtree and total lengths of all strings). 00850 */ 00851 template <typename SourceAllocator> 00852 bool operator==(const GenericValue<Encoding, SourceAllocator>& rhs) const { 00853 typedef GenericValue<Encoding, SourceAllocator> RhsType; 00854 if (GetType() != rhs.GetType()) 00855 return false; 00856 00857 switch (GetType()) { 00858 case kObjectType: // Warning: O(n^2) inner-loop 00859 if (data_.o.size != rhs.data_.o.size) 00860 return false; 00861 for (ConstMemberIterator lhsMemberItr = MemberBegin(); lhsMemberItr != MemberEnd(); ++lhsMemberItr) { 00862 typename RhsType::ConstMemberIterator rhsMemberItr = rhs.FindMember(lhsMemberItr->name); 00863 if (rhsMemberItr == rhs.MemberEnd() || lhsMemberItr->value != rhsMemberItr->value) 00864 return false; 00865 } 00866 return true; 00867 00868 case kArrayType: 00869 if (data_.a.size != rhs.data_.a.size) 00870 return false; 00871 for (SizeType i = 0; i < data_.a.size; i++) 00872 if ((*this)[i] != rhs[i]) 00873 return false; 00874 return true; 00875 00876 case kStringType: 00877 return StringEqual(rhs); 00878 00879 case kNumberType: 00880 if (IsDouble() || rhs.IsDouble()) { 00881 double a = GetDouble(); // May convert from integer to double. 00882 double b = rhs.GetDouble(); // Ditto 00883 return a >= b && a <= b; // Prevent -Wfloat-equal 00884 } 00885 else 00886 return data_.n.u64 == rhs.data_.n.u64; 00887 00888 default: 00889 return true; 00890 } 00891 } 00892 00893 //! Equal-to operator with const C-string pointer 00894 bool operator==(const Ch* rhs) const { return *this == GenericValue(StringRef(rhs)); } 00895 00896 #if RAPIDJSON_HAS_STDSTRING 00897 //! Equal-to operator with string object 00898 /*! \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. 00899 */ 00900 bool operator==(const std::basic_string<Ch>& rhs) const { return *this == GenericValue(StringRef(rhs)); } 00901 #endif 00902 00903 //! Equal-to operator with primitive types 00904 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c double, \c true, \c false 00905 */ 00906 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>,internal::IsGenericValue<T> >), (bool)) operator==(const T& rhs) const { return *this == GenericValue(rhs); } 00907 00908 //! Not-equal-to operator 00909 /*! \return !(*this == rhs) 00910 */ 00911 template <typename SourceAllocator> 00912 bool operator!=(const GenericValue<Encoding, SourceAllocator>& rhs) const { return !(*this == rhs); } 00913 00914 //! Not-equal-to operator with const C-string pointer 00915 bool operator!=(const Ch* rhs) const { return !(*this == rhs); } 00916 00917 //! Not-equal-to operator with arbitrary types 00918 /*! \return !(*this == rhs) 00919 */ 00920 template <typename T> RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& rhs) const { return !(*this == rhs); } 00921 00922 //! Equal-to operator with arbitrary types (symmetric version) 00923 /*! \return (rhs == lhs) 00924 */ 00925 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator==(const T& lhs, const GenericValue& rhs) { return rhs == lhs; } 00926 00927 //! Not-Equal-to operator with arbitrary types (symmetric version) 00928 /*! \return !(rhs == lhs) 00929 */ 00930 template <typename T> friend RAPIDJSON_DISABLEIF_RETURN((internal::IsGenericValue<T>), (bool)) operator!=(const T& lhs, const GenericValue& rhs) { return !(rhs == lhs); } 00931 //@} 00932 00933 //!@name Type 00934 //@{ 00935 00936 Type GetType() const { return static_cast<Type>(data_.f.flags & kTypeMask); } 00937 bool IsNull() const { return data_.f.flags == kNullFlag; } 00938 bool IsFalse() const { return data_.f.flags == kFalseFlag; } 00939 bool IsTrue() const { return data_.f.flags == kTrueFlag; } 00940 bool IsBool() const { return (data_.f.flags & kBoolFlag) != 0; } 00941 bool IsObject() const { return data_.f.flags == kObjectFlag; } 00942 bool IsArray() const { return data_.f.flags == kArrayFlag; } 00943 bool IsNumber() const { return (data_.f.flags & kNumberFlag) != 0; } 00944 bool IsInt() const { return (data_.f.flags & kIntFlag) != 0; } 00945 bool IsUint() const { return (data_.f.flags & kUintFlag) != 0; } 00946 bool IsInt64() const { return (data_.f.flags & kInt64Flag) != 0; } 00947 bool IsUint64() const { return (data_.f.flags & kUint64Flag) != 0; } 00948 bool IsDouble() const { return (data_.f.flags & kDoubleFlag) != 0; } 00949 bool IsString() const { return (data_.f.flags & kStringFlag) != 0; } 00950 00951 // Checks whether a number can be losslessly converted to a double. 00952 bool IsLosslessDouble() const { 00953 if (!IsNumber()) return false; 00954 if (IsUint64()) { 00955 uint64_t u = GetUint64(); 00956 volatile double d = static_cast<double>(u); 00957 return (d >= 0.0) 00958 && (d < static_cast<double>(std::numeric_limits<uint64_t>::max())) 00959 && (u == static_cast<uint64_t>(d)); 00960 } 00961 if (IsInt64()) { 00962 int64_t i = GetInt64(); 00963 volatile double d = static_cast<double>(i); 00964 return (d >= static_cast<double>(std::numeric_limits<int64_t>::min())) 00965 && (d < static_cast<double>(std::numeric_limits<int64_t>::max())) 00966 && (i == static_cast<int64_t>(d)); 00967 } 00968 return true; // double, int, uint are always lossless 00969 } 00970 00971 // Checks whether a number is a float (possible lossy). 00972 bool IsFloat() const { 00973 if ((data_.f.flags & kDoubleFlag) == 0) 00974 return false; 00975 double d = GetDouble(); 00976 return d >= -3.4028234e38 && d <= 3.4028234e38; 00977 } 00978 // Checks whether a number can be losslessly converted to a float. 00979 bool IsLosslessFloat() const { 00980 if (!IsNumber()) return false; 00981 double a = GetDouble(); 00982 if (a < static_cast<double>(-std::numeric_limits<float>::max()) 00983 || a > static_cast<double>(std::numeric_limits<float>::max())) 00984 return false; 00985 double b = static_cast<double>(static_cast<float>(a)); 00986 return a >= b && a <= b; // Prevent -Wfloat-equal 00987 } 00988 00989 //@} 00990 00991 //!@name Null 00992 //@{ 00993 00994 GenericValue& SetNull() { this->~GenericValue(); new (this) GenericValue(); return *this; } 00995 00996 //@} 00997 00998 //!@name Bool 00999 //@{ 01000 01001 bool GetBool() const { RAPIDJSON_ASSERT(IsBool()); return data_.f.flags == kTrueFlag; } 01002 //!< Set boolean value 01003 /*! \post IsBool() == true */ 01004 GenericValue& SetBool(bool b) { this->~GenericValue(); new (this) GenericValue(b); return *this; } 01005 01006 //@} 01007 01008 //!@name Object 01009 //@{ 01010 01011 //! Set this value as an empty object. 01012 /*! \post IsObject() == true */ 01013 GenericValue& SetObject() { this->~GenericValue(); new (this) GenericValue(kObjectType); return *this; } 01014 01015 //! Get the number of members in the object. 01016 SizeType MemberCount() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size; } 01017 01018 //! Check whether the object is empty. 01019 bool ObjectEmpty() const { RAPIDJSON_ASSERT(IsObject()); return data_.o.size == 0; } 01020 01021 //! Get a value from an object associated with the name. 01022 /*! \pre IsObject() == true 01023 \tparam T Either \c Ch or \c const \c Ch (template used for disambiguation with \ref operator[](SizeType)) 01024 \note In version 0.1x, if the member is not found, this function returns a null value. This makes issue 7. 01025 Since 0.2, if the name is not correct, it will assert. 01026 If user is unsure whether a member exists, user should use HasMember() first. 01027 A better approach is to use FindMember(). 01028 \note Linear time complexity. 01029 */ 01030 template <typename T> 01031 RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >),(GenericValue&)) operator[](T* name) { 01032 GenericValue n(StringRef(name)); 01033 return (*this)[n]; 01034 } 01035 template <typename T> 01036 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]; } 01037 01038 //! Get a value from an object associated with the name. 01039 /*! \pre IsObject() == true 01040 \tparam SourceAllocator Allocator of the \c name value 01041 01042 \note Compared to \ref operator[](T*), this version is faster because it does not need a StrLen(). 01043 And it can also handle strings with embedded null characters. 01044 01045 \note Linear time complexity. 01046 */ 01047 template <typename SourceAllocator> 01048 GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) { 01049 MemberIterator member = FindMember(name); 01050 if (member != MemberEnd()) 01051 return member->value; 01052 else { 01053 RAPIDJSON_ASSERT(false); // see above note 01054 01055 // This will generate -Wexit-time-destructors in clang 01056 // static GenericValue NullValue; 01057 // return NullValue; 01058 01059 // Use static buffer and placement-new to prevent destruction 01060 static char buffer[sizeof(GenericValue)]; 01061 return *new (buffer) GenericValue(); 01062 } 01063 } 01064 template <typename SourceAllocator> 01065 const GenericValue& operator[](const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this)[name]; } 01066 01067 #if RAPIDJSON_HAS_STDSTRING 01068 //! Get a value from an object associated with name (string object). 01069 GenericValue& operator[](const std::basic_string<Ch>& name) { return (*this)[GenericValue(StringRef(name))]; } 01070 const GenericValue& operator[](const std::basic_string<Ch>& name) const { return (*this)[GenericValue(StringRef(name))]; } 01071 #endif 01072 01073 //! Const member iterator 01074 /*! \pre IsObject() == true */ 01075 ConstMemberIterator MemberBegin() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer()); } 01076 //! Const \em past-the-end member iterator 01077 /*! \pre IsObject() == true */ 01078 ConstMemberIterator MemberEnd() const { RAPIDJSON_ASSERT(IsObject()); return ConstMemberIterator(GetMembersPointer() + data_.o.size); } 01079 //! Member iterator 01080 /*! \pre IsObject() == true */ 01081 MemberIterator MemberBegin() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer()); } 01082 //! \em Past-the-end member iterator 01083 /*! \pre IsObject() == true */ 01084 MemberIterator MemberEnd() { RAPIDJSON_ASSERT(IsObject()); return MemberIterator(GetMembersPointer() + data_.o.size); } 01085 01086 //! Check whether a member exists in the object. 01087 /*! 01088 \param name Member name to be searched. 01089 \pre IsObject() == true 01090 \return Whether a member with that name exists. 01091 \note It is better to use FindMember() directly if you need the obtain the value as well. 01092 \note Linear time complexity. 01093 */ 01094 bool HasMember(const Ch* name) const { return FindMember(name) != MemberEnd(); } 01095 01096 #if RAPIDJSON_HAS_STDSTRING 01097 //! Check whether a member exists in the object with string object. 01098 /*! 01099 \param name Member name to be searched. 01100 \pre IsObject() == true 01101 \return Whether a member with that name exists. 01102 \note It is better to use FindMember() directly if you need the obtain the value as well. 01103 \note Linear time complexity. 01104 */ 01105 bool HasMember(const std::basic_string<Ch>& name) const { return FindMember(name) != MemberEnd(); } 01106 #endif 01107 01108 //! Check whether a member exists in the object with GenericValue name. 01109 /*! 01110 This version is faster because it does not need a StrLen(). It can also handle string with null character. 01111 \param name Member name to be searched. 01112 \pre IsObject() == true 01113 \return Whether a member with that name exists. 01114 \note It is better to use FindMember() directly if you need the obtain the value as well. 01115 \note Linear time complexity. 01116 */ 01117 template <typename SourceAllocator> 01118 bool HasMember(const GenericValue<Encoding, SourceAllocator>& name) const { return FindMember(name) != MemberEnd(); } 01119 01120 //! Find member by name. 01121 /*! 01122 \param name Member name to be searched. 01123 \pre IsObject() == true 01124 \return Iterator to member, if it exists. 01125 Otherwise returns \ref MemberEnd(). 01126 01127 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case 01128 the requested member doesn't exist. For consistency with e.g. 01129 \c std::map, this has been changed to MemberEnd() now. 01130 \note Linear time complexity. 01131 */ 01132 MemberIterator FindMember(const Ch* name) { 01133 GenericValue n(StringRef(name)); 01134 return FindMember(n); 01135 } 01136 01137 ConstMemberIterator FindMember(const Ch* name) const { return const_cast<GenericValue&>(*this).FindMember(name); } 01138 01139 //! Find member by name. 01140 /*! 01141 This version is faster because it does not need a StrLen(). It can also handle string with null character. 01142 \param name Member name to be searched. 01143 \pre IsObject() == true 01144 \return Iterator to member, if it exists. 01145 Otherwise returns \ref MemberEnd(). 01146 01147 \note Earlier versions of Rapidjson returned a \c NULL pointer, in case 01148 the requested member doesn't exist. For consistency with e.g. 01149 \c std::map, this has been changed to MemberEnd() now. 01150 \note Linear time complexity. 01151 */ 01152 template <typename SourceAllocator> 01153 MemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) { 01154 RAPIDJSON_ASSERT(IsObject()); 01155 RAPIDJSON_ASSERT(name.IsString()); 01156 MemberIterator member = MemberBegin(); 01157 for ( ; member != MemberEnd(); ++member) 01158 if (name.StringEqual(member->name)) 01159 break; 01160 return member; 01161 } 01162 template <typename SourceAllocator> ConstMemberIterator FindMember(const GenericValue<Encoding, SourceAllocator>& name) const { return const_cast<GenericValue&>(*this).FindMember(name); } 01163 01164 #if RAPIDJSON_HAS_STDSTRING 01165 //! Find member by string object name. 01166 /*! 01167 \param name Member name to be searched. 01168 \pre IsObject() == true 01169 \return Iterator to member, if it exists. 01170 Otherwise returns \ref MemberEnd(). 01171 */ 01172 MemberIterator FindMember(const std::basic_string<Ch>& name) { return FindMember(GenericValue(StringRef(name))); } 01173 ConstMemberIterator FindMember(const std::basic_string<Ch>& name) const { return FindMember(GenericValue(StringRef(name))); } 01174 #endif 01175 01176 //! Add a member (name-value pair) to the object. 01177 /*! \param name A string value as name of member. 01178 \param value Value of any type. 01179 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 01180 \return The value itself for fluent API. 01181 \note The ownership of \c name and \c value will be transferred to this object on success. 01182 \pre IsObject() && name.IsString() 01183 \post name.IsNull() && value.IsNull() 01184 \note Amortized Constant time complexity. 01185 */ 01186 GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator) { 01187 RAPIDJSON_ASSERT(IsObject()); 01188 RAPIDJSON_ASSERT(name.IsString()); 01189 01190 ObjectData& o = data_.o; 01191 if (o.size >= o.capacity) { 01192 if (o.capacity == 0) { 01193 o.capacity = kDefaultObjectCapacity; 01194 SetMembersPointer(reinterpret_cast<Member*>(allocator.Malloc(o.capacity * sizeof(Member)))); 01195 } 01196 else { 01197 SizeType oldCapacity = o.capacity; 01198 o.capacity += (oldCapacity + 1) / 2; // grow by factor 1.5 01199 SetMembersPointer(reinterpret_cast<Member*>(allocator.Realloc(GetMembersPointer(), oldCapacity * sizeof(Member), o.capacity * sizeof(Member)))); 01200 } 01201 } 01202 Member* members = GetMembersPointer(); 01203 members[o.size].name.RawAssign(name); 01204 members[o.size].value.RawAssign(value); 01205 o.size++; 01206 return *this; 01207 } 01208 01209 //! Add a constant string value as member (name-value pair) to the object. 01210 /*! \param name A string value as name of member. 01211 \param value constant string reference as value of member. 01212 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 01213 \return The value itself for fluent API. 01214 \pre IsObject() 01215 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. 01216 \note Amortized Constant time complexity. 01217 */ 01218 GenericValue& AddMember(GenericValue& name, StringRefType value, Allocator& allocator) { 01219 GenericValue v(value); 01220 return AddMember(name, v, allocator); 01221 } 01222 01223 #if RAPIDJSON_HAS_STDSTRING 01224 //! Add a string object as member (name-value pair) to the object. 01225 /*! \param name A string value as name of member. 01226 \param value constant string reference as value of member. 01227 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 01228 \return The value itself for fluent API. 01229 \pre IsObject() 01230 \note This overload is needed to avoid clashes with the generic primitive type AddMember(GenericValue&,T,Allocator&) overload below. 01231 \note Amortized Constant time complexity. 01232 */ 01233 GenericValue& AddMember(GenericValue& name, std::basic_string<Ch>& value, Allocator& allocator) { 01234 GenericValue v(value, allocator); 01235 return AddMember(name, v, allocator); 01236 } 01237 #endif 01238 01239 //! Add any primitive value as member (name-value pair) to the object. 01240 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t 01241 \param name A string value as name of member. 01242 \param value Value of primitive type \c T as value of member 01243 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). 01244 \return The value itself for fluent API. 01245 \pre IsObject() 01246 01247 \note The source type \c T explicitly disallows all pointer types, 01248 especially (\c const) \ref Ch*. This helps avoiding implicitly 01249 referencing character strings with insufficient lifetime, use 01250 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref 01251 AddMember(StringRefType, StringRefType, Allocator&). 01252 All other pointer types would implicitly convert to \c bool, 01253 use an explicit cast instead, if needed. 01254 \note Amortized Constant time complexity. 01255 */ 01256 template <typename T> 01257 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) 01258 AddMember(GenericValue& name, T value, Allocator& allocator) { 01259 GenericValue v(value); 01260 return AddMember(name, v, allocator); 01261 } 01262 01263 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 01264 GenericValue& AddMember(GenericValue&& name, GenericValue&& value, Allocator& allocator) { 01265 return AddMember(name, value, allocator); 01266 } 01267 GenericValue& AddMember(GenericValue&& name, GenericValue& value, Allocator& allocator) { 01268 return AddMember(name, value, allocator); 01269 } 01270 GenericValue& AddMember(GenericValue& name, GenericValue&& value, Allocator& allocator) { 01271 return AddMember(name, value, allocator); 01272 } 01273 GenericValue& AddMember(StringRefType name, GenericValue&& value, Allocator& allocator) { 01274 GenericValue n(name); 01275 return AddMember(n, value, allocator); 01276 } 01277 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 01278 01279 01280 //! Add a member (name-value pair) to the object. 01281 /*! \param name A constant string reference as name of member. 01282 \param value Value of any type. 01283 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 01284 \return The value itself for fluent API. 01285 \note The ownership of \c value will be transferred to this object on success. 01286 \pre IsObject() 01287 \post value.IsNull() 01288 \note Amortized Constant time complexity. 01289 */ 01290 GenericValue& AddMember(StringRefType name, GenericValue& value, Allocator& allocator) { 01291 GenericValue n(name); 01292 return AddMember(n, value, allocator); 01293 } 01294 01295 //! Add a constant string value as member (name-value pair) to the object. 01296 /*! \param name A constant string reference as name of member. 01297 \param value constant string reference as value of member. 01298 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 01299 \return The value itself for fluent API. 01300 \pre IsObject() 01301 \note This overload is needed to avoid clashes with the generic primitive type AddMember(StringRefType,T,Allocator&) overload below. 01302 \note Amortized Constant time complexity. 01303 */ 01304 GenericValue& AddMember(StringRefType name, StringRefType value, Allocator& allocator) { 01305 GenericValue v(value); 01306 return AddMember(name, v, allocator); 01307 } 01308 01309 //! Add any primitive value as member (name-value pair) to the object. 01310 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t 01311 \param name A constant string reference as name of member. 01312 \param value Value of primitive type \c T as value of member 01313 \param allocator Allocator for reallocating memory. Commonly use GenericDocument::GetAllocator(). 01314 \return The value itself for fluent API. 01315 \pre IsObject() 01316 01317 \note The source type \c T explicitly disallows all pointer types, 01318 especially (\c const) \ref Ch*. This helps avoiding implicitly 01319 referencing character strings with insufficient lifetime, use 01320 \ref AddMember(StringRefType, GenericValue&, Allocator&) or \ref 01321 AddMember(StringRefType, StringRefType, Allocator&). 01322 All other pointer types would implicitly convert to \c bool, 01323 use an explicit cast instead, if needed. 01324 \note Amortized Constant time complexity. 01325 */ 01326 template <typename T> 01327 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) 01328 AddMember(StringRefType name, T value, Allocator& allocator) { 01329 GenericValue n(name); 01330 return AddMember(n, value, allocator); 01331 } 01332 01333 //! Remove all members in the object. 01334 /*! This function do not deallocate memory in the object, i.e. the capacity is unchanged. 01335 \note Linear time complexity. 01336 */ 01337 void RemoveAllMembers() { 01338 RAPIDJSON_ASSERT(IsObject()); 01339 for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m) 01340 m->~Member(); 01341 data_.o.size = 0; 01342 } 01343 01344 //! Remove a member in object by its name. 01345 /*! \param name Name of member to be removed. 01346 \return Whether the member existed. 01347 \note This function may reorder the object members. Use \ref 01348 EraseMember(ConstMemberIterator) if you need to preserve the 01349 relative order of the remaining members. 01350 \note Linear time complexity. 01351 */ 01352 bool RemoveMember(const Ch* name) { 01353 GenericValue n(StringRef(name)); 01354 return RemoveMember(n); 01355 } 01356 01357 #if RAPIDJSON_HAS_STDSTRING 01358 bool RemoveMember(const std::basic_string<Ch>& name) { return RemoveMember(GenericValue(StringRef(name))); } 01359 #endif 01360 01361 template <typename SourceAllocator> 01362 bool RemoveMember(const GenericValue<Encoding, SourceAllocator>& name) { 01363 MemberIterator m = FindMember(name); 01364 if (m != MemberEnd()) { 01365 RemoveMember(m); 01366 return true; 01367 } 01368 else 01369 return false; 01370 } 01371 01372 //! Remove a member in object by iterator. 01373 /*! \param m member iterator (obtained by FindMember() or MemberBegin()). 01374 \return the new iterator after removal. 01375 \note This function may reorder the object members. Use \ref 01376 EraseMember(ConstMemberIterator) if you need to preserve the 01377 relative order of the remaining members. 01378 \note Constant time complexity. 01379 */ 01380 MemberIterator RemoveMember(MemberIterator m) { 01381 RAPIDJSON_ASSERT(IsObject()); 01382 RAPIDJSON_ASSERT(data_.o.size > 0); 01383 RAPIDJSON_ASSERT(GetMembersPointer() != 0); 01384 RAPIDJSON_ASSERT(m >= MemberBegin() && m < MemberEnd()); 01385 01386 MemberIterator last(GetMembersPointer() + (data_.o.size - 1)); 01387 if (data_.o.size > 1 && m != last) 01388 *m = *last; // Move the last one to this place 01389 else 01390 m->~Member(); // Only one left, just destroy 01391 --data_.o.size; 01392 return m; 01393 } 01394 01395 //! Remove a member from an object by iterator. 01396 /*! \param pos iterator to the member to remove 01397 \pre IsObject() == true && \ref MemberBegin() <= \c pos < \ref MemberEnd() 01398 \return Iterator following the removed element. 01399 If the iterator \c pos refers to the last element, the \ref MemberEnd() iterator is returned. 01400 \note This function preserves the relative order of the remaining object 01401 members. If you do not need this, use the more efficient \ref RemoveMember(MemberIterator). 01402 \note Linear time complexity. 01403 */ 01404 MemberIterator EraseMember(ConstMemberIterator pos) { 01405 return EraseMember(pos, pos +1); 01406 } 01407 01408 //! Remove members in the range [first, last) from an object. 01409 /*! \param first iterator to the first member to remove 01410 \param last iterator following the last member to remove 01411 \pre IsObject() == true && \ref MemberBegin() <= \c first <= \c last <= \ref MemberEnd() 01412 \return Iterator following the last removed element. 01413 \note This function preserves the relative order of the remaining object 01414 members. 01415 \note Linear time complexity. 01416 */ 01417 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) { 01418 RAPIDJSON_ASSERT(IsObject()); 01419 RAPIDJSON_ASSERT(data_.o.size > 0); 01420 RAPIDJSON_ASSERT(GetMembersPointer() != 0); 01421 RAPIDJSON_ASSERT(first >= MemberBegin()); 01422 RAPIDJSON_ASSERT(first <= last); 01423 RAPIDJSON_ASSERT(last <= MemberEnd()); 01424 01425 MemberIterator pos = MemberBegin() + (first - MemberBegin()); 01426 for (MemberIterator itr = pos; itr != last; ++itr) 01427 itr->~Member(); 01428 std::memmove(&*pos, &*last, static_cast<size_t>(MemberEnd() - last) * sizeof(Member)); 01429 data_.o.size -= static_cast<SizeType>(last - first); 01430 return pos; 01431 } 01432 01433 //! Erase a member in object by its name. 01434 /*! \param name Name of member to be removed. 01435 \return Whether the member existed. 01436 \note Linear time complexity. 01437 */ 01438 bool EraseMember(const Ch* name) { 01439 GenericValue n(StringRef(name)); 01440 return EraseMember(n); 01441 } 01442 01443 #if RAPIDJSON_HAS_STDSTRING 01444 bool EraseMember(const std::basic_string<Ch>& name) { return EraseMember(GenericValue(StringRef(name))); } 01445 #endif 01446 01447 template <typename SourceAllocator> 01448 bool EraseMember(const GenericValue<Encoding, SourceAllocator>& name) { 01449 MemberIterator m = FindMember(name); 01450 if (m != MemberEnd()) { 01451 EraseMember(m); 01452 return true; 01453 } 01454 else 01455 return false; 01456 } 01457 01458 Object GetObject() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); } 01459 ConstObject GetObject() const { RAPIDJSON_ASSERT(IsObject()); return ConstObject(*this); } 01460 01461 //@} 01462 01463 //!@name Array 01464 //@{ 01465 01466 //! Set this value as an empty array. 01467 /*! \post IsArray == true */ 01468 GenericValue& SetArray() { this->~GenericValue(); new (this) GenericValue(kArrayType); return *this; } 01469 01470 //! Get the number of elements in array. 01471 SizeType Size() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size; } 01472 01473 //! Get the capacity of array. 01474 SizeType Capacity() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.capacity; } 01475 01476 //! Check whether the array is empty. 01477 bool Empty() const { RAPIDJSON_ASSERT(IsArray()); return data_.a.size == 0; } 01478 01479 //! Remove all elements in the array. 01480 /*! This function do not deallocate memory in the array, i.e. the capacity is unchanged. 01481 \note Linear time complexity. 01482 */ 01483 void Clear() { 01484 RAPIDJSON_ASSERT(IsArray()); 01485 GenericValue* e = GetElementsPointer(); 01486 for (GenericValue* v = e; v != e + data_.a.size; ++v) 01487 v->~GenericValue(); 01488 data_.a.size = 0; 01489 } 01490 01491 //! Get an element from array by index. 01492 /*! \pre IsArray() == true 01493 \param index Zero-based index of element. 01494 \see operator[](T*) 01495 */ 01496 GenericValue& operator[](SizeType index) { 01497 RAPIDJSON_ASSERT(IsArray()); 01498 RAPIDJSON_ASSERT(index < data_.a.size); 01499 return GetElementsPointer()[index]; 01500 } 01501 const GenericValue& operator[](SizeType index) const { return const_cast<GenericValue&>(*this)[index]; } 01502 01503 //! Element iterator 01504 /*! \pre IsArray() == true */ 01505 ValueIterator Begin() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer(); } 01506 //! \em Past-the-end element iterator 01507 /*! \pre IsArray() == true */ 01508 ValueIterator End() { RAPIDJSON_ASSERT(IsArray()); return GetElementsPointer() + data_.a.size; } 01509 //! Constant element iterator 01510 /*! \pre IsArray() == true */ 01511 ConstValueIterator Begin() const { return const_cast<GenericValue&>(*this).Begin(); } 01512 //! Constant \em past-the-end element iterator 01513 /*! \pre IsArray() == true */ 01514 ConstValueIterator End() const { return const_cast<GenericValue&>(*this).End(); } 01515 01516 //! Request the array to have enough capacity to store elements. 01517 /*! \param newCapacity The capacity that the array at least need to have. 01518 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 01519 \return The value itself for fluent API. 01520 \note Linear time complexity. 01521 */ 01522 GenericValue& Reserve(SizeType newCapacity, Allocator &allocator) { 01523 RAPIDJSON_ASSERT(IsArray()); 01524 if (newCapacity > data_.a.capacity) { 01525 SetElementsPointer(reinterpret_cast<GenericValue*>(allocator.Realloc(GetElementsPointer(), data_.a.capacity * sizeof(GenericValue), newCapacity * sizeof(GenericValue)))); 01526 data_.a.capacity = newCapacity; 01527 } 01528 return *this; 01529 } 01530 01531 //! Append a GenericValue at the end of the array. 01532 /*! \param value Value to be appended. 01533 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 01534 \pre IsArray() == true 01535 \post value.IsNull() == true 01536 \return The value itself for fluent API. 01537 \note The ownership of \c value will be transferred to this array on success. 01538 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. 01539 \note Amortized constant time complexity. 01540 */ 01541 GenericValue& PushBack(GenericValue& value, Allocator& allocator) { 01542 RAPIDJSON_ASSERT(IsArray()); 01543 if (data_.a.size >= data_.a.capacity) 01544 Reserve(data_.a.capacity == 0 ? kDefaultArrayCapacity : (data_.a.capacity + (data_.a.capacity + 1) / 2), allocator); 01545 GetElementsPointer()[data_.a.size++].RawAssign(value); 01546 return *this; 01547 } 01548 01549 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 01550 GenericValue& PushBack(GenericValue&& value, Allocator& allocator) { 01551 return PushBack(value, allocator); 01552 } 01553 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 01554 01555 //! Append a constant string reference at the end of the array. 01556 /*! \param value Constant string reference to be appended. 01557 \param allocator Allocator for reallocating memory. It must be the same one used previously. Commonly use GenericDocument::GetAllocator(). 01558 \pre IsArray() == true 01559 \return The value itself for fluent API. 01560 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. 01561 \note Amortized constant time complexity. 01562 \see GenericStringRef 01563 */ 01564 GenericValue& PushBack(StringRefType value, Allocator& allocator) { 01565 return (*this).template PushBack<StringRefType>(value, allocator); 01566 } 01567 01568 //! Append a primitive value at the end of the array. 01569 /*! \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t 01570 \param value Value of primitive type T to be appended. 01571 \param allocator Allocator for reallocating memory. It must be the same one as used before. Commonly use GenericDocument::GetAllocator(). 01572 \pre IsArray() == true 01573 \return The value itself for fluent API. 01574 \note If the number of elements to be appended is known, calls Reserve() once first may be more efficient. 01575 01576 \note The source type \c T explicitly disallows all pointer types, 01577 especially (\c const) \ref Ch*. This helps avoiding implicitly 01578 referencing character strings with insufficient lifetime, use 01579 \ref PushBack(GenericValue&, Allocator&) or \ref 01580 PushBack(StringRefType, Allocator&). 01581 All other pointer types would implicitly convert to \c bool, 01582 use an explicit cast instead, if needed. 01583 \note Amortized constant time complexity. 01584 */ 01585 template <typename T> 01586 RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (GenericValue&)) 01587 PushBack(T value, Allocator& allocator) { 01588 GenericValue v(value); 01589 return PushBack(v, allocator); 01590 } 01591 01592 //! Remove the last element in the array. 01593 /*! 01594 \note Constant time complexity. 01595 */ 01596 GenericValue& PopBack() { 01597 RAPIDJSON_ASSERT(IsArray()); 01598 RAPIDJSON_ASSERT(!Empty()); 01599 GetElementsPointer()[--data_.a.size].~GenericValue(); 01600 return *this; 01601 } 01602 01603 //! Remove an element of array by iterator. 01604 /*! 01605 \param pos iterator to the element to remove 01606 \pre IsArray() == true && \ref Begin() <= \c pos < \ref End() 01607 \return Iterator following the removed element. If the iterator pos refers to the last element, the End() iterator is returned. 01608 \note Linear time complexity. 01609 */ 01610 ValueIterator Erase(ConstValueIterator pos) { 01611 return Erase(pos, pos + 1); 01612 } 01613 01614 //! Remove elements in the range [first, last) of the array. 01615 /*! 01616 \param first iterator to the first element to remove 01617 \param last iterator following the last element to remove 01618 \pre IsArray() == true && \ref Begin() <= \c first <= \c last <= \ref End() 01619 \return Iterator following the last removed element. 01620 \note Linear time complexity. 01621 */ 01622 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) { 01623 RAPIDJSON_ASSERT(IsArray()); 01624 RAPIDJSON_ASSERT(data_.a.size > 0); 01625 RAPIDJSON_ASSERT(GetElementsPointer() != 0); 01626 RAPIDJSON_ASSERT(first >= Begin()); 01627 RAPIDJSON_ASSERT(first <= last); 01628 RAPIDJSON_ASSERT(last <= End()); 01629 ValueIterator pos = Begin() + (first - Begin()); 01630 for (ValueIterator itr = pos; itr != last; ++itr) 01631 itr->~GenericValue(); 01632 std::memmove(pos, last, static_cast<size_t>(End() - last) * sizeof(GenericValue)); 01633 data_.a.size -= static_cast<SizeType>(last - first); 01634 return pos; 01635 } 01636 01637 Array GetArray() { RAPIDJSON_ASSERT(IsArray()); return Array(*this); } 01638 ConstArray GetArray() const { RAPIDJSON_ASSERT(IsArray()); return ConstArray(*this); } 01639 01640 //@} 01641 01642 //!@name Number 01643 //@{ 01644 01645 int GetInt() const { RAPIDJSON_ASSERT(data_.f.flags & kIntFlag); return data_.n.i.i; } 01646 unsigned GetUint() const { RAPIDJSON_ASSERT(data_.f.flags & kUintFlag); return data_.n.u.u; } 01647 int64_t GetInt64() const { RAPIDJSON_ASSERT(data_.f.flags & kInt64Flag); return data_.n.i64; } 01648 uint64_t GetUint64() const { RAPIDJSON_ASSERT(data_.f.flags & kUint64Flag); return data_.n.u64; } 01649 01650 //! Get the value as double type. 01651 /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessDouble() to check whether the converison is lossless. 01652 */ 01653 double GetDouble() const { 01654 RAPIDJSON_ASSERT(IsNumber()); 01655 if ((data_.f.flags & kDoubleFlag) != 0) return data_.n.d; // exact type, no conversion. 01656 if ((data_.f.flags & kIntFlag) != 0) return data_.n.i.i; // int -> double 01657 if ((data_.f.flags & kUintFlag) != 0) return data_.n.u.u; // unsigned -> double 01658 if ((data_.f.flags & kInt64Flag) != 0) return static_cast<double>(data_.n.i64); // int64_t -> double (may lose precision) 01659 RAPIDJSON_ASSERT((data_.f.flags & kUint64Flag) != 0); return static_cast<double>(data_.n.u64); // uint64_t -> double (may lose precision) 01660 } 01661 01662 //! Get the value as float type. 01663 /*! \note If the value is 64-bit integer type, it may lose precision. Use \c IsLosslessFloat() to check whether the converison is lossless. 01664 */ 01665 float GetFloat() const { 01666 return static_cast<float>(GetDouble()); 01667 } 01668 01669 GenericValue& SetInt(int i) { this->~GenericValue(); new (this) GenericValue(i); return *this; } 01670 GenericValue& SetUint(unsigned u) { this->~GenericValue(); new (this) GenericValue(u); return *this; } 01671 GenericValue& SetInt64(int64_t i64) { this->~GenericValue(); new (this) GenericValue(i64); return *this; } 01672 GenericValue& SetUint64(uint64_t u64) { this->~GenericValue(); new (this) GenericValue(u64); return *this; } 01673 GenericValue& SetDouble(double d) { this->~GenericValue(); new (this) GenericValue(d); return *this; } 01674 GenericValue& SetFloat(float f) { this->~GenericValue(); new (this) GenericValue(f); return *this; } 01675 01676 //@} 01677 01678 //!@name String 01679 //@{ 01680 01681 const Ch* GetString() const { RAPIDJSON_ASSERT(IsString()); return (data_.f.flags & kInlineStrFlag) ? data_.ss.str : GetStringPointer(); } 01682 01683 //! Get the length of string. 01684 /*! Since rapidjson permits "\\u0000" in the json string, strlen(v.GetString()) may not equal to v.GetStringLength(). 01685 */ 01686 SizeType GetStringLength() const { RAPIDJSON_ASSERT(IsString()); return ((data_.f.flags & kInlineStrFlag) ? (data_.ss.GetLength()) : data_.s.length); } 01687 01688 //! Set this value as a string without copying source string. 01689 /*! This version has better performance with supplied length, and also support string containing null character. 01690 \param s source string pointer. 01691 \param length The length of source string, excluding the trailing null terminator. 01692 \return The value itself for fluent API. 01693 \post IsString() == true && GetString() == s && GetStringLength() == length 01694 \see SetString(StringRefType) 01695 */ 01696 GenericValue& SetString(const Ch* s, SizeType length) { return SetString(StringRef(s, length)); } 01697 01698 //! Set this value as a string without copying source string. 01699 /*! \param s source string reference 01700 \return The value itself for fluent API. 01701 \post IsString() == true && GetString() == s && GetStringLength() == s.length 01702 */ 01703 GenericValue& SetString(StringRefType s) { this->~GenericValue(); SetStringRaw(s); return *this; } 01704 01705 //! Set this value as a string by copying from source string. 01706 /*! This version has better performance with supplied length, and also support string containing null character. 01707 \param s source string. 01708 \param length The length of source string, excluding the trailing null terminator. 01709 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). 01710 \return The value itself for fluent API. 01711 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length 01712 */ 01713 GenericValue& SetString(const Ch* s, SizeType length, Allocator& allocator) { this->~GenericValue(); SetStringRaw(StringRef(s, length), allocator); return *this; } 01714 01715 //! Set this value as a string by copying from source string. 01716 /*! \param s source string. 01717 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). 01718 \return The value itself for fluent API. 01719 \post IsString() == true && GetString() != s && strcmp(GetString(),s) == 0 && GetStringLength() == length 01720 */ 01721 GenericValue& SetString(const Ch* s, Allocator& allocator) { return SetString(s, internal::StrLen(s), allocator); } 01722 01723 #if RAPIDJSON_HAS_STDSTRING 01724 //! Set this value as a string by copying from source string. 01725 /*! \param s source string. 01726 \param allocator Allocator for allocating copied buffer. Commonly use GenericDocument::GetAllocator(). 01727 \return The value itself for fluent API. 01728 \post IsString() == true && GetString() != s.data() && strcmp(GetString(),s.data() == 0 && GetStringLength() == s.size() 01729 \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING. 01730 */ 01731 GenericValue& SetString(const std::basic_string<Ch>& s, Allocator& allocator) { return SetString(s.data(), SizeType(s.size()), allocator); } 01732 #endif 01733 01734 //@} 01735 01736 //!@name Array 01737 //@{ 01738 01739 //! Templated version for checking whether this value is type T. 01740 /*! 01741 \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> 01742 */ 01743 template <typename T> 01744 bool Is() const { return internal::TypeHelper<ValueType, T>::Is(*this); } 01745 01746 template <typename T> 01747 T Get() const { return internal::TypeHelper<ValueType, T>::Get(*this); } 01748 01749 template <typename T> 01750 T Get() { return internal::TypeHelper<ValueType, T>::Get(*this); } 01751 01752 template<typename T> 01753 ValueType& Set(const T& data) { return internal::TypeHelper<ValueType, T>::Set(*this, data); } 01754 01755 template<typename T> 01756 ValueType& Set(const T& data, AllocatorType& allocator) { return internal::TypeHelper<ValueType, T>::Set(*this, data, allocator); } 01757 01758 //@} 01759 01760 //! Generate events of this value to a Handler. 01761 /*! This function adopts the GoF visitor pattern. 01762 Typical usage is to output this JSON value as JSON text via Writer, which is a Handler. 01763 It can also be used to deep clone this value via GenericDocument, which is also a Handler. 01764 \tparam Handler type of handler. 01765 \param handler An object implementing concept Handler. 01766 */ 01767 template <typename Handler> 01768 bool Accept(Handler& handler) const { 01769 switch(GetType()) { 01770 case kNullType: return handler.Null(); 01771 case kFalseType: return handler.Bool(false); 01772 case kTrueType: return handler.Bool(true); 01773 01774 case kObjectType: 01775 if (RAPIDJSON_UNLIKELY(!handler.StartObject())) 01776 return false; 01777 for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { 01778 RAPIDJSON_ASSERT(m->name.IsString()); // User may change the type of name by MemberIterator. 01779 if (RAPIDJSON_UNLIKELY(!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.data_.f.flags & kCopyFlag) != 0))) 01780 return false; 01781 if (RAPIDJSON_UNLIKELY(!m->value.Accept(handler))) 01782 return false; 01783 } 01784 return handler.EndObject(data_.o.size); 01785 01786 case kArrayType: 01787 if (RAPIDJSON_UNLIKELY(!handler.StartArray())) 01788 return false; 01789 for (const GenericValue* v = Begin(); v != End(); ++v) 01790 if (RAPIDJSON_UNLIKELY(!v->Accept(handler))) 01791 return false; 01792 return handler.EndArray(data_.a.size); 01793 01794 case kStringType: 01795 return handler.String(GetString(), GetStringLength(), (data_.f.flags & kCopyFlag) != 0); 01796 01797 default: 01798 RAPIDJSON_ASSERT(GetType() == kNumberType); 01799 if (IsDouble()) return handler.Double(data_.n.d); 01800 else if (IsInt()) return handler.Int(data_.n.i.i); 01801 else if (IsUint()) return handler.Uint(data_.n.u.u); 01802 else if (IsInt64()) return handler.Int64(data_.n.i64); 01803 else return handler.Uint64(data_.n.u64); 01804 } 01805 } 01806 01807 private: 01808 template <typename, typename> friend class GenericValue; 01809 template <typename, typename, typename> friend class GenericDocument; 01810 01811 enum { 01812 kBoolFlag = 0x0008, 01813 kNumberFlag = 0x0010, 01814 kIntFlag = 0x0020, 01815 kUintFlag = 0x0040, 01816 kInt64Flag = 0x0080, 01817 kUint64Flag = 0x0100, 01818 kDoubleFlag = 0x0200, 01819 kStringFlag = 0x0400, 01820 kCopyFlag = 0x0800, 01821 kInlineStrFlag = 0x1000, 01822 01823 // Initial flags of different types. 01824 kNullFlag = kNullType, 01825 kTrueFlag = kTrueType | kBoolFlag, 01826 kFalseFlag = kFalseType | kBoolFlag, 01827 kNumberIntFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag, 01828 kNumberUintFlag = kNumberType | kNumberFlag | kUintFlag | kUint64Flag | kInt64Flag, 01829 kNumberInt64Flag = kNumberType | kNumberFlag | kInt64Flag, 01830 kNumberUint64Flag = kNumberType | kNumberFlag | kUint64Flag, 01831 kNumberDoubleFlag = kNumberType | kNumberFlag | kDoubleFlag, 01832 kNumberAnyFlag = kNumberType | kNumberFlag | kIntFlag | kInt64Flag | kUintFlag | kUint64Flag | kDoubleFlag, 01833 kConstStringFlag = kStringType | kStringFlag, 01834 kCopyStringFlag = kStringType | kStringFlag | kCopyFlag, 01835 kShortStringFlag = kStringType | kStringFlag | kCopyFlag | kInlineStrFlag, 01836 kObjectFlag = kObjectType, 01837 kArrayFlag = kArrayType, 01838 01839 kTypeMask = 0x07 01840 }; 01841 01842 static const SizeType kDefaultArrayCapacity = 16; 01843 static const SizeType kDefaultObjectCapacity = 16; 01844 01845 struct Flag { 01846 #if RAPIDJSON_48BITPOINTER_OPTIMIZATION 01847 char payload[sizeof(SizeType) * 2 + 6]; // 2 x SizeType + lower 48-bit pointer 01848 #elif RAPIDJSON_64BIT 01849 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 6]; // 6 padding bytes 01850 #else 01851 char payload[sizeof(SizeType) * 2 + sizeof(void*) + 2]; // 2 padding bytes 01852 #endif 01853 uint16_t flags; 01854 }; 01855 01856 struct String { 01857 SizeType length; 01858 SizeType hashcode; //!< reserved 01859 const Ch* str; 01860 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 01861 01862 // implementation detail: ShortString can represent zero-terminated strings up to MaxSize chars 01863 // (excluding the terminating zero) and store a value to determine the length of the contained 01864 // string in the last character str[LenPos] by storing "MaxSize - length" there. If the string 01865 // to store has the maximal length of MaxSize then str[LenPos] will be 0 and therefore act as 01866 // the string terminator as well. For getting the string length back from that value just use 01867 // "MaxSize - str[LenPos]". 01868 // This allows to store 13-chars strings in 32-bit mode, 21-chars strings in 64-bit mode, 01869 // 13-chars strings for RAPIDJSON_48BITPOINTER_OPTIMIZATION=1 inline (for `UTF8`-encoded strings). 01870 struct ShortString { 01871 enum { MaxChars = sizeof(static_cast<Flag*>(0)->payload) / sizeof(Ch), MaxSize = MaxChars - 1, LenPos = MaxSize }; 01872 Ch str[MaxChars]; 01873 01874 inline static bool Usable(SizeType len) { return (MaxSize >= len); } 01875 inline void SetLength(SizeType len) { str[LenPos] = static_cast<Ch>(MaxSize - len); } 01876 inline SizeType GetLength() const { return static_cast<SizeType>(MaxSize - str[LenPos]); } 01877 }; // at most as many bytes as "String" above => 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 01878 01879 // By using proper binary layout, retrieval of different integer types do not need conversions. 01880 union Number { 01881 #if RAPIDJSON_ENDIAN == RAPIDJSON_LITTLEENDIAN 01882 struct I { 01883 int i; 01884 char padding[4]; 01885 }i; 01886 struct U { 01887 unsigned u; 01888 char padding2[4]; 01889 }u; 01890 #else 01891 struct I { 01892 char padding[4]; 01893 int i; 01894 }i; 01895 struct U { 01896 char padding2[4]; 01897 unsigned u; 01898 }u; 01899 #endif 01900 int64_t i64; 01901 uint64_t u64; 01902 double d; 01903 }; // 8 bytes 01904 01905 struct ObjectData { 01906 SizeType size; 01907 SizeType capacity; 01908 Member* members; 01909 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 01910 01911 struct ArrayData { 01912 SizeType size; 01913 SizeType capacity; 01914 GenericValue* elements; 01915 }; // 12 bytes in 32-bit mode, 16 bytes in 64-bit mode 01916 01917 union Data { 01918 String s; 01919 ShortString ss; 01920 Number n; 01921 ObjectData o; 01922 ArrayData a; 01923 Flag f; 01924 }; // 16 bytes in 32-bit mode, 24 bytes in 64-bit mode, 16 bytes in 64-bit with RAPIDJSON_48BITPOINTER_OPTIMIZATION 01925 01926 RAPIDJSON_FORCEINLINE const Ch* GetStringPointer() const { return RAPIDJSON_GETPOINTER(Ch, data_.s.str); } 01927 RAPIDJSON_FORCEINLINE const Ch* SetStringPointer(const Ch* str) { return RAPIDJSON_SETPOINTER(Ch, data_.s.str, str); } 01928 RAPIDJSON_FORCEINLINE GenericValue* GetElementsPointer() const { return RAPIDJSON_GETPOINTER(GenericValue, data_.a.elements); } 01929 RAPIDJSON_FORCEINLINE GenericValue* SetElementsPointer(GenericValue* elements) { return RAPIDJSON_SETPOINTER(GenericValue, data_.a.elements, elements); } 01930 RAPIDJSON_FORCEINLINE Member* GetMembersPointer() const { return RAPIDJSON_GETPOINTER(Member, data_.o.members); } 01931 RAPIDJSON_FORCEINLINE Member* SetMembersPointer(Member* members) { return RAPIDJSON_SETPOINTER(Member, data_.o.members, members); } 01932 01933 // Initialize this value as array with initial data, without calling destructor. 01934 void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) { 01935 data_.f.flags = kArrayFlag; 01936 if (count) { 01937 GenericValue* e = static_cast<GenericValue*>(allocator.Malloc(count * sizeof(GenericValue))); 01938 SetElementsPointer(e); 01939 std::memcpy(e, values, count * sizeof(GenericValue)); 01940 } 01941 else 01942 SetElementsPointer(0); 01943 data_.a.size = data_.a.capacity = count; 01944 } 01945 01946 //! Initialize this value as object with initial data, without calling destructor. 01947 void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) { 01948 data_.f.flags = kObjectFlag; 01949 if (count) { 01950 Member* m = static_cast<Member*>(allocator.Malloc(count * sizeof(Member))); 01951 SetMembersPointer(m); 01952 std::memcpy(m, members, count * sizeof(Member)); 01953 } 01954 else 01955 SetMembersPointer(0); 01956 data_.o.size = data_.o.capacity = count; 01957 } 01958 01959 //! Initialize this value as constant string, without calling destructor. 01960 void SetStringRaw(StringRefType s) RAPIDJSON_NOEXCEPT { 01961 data_.f.flags = kConstStringFlag; 01962 SetStringPointer(s); 01963 data_.s.length = s.length; 01964 } 01965 01966 //! Initialize this value as copy string with initial data, without calling destructor. 01967 void SetStringRaw(StringRefType s, Allocator& allocator) { 01968 Ch* str = 0; 01969 if (ShortString::Usable(s.length)) { 01970 data_.f.flags = kShortStringFlag; 01971 data_.ss.SetLength(s.length); 01972 str = data_.ss.str; 01973 } else { 01974 data_.f.flags = kCopyStringFlag; 01975 data_.s.length = s.length; 01976 str = static_cast<Ch *>(allocator.Malloc((s.length + 1) * sizeof(Ch))); 01977 SetStringPointer(str); 01978 } 01979 std::memcpy(str, s, s.length * sizeof(Ch)); 01980 str[s.length] = '\0'; 01981 } 01982 01983 //! Assignment without calling destructor 01984 void RawAssign(GenericValue& rhs) RAPIDJSON_NOEXCEPT { 01985 data_ = rhs.data_; 01986 // data_.f.flags = rhs.data_.f.flags; 01987 rhs.data_.f.flags = kNullFlag; 01988 } 01989 01990 template <typename SourceAllocator> 01991 bool StringEqual(const GenericValue<Encoding, SourceAllocator>& rhs) const { 01992 RAPIDJSON_ASSERT(IsString()); 01993 RAPIDJSON_ASSERT(rhs.IsString()); 01994 01995 const SizeType len1 = GetStringLength(); 01996 const SizeType len2 = rhs.GetStringLength(); 01997 if(len1 != len2) { return false; } 01998 01999 const Ch* const str1 = GetString(); 02000 const Ch* const str2 = rhs.GetString(); 02001 if(str1 == str2) { return true; } // fast path for constant string 02002 02003 return (std::memcmp(str1, str2, sizeof(Ch) * len1) == 0); 02004 } 02005 02006 Data data_; 02007 }; 02008 02009 //! GenericValue with UTF8 encoding 02010 typedef GenericValue<UTF8<> > Value; 02011 02012 /////////////////////////////////////////////////////////////////////////////// 02013 // GenericDocument 02014 02015 //! A document for parsing JSON text as DOM. 02016 /*! 02017 \note implements Handler concept 02018 \tparam Encoding Encoding for both parsing and string storage. 02019 \tparam Allocator Allocator for allocating memory for the DOM 02020 \tparam StackAllocator Allocator for allocating memory for stack during parsing. 02021 \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. 02022 */ 02023 template <typename Encoding, typename Allocator = MemoryPoolAllocator<>, typename StackAllocator = CrtAllocator> 02024 class GenericDocument : public GenericValue<Encoding, Allocator> { 02025 public: 02026 typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. 02027 typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of the document. 02028 typedef Allocator AllocatorType; //!< Allocator type from template parameter. 02029 02030 //! Constructor 02031 /*! Creates an empty document of specified type. 02032 \param type Mandatory type of object to create. 02033 \param allocator Optional allocator for allocating memory. 02034 \param stackCapacity Optional initial capacity of stack in bytes. 02035 \param stackAllocator Optional allocator for allocating memory for stack. 02036 */ 02037 explicit GenericDocument(Type type, Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : 02038 GenericValue<Encoding, Allocator>(type), allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() 02039 { 02040 if (!allocator_) 02041 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); 02042 } 02043 02044 //! Constructor 02045 /*! Creates an empty document which type is Null. 02046 \param allocator Optional allocator for allocating memory. 02047 \param stackCapacity Optional initial capacity of stack in bytes. 02048 \param stackAllocator Optional allocator for allocating memory for stack. 02049 */ 02050 GenericDocument(Allocator* allocator = 0, size_t stackCapacity = kDefaultStackCapacity, StackAllocator* stackAllocator = 0) : 02051 allocator_(allocator), ownAllocator_(0), stack_(stackAllocator, stackCapacity), parseResult_() 02052 { 02053 if (!allocator_) 02054 ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator()); 02055 } 02056 02057 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 02058 //! Move constructor in C++11 02059 GenericDocument(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT 02060 : ValueType(std::forward<ValueType>(rhs)), // explicit cast to avoid prohibited move from Document 02061 allocator_(rhs.allocator_), 02062 ownAllocator_(rhs.ownAllocator_), 02063 stack_(std::move(rhs.stack_)), 02064 parseResult_(rhs.parseResult_) 02065 { 02066 rhs.allocator_ = 0; 02067 rhs.ownAllocator_ = 0; 02068 rhs.parseResult_ = ParseResult(); 02069 } 02070 #endif 02071 02072 ~GenericDocument() { 02073 Destroy(); 02074 } 02075 02076 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 02077 //! Move assignment in C++11 02078 GenericDocument& operator=(GenericDocument&& rhs) RAPIDJSON_NOEXCEPT 02079 { 02080 // The cast to ValueType is necessary here, because otherwise it would 02081 // attempt to call GenericValue's templated assignment operator. 02082 ValueType::operator=(std::forward<ValueType>(rhs)); 02083 02084 // Calling the destructor here would prematurely call stack_'s destructor 02085 Destroy(); 02086 02087 allocator_ = rhs.allocator_; 02088 ownAllocator_ = rhs.ownAllocator_; 02089 stack_ = std::move(rhs.stack_); 02090 parseResult_ = rhs.parseResult_; 02091 02092 rhs.allocator_ = 0; 02093 rhs.ownAllocator_ = 0; 02094 rhs.parseResult_ = ParseResult(); 02095 02096 return *this; 02097 } 02098 #endif 02099 02100 //! Exchange the contents of this document with those of another. 02101 /*! 02102 \param rhs Another document. 02103 \note Constant complexity. 02104 \see GenericValue::Swap 02105 */ 02106 GenericDocument& Swap(GenericDocument& rhs) RAPIDJSON_NOEXCEPT { 02107 ValueType::Swap(rhs); 02108 stack_.Swap(rhs.stack_); 02109 internal::Swap(allocator_, rhs.allocator_); 02110 internal::Swap(ownAllocator_, rhs.ownAllocator_); 02111 internal::Swap(parseResult_, rhs.parseResult_); 02112 return *this; 02113 } 02114 02115 //! free-standing swap function helper 02116 /*! 02117 Helper function to enable support for common swap implementation pattern based on \c std::swap: 02118 \code 02119 void swap(MyClass& a, MyClass& b) { 02120 using std::swap; 02121 swap(a.doc, b.doc); 02122 // ... 02123 } 02124 \endcode 02125 \see Swap() 02126 */ 02127 friend inline void swap(GenericDocument& a, GenericDocument& b) RAPIDJSON_NOEXCEPT { a.Swap(b); } 02128 02129 //! Populate this document by a generator which produces SAX events. 02130 /*! \tparam Generator A functor with <tt>bool f(Handler)</tt> prototype. 02131 \param g Generator functor which sends SAX events to the parameter. 02132 \return The document itself for fluent API. 02133 */ 02134 template <typename Generator> 02135 GenericDocument& Populate(Generator& g) { 02136 ClearStackOnExit scope(*this); 02137 if (g(*this)) { 02138 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object 02139 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document 02140 } 02141 return *this; 02142 } 02143 02144 //!@name Parse from stream 02145 //!@{ 02146 02147 //! Parse JSON text from an input stream (with Encoding conversion) 02148 /*! \tparam parseFlags Combination of \ref ParseFlag. 02149 \tparam SourceEncoding Encoding of input stream 02150 \tparam InputStream Type of input stream, implementing Stream concept 02151 \param is Input stream to be parsed. 02152 \return The document itself for fluent API. 02153 */ 02154 template <unsigned parseFlags, typename SourceEncoding, typename InputStream> 02155 GenericDocument& ParseStream(InputStream& is) { 02156 GenericReader<SourceEncoding, Encoding, StackAllocator> reader( 02157 stack_.HasAllocator() ? &stack_.GetAllocator() : 0); 02158 ClearStackOnExit scope(*this); 02159 parseResult_ = reader.template Parse<parseFlags>(is, *this); 02160 if (parseResult_) { 02161 RAPIDJSON_ASSERT(stack_.GetSize() == sizeof(ValueType)); // Got one and only one root object 02162 ValueType::operator=(*stack_.template Pop<ValueType>(1));// Move value from stack to document 02163 } 02164 return *this; 02165 } 02166 02167 //! Parse JSON text from an input stream 02168 /*! \tparam parseFlags Combination of \ref ParseFlag. 02169 \tparam InputStream Type of input stream, implementing Stream concept 02170 \param is Input stream to be parsed. 02171 \return The document itself for fluent API. 02172 */ 02173 template <unsigned parseFlags, typename InputStream> 02174 GenericDocument& ParseStream(InputStream& is) { 02175 return ParseStream<parseFlags, Encoding, InputStream>(is); 02176 } 02177 02178 //! Parse JSON text from an input stream (with \ref kParseDefaultFlags) 02179 /*! \tparam InputStream Type of input stream, implementing Stream concept 02180 \param is Input stream to be parsed. 02181 \return The document itself for fluent API. 02182 */ 02183 template <typename InputStream> 02184 GenericDocument& ParseStream(InputStream& is) { 02185 return ParseStream<kParseDefaultFlags, Encoding, InputStream>(is); 02186 } 02187 //!@} 02188 02189 //!@name Parse in-place from mutable string 02190 //!@{ 02191 02192 //! Parse JSON text from a mutable string 02193 /*! \tparam parseFlags Combination of \ref ParseFlag. 02194 \param str Mutable zero-terminated string to be parsed. 02195 \return The document itself for fluent API. 02196 */ 02197 template <unsigned parseFlags> 02198 GenericDocument& ParseInsitu(Ch* str) { 02199 GenericInsituStringStream<Encoding> s(str); 02200 return ParseStream<parseFlags | kParseInsituFlag>(s); 02201 } 02202 02203 //! Parse JSON text from a mutable string (with \ref kParseDefaultFlags) 02204 /*! \param str Mutable zero-terminated string to be parsed. 02205 \return The document itself for fluent API. 02206 */ 02207 GenericDocument& ParseInsitu(Ch* str) { 02208 return ParseInsitu<kParseDefaultFlags>(str); 02209 } 02210 //!@} 02211 02212 //!@name Parse from read-only string 02213 //!@{ 02214 02215 //! Parse JSON text from a read-only string (with Encoding conversion) 02216 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). 02217 \tparam SourceEncoding Transcoding from input Encoding 02218 \param str Read-only zero-terminated string to be parsed. 02219 */ 02220 template <unsigned parseFlags, typename SourceEncoding> 02221 GenericDocument& Parse(const typename SourceEncoding::Ch* str) { 02222 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 02223 GenericStringStream<SourceEncoding> s(str); 02224 return ParseStream<parseFlags, SourceEncoding>(s); 02225 } 02226 02227 //! Parse JSON text from a read-only string 02228 /*! \tparam parseFlags Combination of \ref ParseFlag (must not contain \ref kParseInsituFlag). 02229 \param str Read-only zero-terminated string to be parsed. 02230 */ 02231 template <unsigned parseFlags> 02232 GenericDocument& Parse(const Ch* str) { 02233 return Parse<parseFlags, Encoding>(str); 02234 } 02235 02236 //! Parse JSON text from a read-only string (with \ref kParseDefaultFlags) 02237 /*! \param str Read-only zero-terminated string to be parsed. 02238 */ 02239 GenericDocument& Parse(const Ch* str) { 02240 return Parse<kParseDefaultFlags>(str); 02241 } 02242 02243 template <unsigned parseFlags, typename SourceEncoding> 02244 GenericDocument& Parse(const typename SourceEncoding::Ch* str, size_t length) { 02245 RAPIDJSON_ASSERT(!(parseFlags & kParseInsituFlag)); 02246 MemoryStream ms(static_cast<const char*>(str), length * sizeof(typename SourceEncoding::Ch)); 02247 EncodedInputStream<SourceEncoding, MemoryStream> is(ms); 02248 ParseStream<parseFlags, SourceEncoding>(is); 02249 return *this; 02250 } 02251 02252 template <unsigned parseFlags> 02253 GenericDocument& Parse(const Ch* str, size_t length) { 02254 return Parse<parseFlags, Encoding>(str, length); 02255 } 02256 02257 GenericDocument& Parse(const Ch* str, size_t length) { 02258 return Parse<kParseDefaultFlags>(str, length); 02259 } 02260 02261 #if RAPIDJSON_HAS_STDSTRING 02262 template <unsigned parseFlags, typename SourceEncoding> 02263 GenericDocument& Parse(const std::basic_string<typename SourceEncoding::Ch>& str) { 02264 // c_str() is constant complexity according to standard. Should be faster than Parse(const char*, size_t) 02265 return Parse<parseFlags, SourceEncoding>(str.c_str()); 02266 } 02267 02268 template <unsigned parseFlags> 02269 GenericDocument& Parse(const std::basic_string<Ch>& str) { 02270 return Parse<parseFlags, Encoding>(str.c_str()); 02271 } 02272 02273 GenericDocument& Parse(const std::basic_string<Ch>& str) { 02274 return Parse<kParseDefaultFlags>(str); 02275 } 02276 #endif // RAPIDJSON_HAS_STDSTRING 02277 02278 //!@} 02279 02280 //!@name Handling parse errors 02281 //!@{ 02282 02283 //! Whether a parse error has occured in the last parsing. 02284 bool HasParseError() const { return parseResult_.IsError(); } 02285 02286 //! Get the \ref ParseErrorCode of last parsing. 02287 ParseErrorCode GetParseError() const { return parseResult_.Code(); } 02288 02289 //! Get the position of last parsing error in input, 0 otherwise. 02290 size_t GetErrorOffset() const { return parseResult_.Offset(); } 02291 02292 //! Implicit conversion to get the last parse result 02293 #ifndef __clang // -Wdocumentation 02294 /*! \return \ref ParseResult of the last parse operation 02295 02296 \code 02297 Document doc; 02298 ParseResult ok = doc.Parse(json); 02299 if (!ok) 02300 printf( "JSON parse error: %s (%u)\n", GetParseError_En(ok.Code()), ok.Offset()); 02301 \endcode 02302 */ 02303 #endif 02304 operator ParseResult() const { return parseResult_; } 02305 //!@} 02306 02307 //! Get the allocator of this document. 02308 Allocator& GetAllocator() { 02309 RAPIDJSON_ASSERT(allocator_); 02310 return *allocator_; 02311 } 02312 02313 //! Get the capacity of stack in bytes. 02314 size_t GetStackCapacity() const { return stack_.GetCapacity(); } 02315 02316 private: 02317 // clear stack on any exit from ParseStream, e.g. due to exception 02318 struct ClearStackOnExit { 02319 explicit ClearStackOnExit(GenericDocument& d) : d_(d) {} 02320 ~ClearStackOnExit() { d_.ClearStack(); } 02321 private: 02322 ClearStackOnExit(const ClearStackOnExit&); 02323 ClearStackOnExit& operator=(const ClearStackOnExit&); 02324 GenericDocument& d_; 02325 }; 02326 02327 // callers of the following private Handler functions 02328 // template <typename,typename,typename> friend class GenericReader; // for parsing 02329 template <typename, typename> friend class GenericValue; // for deep copying 02330 02331 public: 02332 // Implementation of Handler 02333 bool Null() { new (stack_.template Push<ValueType>()) ValueType(); return true; } 02334 bool Bool(bool b) { new (stack_.template Push<ValueType>()) ValueType(b); return true; } 02335 bool Int(int i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } 02336 bool Uint(unsigned i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } 02337 bool Int64(int64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } 02338 bool Uint64(uint64_t i) { new (stack_.template Push<ValueType>()) ValueType(i); return true; } 02339 bool Double(double d) { new (stack_.template Push<ValueType>()) ValueType(d); return true; } 02340 02341 bool RawNumber(const Ch* str, SizeType length, bool copy) { 02342 if (copy) 02343 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator()); 02344 else 02345 new (stack_.template Push<ValueType>()) ValueType(str, length); 02346 return true; 02347 } 02348 02349 bool String(const Ch* str, SizeType length, bool copy) { 02350 if (copy) 02351 new (stack_.template Push<ValueType>()) ValueType(str, length, GetAllocator()); 02352 else 02353 new (stack_.template Push<ValueType>()) ValueType(str, length); 02354 return true; 02355 } 02356 02357 bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; } 02358 02359 bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); } 02360 02361 bool EndObject(SizeType memberCount) { 02362 typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount); 02363 stack_.template Top<ValueType>()->SetObjectRaw(members, memberCount, GetAllocator()); 02364 return true; 02365 } 02366 02367 bool StartArray() { new (stack_.template Push<ValueType>()) ValueType(kArrayType); return true; } 02368 02369 bool EndArray(SizeType elementCount) { 02370 ValueType* elements = stack_.template Pop<ValueType>(elementCount); 02371 stack_.template Top<ValueType>()->SetArrayRaw(elements, elementCount, GetAllocator()); 02372 return true; 02373 } 02374 02375 private: 02376 //! Prohibit copying 02377 GenericDocument(const GenericDocument&); 02378 //! Prohibit assignment 02379 GenericDocument& operator=(const GenericDocument&); 02380 02381 void ClearStack() { 02382 if (Allocator::kNeedFree) 02383 while (stack_.GetSize() > 0) // Here assumes all elements in stack array are GenericValue (Member is actually 2 GenericValue objects) 02384 (stack_.template Pop<ValueType>(1))->~ValueType(); 02385 else 02386 stack_.Clear(); 02387 stack_.ShrinkToFit(); 02388 } 02389 02390 void Destroy() { 02391 RAPIDJSON_DELETE(ownAllocator_); 02392 } 02393 02394 static const size_t kDefaultStackCapacity = 1024; 02395 Allocator* allocator_; 02396 Allocator* ownAllocator_; 02397 internal::Stack<StackAllocator> stack_; 02398 ParseResult parseResult_; 02399 }; 02400 02401 //! GenericDocument with UTF8 encoding 02402 typedef GenericDocument<UTF8<> > Document; 02403 02404 // defined here due to the dependency on GenericDocument 02405 template <typename Encoding, typename Allocator> 02406 template <typename SourceAllocator> 02407 inline 02408 GenericValue<Encoding,Allocator>::GenericValue(const GenericValue<Encoding,SourceAllocator>& rhs, Allocator& allocator) 02409 { 02410 switch (rhs.GetType()) { 02411 case kObjectType: 02412 case kArrayType: { // perform deep copy via SAX Handler 02413 GenericDocument<Encoding,Allocator> d(&allocator); 02414 rhs.Accept(d); 02415 RawAssign(*d.stack_.template Pop<GenericValue>(1)); 02416 } 02417 break; 02418 case kStringType: 02419 if (rhs.data_.f.flags == kConstStringFlag) { 02420 data_.f.flags = rhs.data_.f.flags; 02421 data_ = *reinterpret_cast<const Data*>(&rhs.data_); 02422 } else { 02423 SetStringRaw(StringRef(rhs.GetString(), rhs.GetStringLength()), allocator); 02424 } 02425 break; 02426 default: 02427 data_.f.flags = rhs.data_.f.flags; 02428 data_ = *reinterpret_cast<const Data*>(&rhs.data_); 02429 break; 02430 } 02431 } 02432 02433 //! Helper class for accessing Value of array type. 02434 /*! 02435 Instance of this helper class is obtained by \c GenericValue::GetArray(). 02436 In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. 02437 */ 02438 template <bool Const, typename ValueT> 02439 class GenericArray { 02440 public: 02441 typedef GenericArray<true, ValueT> ConstArray; 02442 typedef GenericArray<false, ValueT> Array; 02443 typedef ValueT PlainType; 02444 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType; 02445 typedef ValueType* ValueIterator; // This may be const or non-const iterator 02446 typedef const ValueT* ConstValueIterator; 02447 typedef typename ValueType::AllocatorType AllocatorType; 02448 typedef typename ValueType::StringRefType StringRefType; 02449 02450 template <typename, typename> 02451 friend class GenericValue; 02452 02453 GenericArray(const GenericArray& rhs) : value_(rhs.value_) {} 02454 GenericArray& operator=(const GenericArray& rhs) { value_ = rhs.value_; return *this; } 02455 ~GenericArray() {} 02456 02457 SizeType Size() const { return value_.Size(); } 02458 SizeType Capacity() const { return value_.Capacity(); } 02459 bool Empty() const { return value_.Empty(); } 02460 void Clear() const { value_.Clear(); } 02461 ValueType& operator[](SizeType index) const { return value_[index]; } 02462 ValueIterator Begin() const { return value_.Begin(); } 02463 ValueIterator End() const { return value_.End(); } 02464 GenericArray Reserve(SizeType newCapacity, AllocatorType &allocator) const { value_.Reserve(newCapacity, allocator); return *this; } 02465 GenericArray PushBack(ValueType& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } 02466 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 02467 GenericArray PushBack(ValueType&& value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } 02468 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 02469 GenericArray PushBack(StringRefType value, AllocatorType& allocator) const { value_.PushBack(value, allocator); return *this; } 02470 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; } 02471 GenericArray PopBack() const { value_.PopBack(); return *this; } 02472 ValueIterator Erase(ConstValueIterator pos) const { return value_.Erase(pos); } 02473 ValueIterator Erase(ConstValueIterator first, ConstValueIterator last) const { return value_.Erase(first, last); } 02474 02475 #if RAPIDJSON_HAS_CXX11_RANGE_FOR 02476 ValueIterator begin() const { return value_.Begin(); } 02477 ValueIterator end() const { return value_.End(); } 02478 #endif 02479 02480 private: 02481 GenericArray(); 02482 GenericArray(ValueType& value) : value_(value) {} 02483 ValueType& value_; 02484 }; 02485 02486 //! Helper class for accessing Value of object type. 02487 /*! 02488 Instance of this helper class is obtained by \c GenericValue::GetObject(). 02489 In addition to all APIs for array type, it provides range-based for loop if \c RAPIDJSON_HAS_CXX11_RANGE_FOR=1. 02490 */ 02491 template <bool Const, typename ValueT> 02492 class GenericObject { 02493 public: 02494 typedef GenericObject<true, ValueT> ConstObject; 02495 typedef GenericObject<false, ValueT> Object; 02496 typedef ValueT PlainType; 02497 typedef typename internal::MaybeAddConst<Const,PlainType>::Type ValueType; 02498 typedef GenericMemberIterator<Const, typename ValueT::EncodingType, typename ValueT::AllocatorType> MemberIterator; // This may be const or non-const iterator 02499 typedef GenericMemberIterator<true, typename ValueT::EncodingType, typename ValueT::AllocatorType> ConstMemberIterator; 02500 typedef typename ValueType::AllocatorType AllocatorType; 02501 typedef typename ValueType::StringRefType StringRefType; 02502 typedef typename ValueType::EncodingType EncodingType; 02503 typedef typename ValueType::Ch Ch; 02504 02505 template <typename, typename> 02506 friend class GenericValue; 02507 02508 GenericObject(const GenericObject& rhs) : value_(rhs.value_) {} 02509 GenericObject& operator=(const GenericObject& rhs) { value_ = rhs.value_; return *this; } 02510 ~GenericObject() {} 02511 02512 SizeType MemberCount() const { return value_.MemberCount(); } 02513 bool ObjectEmpty() const { return value_.ObjectEmpty(); } 02514 template <typename T> ValueType& operator[](T* name) const { return value_[name]; } 02515 template <typename SourceAllocator> ValueType& operator[](const GenericValue<EncodingType, SourceAllocator>& name) const { return value_[name]; } 02516 #if RAPIDJSON_HAS_STDSTRING 02517 ValueType& operator[](const std::basic_string<Ch>& name) const { return value_[name]; } 02518 #endif 02519 MemberIterator MemberBegin() const { return value_.MemberBegin(); } 02520 MemberIterator MemberEnd() const { return value_.MemberEnd(); } 02521 bool HasMember(const Ch* name) const { return value_.HasMember(name); } 02522 #if RAPIDJSON_HAS_STDSTRING 02523 bool HasMember(const std::basic_string<Ch>& name) const { return value_.HasMember(name); } 02524 #endif 02525 template <typename SourceAllocator> bool HasMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.HasMember(name); } 02526 MemberIterator FindMember(const Ch* name) const { return value_.FindMember(name); } 02527 template <typename SourceAllocator> MemberIterator FindMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.FindMember(name); } 02528 #if RAPIDJSON_HAS_STDSTRING 02529 MemberIterator FindMember(const std::basic_string<Ch>& name) const { return value_.FindMember(name); } 02530 #endif 02531 GenericObject AddMember(ValueType& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02532 GenericObject AddMember(ValueType& name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02533 #if RAPIDJSON_HAS_STDSTRING 02534 GenericObject AddMember(ValueType& name, std::basic_string<Ch>& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02535 #endif 02536 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; } 02537 #if RAPIDJSON_HAS_CXX11_RVALUE_REFS 02538 GenericObject AddMember(ValueType&& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02539 GenericObject AddMember(ValueType&& name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02540 GenericObject AddMember(ValueType& name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02541 GenericObject AddMember(StringRefType name, ValueType&& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02542 #endif // RAPIDJSON_HAS_CXX11_RVALUE_REFS 02543 GenericObject AddMember(StringRefType name, ValueType& value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02544 GenericObject AddMember(StringRefType name, StringRefType value, AllocatorType& allocator) const { value_.AddMember(name, value, allocator); return *this; } 02545 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; } 02546 void RemoveAllMembers() { return value_.RemoveAllMembers(); } 02547 bool RemoveMember(const Ch* name) const { return value_.RemoveMember(name); } 02548 #if RAPIDJSON_HAS_STDSTRING 02549 bool RemoveMember(const std::basic_string<Ch>& name) const { return value_.RemoveMember(name); } 02550 #endif 02551 template <typename SourceAllocator> bool RemoveMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.RemoveMember(name); } 02552 MemberIterator RemoveMember(MemberIterator m) const { return value_.RemoveMember(m); } 02553 MemberIterator EraseMember(ConstMemberIterator pos) const { return value_.EraseMember(pos); } 02554 MemberIterator EraseMember(ConstMemberIterator first, ConstMemberIterator last) const { return value_.EraseMember(first, last); } 02555 bool EraseMember(const Ch* name) const { return value_.EraseMember(name); } 02556 #if RAPIDJSON_HAS_STDSTRING 02557 bool EraseMember(const std::basic_string<Ch>& name) const { return EraseMember(ValueType(StringRef(name))); } 02558 #endif 02559 template <typename SourceAllocator> bool EraseMember(const GenericValue<EncodingType, SourceAllocator>& name) const { return value_.EraseMember(name); } 02560 02561 #if RAPIDJSON_HAS_CXX11_RANGE_FOR 02562 MemberIterator begin() const { return value_.MemberBegin(); } 02563 MemberIterator end() const { return value_.MemberEnd(); } 02564 #endif 02565 02566 private: 02567 GenericObject(); 02568 GenericObject(ValueType& value) : value_(value) {} 02569 ValueType& value_; 02570 }; 02571 02572 RAPIDJSON_NAMESPACE_END 02573 RAPIDJSON_DIAG_POP 02574 02575 #endif // RAPIDJSON_DOCUMENT_H_
Generated on Tue Jul 12 2022 12:06:48 by 1.7.2