isotree 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/LICENSE.txt +2 -2
  4. data/README.md +32 -14
  5. data/ext/isotree/ext.cpp +144 -31
  6. data/ext/isotree/extconf.rb +7 -7
  7. data/lib/isotree/isolation_forest.rb +110 -30
  8. data/lib/isotree/version.rb +1 -1
  9. data/vendor/isotree/LICENSE +1 -1
  10. data/vendor/isotree/README.md +165 -27
  11. data/vendor/isotree/include/isotree.hpp +2111 -0
  12. data/vendor/isotree/include/isotree_oop.hpp +394 -0
  13. data/vendor/isotree/inst/COPYRIGHTS +62 -0
  14. data/vendor/isotree/src/RcppExports.cpp +525 -52
  15. data/vendor/isotree/src/Rwrapper.cpp +1931 -268
  16. data/vendor/isotree/src/c_interface.cpp +953 -0
  17. data/vendor/isotree/src/crit.hpp +4232 -0
  18. data/vendor/isotree/src/dist.hpp +1886 -0
  19. data/vendor/isotree/src/exp_depth_table.hpp +134 -0
  20. data/vendor/isotree/src/extended.hpp +1444 -0
  21. data/vendor/isotree/src/external_facing_generic.hpp +399 -0
  22. data/vendor/isotree/src/fit_model.hpp +2401 -0
  23. data/vendor/isotree/src/{dealloc.cpp → headers_joined.hpp} +38 -22
  24. data/vendor/isotree/src/helpers_iforest.hpp +813 -0
  25. data/vendor/isotree/src/{impute.cpp → impute.hpp} +353 -122
  26. data/vendor/isotree/src/indexer.cpp +515 -0
  27. data/vendor/isotree/src/instantiate_template_headers.cpp +118 -0
  28. data/vendor/isotree/src/instantiate_template_headers.hpp +240 -0
  29. data/vendor/isotree/src/isoforest.hpp +1659 -0
  30. data/vendor/isotree/src/isotree.hpp +1804 -392
  31. data/vendor/isotree/src/isotree_exportable.hpp +99 -0
  32. data/vendor/isotree/src/merge_models.cpp +159 -16
  33. data/vendor/isotree/src/mult.hpp +1321 -0
  34. data/vendor/isotree/src/oop_interface.cpp +842 -0
  35. data/vendor/isotree/src/oop_interface.hpp +278 -0
  36. data/vendor/isotree/src/other_helpers.hpp +219 -0
  37. data/vendor/isotree/src/predict.hpp +1932 -0
  38. data/vendor/isotree/src/python_helpers.hpp +134 -0
  39. data/vendor/isotree/src/ref_indexer.hpp +154 -0
  40. data/vendor/isotree/src/robinmap/LICENSE +21 -0
  41. data/vendor/isotree/src/robinmap/README.md +483 -0
  42. data/vendor/isotree/src/robinmap/include/tsl/robin_growth_policy.h +406 -0
  43. data/vendor/isotree/src/robinmap/include/tsl/robin_hash.h +1620 -0
  44. data/vendor/isotree/src/robinmap/include/tsl/robin_map.h +807 -0
  45. data/vendor/isotree/src/robinmap/include/tsl/robin_set.h +660 -0
  46. data/vendor/isotree/src/serialize.cpp +4300 -139
  47. data/vendor/isotree/src/sql.cpp +141 -59
  48. data/vendor/isotree/src/subset_models.cpp +174 -0
  49. data/vendor/isotree/src/utils.hpp +3808 -0
  50. data/vendor/isotree/src/xoshiro.hpp +467 -0
  51. data/vendor/isotree/src/ziggurat.hpp +405 -0
  52. metadata +38 -104
  53. data/vendor/cereal/LICENSE +0 -24
  54. data/vendor/cereal/README.md +0 -85
  55. data/vendor/cereal/include/cereal/access.hpp +0 -351
  56. data/vendor/cereal/include/cereal/archives/adapters.hpp +0 -163
  57. data/vendor/cereal/include/cereal/archives/binary.hpp +0 -169
  58. data/vendor/cereal/include/cereal/archives/json.hpp +0 -1019
  59. data/vendor/cereal/include/cereal/archives/portable_binary.hpp +0 -334
  60. data/vendor/cereal/include/cereal/archives/xml.hpp +0 -956
  61. data/vendor/cereal/include/cereal/cereal.hpp +0 -1089
  62. data/vendor/cereal/include/cereal/details/helpers.hpp +0 -422
  63. data/vendor/cereal/include/cereal/details/polymorphic_impl.hpp +0 -796
  64. data/vendor/cereal/include/cereal/details/polymorphic_impl_fwd.hpp +0 -65
  65. data/vendor/cereal/include/cereal/details/static_object.hpp +0 -127
  66. data/vendor/cereal/include/cereal/details/traits.hpp +0 -1411
  67. data/vendor/cereal/include/cereal/details/util.hpp +0 -84
  68. data/vendor/cereal/include/cereal/external/base64.hpp +0 -134
  69. data/vendor/cereal/include/cereal/external/rapidjson/allocators.h +0 -284
  70. data/vendor/cereal/include/cereal/external/rapidjson/cursorstreamwrapper.h +0 -78
  71. data/vendor/cereal/include/cereal/external/rapidjson/document.h +0 -2652
  72. data/vendor/cereal/include/cereal/external/rapidjson/encodedstream.h +0 -299
  73. data/vendor/cereal/include/cereal/external/rapidjson/encodings.h +0 -716
  74. data/vendor/cereal/include/cereal/external/rapidjson/error/en.h +0 -74
  75. data/vendor/cereal/include/cereal/external/rapidjson/error/error.h +0 -161
  76. data/vendor/cereal/include/cereal/external/rapidjson/filereadstream.h +0 -99
  77. data/vendor/cereal/include/cereal/external/rapidjson/filewritestream.h +0 -104
  78. data/vendor/cereal/include/cereal/external/rapidjson/fwd.h +0 -151
  79. data/vendor/cereal/include/cereal/external/rapidjson/internal/biginteger.h +0 -290
  80. data/vendor/cereal/include/cereal/external/rapidjson/internal/diyfp.h +0 -271
  81. data/vendor/cereal/include/cereal/external/rapidjson/internal/dtoa.h +0 -245
  82. data/vendor/cereal/include/cereal/external/rapidjson/internal/ieee754.h +0 -78
  83. data/vendor/cereal/include/cereal/external/rapidjson/internal/itoa.h +0 -308
  84. data/vendor/cereal/include/cereal/external/rapidjson/internal/meta.h +0 -186
  85. data/vendor/cereal/include/cereal/external/rapidjson/internal/pow10.h +0 -55
  86. data/vendor/cereal/include/cereal/external/rapidjson/internal/regex.h +0 -740
  87. data/vendor/cereal/include/cereal/external/rapidjson/internal/stack.h +0 -232
  88. data/vendor/cereal/include/cereal/external/rapidjson/internal/strfunc.h +0 -69
  89. data/vendor/cereal/include/cereal/external/rapidjson/internal/strtod.h +0 -290
  90. data/vendor/cereal/include/cereal/external/rapidjson/internal/swap.h +0 -46
  91. data/vendor/cereal/include/cereal/external/rapidjson/istreamwrapper.h +0 -128
  92. data/vendor/cereal/include/cereal/external/rapidjson/memorybuffer.h +0 -70
  93. data/vendor/cereal/include/cereal/external/rapidjson/memorystream.h +0 -71
  94. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/inttypes.h +0 -316
  95. data/vendor/cereal/include/cereal/external/rapidjson/msinttypes/stdint.h +0 -300
  96. data/vendor/cereal/include/cereal/external/rapidjson/ostreamwrapper.h +0 -81
  97. data/vendor/cereal/include/cereal/external/rapidjson/pointer.h +0 -1414
  98. data/vendor/cereal/include/cereal/external/rapidjson/prettywriter.h +0 -277
  99. data/vendor/cereal/include/cereal/external/rapidjson/rapidjson.h +0 -656
  100. data/vendor/cereal/include/cereal/external/rapidjson/reader.h +0 -2230
  101. data/vendor/cereal/include/cereal/external/rapidjson/schema.h +0 -2497
  102. data/vendor/cereal/include/cereal/external/rapidjson/stream.h +0 -223
  103. data/vendor/cereal/include/cereal/external/rapidjson/stringbuffer.h +0 -121
  104. data/vendor/cereal/include/cereal/external/rapidjson/writer.h +0 -709
  105. data/vendor/cereal/include/cereal/external/rapidxml/license.txt +0 -52
  106. data/vendor/cereal/include/cereal/external/rapidxml/manual.html +0 -406
  107. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml.hpp +0 -2624
  108. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_iterators.hpp +0 -175
  109. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_print.hpp +0 -428
  110. data/vendor/cereal/include/cereal/external/rapidxml/rapidxml_utils.hpp +0 -123
  111. data/vendor/cereal/include/cereal/macros.hpp +0 -154
  112. data/vendor/cereal/include/cereal/specialize.hpp +0 -139
  113. data/vendor/cereal/include/cereal/types/array.hpp +0 -79
  114. data/vendor/cereal/include/cereal/types/atomic.hpp +0 -55
  115. data/vendor/cereal/include/cereal/types/base_class.hpp +0 -203
  116. data/vendor/cereal/include/cereal/types/bitset.hpp +0 -176
  117. data/vendor/cereal/include/cereal/types/boost_variant.hpp +0 -164
  118. data/vendor/cereal/include/cereal/types/chrono.hpp +0 -72
  119. data/vendor/cereal/include/cereal/types/common.hpp +0 -129
  120. data/vendor/cereal/include/cereal/types/complex.hpp +0 -56
  121. data/vendor/cereal/include/cereal/types/concepts/pair_associative_container.hpp +0 -73
  122. data/vendor/cereal/include/cereal/types/deque.hpp +0 -62
  123. data/vendor/cereal/include/cereal/types/forward_list.hpp +0 -68
  124. data/vendor/cereal/include/cereal/types/functional.hpp +0 -43
  125. data/vendor/cereal/include/cereal/types/list.hpp +0 -62
  126. data/vendor/cereal/include/cereal/types/map.hpp +0 -36
  127. data/vendor/cereal/include/cereal/types/memory.hpp +0 -425
  128. data/vendor/cereal/include/cereal/types/optional.hpp +0 -66
  129. data/vendor/cereal/include/cereal/types/polymorphic.hpp +0 -483
  130. data/vendor/cereal/include/cereal/types/queue.hpp +0 -132
  131. data/vendor/cereal/include/cereal/types/set.hpp +0 -103
  132. data/vendor/cereal/include/cereal/types/stack.hpp +0 -76
  133. data/vendor/cereal/include/cereal/types/string.hpp +0 -61
  134. data/vendor/cereal/include/cereal/types/tuple.hpp +0 -123
  135. data/vendor/cereal/include/cereal/types/unordered_map.hpp +0 -36
  136. data/vendor/cereal/include/cereal/types/unordered_set.hpp +0 -99
  137. data/vendor/cereal/include/cereal/types/utility.hpp +0 -47
  138. data/vendor/cereal/include/cereal/types/valarray.hpp +0 -89
  139. data/vendor/cereal/include/cereal/types/variant.hpp +0 -109
  140. data/vendor/cereal/include/cereal/types/vector.hpp +0 -112
  141. data/vendor/cereal/include/cereal/version.hpp +0 -52
  142. data/vendor/isotree/src/Makevars +0 -4
  143. data/vendor/isotree/src/crit.cpp +0 -912
  144. data/vendor/isotree/src/dist.cpp +0 -749
  145. data/vendor/isotree/src/extended.cpp +0 -790
  146. data/vendor/isotree/src/fit_model.cpp +0 -1090
  147. data/vendor/isotree/src/helpers_iforest.cpp +0 -324
  148. data/vendor/isotree/src/isoforest.cpp +0 -771
  149. data/vendor/isotree/src/mult.cpp +0 -607
  150. data/vendor/isotree/src/predict.cpp +0 -853
  151. data/vendor/isotree/src/utils.cpp +0 -1566
