sq_detailed_metrics 0.1.0

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