LCOV - code coverage report
Current view: top level - core/data - SPDataValue.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 429 538 79.7 %
Date: 2024-05-12 00:16:13 Functions: 420 602 69.8 %

          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_ */

Generated by: LCOV version 1.14