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