Line data Source code
1 : /**
2 : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #ifndef STAPPLER_DATA_SPDATAVALUE_H_
25 : #define STAPPLER_DATA_SPDATAVALUE_H_
26 :
27 : #include "SPString.h"
28 : #include "SPLog.h"
29 : #include "SPTime.h"
30 : #include "SPDataTraits.h"
31 :
32 : namespace STAPPLER_VERSIONIZED stappler::data {
33 :
34 : template <typename Interface> class JsonBuffer;
35 : template <typename Interface> class CborBuffer;
36 :
37 : namespace json {
38 :
39 : template <typename Interface>
40 : struct Decoder;
41 :
42 : }
43 :
44 : namespace cbor {
45 :
46 : template <typename Interface>
47 : struct Decoder;
48 :
49 : }
50 :
51 : namespace serenity {
52 :
53 : template <typename Interface>
54 : struct Decoder;
55 :
56 : }
57 :
58 : template <typename Interface>
59 : class ValueTemplate;
60 :
61 : }
62 :
63 :
64 : namespace STAPPLER_VERSIONIZED stappler::memory {
65 :
66 : template <typename Interface>
67 : struct mem_sso_test<data::ValueTemplate<Interface>> {
68 : static constexpr bool value = true;
69 : };
70 :
71 : }
72 :
73 :
74 : namespace STAPPLER_VERSIONIZED stappler::data {
75 :
76 : template <typename Interface>
77 : class ValueTemplate : public Interface::AllocBaseType {
78 : public:
79 : using Self = ValueTemplate<Interface>;
80 : using InterfaceType = Interface;
81 :
82 : using StringType = typename Interface::StringType;
83 : using BytesType = typename Interface::BytesType;
84 : using ArrayType = typename Interface::template ArrayType<Self>;
85 : using DictionaryType = typename Interface::template DictionaryType<Self>;
86 :
87 : static const Self Null;
88 : static const StringType StringNull;
89 : static const BytesType BytesNull;
90 : static const ArrayType ArrayNull;
91 : static const DictionaryType DictionaryNull;
92 :
93 : enum class Type : uint8_t {
94 : EMPTY = 0,
95 : INTEGER,
96 : DOUBLE,
97 : BOOLEAN,
98 : CHARSTRING,
99 : BYTESTRING,
100 : ARRAY,
101 : DICTIONARY,
102 : NONE = 0xFF,
103 : };
104 :
105 : public:
106 : ValueTemplate() noexcept;
107 : ValueTemplate(Type type) noexcept;
108 : ~ValueTemplate() noexcept;
109 :
110 : ValueTemplate(const Self &other) noexcept;
111 : ValueTemplate(Self &&other) noexcept;
112 :
113 : template <typename OtherInterface>
114 : ValueTemplate(const ValueTemplate<OtherInterface> &);
115 :
116 : ValueTemplate(InitializerList<Self> il);
117 : ValueTemplate(InitializerList<Pair<StringType, Self>> il);
118 :
119 : explicit ValueTemplate(nullptr_t) : _type(Type::EMPTY) { }
120 19150 : explicit ValueTemplate(bool v) : _type(Type::BOOLEAN) { boolVal = v; }
121 1375 : explicit ValueTemplate(int32_t v) : _type(Type::INTEGER) { intVal = int64_t(v); }
122 67375 : explicit ValueTemplate(int64_t v) : _type(Type::INTEGER) { intVal = v; }
123 2250 : explicit ValueTemplate(uint32_t v) : _type(Type::INTEGER) { intVal = int64_t(v); }
124 17921 : explicit ValueTemplate(uint64_t v) : _type(Type::INTEGER) { intVal = int64_t(v); }
125 21 : explicit ValueTemplate(Time v) : _type(Type::INTEGER) { intVal = int64_t(v.toMicros()); }
126 21 : explicit ValueTemplate(TimeInterval v) : _type(Type::INTEGER) { intVal = int64_t(v.toMicros()); }
127 75 : explicit ValueTemplate(float v) : _type(Type::DOUBLE) { doubleVal = v; }
128 50139 : explicit ValueTemplate(double v) : _type(Type::DOUBLE) { doubleVal = v; }
129 9961 : explicit ValueTemplate(const char *v) : _type(Type::CHARSTRING) { strVal = (v ? new StringType(v) : new StringType()); }
130 54750 : explicit ValueTemplate(const StringView &v) : _type(Type::CHARSTRING) { strVal = new StringType(v.data(), v.size()); }
131 27908 : explicit ValueTemplate(const StringType &v): _type(Type::CHARSTRING) { strVal = new StringType(v); }
132 23485 : explicit ValueTemplate(StringType &&v) : _type(Type::CHARSTRING) { strVal = new StringType(std::move(v)); }
133 225 : explicit ValueTemplate(const BytesType &v) : _type(Type::BYTESTRING) { bytesVal = new BytesType(v); }
134 2900 : explicit ValueTemplate(BytesType &&v) : _type(Type::BYTESTRING) { bytesVal = new BytesType(std::move(v)); }
135 : explicit ValueTemplate(const BytesViewTemplate<Endian::Big> &v) : _type(Type::BYTESTRING) { bytesVal = new BytesType(v.data(), v.data() + v.size()); }
136 433243 : explicit ValueTemplate(const BytesViewTemplate<Endian::Little> &v) : _type(Type::BYTESTRING) { bytesVal = new BytesType(v.data(), v.data() + v.size()); }
137 25 : explicit ValueTemplate(const ArrayType &v) : _type(Type::ARRAY) { arrayVal = new ArrayType(v); }
138 300 : explicit ValueTemplate(ArrayType &&v) : _type(Type::ARRAY) { arrayVal = new ArrayType(std::move(v)); }
139 : explicit ValueTemplate(const DictionaryType &v) : _type(Type::DICTIONARY) { dictVal = new DictionaryType(v); }
140 150 : explicit ValueTemplate(DictionaryType &&v) : _type(Type::DICTIONARY) { dictVal = new DictionaryType(std::move(v)); }
141 :
142 : Self& operator= (const Self& other) noexcept;
143 : Self& operator= (Self&& other) noexcept;
144 :
145 : template <typename OtherInterface>
146 : Self& operator= (const ValueTemplate<OtherInterface> &) noexcept;
147 :
148 : Self& operator= (nullptr_t) { clear(); _type = Type::EMPTY; return *this; }
149 2875 : Self& operator= (bool v) { reset(Type::BOOLEAN); boolVal = v; return *this; }
150 : Self& operator= (int32_t v) { reset(Type::INTEGER); intVal = int64_t(v); return *this; }
151 11525 : Self& operator= (int64_t v) { reset(Type::INTEGER); intVal = int64_t(v); return *this; }
152 : Self& operator= (size_t v) { reset(Type::INTEGER); intVal = int64_t(v); return *this; }
153 : Self& operator= (float v) { reset(Type::DOUBLE); doubleVal = double(v); return *this; }
154 2550 : Self& operator= (double v) { reset(Type::DOUBLE); doubleVal = double(v); return *this; }
155 0 : Self& operator= (const char *v) { return (*this = Self(v)); }
156 17800 : Self& operator= (const StringView &v) { return (*this = Self(v)); }
157 1275 : Self& operator= (const StringType &v) { return (*this = Self(v)); }
158 475 : Self& operator= (StringType &&v) { return (*this = Self(std::move(v))); }
159 0 : Self& operator= (const BytesView &v) { return (*this = Self(v)); }
160 : Self& operator= (const BytesType &v) { return (*this = Self(v)); }
161 100 : Self& operator= (BytesType &&v) { return (*this = Self(std::move(v))); }
162 : Self& operator= (const ArrayType &v) { return (*this = Self(v)); }
163 225 : Self& operator= (ArrayType &&v) { return (*this = Self(std::move(v))); }
164 : Self& operator= (const DictionaryType &v) { return (*this = Self(v)); }
165 100 : Self& operator= (DictionaryType &&v) { return (*this = Self(std::move(v))); }
166 :
167 : bool operator== (const Self& v) const;
168 :
169 : bool operator== (bool v) const { return isBasicType() ? v == asBool() : false; }
170 : bool operator== (int32_t v) const { return isBasicType() ? v == asInteger() : false; }
171 : bool operator== (int64_t v) const { return isBasicType() ? v == asInteger() : false; }
172 : bool operator== (size_t v) const { return isBasicType() ? v == asInteger() : false; }
173 : bool operator== (float v) const { return isBasicType() ? fabs(v - asDouble()) < epsilon<double>() : false; }
174 : bool operator== (double v) const { return isBasicType() ? fabs(v - asDouble()) < epsilon<double>() : false; }
175 : bool operator== (const char *v) const { return isString() ? strVal->compare(v) == 0 : false; }
176 : bool operator== (const StringView &v) const { return isString() ? string::compare_c(*strVal, v) == 0 : false; }
177 : bool operator== (const BytesView &v) const { return isBytes() ? (*bytesVal) == v : false; }
178 : bool operator== (const ArrayType &v) const { return isArray() ? compare(*arrayVal, v) : false; }
179 : bool operator== (const DictionaryType &v) const { return isDictionary() ? compare(*dictVal, v) : false; }
180 :
181 48075 : bool operator!= (const Self& v) const { return !(*this == v); }
182 : bool operator!= (bool v) const { return !(*this == v); }
183 : bool operator!= (int32_t v) const { return !(*this == v); }
184 : bool operator!= (int64_t v) const { return !(*this == v); }
185 : bool operator!= (size_t v) const { return !(*this == v); }
186 : bool operator!= (float v) const { return !(*this == v); }
187 : bool operator!= (double v) const { return !(*this == v); }
188 : bool operator!= (const char *v) const { return !(*this == v); }
189 : bool operator!= (const StringView &v) const { return !(*this == v); }
190 : bool operator!= (const BytesView &v) const { return !(*this == v); }
191 : bool operator!= (const ArrayType &v) const { return !(*this == v); }
192 : bool operator!= (const DictionaryType &v) const { return !(*this == v); }
193 :
194 : template <class Val, class Key> Self &setValue(Val &&value, Key &&key);
195 :
196 : template <class Val> Self &setValue(Val &&value);
197 : template <class Val> Self &addValue(Val &&value);
198 : template <class Key> Self &getValue(Key &&key);
199 : template <class Key> const Self &getValue(Key &&key) const;
200 :
201 : Self &emplace();
202 : template <class Key> Self &emplace(Key &&);
203 : template <class Key> bool hasValue(Key &&) const;
204 :
205 :
206 0 : template <class Key> void setNull(Key && key) { setValue(Self(), std::forward<Key>(key)); }
207 3625 : template <class Key> void setBool(bool value, Key && key) { setValue(Self(value), std::forward<Key>(key)); }
208 37539 : template <class Key> void setInteger(int64_t value, Key && key) { setValue(Self(value), std::forward<Key>(key)); }
209 299486 : template <class Key> void setDouble(double value, Key && key) { setValue(Self(value), std::forward<Key>(key)); }
210 85549 : template <class Key> void setString(const StringType &v, Key &&key) { setValue(Self(v), std::forward<Key>(key)); }
211 2775 : template <class Key> void setString(StringType &&v, Key &&key) { setValue(Self(std::move(v)), std::forward<Key>(key)); }
212 4575 : template <class Key> void setString(const char *v, Key &&key) { setValue(Self(v), std::forward<Key>(key)); }
213 5875 : template <class Key> void setString(const StringView &v, Key &&key) { setValue(Self(std::move(v)), std::forward<Key>(key)); }
214 : template <class Key> void setBytes(const BytesType &v, Key &&key) { setValue(Self(v), std::forward<Key>(key)); }
215 325 : template <class Key> void setBytes(BytesType &&v, Key &&key) { setValue(Self(std::move(v)), std::forward<Key>(key)); }
216 : template <class Key> void setBytes(const BytesViewTemplate<Endian::Big> &v, Key &&key) { setValue(Self(v), std::forward<Key>(key)); }
217 170273 : template <class Key> void setBytes(const BytesViewTemplate<Endian::Little> &v, Key &&key) { setValue(Self(v), std::forward<Key>(key)); }
218 25 : template <class Key> void setArray(const ArrayType &v, Key &&key) { setValue(Self(v), std::forward<Key>(key)); }
219 50 : template <class Key> void setArray(ArrayType &&v, Key &&key) { setValue(Self(std::move(v)), std::forward<Key>(key)); }
220 : template <class Key> void setDict(const DictionaryType &v, Key &&key) { setValue(Self(v), std::forward<Key>(key)); }
221 : template <class Key> void setDict(DictionaryType &&v, Key &&key) { setValue(Self(std::move(v)), std::forward<Key>(key)); }
222 :
223 0 : void setNull() { clear(); _type = Type::EMPTY; }
224 2875 : void setBool(bool value) { *this = value; }
225 : void setInteger(int32_t value) { *this = value; }
226 11525 : void setInteger(int64_t value) { *this = value; }
227 : void setInteger(size_t value) { *this = value; }
228 : void setDouble(float value) { *this = value; }
229 2550 : void setDouble(double value) { *this = value; }
230 0 : void setString(const char *value) { *this = value; }
231 17800 : void setString(const StringView &value) { *this = value; }
232 1275 : void setString(const StringType &value) { *this = value; }
233 475 : void setString(StringType &&value) { *this = std::move(value); }
234 : void setBytes(const BytesType &value) { *this = value; }
235 100 : void setBytes(BytesType &&value) { *this = std::move(value); }
236 0 : void setBytes(const BytesView &value) { *this = value; }
237 : void setArray(const ArrayType &value) { *this = value; }
238 225 : void setArray(ArrayType &&value) { *this = std::move(value); }
239 : void setDict(const DictionaryType &value) { *this = value; }
240 100 : void setDict(DictionaryType &&value) { *this = std::move(value); }
241 :
242 0 : void addBool(bool value) { addValue(Self(value)); }
243 3225 : void addInteger(int64_t value) { addValue(Self(value)); }
244 0 : void addDouble(double value) { addValue(Self(value)); }
245 2325 : void addString(const char *value) { addValue(Self(value)); }
246 13275 : void addString(const StringView &value) { addValue(Self(value)); }
247 100 : void addString(const StringType &value) { addValue(Self(value)); }
248 0 : void addString(StringType &&value) { addValue(Self(std::move(value))); }
249 0 : void addBytes(const BytesView &value) { addValue(Self(value)); }
250 : void addBytes(const BytesType &value) { addValue(Self(value)); }
251 : void addBytes(BytesType &&value) { addValue(Self(std::move(value))); }
252 : void addArray(const ArrayType &value) { addValue(Self(value)); }
253 : void addArray(ArrayType &&value) { addValue(Self(std::move(value))); }
254 : void addDict(const DictionaryType &value) { addValue(Self(value)); }
255 : void addDict(DictionaryType &&value) { addValue(Self(std::move(value))); }
256 :
257 1996 : bool getBool() const { return isBasicType() ? asBool() : false; }
258 25958 : int64_t getInteger(int64_t def = 0) const { return isBasicType() ? asInteger() : def; }
259 356970 : double getDouble(double def = 0) const { return isBasicType() ? asDouble() : def; }
260 :
261 243356 : StringType &getString() { return isString() ? *strVal : const_cast<StringType &>(StringNull); }
262 426228 : BytesType &getBytes(){ return isBytes() ? *bytesVal : const_cast<BytesType &>(BytesNull); }
263 3084 : ArrayType &getArray() { return asArray(); }
264 625 : DictionaryType &getDict() { return asDict(); }
265 :
266 69275 : const StringType &getString() const { return isString() ? *strVal : StringNull; }
267 225 : const BytesType &getBytes() const { return isBytes() ? *bytesVal : BytesNull; }
268 4368 : const ArrayType &getArray() const { return asArray(); }
269 : const DictionaryType &getDict() const { return asDict(); }
270 :
271 : template <class Key> bool getBool(Key &&key) const;
272 : template <class Key> int64_t getInteger(Key &&key, int64_t def = 0) const;
273 : template <class Key> double getDouble(Key &&key, double def = 0) const;
274 : template <class Key> StringType &getString(Key &&key);
275 : template <class Key> const StringType &getString(Key &&key) const;
276 : template <class Key> BytesType &getBytes(Key &&key);
277 : template <class Key> const BytesType &getBytes(Key &&key) const;
278 : template <class Key> ArrayType &getArray(Key &&key);
279 : template <class Key> const ArrayType &getArray(Key &&key) const;
280 : template <class Key> DictionaryType &getDict(Key &&key);
281 : template <class Key> const DictionaryType &getDict(Key &&key) const;
282 :
283 : template <class Key> bool erase(Key &&key);
284 :
285 25 : template <class Key> Self& newDict(Key &&key) { return setValue(Self(Type::DICTIONARY), std::forward<Key>(key)); }
286 : template <class Key> Self& newArray(Key &&key) { return setValue(Self(Type::ARRAY), std::forward<Key>(key)); }
287 :
288 0 : Self& addDict() { return addValue(Self( DictionaryType() )); }
289 0 : Self& addArray() { return addValue(Self( ArrayType() )); }
290 :
291 : Self slice(int start, int count);
292 :
293 103900 : explicit operator bool() const noexcept { return (_type != Type::EMPTY && _type != Type::NONE); }
294 :
295 : int64_t asInteger() const;
296 : double asDouble() const;
297 : bool asBool() const;
298 : StringType asString() const;
299 : BytesType asBytes() const;
300 :
301 28125 : ArrayType& asArray() { return isArray() ? *arrayVal : const_cast<ArrayType &>(ArrayNull); }
302 8425 : const ArrayType& asArray() const { return isArray() ? *arrayVal : ArrayNull; }
303 :
304 55125 : DictionaryType& asDict() { return isDictionary() ? *dictVal : const_cast<DictionaryType &>(DictionaryNull); }
305 26228 : const DictionaryType& asDict() const { return isDictionary() ? *dictVal : DictionaryNull; }
306 :
307 : size_t size() const noexcept;
308 : bool empty() const noexcept;
309 : void clear();
310 :
311 : template <class Stream, class Traits = StreamTraits<Stream>>
312 : void encode(Stream &stream) const;
313 :
314 788501 : inline bool isNull() const noexcept { return _type == Type::EMPTY || _type == Type::NONE; }
315 484645 : inline bool isBasicType() const noexcept { return _type != Type::ARRAY && _type != Type::DICTIONARY; }
316 15423900 : inline bool isArray() const noexcept { return _type == Type::ARRAY; }
317 344578 : inline bool isDictionary() const noexcept { return _type == Type::DICTIONARY; }
318 :
319 5350 : inline bool isBool() const noexcept { return _type == Type::BOOLEAN; }
320 23485 : inline bool isInteger() const noexcept { return _type == Type::INTEGER; }
321 100 : inline bool isDouble() const noexcept { return _type == Type::DOUBLE; }
322 368931 : inline bool isString() const noexcept { return _type == Type::CHARSTRING; }
323 852906 : inline bool isBytes() const noexcept { return _type == Type::BYTESTRING; }
324 :
325 71271 : inline Type getType() const noexcept { return _type; }
326 :
327 : template <class Key> bool isNull(Key &&) const;
328 : template <class Key> bool isBasicType(Key &&) const;
329 : template <class Key> bool isArray(Key &&) const;
330 : template <class Key> bool isDictionary(Key &&) const;
331 :
332 : template <class Key> bool isBool(Key &&) const;
333 : template <class Key> bool isInteger(Key &&) const;
334 : template <class Key> bool isDouble(Key &&) const;
335 : template <class Key> bool isString(Key &&) const;
336 : template <class Key> bool isBytes(Key &&) const;
337 :
338 : template <class Key> Type getType(Key &&) const;
339 :
340 : template <typename NewInterface> auto convert() const -> ValueTemplate<NewInterface>;
341 :
342 : protected:
343 : template <typename Iface>
344 : friend class JsonBuffer;
345 :
346 : template <typename Iface>
347 : friend class CborBuffer;
348 :
349 : template <typename Iface>
350 : friend struct cbor::Decoder;
351 :
352 : template <typename Iface>
353 : friend struct json::Decoder;
354 :
355 : template <typename Iface>
356 : friend struct serenity::Decoder;
357 :
358 : template <typename Iface>
359 : friend class ValueTemplate;
360 :
361 : void reset(Type type);
362 :
363 : bool convertToDict();
364 : bool convertToArray(int size = 0);
365 :
366 : bool compare(const ArrayType &a1, const ArrayType &a2) const;
367 : bool compare(const DictionaryType &a1, const DictionaryType &a2) const;
368 :
369 : Type _type = Type::EMPTY;
370 :
371 : union {
372 : int64_t intVal;
373 : double doubleVal;
374 : bool boolVal;
375 :
376 : StringType * strVal;
377 : BytesType * bytesVal;
378 : ArrayType * arrayVal;
379 : DictionaryType * dictVal;
380 : };
381 : };
382 :
383 : template <typename Interface>
384 : const typename ValueTemplate<Interface>::Self ValueTemplate<Interface>::Null(ValueTemplate<Interface>::Type::NONE);
385 :
386 : template <typename Interface>
387 : const typename ValueTemplate<Interface>::StringType ValueTemplate<Interface>::StringNull;
388 :
389 : template <typename Interface>
390 : const typename ValueTemplate<Interface>::BytesType ValueTemplate<Interface>::BytesNull;
391 :
392 : template <typename Interface>
393 : const typename ValueTemplate<Interface>::ArrayType ValueTemplate<Interface>::ArrayNull;
394 :
395 : template <typename Interface>
396 : const typename ValueTemplate<Interface>::DictionaryType ValueTemplate<Interface>::DictionaryNull;
397 :
398 : template <typename Interface>
399 18036412 : ValueTemplate<Interface>::ValueTemplate() noexcept { }
400 :
401 : template <typename Interface>
402 77555436 : ValueTemplate<Interface>::ValueTemplate(Type type) noexcept : _type(type) {
403 77555436 : switch (type) {
404 50 : case Type::NONE: _type = Type::EMPTY; break;
405 0 : case Type::BOOLEAN: boolVal = false; break;
406 0 : case Type::INTEGER: intVal = int64_t(0); break;
407 0 : case Type::DOUBLE: doubleVal = double(0.0); break;
408 0 : case Type::CHARSTRING: strVal = new StringType(""); break;
409 0 : case Type::BYTESTRING: bytesVal = new BytesType; break;
410 35975 : case Type::DICTIONARY: dictVal = new DictionaryType; break;
411 25350 : case Type::ARRAY: arrayVal = new ArrayType; break;
412 77494061 : default: break;
413 : }
414 77555436 : }
415 :
416 : template <typename Interface>
417 102094249 : ValueTemplate<Interface>::~ValueTemplate() noexcept { clear(); }
418 :
419 : template <typename Interface>
420 9670671 : ValueTemplate<Interface>::ValueTemplate(const Self &other) noexcept { *this = other; }
421 :
422 : template <typename Interface>
423 7690369 : ValueTemplate<Interface>::ValueTemplate(Self &&other) noexcept { *this = std::move(other); }
424 :
425 : template <typename Interface>
426 : template <typename OtherInterface>
427 46850 : ValueTemplate<Interface>::ValueTemplate(const ValueTemplate<OtherInterface> &other) {
428 : using OtherType = typename ValueTemplate<OtherInterface>::Type;
429 :
430 46850 : switch (other._type) {
431 975 : case OtherType::NONE:
432 : case OtherType::EMPTY:
433 975 : _type = Type::EMPTY;
434 975 : break;
435 3300 : case OtherType::BOOLEAN:
436 3300 : _type = Type::BOOLEAN;
437 3300 : boolVal = other.boolVal;
438 3300 : break;
439 14125 : case OtherType::INTEGER:
440 14125 : _type = Type::INTEGER;
441 14125 : intVal = other.intVal;
442 14125 : break;
443 3075 : case OtherType::DOUBLE:
444 3075 : _type = Type::DOUBLE;
445 3075 : doubleVal = other.doubleVal;
446 3075 : break;
447 13225 : case OtherType::CHARSTRING:
448 13225 : _type = Type::CHARSTRING;
449 13225 : strVal = new StringType(other.strVal->data(), other.strVal->size());
450 13225 : break;
451 1225 : case OtherType::BYTESTRING:
452 1225 : _type = Type::BYTESTRING;
453 1225 : bytesVal = new BytesType(other.bytesVal->begin(), other.bytesVal->end());
454 1225 : break;
455 6375 : case OtherType::DICTIONARY:
456 6375 : _type = Type::DICTIONARY;
457 7075 : dictVal = new DictionaryType();
458 36675 : for (auto &it : (*other.dictVal)) {
459 30300 : dictVal->emplace(StringType(it.first.data(), it.first.size()), it.second);
460 : }
461 6375 : break;
462 4550 : case OtherType::ARRAY:
463 4550 : _type = Type::ARRAY;
464 4550 : arrayVal = new ArrayType(other.arrayVal->begin(), other.arrayVal->end());
465 4550 : break;
466 : }
467 46850 : }
468 :
469 : template <typename Interface>
470 11300 : ValueTemplate<Interface>::ValueTemplate(InitializerList<Self> il) : ValueTemplate(Type::ARRAY) {
471 11300 : arrayVal->reserve(il.size());
472 38525 : for (auto &it : il) {
473 27225 : arrayVal->emplace_back(std::move(const_cast<Self &>(it)));
474 : }
475 11300 : }
476 :
477 : template <typename Interface>
478 9575 : ValueTemplate<Interface>::ValueTemplate(InitializerList<Pair<StringType, Self>> il) : ValueTemplate(Type::DICTIONARY) {
479 53250 : for (auto &it : il) {
480 43675 : dictVal->emplace(std::move(const_cast<StringType &>(it.first)), std::move(const_cast<Self &>(it.second)));
481 : }
482 9575 : }
483 :
484 : template <typename Interface>
485 9687496 : auto ValueTemplate<Interface>::operator= (const Self& other) noexcept -> Self & {
486 9687496 : if (_type == Type::NONE) {
487 0 : return *this;
488 : }
489 9687496 : if (this != &other) {
490 9687496 : Self mv;
491 9687496 : memcpy((void *)&mv, (const void *)this, sizeof(Self));
492 9687496 : memset((void *)this, 0, sizeof(Self));
493 :
494 9687496 : switch (other._type) {
495 0 : case Type::NONE: _type = Type::EMPTY; return *this; break;
496 656875 : case Type::INTEGER: intVal = other.intVal; break;
497 17650 : case Type::DOUBLE: doubleVal = other.doubleVal; break;
498 1007975 : case Type::BOOLEAN: boolVal = other.boolVal; break;
499 6115972 : case Type::CHARSTRING: strVal = new StringType(*other.strVal); break;
500 7575 : case Type::BYTESTRING: bytesVal = new BytesType(*other.bytesVal); break;
501 561250 : case Type::ARRAY: arrayVal = new ArrayType(*other.arrayVal); break;
502 1298099 : case Type::DICTIONARY: dictVal = new DictionaryType(*other.dictVal); break;
503 22100 : default: break;
504 : }
505 :
506 9687497 : _type = other._type;
507 9687497 : }
508 9687496 : return *this;
509 : }
510 :
511 : template <typename Interface>
512 7773066 : auto ValueTemplate<Interface>::operator= (Self&& other) noexcept -> Self & {
513 7773066 : if (_type == Type::NONE) {
514 0 : return *this;
515 : }
516 7773066 : if (this != &other) {
517 7773067 : if (other._type == Type::NONE) {
518 0 : clear();
519 0 : _type = Type::EMPTY;
520 : } else {
521 7773067 : Self mv;
522 7773067 : memcpy((void *)&mv, (const void *)this, sizeof(Self));
523 7773067 : memcpy((void *)this, (const void *)&other, sizeof(Self));
524 7773067 : other._type = Type::EMPTY;
525 7773067 : }
526 : }
527 7773069 : return *this;
528 : }
529 :
530 : template <typename Interface>
531 : template <typename OtherInterface>
532 : auto ValueTemplate<Interface>::operator= (const ValueTemplate<OtherInterface> &other) noexcept -> Self & {
533 : return *this = ValueTemplate<Interface>(other);
534 : }
535 :
536 : template <typename Interface>
537 51275 : bool ValueTemplate<Interface>::operator== (const Self& v) const {
538 51275 : if (this == &v) return true;
539 51275 : if (v._type != this->_type) return false;
540 49600 : switch (_type) {
541 13025 : case Type::INTEGER: return v.intVal == this->intVal; break;
542 6300 : case Type::BOOLEAN: return v.boolVal == this->boolVal; break;
543 17350 : case Type::CHARSTRING: return *v.strVal == *this->strVal; break;
544 0 : case Type::BYTESTRING: return *v.bytesVal == *this->bytesVal; break;
545 1650 : case Type::DOUBLE: return fabs(v.doubleVal - this->doubleVal) <= DBL_EPSILON; break;
546 3450 : case Type::ARRAY: return compare(*(this->arrayVal), *(v.arrayVal)); break;
547 7675 : case Type::DICTIONARY: return compare(*(this->dictVal), *(v.dictVal)); break;
548 150 : case Type::EMPTY:
549 : case Type::NONE:
550 150 : return true;
551 : break;
552 0 : default:
553 0 : break;
554 : };
555 :
556 0 : return false;
557 : }
558 :
559 : template <typename Interface>
560 900 : auto ValueTemplate<Interface>::emplace() -> Self & {
561 900 : if (convertToArray(-1)) {
562 900 : arrayVal->emplace_back(Type::EMPTY);
563 900 : return arrayVal->back();
564 : }
565 0 : return const_cast<Self &>(Self::Null);
566 : }
567 :
568 : template <typename Interface>
569 : auto ValueTemplate<Interface>::slice(int start, int count) -> Self {
570 : if (!isArray() || (size_t)(start + count) > size()) {
571 : return Self();
572 : }
573 :
574 : Self ret;
575 : for (auto it = arrayVal->begin() + start; it != arrayVal->begin() + start + count; it ++) {
576 : ret.addValue(std::move(*it));
577 : }
578 :
579 : arrayVal->erase(arrayVal->begin() + start, arrayVal->begin() + start + count);
580 :
581 : return ret;
582 : }
583 :
584 : template <typename Interface>
585 60108 : int64_t ValueTemplate<Interface>::asInteger() const {
586 60108 : switch (_type) {
587 59733 : case Type::INTEGER: return intVal; break;
588 100 : case Type::DOUBLE: return static_cast<int64_t>(doubleVal); break;
589 0 : case Type::BOOLEAN: return boolVal ? 1 : 0; break;
590 250 : case Type::CHARSTRING: return StringToNumber<int64_t>(strVal->c_str(), nullptr, 0); break;
591 25 : default: return 0; break;
592 : }
593 : return 0;
594 : }
595 :
596 : template <typename Interface>
597 370520 : double ValueTemplate<Interface>::asDouble() const {
598 370520 : switch (_type) {
599 250 : case Type::INTEGER: return static_cast<double>(intVal); break;
600 370220 : case Type::DOUBLE: return doubleVal; break;
601 50 : case Type::BOOLEAN: return boolVal ? 1.0 : 0.0; break;
602 0 : case Type::CHARSTRING: return StringToNumber<double>(strVal->c_str(), nullptr, 0); break;
603 0 : default: return 0.0; break;
604 : }
605 : return 0.0;
606 : }
607 :
608 : template <typename Interface>
609 17225 : bool ValueTemplate<Interface>::asBool() const {
610 17225 : switch (_type) {
611 100 : case Type::INTEGER: return intVal == 0 ? false : true; break;
612 0 : case Type::DOUBLE: return doubleVal == 0.0 ? false : true; break;
613 11700 : case Type::BOOLEAN: return boolVal; break;
614 1225 : case Type::CHARSTRING: return (strVal->empty() || *strVal == "0" || *strVal == "false") ? false : true; break;
615 4200 : default: return false; break;
616 : }
617 : return false;
618 : }
619 :
620 : template <typename Interface>
621 15150 : auto ValueTemplate<Interface>::asString() const -> StringType {
622 15150 : if (_type == Type::CHARSTRING) {
623 11175 : return *strVal;
624 : }
625 :
626 3975 : typename Interface::StringStreamType ret;
627 3975 : switch (_type) {
628 1125 : case Type::INTEGER:
629 1125 : ret << intVal;
630 1125 : break;
631 175 : case Type::DOUBLE: {
632 175 : ret << std::fixed << std::setprecision(std::numeric_limits<double>::digits10 + 1) << doubleVal;
633 175 : typename Interface::StringType r = ret.str();
634 175 : auto pos = r.find_last_of('.');
635 175 : if (pos != Interface::StringType::npos) {
636 1400 : while (r.size() > pos + 2 && r.back() == '0') {
637 1275 : r.pop_back();
638 : }
639 : }
640 175 : return r;
641 : break;
642 175 : }
643 2675 : case Type::BOOLEAN:
644 2675 : ret << (boolVal ? "true" : "false");
645 2675 : break;
646 0 : case Type::BYTESTRING:
647 0 : ret << "BASE64:" << base64::encode<Interface>(*bytesVal);
648 0 : break;
649 0 : default:
650 0 : break;
651 : }
652 3800 : return ret.str();
653 3975 : }
654 :
655 : template <typename Interface>
656 2550 : auto ValueTemplate<Interface>::asBytes() const -> BytesType {
657 2550 : if (_type == Type::BYTESTRING) {
658 2550 : return *bytesVal;
659 : }
660 :
661 0 : BytesType ret;
662 0 : switch (_type) {
663 0 : case Type::INTEGER:
664 0 : ret.resize(sizeof(intVal));
665 0 : memcpy(ret.data(), (void *)&intVal, sizeof(intVal));
666 0 : break;
667 0 : case Type::DOUBLE:
668 0 : ret.resize(sizeof(doubleVal));
669 0 : memcpy(ret.data(), (void *)&doubleVal, sizeof(doubleVal));
670 0 : break;
671 0 : case Type::BOOLEAN:
672 0 : ret.resize(1);
673 0 : ret[0] = (boolVal ? 1 : 0);
674 0 : break;
675 0 : case Type::CHARSTRING:
676 0 : ret.resize(strVal->length());
677 0 : memcpy(ret.data(), strVal->c_str(), strVal->length());
678 0 : break;
679 0 : default:
680 0 : break;
681 : }
682 0 : return ret;
683 0 : }
684 :
685 : template <typename Interface>
686 16975 : size_t ValueTemplate<Interface>::size() const noexcept {
687 16975 : switch (_type) {
688 150 : case Type::DICTIONARY: return dictVal->size(); break;
689 13300 : case Type::ARRAY: return arrayVal->size(); break;
690 3525 : case Type::CHARSTRING: return strVal->size(); break;
691 0 : case Type::BYTESTRING: return bytesVal->size(); break;
692 0 : default: return 0; break;
693 : }
694 : return 0;
695 : }
696 :
697 : template <typename Interface>
698 30100 : bool ValueTemplate<Interface>::empty() const noexcept {
699 30100 : switch (_type) {
700 17825 : case Type::DICTIONARY: return dictVal->empty(); break;
701 8325 : case Type::ARRAY: return arrayVal->empty(); break;
702 25 : case Type::CHARSTRING: return strVal->empty(); break;
703 0 : case Type::BYTESTRING: return bytesVal->empty(); break;
704 3250 : case Type::EMPTY: return true; break;
705 0 : case Type::NONE: return true; break;
706 675 : default: return false; break;
707 : }
708 : return false;
709 : }
710 :
711 : template <typename Interface>
712 1252048 : bool ValueTemplate<Interface>::convertToDict() {
713 1252048 : switch (_type) {
714 1016936 : case Type::DICTIONARY: return true; break;
715 235112 : case Type::EMPTY: reset(Type::DICTIONARY); return true; break;
716 0 : default: return false; break;
717 : }
718 : return false;
719 : }
720 :
721 : template <typename Interface>
722 217014 : bool ValueTemplate<Interface>::convertToArray(int size) {
723 217014 : if (size < 0) {
724 217014 : switch (_type) {
725 212822 : case Type::ARRAY: return true; break;
726 4192 : case Type::EMPTY: reset(Type::ARRAY); return true; break;
727 0 : default: return false; break;
728 : }
729 : return false;
730 0 : } else if (_type == Type::ARRAY) {
731 0 : if (size == 0 || (int)arrayVal->size() > size) {
732 0 : return true;
733 : }
734 0 : } else if (_type == Type::EMPTY) {
735 0 : reset(Type::ARRAY);
736 0 : arrayVal->resize(size + 1);
737 0 : return true;
738 : } else {
739 0 : return false;
740 : }
741 0 : return false;
742 : }
743 :
744 : template <typename Interface>
745 3450 : bool ValueTemplate<Interface>::compare(const ArrayType &v1, const ArrayType &v2) const {
746 3450 : const auto size = v1.size();
747 3450 : if (size == v2.size()) {
748 22050 : for (size_t i = 0; i < size; i++) {
749 18600 : if (v1[i] != v2[i]) return false;
750 : }
751 3450 : return true;
752 : }
753 0 : return false;
754 : }
755 :
756 : template <typename Interface>
757 7675 : bool ValueTemplate<Interface>::compare(const DictionaryType &map1, const DictionaryType &map2) const {
758 7675 : if (map1.size() != map2.size()) {
759 0 : return false;
760 : }
761 35100 : for (const auto &kvp : map1) {
762 27500 : auto it = map2.find(kvp.first);
763 27500 : if (it == map2.end() || it->second != kvp.second) {
764 75 : return false;
765 : }
766 : }
767 7600 : return true;
768 : }
769 :
770 : template <typename Interface>
771 102350525 : void ValueTemplate<Interface>::clear() {
772 102350525 : switch (_type) {
773 0 : case Type::NONE: return; break;
774 5395000 : case Type::INTEGER: intVal = 0; break;
775 920907 : case Type::DOUBLE: doubleVal = 0.0; break;
776 8996725 : case Type::BOOLEAN: boolVal = false; break;
777 44182748 : case Type::CHARSTRING: delete strVal; strVal = nullptr; break;
778 869280 : case Type::BYTESTRING: delete bytesVal; bytesVal = nullptr; break;
779 3802425 : case Type::ARRAY: delete arrayVal; arrayVal = nullptr; break;
780 12299792 : case Type::DICTIONARY: delete dictVal; dictVal = nullptr; break;
781 25883648 : default: break;
782 : }
783 :
784 102350526 : _type = Type::EMPTY;
785 : }
786 :
787 : template <typename Interface>
788 256262 : void ValueTemplate<Interface>::reset(Type type) {
789 256262 : if (_type == Type::NONE && _type == type) {
790 0 : return;
791 : }
792 :
793 256262 : clear();
794 :
795 : // Allocate memory for the new value
796 256262 : switch (type) {
797 0 : case Type::CHARSTRING: strVal = new StringType(); break;
798 0 : case Type::BYTESTRING: bytesVal = new BytesType(); break;
799 8350 : case Type::ARRAY: arrayVal = new ArrayType(); break;
800 256037 : case Type::DICTIONARY: dictVal = new DictionaryType(); break;
801 16950 : default: break;
802 : }
803 :
804 256262 : _type = type;
805 : }
806 :
807 : template <typename Interface>
808 : template <class Val, class Key>
809 1119013 : auto ValueTemplate<Interface>::setValue(Val &&value, Key &&key) -> Self & {
810 : if constexpr (std::is_integral<typename std::remove_reference<Key>::type>::value) {
811 0 : if (convertToArray((int)key)) {
812 0 : arrayVal->at(key) = std::forward<Val>(value);
813 0 : return arrayVal->at(key);
814 : }
815 0 : return const_cast<Self &>(Null);
816 : } else {
817 1119013 : if (convertToDict()) {
818 1119013 : auto i = dictVal->find(key);
819 1119013 : if (i != dictVal->end()) {
820 8575 : i->second = std::forward<Val>(value);
821 8575 : return i->second;
822 : } else {
823 : if constexpr (std::is_same<StringView, typename std::remove_cv<typename std::remove_reference<Key>::type>::type>()) {
824 31400 : return dictVal->emplace(key.template str<Interface>(), std::forward<Val>(value)).first->second;
825 : } else {
826 1079038 : return dictVal->emplace(std::forward<Key>(key), std::forward<Val>(value)).first->second;
827 : }
828 : }
829 : }
830 0 : return const_cast<Self &>(Null);
831 : }
832 : }
833 :
834 : template <typename Interface>
835 : template <class Val>
836 3275 : auto ValueTemplate<Interface>::setValue(Val &&value) -> Self & {
837 3275 : *this = std::forward<Val>(value);
838 3275 : return *this;
839 : }
840 :
841 : template <typename Interface>
842 : template <class Val>
843 216114 : auto ValueTemplate<Interface>::addValue(Val &&value) -> Self & {
844 216114 : if (convertToArray(-1)) {
845 216114 : arrayVal->emplace_back(std::forward<Val>(value));
846 216114 : return arrayVal->back();
847 : }
848 0 : return const_cast<Self &>(Self::Null);
849 : }
850 :
851 : template <typename Interface>
852 : template <class Key>
853 551799 : auto ValueTemplate<Interface>::getValue(Key &&key) -> Self & {
854 : if constexpr (std::is_integral<typename std::remove_reference<Key>::type>::value) {
855 11725 : if (_type == Type::ARRAY) {
856 11625 : if (size_t(key) < arrayVal->size()) {
857 11625 : return arrayVal->at(key);
858 : }
859 : }
860 100 : return const_cast<Self &>(Null);
861 : } else {
862 540074 : if (_type == Type::DICTIONARY) {
863 540074 : auto it = dictVal->find(key);
864 540074 : if (it != dictVal->end()) {
865 524257 : return it->second;
866 : }
867 : }
868 15817 : return const_cast<Self &>(Null);
869 : }
870 : }
871 :
872 : template <typename Interface>
873 : template <class Key>
874 242508 : auto ValueTemplate<Interface>::getValue(Key &&key) const -> const Self & {
875 : if constexpr (std::is_integral<typename std::remove_reference<Key>::type>::value) {
876 2212 : if (_type == Type::ARRAY) {
877 2212 : if (size_t(key) < arrayVal->size()) {
878 2212 : return arrayVal->at(key);
879 : }
880 : }
881 0 : return Null;
882 : } else {
883 240296 : if (_type == Type::DICTIONARY) {
884 234604 : auto it = dictVal->find(key);
885 234604 : if (it != dictVal->end()) {
886 230619 : return it->second;
887 : }
888 : }
889 9677 : return Null;
890 : }
891 : }
892 :
893 : template <typename Interface>
894 : template <class Key>
895 5150 : auto ValueTemplate<Interface>::emplace(Key &&key) -> Self & {
896 5150 : if (convertToDict()) {
897 5150 : auto it = dictVal->find(key);
898 5150 : if (it == dictVal->end()) {
899 : if constexpr (std::is_same<StringView, typename std::remove_cv<typename std::remove_reference<Key>::type>::type>()) {
900 750 : return dictVal->emplace(key.template str<Interface>(), Type::EMPTY).first->second;
901 : } else {
902 4200 : return dictVal->emplace(std::forward<Key>(key), Type::EMPTY).first->second;
903 : }
904 : } else {
905 200 : return it->second;
906 : }
907 : }
908 0 : return const_cast<Self &>(Null);
909 : }
910 :
911 : template <typename Interface>
912 : template <class Key>
913 54775 : bool ValueTemplate<Interface>::hasValue(Key &&key) const {
914 : if constexpr (std::is_integral<typename std::remove_reference<Key>::type>::value) {
915 0 : if (_type == Type::ARRAY) {
916 0 : return size_t(key) < arrayVal->size();
917 : }
918 0 : return false;
919 : } else {
920 54775 : if (_type == Type::DICTIONARY) {
921 48400 : return dictVal->find(key) != dictVal->end();
922 : }
923 6375 : return false;
924 : }
925 : }
926 :
927 : template <typename Interface>
928 : template <class Key>
929 5021 : bool ValueTemplate<Interface>::getBool(Key &&key) const {
930 5021 : const auto &v = getValue(std::forward<Key>(key));
931 5021 : if (!v.isNull()) {
932 1921 : return v.getBool();
933 : }
934 3100 : return false;
935 : }
936 :
937 : template <typename Interface>
938 : template <class Key>
939 20915 : int64_t ValueTemplate<Interface>::getInteger(Key &&key, int64_t def) const {
940 20915 : const auto &v = getValue(std::forward<Key>(key));
941 20915 : if (!v.isNull()) {
942 20227 : return v.getInteger(def);
943 : }
944 688 : return def;
945 : }
946 :
947 : template <typename Interface>
948 : template <class Key>
949 263481 : double ValueTemplate<Interface>::getDouble(Key &&key, double def) const {
950 263481 : const auto &v = getValue(std::forward<Key>(key));
951 263481 : if (!v.isNull()) {
952 263481 : return v.getDouble(def);
953 : }
954 0 : return def;
955 : }
956 :
957 : template <typename Interface>
958 : template <class Key>
959 213562 : auto ValueTemplate<Interface>::getString(Key &&key) -> StringType & {
960 213562 : auto &v = getValue(std::forward<Key>(key));
961 213562 : if (!v.isNull()) {
962 213537 : return v.getString();
963 : }
964 25 : return const_cast<StringType &>(StringNull);
965 : }
966 :
967 : template <typename Interface>
968 : template <class Key>
969 12506 : auto ValueTemplate<Interface>::getString(Key &&key) const -> const StringType & {
970 12506 : const auto &v = getValue(std::forward<Key>(key));
971 12506 : if (!v.isNull()) {
972 9460 : return v.getString();
973 : }
974 3046 : return StringNull;
975 : }
976 :
977 : template <typename Interface>
978 : template <class Key>
979 171336 : auto ValueTemplate<Interface>::getBytes(Key &&key) -> BytesType & {
980 171336 : auto &ret = getValue(std::forward<Key>(key));
981 171336 : if (ret.isBytes()) {
982 171336 : return ret.getBytes();
983 : }
984 0 : return const_cast<BytesType &>(BytesNull);
985 : }
986 :
987 : template <typename Interface>
988 : template <class Key>
989 225 : auto ValueTemplate<Interface>::getBytes(Key &&key) const -> const BytesType & {
990 225 : const auto &ret = getValue(std::forward<Key>(key));
991 225 : if (ret.isBytes()) {
992 225 : return ret.getBytes();
993 : }
994 0 : return BytesNull;
995 : }
996 :
997 : template <typename Interface>
998 : template <class Key>
999 126 : auto ValueTemplate<Interface>::getArray(Key &&key) -> ArrayType & {
1000 126 : auto &v = getValue(key);
1001 126 : if (!v.isNull()) {
1002 84 : return v.getArray();
1003 : }
1004 42 : return const_cast<ArrayType &>(ArrayNull);
1005 : }
1006 :
1007 : template <typename Interface>
1008 : template <class Key>
1009 4502 : auto ValueTemplate<Interface>::getArray(Key &&key) const -> const ArrayType & {
1010 4502 : const auto &v = getValue(key);
1011 4502 : if (!v.isNull()) {
1012 4368 : return v.getArray();
1013 : }
1014 134 : return ArrayNull;
1015 : }
1016 :
1017 : template <typename Interface>
1018 : template <class Key>
1019 550 : auto ValueTemplate<Interface>::getDict(Key &&key) -> DictionaryType & {
1020 550 : auto &v = getValue(key);
1021 550 : if (!v.isNull()) {
1022 550 : return v.getDict();
1023 : }
1024 0 : return const_cast<DictionaryType &>(DictionaryNull);
1025 : }
1026 :
1027 : template <typename Interface>
1028 : template <class Key>
1029 : auto ValueTemplate<Interface>::getDict(Key &&key) const -> const DictionaryType & {
1030 : const auto &v = getValue(key);
1031 : if (!v.isNull()) {
1032 : return v.getDict();
1033 : }
1034 : return DictionaryNull;
1035 : }
1036 :
1037 : template <typename Interface>
1038 : template <class Key>
1039 375 : bool ValueTemplate<Interface>::erase(Key &&key) {
1040 : if constexpr (std::is_integral<typename std::remove_reference<Key>::type>::value) {
1041 25 : if (_type != Type::ARRAY) {
1042 0 : return false;
1043 : }
1044 :
1045 25 : if (size_t(key) < arrayVal->size()) {
1046 25 : arrayVal->erase(arrayVal->begin() + key);
1047 25 : return true;
1048 : }
1049 0 : return false;
1050 : } else {
1051 350 : if (_type != Type::DICTIONARY) {
1052 0 : return false;
1053 : }
1054 :
1055 350 : auto it = dictVal->find(key);
1056 350 : if (it != dictVal->end()) {
1057 300 : dictVal->erase(it);
1058 300 : return true;
1059 : }
1060 50 : return false;
1061 : }
1062 : }
1063 :
1064 : template <typename Interface>
1065 : template <class Stream, class Traits>
1066 19964454 : void ValueTemplate<Interface>::encode(Stream &stream) const {
1067 19964454 : bool begin = false;
1068 1372900 : if constexpr (Traits::onValue) { stream.onValue(*this); }
1069 19964454 : switch (_type) {
1070 8775 : case Type::EMPTY: stream.write(nullptr); break;
1071 1996500 : case Type::BOOLEAN: stream.write(boolVal); break;
1072 1172800 : case Type::INTEGER: stream.write(intVal); break;
1073 433843 : case Type::DOUBLE: stream.write(doubleVal); break;
1074 12144109 : case Type::CHARSTRING: stream.write(*strVal); break;
1075 430993 : case Type::BYTESTRING: stream.write(*bytesVal); break;
1076 1040600 : case Type::ARRAY:
1077 1040600 : if constexpr (Traits::onBeginArray) { stream.onBeginArray(*arrayVal); }
1078 4690984 : for (auto &it : *arrayVal) {
1079 3650384 : if (!begin) {
1080 1027025 : begin = true;
1081 : } else {
1082 1292950 : if constexpr (Traits::onNextValue) { stream.onNextValue(); }
1083 : }
1084 : if constexpr (Traits::onArrayValue) {
1085 0 : stream.onArrayValue(it);
1086 : } else {
1087 3650384 : it.encode(stream);
1088 : }
1089 : }
1090 557825 : if constexpr (Traits::onEndArray) { stream.onEndArray(*arrayVal); }
1091 1040600 : break;
1092 2736834 : case Type::DICTIONARY:
1093 2736834 : if constexpr (Traits::onBeginDict) { stream.onBeginDict(*dictVal); }
1094 19022104 : for (auto &it : *dictVal) {
1095 16285270 : if (!begin) {
1096 2736809 : begin = true;
1097 : } else {
1098 6844225 : if constexpr (Traits::onNextValue) { stream.onNextValue(); }
1099 : }
1100 : if constexpr (Traits::onKeyValuePair) {
1101 0 : stream.onKeyValuePair(it.first, it.second);
1102 : } else if constexpr (Traits::onKey) {
1103 8205650 : stream.onKey(it.first);
1104 8205650 : it.second.encode(stream);
1105 : } else {
1106 8079620 : stream.write(it.first);
1107 8079620 : it.second.encode(stream);
1108 : }
1109 : }
1110 1361450 : if constexpr (Traits::onEndDict) { stream.onEndDict(*dictVal); }
1111 2736834 : break;
1112 0 : default:
1113 0 : break;
1114 : }
1115 19964454 : };
1116 :
1117 : template <typename Interface>
1118 : template <class Key>
1119 0 : bool ValueTemplate<Interface>::isNull(Key &&key) const {
1120 0 : return getType(std::forward<Key>(key)) == Type::EMPTY || getType(std::forward<Key>(key)) == Type::NONE;
1121 : }
1122 :
1123 : template <typename Interface>
1124 : template <class Key>
1125 0 : bool ValueTemplate<Interface>::isBasicType(Key &&key) const {
1126 0 : const auto type = getType(std::forward<Key>(key));
1127 0 : return type != Type::ARRAY && type != Type::DICTIONARY && type != Type::NONE;
1128 : }
1129 :
1130 : template <typename Interface>
1131 : template <class Key>
1132 2275 : bool ValueTemplate<Interface>::isArray(Key &&key) const {
1133 2275 : return getType(std::forward<Key>(key)) == Type::ARRAY;
1134 : }
1135 :
1136 : template <typename Interface>
1137 : template <class Key>
1138 500 : bool ValueTemplate<Interface>::isDictionary(Key &&key) const {
1139 500 : return getType(std::forward<Key>(key)) == Type::DICTIONARY;
1140 : }
1141 :
1142 : template <typename Interface>
1143 : template <class Key>
1144 121 : bool ValueTemplate<Interface>::isBool(Key &&key) const {
1145 121 : return getType(std::forward<Key>(key)) == Type::BOOLEAN;
1146 : }
1147 :
1148 : template <typename Interface>
1149 : template <class Key>
1150 275 : bool ValueTemplate<Interface>::isInteger(Key &&key) const {
1151 275 : return getType(std::forward<Key>(key)) == Type::INTEGER;
1152 : }
1153 :
1154 : template <typename Interface>
1155 : template <class Key>
1156 4900 : bool ValueTemplate<Interface>::isDouble(Key &&key) const {
1157 4900 : return getType(std::forward<Key>(key)) == Type::DOUBLE;
1158 : }
1159 :
1160 : template <typename Interface>
1161 : template <class Key>
1162 6496 : bool ValueTemplate<Interface>::isString(Key &&key) const {
1163 6496 : return getType(std::forward<Key>(key)) == Type::CHARSTRING;
1164 : }
1165 :
1166 : template <typename Interface>
1167 : template <class Key>
1168 0 : bool ValueTemplate<Interface>::isBytes(Key &&key) const {
1169 0 : return getType(std::forward<Key>(key)) == Type::BYTESTRING;
1170 : }
1171 :
1172 : template <typename Interface>
1173 : template <class Key>
1174 14567 : auto ValueTemplate<Interface>::getType(Key &&key) const -> Type {
1175 : if constexpr (std::is_integral<typename std::remove_reference<Key>::type>::value) {
1176 4900 : if (_type == Type::ARRAY) {
1177 4900 : if (size_t(key) < arrayVal->size()) {
1178 4900 : return arrayVal->at(key).getType();
1179 : }
1180 : }
1181 0 : return Type::NONE;
1182 : } else {
1183 9667 : if (_type == Type::DICTIONARY) {
1184 6442 : auto it = dictVal->find(key);
1185 6442 : if (it != dictVal->end()) {
1186 746 : return it->second.getType();
1187 : }
1188 : }
1189 8921 : return Type::NONE;
1190 : }
1191 : }
1192 :
1193 : }
1194 :
1195 : #endif /* STAPPLER_DATA_SPDATAVALUE_H_ */
|