DeepCover Embedded Security in IoT: Public-key Secured Data Paths

Dependencies:   MaximInterface

The MAXREFDES155# is an internet-of-things (IoT) embedded-security reference design, built to authenticate and control a sensing node using elliptic-curve-based public-key cryptography with control and notification from a web server.

The hardware includes an ARM® mbed™ shield and attached sensor endpoint. The shield contains a DS2476 DeepCover® ECDSA/SHA-2 coprocessor, Wifi communication, LCD push-button controls, and status LEDs. The sensor endpoint is attached to the shield using a 300mm cable and contains a DS28C36 DeepCover ECDSA/SHA-2 authenticator, IR-thermal sensor, and aiming laser for the IR sensor. The MAXREFDES155# is equipped with a standard Arduino® form-factor shield connector for immediate testing using an mbed board such as the MAX32600MBED#. The combination of these two devices represent an IoT device. Communication to the web server is accomplished with the shield Wifi circuitry. Communication from the shield to the attached sensor module is accomplished over I2C . The sensor module represents an IoT endpoint that generates small data with a requirement for message authenticity/integrity and secure on/off operational control.

The design is hierarchical with each mbed platform and shield communicating data from the sensor node to a web server that maintains a centralized log and dispatches notifications as necessary. The simplicity of this design enables rapid integration into any star-topology IoT network to provide security with the low overhead and cost provided by the ECDSA-P256 asymmetric-key and SHA-256 symmetric-key algorithms.

More information about the MAXREFDES155# is available on the Maxim Integrated website.

Committer:
IanBenzMaxim
Date:
Fri Jan 19 10:28:27 2018 -0600
Revision:
15:75404fab3615
Parent:
0:33d4e66780c0
Updated MaximInterface revision.

Who changed what in which revision?

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