@@ -1,1414 +0,0 @@
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_POINTER_H_
16
- #define CEREAL_RAPIDJSON_POINTER_H_
17
-
18
- #include "document.h"
19
- #include "internal/itoa.h"
20
-
21
- #ifdef __clang__
22
- CEREAL_RAPIDJSON_DIAG_PUSH
23
- CEREAL_RAPIDJSON_DIAG_OFF(switch-enum)
24
- #elif defined(_MSC_VER)
25
- CEREAL_RAPIDJSON_DIAG_PUSH
26
- CEREAL_RAPIDJSON_DIAG_OFF(4512) // assignment operator could not be generated
27
- #endif
28
-
29
- CEREAL_RAPIDJSON_NAMESPACE_BEGIN
30
-
31
- static const SizeType kPointerInvalidIndex = ~SizeType(0); //!< Represents an invalid index in GenericPointer::Token
32
-
33
- //! Error code of parsing.
34
- /*! \ingroup CEREAL_RAPIDJSON_ERRORS
35
- \see GenericPointer::GenericPointer, GenericPointer::GetParseErrorCode
36
- */
37
- enum PointerParseErrorCode {
38
- kPointerParseErrorNone = 0, //!< The parse is successful
39
-
40
- kPointerParseErrorTokenMustBeginWithSolidus, //!< A token must begin with a '/'
41
- kPointerParseErrorInvalidEscape, //!< Invalid escape
42
- kPointerParseErrorInvalidPercentEncoding, //!< Invalid percent encoding in URI fragment
43
- kPointerParseErrorCharacterMustPercentEncode //!< A character must percent encoded in URI fragment
44
- };
45
-
46
- ///////////////////////////////////////////////////////////////////////////////
47
- // GenericPointer
48
-
49
- //! Represents a JSON Pointer. Use Pointer for UTF8 encoding and default allocator.
50
- /*!
51
- This class implements RFC 6901 "JavaScript Object Notation (JSON) Pointer"
52
- (https://tools.ietf.org/html/rfc6901).
53
-
54
- A JSON pointer is for identifying a specific value in a JSON document
55
- (GenericDocument). It can simplify coding of DOM tree manipulation, because it
56
- can access multiple-level depth of DOM tree with single API call.
57
-
58
- After it parses a string representation (e.g. "/foo/0" or URI fragment
59
- representation (e.g. "#/foo/0") into its internal representation (tokens),
60
- it can be used to resolve a specific value in multiple documents, or sub-tree
61
- of documents.
62
-
63
- Contrary to GenericValue, Pointer can be copy constructed and copy assigned.
64
- Apart from assignment, a Pointer cannot be modified after construction.
65
-
66
- Although Pointer is very convenient, please aware that constructing Pointer
67
- involves parsing and dynamic memory allocation. A special constructor with user-
68
- supplied tokens eliminates these.
69
-
70
- GenericPointer depends on GenericDocument and GenericValue.
71
-
72
- \tparam ValueType The value type of the DOM tree. E.g. GenericValue<UTF8<> >
73
- \tparam Allocator The allocator type for allocating memory for internal representation.
74
-
75
- \note GenericPointer uses same encoding of ValueType.
76
- However, Allocator of GenericPointer is independent of Allocator of Value.
77
- */
78
- template <typename ValueType, typename Allocator = CrtAllocator>
79
- class GenericPointer {
80
- public:
81
- typedef typename ValueType::EncodingType EncodingType; //!< Encoding type from Value
82
- typedef typename ValueType::Ch Ch; //!< Character type from Value
83
-
84
- //! A token is the basic units of internal representation.
85
- /*!
86
- A JSON pointer string representation "/foo/123" is parsed to two tokens:
87
- "foo" and 123. 123 will be represented in both numeric form and string form.
88
- They are resolved according to the actual value type (object or array).
89
-
90
- For token that are not numbers, or the numeric value is out of bound
91
- (greater than limits of SizeType), they are only treated as string form
92
- (i.e. the token's index will be equal to kPointerInvalidIndex).
93
-
94
- This struct is public so that user can create a Pointer without parsing and
95
- allocation, using a special constructor.
96
- */
97
- struct Token {
98
- const Ch* name; //!< Name of the token. It has null character at the end but it can contain null character.
99
- SizeType length; //!< Length of the name.
100
- SizeType index; //!< A valid array index, if it is not equal to kPointerInvalidIndex.
101
- };
102
-
103
- //!@name Constructors and destructor.
104
- //@{
105
-
106
- //! Default constructor.
107
- GenericPointer(Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
108
-
109
- //! Constructor that parses a string or URI fragment representation.
110
- /*!
111
- \param source A null-terminated, string or URI fragment representation of JSON pointer.
112
- \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
113
- */
114
- explicit GenericPointer(const Ch* source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
115
- Parse(source, internal::StrLen(source));
116
- }
117
-
118
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
119
- //! Constructor that parses a string or URI fragment representation.
120
- /*!
121
- \param source A string or URI fragment representation of JSON pointer.
122
- \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
123
- \note Requires the definition of the preprocessor symbol \ref CEREAL_RAPIDJSON_HAS_STDSTRING.
124
- */
125
- explicit GenericPointer(const std::basic_string<Ch>& source, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
126
- Parse(source.c_str(), source.size());
127
- }
128
- #endif
129
-
130
- //! Constructor that parses a string or URI fragment representation, with length of the source string.
131
- /*!
132
- \param source A string or URI fragment representation of JSON pointer.
133
- \param length Length of source.
134
- \param allocator User supplied allocator for this pointer. If no allocator is provided, it creates a self-owned one.
135
- \note Slightly faster than the overload without length.
136
- */
137
- GenericPointer(const Ch* source, size_t length, Allocator* allocator = 0) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
138
- Parse(source, length);
139
- }
140
-
141
- //! Constructor with user-supplied tokens.
142
- /*!
143
- This constructor let user supplies const array of tokens.
144
- This prevents the parsing process and eliminates allocation.
145
- This is preferred for memory constrained environments.
146
-
147
- \param tokens An constant array of tokens representing the JSON pointer.
148
- \param tokenCount Number of tokens.
149
-
150
- \b Example
151
- \code
152
- #define NAME(s) { s, sizeof(s) / sizeof(s[0]) - 1, kPointerInvalidIndex }
153
- #define INDEX(i) { #i, sizeof(#i) - 1, i }
154
-
155
- static const Pointer::Token kTokens[] = { NAME("foo"), INDEX(123) };
156
- static const Pointer p(kTokens, sizeof(kTokens) / sizeof(kTokens[0]));
157
- // Equivalent to static const Pointer p("/foo/123");
158
-
159
- #undef NAME
160
- #undef INDEX
161
- \endcode
162
- */
163
- GenericPointer(const Token* tokens, size_t tokenCount) : allocator_(), ownAllocator_(), nameBuffer_(), tokens_(const_cast<Token*>(tokens)), tokenCount_(tokenCount), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {}
164
-
165
- //! Copy constructor.
166
- GenericPointer(const GenericPointer& rhs) : allocator_(rhs.allocator_), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
167
- *this = rhs;
168
- }
169
-
170
- //! Copy constructor.
171
- GenericPointer(const GenericPointer& rhs, Allocator* allocator) : allocator_(allocator), ownAllocator_(), nameBuffer_(), tokens_(), tokenCount_(), parseErrorOffset_(), parseErrorCode_(kPointerParseErrorNone) {
172
- *this = rhs;
173
- }
174
-
175
- //! Destructor.
176
- ~GenericPointer() {
177
- if (nameBuffer_) // If user-supplied tokens constructor is used, nameBuffer_ is nullptr and tokens_ are not deallocated.
178
- Allocator::Free(tokens_);
179
- CEREAL_RAPIDJSON_DELETE(ownAllocator_);
180
- }
181
-
182
- //! Assignment operator.
183
- GenericPointer& operator=(const GenericPointer& rhs) {
184
- if (this != &rhs) {
185
- // Do not delete ownAllcator
186
- if (nameBuffer_)
187
- Allocator::Free(tokens_);
188
-
189
- tokenCount_ = rhs.tokenCount_;
190
- parseErrorOffset_ = rhs.parseErrorOffset_;
191
- parseErrorCode_ = rhs.parseErrorCode_;
192
-
193
- if (rhs.nameBuffer_)
194
- CopyFromRaw(rhs); // Normally parsed tokens.
195
- else {
196
- tokens_ = rhs.tokens_; // User supplied const tokens.
197
- nameBuffer_ = 0;
198
- }
199
- }
200
- return *this;
201
- }
202
-
203
- //! Swap the content of this pointer with an other.
204
- /*!
205
- \param other The pointer to swap with.
206
- \note Constant complexity.
207
- */
208
- GenericPointer& Swap(GenericPointer& other) CEREAL_RAPIDJSON_NOEXCEPT {
209
- internal::Swap(allocator_, other.allocator_);
210
- internal::Swap(ownAllocator_, other.ownAllocator_);
211
- internal::Swap(nameBuffer_, other.nameBuffer_);
212
- internal::Swap(tokens_, other.tokens_);
213
- internal::Swap(tokenCount_, other.tokenCount_);
214
- internal::Swap(parseErrorOffset_, other.parseErrorOffset_);
215
- internal::Swap(parseErrorCode_, other.parseErrorCode_);
216
- return *this;
217
- }
218
-
219
- //! free-standing swap function helper
220
- /*!
221
- Helper function to enable support for common swap implementation pattern based on \c std::swap:
222
- \code
223
- void swap(MyClass& a, MyClass& b) {
224
- using std::swap;
225
- swap(a.pointer, b.pointer);
226
- // ...
227
- }
228
- \endcode
229
- \see Swap()
230
- */
231
- friend inline void swap(GenericPointer& a, GenericPointer& b) CEREAL_RAPIDJSON_NOEXCEPT { a.Swap(b); }
232
-
233
- //@}
234
-
235
- //!@name Append token
236
- //@{
237
-
238
- //! Append a token and return a new Pointer
239
- /*!
240
- \param token Token to be appended.
241
- \param allocator Allocator for the newly return Pointer.
242
- \return A new Pointer with appended token.
243
- */
244
- GenericPointer Append(const Token& token, Allocator* allocator = 0) const {
245
- GenericPointer r;
246
- r.allocator_ = allocator;
247
- Ch *p = r.CopyFromRaw(*this, 1, token.length + 1);
248
- std::memcpy(p, token.name, (token.length + 1) * sizeof(Ch));
249
- r.tokens_[tokenCount_].name = p;
250
- r.tokens_[tokenCount_].length = token.length;
251
- r.tokens_[tokenCount_].index = token.index;
252
- return r;
253
- }
254
-
255
- //! Append a name token with length, and return a new Pointer
256
- /*!
257
- \param name Name to be appended.
258
- \param length Length of name.
259
- \param allocator Allocator for the newly return Pointer.
260
- \return A new Pointer with appended token.
261
- */
262
- GenericPointer Append(const Ch* name, SizeType length, Allocator* allocator = 0) const {
263
- Token token = { name, length, kPointerInvalidIndex };
264
- return Append(token, allocator);
265
- }
266
-
267
- //! Append a name token without length, and return a new Pointer
268
- /*!
269
- \param name Name (const Ch*) to be appended.
270
- \param allocator Allocator for the newly return Pointer.
271
- \return A new Pointer with appended token.
272
- */
273
- template <typename T>
274
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::NotExpr<internal::IsSame<typename internal::RemoveConst<T>::Type, Ch> >), (GenericPointer))
275
- Append(T* name, Allocator* allocator = 0) const {
276
- return Append(name, internal::StrLen(name), allocator);
277
- }
278
-
279
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
280
- //! Append a name token, and return a new Pointer
281
- /*!
282
- \param name Name to be appended.
283
- \param allocator Allocator for the newly return Pointer.
284
- \return A new Pointer with appended token.
285
- */
286
- GenericPointer Append(const std::basic_string<Ch>& name, Allocator* allocator = 0) const {
287
- return Append(name.c_str(), static_cast<SizeType>(name.size()), allocator);
288
- }
289
- #endif
290
-
291
- //! Append a index token, and return a new Pointer
292
- /*!
293
- \param index Index to be appended.
294
- \param allocator Allocator for the newly return Pointer.
295
- \return A new Pointer with appended token.
296
- */
297
- GenericPointer Append(SizeType index, Allocator* allocator = 0) const {
298
- char buffer[21];
299
- char* end = sizeof(SizeType) == 4 ? internal::u32toa(index, buffer) : internal::u64toa(index, buffer);
300
- SizeType length = static_cast<SizeType>(end - buffer);
301
- buffer[length] = '\0';
302
-
303
- if (sizeof(Ch) == 1) {
304
- Token token = { reinterpret_cast<Ch*>(buffer), length, index };
305
- return Append(token, allocator);
306
- }
307
- else {
308
- Ch name[21];
309
- for (size_t i = 0; i <= length; i++)
310
- name[i] = static_cast<Ch>(buffer[i]);
311
- Token token = { name, length, index };
312
- return Append(token, allocator);
313
- }
314
- }
315
-
316
- //! Append a token by value, and return a new Pointer
317
- /*!
318
- \param token token to be appended.
319
- \param allocator Allocator for the newly return Pointer.
320
- \return A new Pointer with appended token.
321
- */
322
- GenericPointer Append(const ValueType& token, Allocator* allocator = 0) const {
323
- if (token.IsString())
324
- return Append(token.GetString(), token.GetStringLength(), allocator);
325
- else {
326
- CEREAL_RAPIDJSON_ASSERT(token.IsUint64());
327
- CEREAL_RAPIDJSON_ASSERT(token.GetUint64() <= SizeType(~0));
328
- return Append(static_cast<SizeType>(token.GetUint64()), allocator);
329
- }
330
- }
331
-
332
- //!@name Handling Parse Error
333
- //@{
334
-
335
- //! Check whether this is a valid pointer.
336
- bool IsValid() const { return parseErrorCode_ == kPointerParseErrorNone; }
337
-
338
- //! Get the parsing error offset in code unit.
339
- size_t GetParseErrorOffset() const { return parseErrorOffset_; }
340
-
341
- //! Get the parsing error code.
342
- PointerParseErrorCode GetParseErrorCode() const { return parseErrorCode_; }
343
-
344
- //@}
345
-
346
- //! Get the allocator of this pointer.
347
- Allocator& GetAllocator() { return *allocator_; }
348
-
349
- //!@name Tokens
350
- //@{
351
-
352
- //! Get the token array (const version only).
353
- const Token* GetTokens() const { return tokens_; }
354
-
355
- //! Get the number of tokens.
356
- size_t GetTokenCount() const { return tokenCount_; }
357
-
358
- //@}
359
-
360
- //!@name Equality/inequality operators
361
- //@{
362
-
363
- //! Equality operator.
364
- /*!
365
- \note When any pointers are invalid, always returns false.
366
- */
367
- bool operator==(const GenericPointer& rhs) const {
368
- if (!IsValid() || !rhs.IsValid() || tokenCount_ != rhs.tokenCount_)
369
- return false;
370
-
371
- for (size_t i = 0; i < tokenCount_; i++) {
372
- if (tokens_[i].index != rhs.tokens_[i].index ||
373
- tokens_[i].length != rhs.tokens_[i].length ||
374
- (tokens_[i].length != 0 && std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch)* tokens_[i].length) != 0))
375
- {
376
- return false;
377
- }
378
- }
379
-
380
- return true;
381
- }
382
-
383
- //! Inequality operator.
384
- /*!
385
- \note When any pointers are invalid, always returns true.
386
- */
387
- bool operator!=(const GenericPointer& rhs) const { return !(*this == rhs); }
388
-
389
- //! Less than operator.
390
- /*!
391
- \note Invalid pointers are always greater than valid ones.
392
- */
393
- bool operator<(const GenericPointer& rhs) const {
394
- if (!IsValid())
395
- return false;
396
- if (!rhs.IsValid())
397
- return true;
398
-
399
- if (tokenCount_ != rhs.tokenCount_)
400
- return tokenCount_ < rhs.tokenCount_;
401
-
402
- for (size_t i = 0; i < tokenCount_; i++) {
403
- if (tokens_[i].index != rhs.tokens_[i].index)
404
- return tokens_[i].index < rhs.tokens_[i].index;
405
-
406
- if (tokens_[i].length != rhs.tokens_[i].length)
407
- return tokens_[i].length < rhs.tokens_[i].length;
408
-
409
- if (int cmp = std::memcmp(tokens_[i].name, rhs.tokens_[i].name, sizeof(Ch) * tokens_[i].length))
410
- return cmp < 0;
411
- }
412
-
413
- return false;
414
- }
415
-
416
- //@}
417
-
418
- //!@name Stringify
419
- //@{
420
-
421
- //! Stringify the pointer into string representation.
422
- /*!
423
- \tparam OutputStream Type of output stream.
424
- \param os The output stream.
425
- */
426
- template<typename OutputStream>
427
- bool Stringify(OutputStream& os) const {
428
- return Stringify<false, OutputStream>(os);
429
- }
430
-
431
- //! Stringify the pointer into URI fragment representation.
432
- /*!
433
- \tparam OutputStream Type of output stream.
434
- \param os The output stream.
435
- */
436
- template<typename OutputStream>
437
- bool StringifyUriFragment(OutputStream& os) const {
438
- return Stringify<true, OutputStream>(os);
439
- }
440
-
441
- //@}
442
-
443
- //!@name Create value
444
- //@{
445
-
446
- //! Create a value in a subtree.
447
- /*!
448
- If the value is not exist, it creates all parent values and a JSON Null value.
449
- So it always succeed and return the newly created or existing value.
450
-
451
- Remind that it may change types of parents according to tokens, so it
452
- potentially removes previously stored values. For example, if a document
453
- was an array, and "/foo" is used to create a value, then the document
454
- will be changed to an object, and all existing array elements are lost.
455
-
456
- \param root Root value of a DOM subtree to be resolved. It can be any value other than document root.
457
- \param allocator Allocator for creating the values if the specified value or its parents are not exist.
458
- \param alreadyExist If non-null, it stores whether the resolved value is already exist.
459
- \return The resolved newly created (a JSON Null value), or already exists value.
460
- */
461
- ValueType& Create(ValueType& root, typename ValueType::AllocatorType& allocator, bool* alreadyExist = 0) const {
462
- CEREAL_RAPIDJSON_ASSERT(IsValid());
463
- ValueType* v = &root;
464
- bool exist = true;
465
- for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
466
- if (v->IsArray() && t->name[0] == '-' && t->length == 1) {
467
- v->PushBack(ValueType().Move(), allocator);
468
- v = &((*v)[v->Size() - 1]);
469
- exist = false;
470
- }
471
- else {
472
- if (t->index == kPointerInvalidIndex) { // must be object name
473
- if (!v->IsObject())
474
- v->SetObject(); // Change to Object
475
- }
476
- else { // object name or array index
477
- if (!v->IsArray() && !v->IsObject())
478
- v->SetArray(); // Change to Array
479
- }
480
-
481
- if (v->IsArray()) {
482
- if (t->index >= v->Size()) {
483
- v->Reserve(t->index + 1, allocator);
484
- while (t->index >= v->Size())
485
- v->PushBack(ValueType().Move(), allocator);
486
- exist = false;
487
- }
488
- v = &((*v)[t->index]);
489
- }
490
- else {
491
- typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
492
- if (m == v->MemberEnd()) {
493
- v->AddMember(ValueType(t->name, t->length, allocator).Move(), ValueType().Move(), allocator);
494
- v = &(--v->MemberEnd())->value; // Assumes AddMember() appends at the end
495
- exist = false;
496
- }
497
- else
498
- v = &m->value;
499
- }
500
- }
501
- }
502
-
503
- if (alreadyExist)
504
- *alreadyExist = exist;
505
-
506
- return *v;
507
- }
508
-
509
- //! Creates a value in a document.
510
- /*!
511
- \param document A document to be resolved.
512
- \param alreadyExist If non-null, it stores whether the resolved value is already exist.
513
- \return The resolved newly created, or already exists value.
514
- */
515
- template <typename stackAllocator>
516
- ValueType& Create(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, bool* alreadyExist = 0) const {
517
- return Create(document, document.GetAllocator(), alreadyExist);
518
- }
519
-
520
- //@}
521
-
522
- //!@name Query value
523
- //@{
524
-
525
- //! Query a value in a subtree.
526
- /*!
527
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
528
- \param unresolvedTokenIndex If the pointer cannot resolve a token in the pointer, this parameter can obtain the index of unresolved token.
529
- \return Pointer to the value if it can be resolved. Otherwise null.
530
-
531
- \note
532
- There are only 3 situations when a value cannot be resolved:
533
- 1. A value in the path is not an array nor object.
534
- 2. An object value does not contain the token.
535
- 3. A token is out of range of an array value.
536
-
537
- Use unresolvedTokenIndex to retrieve the token index.
538
- */
539
- ValueType* Get(ValueType& root, size_t* unresolvedTokenIndex = 0) const {
540
- CEREAL_RAPIDJSON_ASSERT(IsValid());
541
- ValueType* v = &root;
542
- for (const Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
543
- switch (v->GetType()) {
544
- case kObjectType:
545
- {
546
- typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
547
- if (m == v->MemberEnd())
548
- break;
549
- v = &m->value;
550
- }
551
- continue;
552
- case kArrayType:
553
- if (t->index == kPointerInvalidIndex || t->index >= v->Size())
554
- break;
555
- v = &((*v)[t->index]);
556
- continue;
557
- default:
558
- break;
559
- }
560
-
561
- // Error: unresolved token
562
- if (unresolvedTokenIndex)
563
- *unresolvedTokenIndex = static_cast<size_t>(t - tokens_);
564
- return 0;
565
- }
566
- return v;
567
- }
568
-
569
- //! Query a const value in a const subtree.
570
- /*!
571
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
572
- \return Pointer to the value if it can be resolved. Otherwise null.
573
- */
574
- const ValueType* Get(const ValueType& root, size_t* unresolvedTokenIndex = 0) const {
575
- return Get(const_cast<ValueType&>(root), unresolvedTokenIndex);
576
- }
577
-
578
- //@}
579
-
580
- //!@name Query a value with default
581
- //@{
582
-
583
- //! Query a value in a subtree with default value.
584
- /*!
585
- Similar to Get(), but if the specified value do not exists, it creates all parents and clone the default value.
586
- So that this function always succeed.
587
-
588
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
589
- \param defaultValue Default value to be cloned if the value was not exists.
590
- \param allocator Allocator for creating the values if the specified value or its parents are not exist.
591
- \see Create()
592
- */
593
- ValueType& GetWithDefault(ValueType& root, const ValueType& defaultValue, typename ValueType::AllocatorType& allocator) const {
594
- bool alreadyExist;
595
- ValueType& v = Create(root, allocator, &alreadyExist);
596
- return alreadyExist ? v : v.CopyFrom(defaultValue, allocator);
597
- }
598
-
599
- //! Query a value in a subtree with default null-terminated string.
600
- ValueType& GetWithDefault(ValueType& root, const Ch* defaultValue, typename ValueType::AllocatorType& allocator) const {
601
- bool alreadyExist;
602
- ValueType& v = Create(root, allocator, &alreadyExist);
603
- return alreadyExist ? v : v.SetString(defaultValue, allocator);
604
- }
605
-
606
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
607
- //! Query a value in a subtree with default std::basic_string.
608
- ValueType& GetWithDefault(ValueType& root, const std::basic_string<Ch>& defaultValue, typename ValueType::AllocatorType& allocator) const {
609
- bool alreadyExist;
610
- ValueType& v = Create(root, allocator, &alreadyExist);
611
- return alreadyExist ? v : v.SetString(defaultValue, allocator);
612
- }
613
- #endif
614
-
615
- //! Query a value in a subtree with default primitive value.
616
- /*!
617
- \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
618
- */
619
- template <typename T>
620
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
621
- GetWithDefault(ValueType& root, T defaultValue, typename ValueType::AllocatorType& allocator) const {
622
- return GetWithDefault(root, ValueType(defaultValue).Move(), allocator);
623
- }
624
-
625
- //! Query a value in a document with default value.
626
- template <typename stackAllocator>
627
- ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& defaultValue) const {
628
- return GetWithDefault(document, defaultValue, document.GetAllocator());
629
- }
630
-
631
- //! Query a value in a document with default null-terminated string.
632
- template <typename stackAllocator>
633
- ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* defaultValue) const {
634
- return GetWithDefault(document, defaultValue, document.GetAllocator());
635
- }
636
-
637
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
638
- //! Query a value in a document with default std::basic_string.
639
- template <typename stackAllocator>
640
- ValueType& GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& defaultValue) const {
641
- return GetWithDefault(document, defaultValue, document.GetAllocator());
642
- }
643
- #endif
644
-
645
- //! Query a value in a document with default primitive value.
646
- /*!
647
- \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
648
- */
649
- template <typename T, typename stackAllocator>
650
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
651
- GetWithDefault(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T defaultValue) const {
652
- return GetWithDefault(document, defaultValue, document.GetAllocator());
653
- }
654
-
655
- //@}
656
-
657
- //!@name Set a value
658
- //@{
659
-
660
- //! Set a value in a subtree, with move semantics.
661
- /*!
662
- It creates all parents if they are not exist or types are different to the tokens.
663
- So this function always succeeds but potentially remove existing values.
664
-
665
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
666
- \param value Value to be set.
667
- \param allocator Allocator for creating the values if the specified value or its parents are not exist.
668
- \see Create()
669
- */
670
- ValueType& Set(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
671
- return Create(root, allocator) = value;
672
- }
673
-
674
- //! Set a value in a subtree, with copy semantics.
675
- ValueType& Set(ValueType& root, const ValueType& value, typename ValueType::AllocatorType& allocator) const {
676
- return Create(root, allocator).CopyFrom(value, allocator);
677
- }
678
-
679
- //! Set a null-terminated string in a subtree.
680
- ValueType& Set(ValueType& root, const Ch* value, typename ValueType::AllocatorType& allocator) const {
681
- return Create(root, allocator) = ValueType(value, allocator).Move();
682
- }
683
-
684
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
685
- //! Set a std::basic_string in a subtree.
686
- ValueType& Set(ValueType& root, const std::basic_string<Ch>& value, typename ValueType::AllocatorType& allocator) const {
687
- return Create(root, allocator) = ValueType(value, allocator).Move();
688
- }
689
- #endif
690
-
691
- //! Set a primitive value in a subtree.
692
- /*!
693
- \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
694
- */
695
- template <typename T>
696
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
697
- Set(ValueType& root, T value, typename ValueType::AllocatorType& allocator) const {
698
- return Create(root, allocator) = ValueType(value).Move();
699
- }
700
-
701
- //! Set a value in a document, with move semantics.
702
- template <typename stackAllocator>
703
- ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
704
- return Create(document) = value;
705
- }
706
-
707
- //! Set a value in a document, with copy semantics.
708
- template <typename stackAllocator>
709
- ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const ValueType& value) const {
710
- return Create(document).CopyFrom(value, document.GetAllocator());
711
- }
712
-
713
- //! Set a null-terminated string in a document.
714
- template <typename stackAllocator>
715
- ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const Ch* value) const {
716
- return Create(document) = ValueType(value, document.GetAllocator()).Move();
717
- }
718
-
719
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
720
- //! Sets a std::basic_string in a document.
721
- template <typename stackAllocator>
722
- ValueType& Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, const std::basic_string<Ch>& value) const {
723
- return Create(document) = ValueType(value, document.GetAllocator()).Move();
724
- }
725
- #endif
726
-
727
- //! Set a primitive value in a document.
728
- /*!
729
- \tparam T Either \ref Type, \c int, \c unsigned, \c int64_t, \c uint64_t, \c bool
730
- */
731
- template <typename T, typename stackAllocator>
732
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T>, internal::IsGenericValue<T> >), (ValueType&))
733
- Set(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, T value) const {
734
- return Create(document) = value;
735
- }
736
-
737
- //@}
738
-
739
- //!@name Swap a value
740
- //@{
741
-
742
- //! Swap a value with a value in a subtree.
743
- /*!
744
- It creates all parents if they are not exist or types are different to the tokens.
745
- So this function always succeeds but potentially remove existing values.
746
-
747
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
748
- \param value Value to be swapped.
749
- \param allocator Allocator for creating the values if the specified value or its parents are not exist.
750
- \see Create()
751
- */
752
- ValueType& Swap(ValueType& root, ValueType& value, typename ValueType::AllocatorType& allocator) const {
753
- return Create(root, allocator).Swap(value);
754
- }
755
-
756
- //! Swap a value with a value in a document.
757
- template <typename stackAllocator>
758
- ValueType& Swap(GenericDocument<EncodingType, typename ValueType::AllocatorType, stackAllocator>& document, ValueType& value) const {
759
- return Create(document).Swap(value);
760
- }
761
-
762
- //@}
763
-
764
- //! Erase a value in a subtree.
765
- /*!
766
- \param root Root value of a DOM sub-tree to be resolved. It can be any value other than document root.
767
- \return Whether the resolved value is found and erased.
768
-
769
- \note Erasing with an empty pointer \c Pointer(""), i.e. the root, always fail and return false.
770
- */
771
- bool Erase(ValueType& root) const {
772
- CEREAL_RAPIDJSON_ASSERT(IsValid());
773
- if (tokenCount_ == 0) // Cannot erase the root
774
- return false;
775
-
776
- ValueType* v = &root;
777
- const Token* last = tokens_ + (tokenCount_ - 1);
778
- for (const Token *t = tokens_; t != last; ++t) {
779
- switch (v->GetType()) {
780
- case kObjectType:
781
- {
782
- typename ValueType::MemberIterator m = v->FindMember(GenericStringRef<Ch>(t->name, t->length));
783
- if (m == v->MemberEnd())
784
- return false;
785
- v = &m->value;
786
- }
787
- break;
788
- case kArrayType:
789
- if (t->index == kPointerInvalidIndex || t->index >= v->Size())
790
- return false;
791
- v = &((*v)[t->index]);
792
- break;
793
- default:
794
- return false;
795
- }
796
- }
797
-
798
- switch (v->GetType()) {
799
- case kObjectType:
800
- return v->EraseMember(GenericStringRef<Ch>(last->name, last->length));
801
- case kArrayType:
802
- if (last->index == kPointerInvalidIndex || last->index >= v->Size())
803
- return false;
804
- v->Erase(v->Begin() + last->index);
805
- return true;
806
- default:
807
- return false;
808
- }
809
- }
810
-
811
- private:
812
- //! Clone the content from rhs to this.
813
- /*!
814
- \param rhs Source pointer.
815
- \param extraToken Extra tokens to be allocated.
816
- \param extraNameBufferSize Extra name buffer size (in number of Ch) to be allocated.
817
- \return Start of non-occupied name buffer, for storing extra names.
818
- */
819
- Ch* CopyFromRaw(const GenericPointer& rhs, size_t extraToken = 0, size_t extraNameBufferSize = 0) {
820
- if (!allocator_) // allocator is independently owned.
821
- ownAllocator_ = allocator_ = CEREAL_RAPIDJSON_NEW(Allocator)();
822
-
823
- size_t nameBufferSize = rhs.tokenCount_; // null terminators for tokens
824
- for (Token *t = rhs.tokens_; t != rhs.tokens_ + rhs.tokenCount_; ++t)
825
- nameBufferSize += t->length;
826
-
827
- tokenCount_ = rhs.tokenCount_ + extraToken;
828
- tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + (nameBufferSize + extraNameBufferSize) * sizeof(Ch)));
829
- nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
830
- if (rhs.tokenCount_ > 0) {
831
- std::memcpy(tokens_, rhs.tokens_, rhs.tokenCount_ * sizeof(Token));
832
- }
833
- if (nameBufferSize > 0) {
834
- std::memcpy(nameBuffer_, rhs.nameBuffer_, nameBufferSize * sizeof(Ch));
835
- }
836
-
837
- // Adjust pointers to name buffer
838
- std::ptrdiff_t diff = nameBuffer_ - rhs.nameBuffer_;
839
- for (Token *t = tokens_; t != tokens_ + rhs.tokenCount_; ++t)
840
- t->name += diff;
841
-
842
- return nameBuffer_ + nameBufferSize;
843
- }
844
-
845
- //! Check whether a character should be percent-encoded.
846
- /*!
847
- According to RFC 3986 2.3 Unreserved Characters.
848
- \param c The character (code unit) to be tested.
849
- */
850
- bool NeedPercentEncode(Ch c) const {
851
- return !((c >= '0' && c <= '9') || (c >= 'A' && c <='Z') || (c >= 'a' && c <= 'z') || c == '-' || c == '.' || c == '_' || c =='~');
852
- }
853
-
854
- //! Parse a JSON String or its URI fragment representation into tokens.
855
- #ifndef __clang__ // -Wdocumentation
856
- /*!
857
- \param source Either a JSON Pointer string, or its URI fragment representation. Not need to be null terminated.
858
- \param length Length of the source string.
859
- \note Source cannot be JSON String Representation of JSON Pointer, e.g. In "/\u0000", \u0000 will not be unescaped.
860
- */
861
- #endif
862
- void Parse(const Ch* source, size_t length) {
863
- CEREAL_RAPIDJSON_ASSERT(source != NULL);
864
- CEREAL_RAPIDJSON_ASSERT(nameBuffer_ == 0);
865
- CEREAL_RAPIDJSON_ASSERT(tokens_ == 0);
866
-
867
- // Create own allocator if user did not supply.
868
- if (!allocator_)
869
- ownAllocator_ = allocator_ = CEREAL_RAPIDJSON_NEW(Allocator)();
870
-
871
- // Count number of '/' as tokenCount
872
- tokenCount_ = 0;
873
- for (const Ch* s = source; s != source + length; s++)
874
- if (*s == '/')
875
- tokenCount_++;
876
-
877
- Token* token = tokens_ = static_cast<Token *>(allocator_->Malloc(tokenCount_ * sizeof(Token) + length * sizeof(Ch)));
878
- Ch* name = nameBuffer_ = reinterpret_cast<Ch *>(tokens_ + tokenCount_);
879
- size_t i = 0;
880
-
881
- // Detect if it is a URI fragment
882
- bool uriFragment = false;
883
- if (source[i] == '#') {
884
- uriFragment = true;
885
- i++;
886
- }
887
-
888
- if (i != length && source[i] != '/') {
889
- parseErrorCode_ = kPointerParseErrorTokenMustBeginWithSolidus;
890
- goto error;
891
- }
892
-
893
- while (i < length) {
894
- CEREAL_RAPIDJSON_ASSERT(source[i] == '/');
895
- i++; // consumes '/'
896
-
897
- token->name = name;
898
- bool isNumber = true;
899
-
900
- while (i < length && source[i] != '/') {
901
- Ch c = source[i];
902
- if (uriFragment) {
903
- // Decoding percent-encoding for URI fragment
904
- if (c == '%') {
905
- PercentDecodeStream is(&source[i], source + length);
906
- GenericInsituStringStream<EncodingType> os(name);
907
- Ch* begin = os.PutBegin();
908
- if (!Transcoder<UTF8<>, EncodingType>().Validate(is, os) || !is.IsValid()) {
909
- parseErrorCode_ = kPointerParseErrorInvalidPercentEncoding;
910
- goto error;
911
- }
912
- size_t len = os.PutEnd(begin);
913
- i += is.Tell() - 1;
914
- if (len == 1)
915
- c = *name;
916
- else {
917
- name += len;
918
- isNumber = false;
919
- i++;
920
- continue;
921
- }
922
- }
923
- else if (NeedPercentEncode(c)) {
924
- parseErrorCode_ = kPointerParseErrorCharacterMustPercentEncode;
925
- goto error;
926
- }
927
- }
928
-
929
- i++;
930
-
931
- // Escaping "~0" -> '~', "~1" -> '/'
932
- if (c == '~') {
933
- if (i < length) {
934
- c = source[i];
935
- if (c == '0') c = '~';
936
- else if (c == '1') c = '/';
937
- else {
938
- parseErrorCode_ = kPointerParseErrorInvalidEscape;
939
- goto error;
940
- }
941
- i++;
942
- }
943
- else {
944
- parseErrorCode_ = kPointerParseErrorInvalidEscape;
945
- goto error;
946
- }
947
- }
948
-
949
- // First check for index: all of characters are digit
950
- if (c < '0' || c > '9')
951
- isNumber = false;
952
-
953
- *name++ = c;
954
- }
955
- token->length = static_cast<SizeType>(name - token->name);
956
- if (token->length == 0)
957
- isNumber = false;
958
- *name++ = '\0'; // Null terminator
959
-
960
- // Second check for index: more than one digit cannot have leading zero
961
- if (isNumber && token->length > 1 && token->name[0] == '0')
962
- isNumber = false;
963
-
964
- // String to SizeType conversion
965
- SizeType n = 0;
966
- if (isNumber) {
967
- for (size_t j = 0; j < token->length; j++) {
968
- SizeType m = n * 10 + static_cast<SizeType>(token->name[j] - '0');
969
- if (m < n) { // overflow detection
970
- isNumber = false;
971
- break;
972
- }
973
- n = m;
974
- }
975
- }
976
-
977
- token->index = isNumber ? n : kPointerInvalidIndex;
978
- token++;
979
- }
980
-
981
- CEREAL_RAPIDJSON_ASSERT(name <= nameBuffer_ + length); // Should not overflow buffer
982
- parseErrorCode_ = kPointerParseErrorNone;
983
- return;
984
-
985
- error:
986
- Allocator::Free(tokens_);
987
- nameBuffer_ = 0;
988
- tokens_ = 0;
989
- tokenCount_ = 0;
990
- parseErrorOffset_ = i;
991
- return;
992
- }
993
-
994
- //! Stringify to string or URI fragment representation.
995
- /*!
996
- \tparam uriFragment True for stringifying to URI fragment representation. False for string representation.
997
- \tparam OutputStream type of output stream.
998
- \param os The output stream.
999
- */
1000
- template<bool uriFragment, typename OutputStream>
1001
- bool Stringify(OutputStream& os) const {
1002
- CEREAL_RAPIDJSON_ASSERT(IsValid());
1003
-
1004
- if (uriFragment)
1005
- os.Put('#');
1006
-
1007
- for (Token *t = tokens_; t != tokens_ + tokenCount_; ++t) {
1008
- os.Put('/');
1009
- for (size_t j = 0; j < t->length; j++) {
1010
- Ch c = t->name[j];
1011
- if (c == '~') {
1012
- os.Put('~');
1013
- os.Put('0');
1014
- }
1015
- else if (c == '/') {
1016
- os.Put('~');
1017
- os.Put('1');
1018
- }
1019
- else if (uriFragment && NeedPercentEncode(c)) {
1020
- // Transcode to UTF8 sequence
1021
- GenericStringStream<typename ValueType::EncodingType> source(&t->name[j]);
1022
- PercentEncodeStream<OutputStream> target(os);
1023
- if (!Transcoder<EncodingType, UTF8<> >().Validate(source, target))
1024
- return false;
1025
- j += source.Tell() - 1;
1026
- }
1027
- else
1028
- os.Put(c);
1029
- }
1030
- }
1031
- return true;
1032
- }
1033
-
1034
- //! A helper stream for decoding a percent-encoded sequence into code unit.
1035
- /*!
1036
- This stream decodes %XY triplet into code unit (0-255).
1037
- If it encounters invalid characters, it sets output code unit as 0 and
1038
- mark invalid, and to be checked by IsValid().
1039
- */
1040
- class PercentDecodeStream {
1041
- public:
1042
- typedef typename ValueType::Ch Ch;
1043
-
1044
- //! Constructor
1045
- /*!
1046
- \param source Start of the stream
1047
- \param end Past-the-end of the stream.
1048
- */
1049
- PercentDecodeStream(const Ch* source, const Ch* end) : src_(source), head_(source), end_(end), valid_(true) {}
1050
-
1051
- Ch Take() {
1052
- if (*src_ != '%' || src_ + 3 > end_) { // %XY triplet
1053
- valid_ = false;
1054
- return 0;
1055
- }
1056
- src_++;
1057
- Ch c = 0;
1058
- for (int j = 0; j < 2; j++) {
1059
- c = static_cast<Ch>(c << 4);
1060
- Ch h = *src_;
1061
- if (h >= '0' && h <= '9') c = static_cast<Ch>(c + h - '0');
1062
- else if (h >= 'A' && h <= 'F') c = static_cast<Ch>(c + h - 'A' + 10);
1063
- else if (h >= 'a' && h <= 'f') c = static_cast<Ch>(c + h - 'a' + 10);
1064
- else {
1065
- valid_ = false;
1066
- return 0;
1067
- }
1068
- src_++;
1069
- }
1070
- return c;
1071
- }
1072
-
1073
- size_t Tell() const { return static_cast<size_t>(src_ - head_); }
1074
- bool IsValid() const { return valid_; }
1075
-
1076
- private:
1077
- const Ch* src_; //!< Current read position.
1078
- const Ch* head_; //!< Original head of the string.
1079
- const Ch* end_; //!< Past-the-end position.
1080
- bool valid_; //!< Whether the parsing is valid.
1081
- };
1082
-
1083
- //! A helper stream to encode character (UTF-8 code unit) into percent-encoded sequence.
1084
- template <typename OutputStream>
1085
- class PercentEncodeStream {
1086
- public:
1087
- PercentEncodeStream(OutputStream& os) : os_(os) {}
1088
- void Put(char c) { // UTF-8 must be byte
1089
- unsigned char u = static_cast<unsigned char>(c);
1090
- static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
1091
- os_.Put('%');
1092
- os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u >> 4]));
1093
- os_.Put(static_cast<typename OutputStream::Ch>(hexDigits[u & 15]));
1094
- }
1095
- private:
1096
- OutputStream& os_;
1097
- };
1098
-
1099
- Allocator* allocator_; //!< The current allocator. It is either user-supplied or equal to ownAllocator_.
1100
- Allocator* ownAllocator_; //!< Allocator owned by this Pointer.
1101
- Ch* nameBuffer_; //!< A buffer containing all names in tokens.
1102
- Token* tokens_; //!< A list of tokens.
1103
- size_t tokenCount_; //!< Number of tokens in tokens_.
1104
- size_t parseErrorOffset_; //!< Offset in code unit when parsing fail.
1105
- PointerParseErrorCode parseErrorCode_; //!< Parsing error code.
1106
- };
1107
-
1108
- //! GenericPointer for Value (UTF-8, default allocator).
1109
- typedef GenericPointer<Value> Pointer;
1110
-
1111
- //!@name Helper functions for GenericPointer
1112
- //@{
1113
-
1114
- //////////////////////////////////////////////////////////////////////////////
1115
-
1116
- template <typename T>
1117
- typename T::ValueType& CreateValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::AllocatorType& a) {
1118
- return pointer.Create(root, a);
1119
- }
1120
-
1121
- template <typename T, typename CharType, size_t N>
1122
- typename T::ValueType& CreateValueByPointer(T& root, const CharType(&source)[N], typename T::AllocatorType& a) {
1123
- return GenericPointer<typename T::ValueType>(source, N - 1).Create(root, a);
1124
- }
1125
-
1126
- // No allocator parameter
1127
-
1128
- template <typename DocumentType>
1129
- typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer) {
1130
- return pointer.Create(document);
1131
- }
1132
-
1133
- template <typename DocumentType, typename CharType, size_t N>
1134
- typename DocumentType::ValueType& CreateValueByPointer(DocumentType& document, const CharType(&source)[N]) {
1135
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Create(document);
1136
- }
1137
-
1138
- //////////////////////////////////////////////////////////////////////////////
1139
-
1140
- template <typename T>
1141
- typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1142
- return pointer.Get(root, unresolvedTokenIndex);
1143
- }
1144
-
1145
- template <typename T>
1146
- const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
1147
- return pointer.Get(root, unresolvedTokenIndex);
1148
- }
1149
-
1150
- template <typename T, typename CharType, size_t N>
1151
- typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
1152
- return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1153
- }
1154
-
1155
- template <typename T, typename CharType, size_t N>
1156
- const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
1157
- return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
1158
- }
1159
-
1160
- //////////////////////////////////////////////////////////////////////////////
1161
-
1162
- template <typename T>
1163
- typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1164
- return pointer.GetWithDefault(root, defaultValue, a);
1165
- }
1166
-
1167
- template <typename T>
1168
- typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1169
- return pointer.GetWithDefault(root, defaultValue, a);
1170
- }
1171
-
1172
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
1173
- template <typename T>
1174
- typename T::ValueType& GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1175
- return pointer.GetWithDefault(root, defaultValue, a);
1176
- }
1177
- #endif
1178
-
1179
- template <typename T, typename T2>
1180
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1181
- GetValueByPointerWithDefault(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 defaultValue, typename T::AllocatorType& a) {
1182
- return pointer.GetWithDefault(root, defaultValue, a);
1183
- }
1184
-
1185
- template <typename T, typename CharType, size_t N>
1186
- typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::ValueType& defaultValue, typename T::AllocatorType& a) {
1187
- return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1188
- }
1189
-
1190
- template <typename T, typename CharType, size_t N>
1191
- typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const typename T::Ch* defaultValue, typename T::AllocatorType& a) {
1192
- return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1193
- }
1194
-
1195
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
1196
- template <typename T, typename CharType, size_t N>
1197
- typename T::ValueType& GetValueByPointerWithDefault(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& defaultValue, typename T::AllocatorType& a) {
1198
- return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1199
- }
1200
- #endif
1201
-
1202
- template <typename T, typename CharType, size_t N, typename T2>
1203
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1204
- GetValueByPointerWithDefault(T& root, const CharType(&source)[N], T2 defaultValue, typename T::AllocatorType& a) {
1205
- return GenericPointer<typename T::ValueType>(source, N - 1).GetWithDefault(root, defaultValue, a);
1206
- }
1207
-
1208
- // No allocator parameter
1209
-
1210
- template <typename DocumentType>
1211
- typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& defaultValue) {
1212
- return pointer.GetWithDefault(document, defaultValue);
1213
- }
1214
-
1215
- template <typename DocumentType>
1216
- typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* defaultValue) {
1217
- return pointer.GetWithDefault(document, defaultValue);
1218
- }
1219
-
1220
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
1221
- template <typename DocumentType>
1222
- typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1223
- return pointer.GetWithDefault(document, defaultValue);
1224
- }
1225
- #endif
1226
-
1227
- template <typename DocumentType, typename T2>
1228
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1229
- GetValueByPointerWithDefault(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 defaultValue) {
1230
- return pointer.GetWithDefault(document, defaultValue);
1231
- }
1232
-
1233
- template <typename DocumentType, typename CharType, size_t N>
1234
- typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& defaultValue) {
1235
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1236
- }
1237
-
1238
- template <typename DocumentType, typename CharType, size_t N>
1239
- typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* defaultValue) {
1240
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1241
- }
1242
-
1243
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
1244
- template <typename DocumentType, typename CharType, size_t N>
1245
- typename DocumentType::ValueType& GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& defaultValue) {
1246
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1247
- }
1248
- #endif
1249
-
1250
- template <typename DocumentType, typename CharType, size_t N, typename T2>
1251
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1252
- GetValueByPointerWithDefault(DocumentType& document, const CharType(&source)[N], T2 defaultValue) {
1253
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).GetWithDefault(document, defaultValue);
1254
- }
1255
-
1256
- //////////////////////////////////////////////////////////////////////////////
1257
-
1258
- template <typename T>
1259
- typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1260
- return pointer.Set(root, value, a);
1261
- }
1262
-
1263
- template <typename T>
1264
- typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::ValueType& value, typename T::AllocatorType& a) {
1265
- return pointer.Set(root, value, a);
1266
- }
1267
-
1268
- template <typename T>
1269
- typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const typename T::Ch* value, typename T::AllocatorType& a) {
1270
- return pointer.Set(root, value, a);
1271
- }
1272
-
1273
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
1274
- template <typename T>
1275
- typename T::ValueType& SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1276
- return pointer.Set(root, value, a);
1277
- }
1278
- #endif
1279
-
1280
- template <typename T, typename T2>
1281
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1282
- SetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, T2 value, typename T::AllocatorType& a) {
1283
- return pointer.Set(root, value, a);
1284
- }
1285
-
1286
- template <typename T, typename CharType, size_t N>
1287
- typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1288
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1289
- }
1290
-
1291
- template <typename T, typename CharType, size_t N>
1292
- typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::ValueType& value, typename T::AllocatorType& a) {
1293
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1294
- }
1295
-
1296
- template <typename T, typename CharType, size_t N>
1297
- typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const typename T::Ch* value, typename T::AllocatorType& a) {
1298
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1299
- }
1300
-
1301
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
1302
- template <typename T, typename CharType, size_t N>
1303
- typename T::ValueType& SetValueByPointer(T& root, const CharType(&source)[N], const std::basic_string<typename T::Ch>& value, typename T::AllocatorType& a) {
1304
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1305
- }
1306
- #endif
1307
-
1308
- template <typename T, typename CharType, size_t N, typename T2>
1309
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename T::ValueType&))
1310
- SetValueByPointer(T& root, const CharType(&source)[N], T2 value, typename T::AllocatorType& a) {
1311
- return GenericPointer<typename T::ValueType>(source, N - 1).Set(root, value, a);
1312
- }
1313
-
1314
- // No allocator parameter
1315
-
1316
- template <typename DocumentType>
1317
- typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1318
- return pointer.Set(document, value);
1319
- }
1320
-
1321
- template <typename DocumentType>
1322
- typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::ValueType& value) {
1323
- return pointer.Set(document, value);
1324
- }
1325
-
1326
- template <typename DocumentType>
1327
- typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const typename DocumentType::Ch* value) {
1328
- return pointer.Set(document, value);
1329
- }
1330
-
1331
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
1332
- template <typename DocumentType>
1333
- typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, const std::basic_string<typename DocumentType::Ch>& value) {
1334
- return pointer.Set(document, value);
1335
- }
1336
- #endif
1337
-
1338
- template <typename DocumentType, typename T2>
1339
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1340
- SetValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, T2 value) {
1341
- return pointer.Set(document, value);
1342
- }
1343
-
1344
- template <typename DocumentType, typename CharType, size_t N>
1345
- typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1346
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1347
- }
1348
-
1349
- template <typename DocumentType, typename CharType, size_t N>
1350
- typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::ValueType& value) {
1351
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1352
- }
1353
-
1354
- template <typename DocumentType, typename CharType, size_t N>
1355
- typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const typename DocumentType::Ch* value) {
1356
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1357
- }
1358
-
1359
- #if CEREAL_RAPIDJSON_HAS_STDSTRING
1360
- template <typename DocumentType, typename CharType, size_t N>
1361
- typename DocumentType::ValueType& SetValueByPointer(DocumentType& document, const CharType(&source)[N], const std::basic_string<typename DocumentType::Ch>& value) {
1362
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1363
- }
1364
- #endif
1365
-
1366
- template <typename DocumentType, typename CharType, size_t N, typename T2>
1367
- CEREAL_RAPIDJSON_DISABLEIF_RETURN((internal::OrExpr<internal::IsPointer<T2>, internal::IsGenericValue<T2> >), (typename DocumentType::ValueType&))
1368
- SetValueByPointer(DocumentType& document, const CharType(&source)[N], T2 value) {
1369
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Set(document, value);
1370
- }
1371
-
1372
- //////////////////////////////////////////////////////////////////////////////
1373
-
1374
- template <typename T>
1375
- typename T::ValueType& SwapValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, typename T::ValueType& value, typename T::AllocatorType& a) {
1376
- return pointer.Swap(root, value, a);
1377
- }
1378
-
1379
- template <typename T, typename CharType, size_t N>
1380
- typename T::ValueType& SwapValueByPointer(T& root, const CharType(&source)[N], typename T::ValueType& value, typename T::AllocatorType& a) {
1381
- return GenericPointer<typename T::ValueType>(source, N - 1).Swap(root, value, a);
1382
- }
1383
-
1384
- template <typename DocumentType>
1385
- typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const GenericPointer<typename DocumentType::ValueType>& pointer, typename DocumentType::ValueType& value) {
1386
- return pointer.Swap(document, value);
1387
- }
1388
-
1389
- template <typename DocumentType, typename CharType, size_t N>
1390
- typename DocumentType::ValueType& SwapValueByPointer(DocumentType& document, const CharType(&source)[N], typename DocumentType::ValueType& value) {
1391
- return GenericPointer<typename DocumentType::ValueType>(source, N - 1).Swap(document, value);
1392
- }
1393
-
1394
- //////////////////////////////////////////////////////////////////////////////
1395
-
1396
- template <typename T>
1397
- bool EraseValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer) {
1398
- return pointer.Erase(root);
1399
- }
1400
-
1401
- template <typename T, typename CharType, size_t N>
1402
- bool EraseValueByPointer(T& root, const CharType(&source)[N]) {
1403
- return GenericPointer<typename T::ValueType>(source, N - 1).Erase(root);
1404
- }
1405
-
1406
- //@}
1407
-
1408
- CEREAL_RAPIDJSON_NAMESPACE_END
1409
-
1410
- #if defined(__clang__) || defined(_MSC_VER)
1411
- CEREAL_RAPIDJSON_DIAG_POP
1412
- #endif
1413
-
1414
- #endif // CEREAL_RAPIDJSON_POINTER_H_