isotree 0.1.4 → 0.1.5

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