diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index abb8dd1f..b63cb756 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -23,7 +23,7 @@ #include "ArduinoJson/Array/ArrayRef.hpp" #include "ArduinoJson/Object/ObjectRef.hpp" -#include "ArduinoJson/Variant/VariantRef.hpp" +#include "ArduinoJson/Variant/VariantConstRef.hpp" #include "ArduinoJson/Document/DynamicJsonDocument.hpp" #include "ArduinoJson/Document/StaticJsonDocument.hpp" diff --git a/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp b/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp index 0112f749..1e1e5154 100644 --- a/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp +++ b/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp @@ -5,7 +5,7 @@ #pragma once #include -#include +#include namespace ARDUINOJSON_NAMESPACE { diff --git a/src/ArduinoJson/Document/JsonDocument.hpp b/src/ArduinoJson/Document/JsonDocument.hpp index b7b178b8..55a96240 100644 --- a/src/ArduinoJson/Document/JsonDocument.hpp +++ b/src/ArduinoJson/Document/JsonDocument.hpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include namespace ARDUINOJSON_NAMESPACE { diff --git a/src/ArduinoJson/Object/Pair.hpp b/src/ArduinoJson/Object/Pair.hpp index 7e3ca32c..29f10a5f 100644 --- a/src/ArduinoJson/Object/Pair.hpp +++ b/src/ArduinoJson/Object/Pair.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include #include namespace ARDUINOJSON_NAMESPACE { diff --git a/src/ArduinoJson/Variant/ConverterImpl.hpp b/src/ArduinoJson/Variant/ConverterImpl.hpp index 53a44d18..62fef3c9 100644 --- a/src/ArduinoJson/Variant/ConverterImpl.hpp +++ b/src/ArduinoJson/Variant/ConverterImpl.hpp @@ -5,8 +5,8 @@ #pragma once #include +#include #include -#include namespace ARDUINOJSON_NAMESPACE { diff --git a/src/ArduinoJson/Variant/VariantAttorney.hpp b/src/ArduinoJson/Variant/VariantAttorney.hpp index 869c3c3e..ebb7d879 100644 --- a/src/ArduinoJson/Variant/VariantAttorney.hpp +++ b/src/ArduinoJson/Variant/VariantAttorney.hpp @@ -7,7 +7,7 @@ #include #include #include -#include "VariantRef.hpp" +#include "VariantConstRef.hpp" namespace ARDUINOJSON_NAMESPACE { diff --git a/src/ArduinoJson/Variant/VariantConstRef.hpp b/src/ArduinoJson/Variant/VariantConstRef.hpp new file mode 100644 index 00000000..34ec29c7 --- /dev/null +++ b/src/ArduinoJson/Variant/VariantConstRef.hpp @@ -0,0 +1,138 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2022, Benoit BLANCHON +// MIT License + +#pragma once + +#include +#include // for uint8_t + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ARDUINOJSON_NAMESPACE { + +// Forward declarations. +class ArrayRef; +class ObjectRef; + +class VariantConstRef : public VariantTag, + public VariantOperators, + public VariantShortcuts { + friend class VariantAttorney; + + public: + VariantConstRef() : _data(0) {} + explicit VariantConstRef(const VariantData* data) : _data(data) {} + + FORCE_INLINE bool isNull() const { + return variantIsNull(_data); + } + + FORCE_INLINE bool isUnbound() const { + return !_data; + } + + FORCE_INLINE size_t memoryUsage() const { + return _data ? _data->memoryUsage() : 0; + } + + FORCE_INLINE size_t nesting() const { + return variantNesting(_data); + } + + size_t size() const { + return variantSize(_data); + } + + template + FORCE_INLINE + typename enable_if::value && !is_same::value, + T>::type + as() const { + return Converter::fromJson(*this); + } + + template + FORCE_INLINE typename enable_if::value, const char*>::type + ARDUINOJSON_DEPRECATED("Replace as() with as()") + as() const { + return as(); + } + + template + FORCE_INLINE typename enable_if::value, char>::type + ARDUINOJSON_DEPRECATED( + "Support for char is deprecated, use int8_t or uint8_t instead") + as() const { + return static_cast(as()); + } + + template + FORCE_INLINE + typename enable_if::value && !is_same::value, + bool>::type + is() const { + return Converter::checkJson(*this); + } + + template + FORCE_INLINE typename enable_if::value, bool>::type + ARDUINOJSON_DEPRECATED("Replace is() with is()") + is() const { + return is(); + } + + template + FORCE_INLINE typename enable_if::value, bool>::type + ARDUINOJSON_DEPRECATED( + "Support for char is deprecated, use int8_t or uint8_t instead") + is() const { + return is(); + } + + template + FORCE_INLINE operator T() const { + return as(); + } + + FORCE_INLINE VariantConstRef operator[](size_t index) const { + return VariantConstRef(variantGetElement(_data, index)); + } + + // operator[](const std::string&) const + // operator[](const String&) const + template + FORCE_INLINE + typename enable_if::value, VariantConstRef>::type + operator[](const TString& key) const { + return VariantConstRef(variantGetMember(_data, adaptString(key))); + } + + // operator[](char*) const + // operator[](const char*) const + // operator[](const __FlashStringHelper*) const + template + FORCE_INLINE + typename enable_if::value, VariantConstRef>::type + operator[](TChar* key) const { + return VariantConstRef(variantGetMember(_data, adaptString(key))); + } + + protected: + const VariantData* getData() const { + return _data; + } + + private: + const VariantData* _data; +}; + +} // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantImpl.hpp b/src/ArduinoJson/Variant/VariantImpl.hpp index 203cae23..9b52006d 100644 --- a/src/ArduinoJson/Variant/VariantImpl.hpp +++ b/src/ArduinoJson/Variant/VariantImpl.hpp @@ -105,30 +105,55 @@ inline bool VariantData::copyFrom(const VariantData& src, MemoryPool* pool) { } } +template +inline VariantRef VariantRefBase::add() const { + return VariantRef(getPool(), variantAddElement(getOrCreateData(), getPool())); +} + +template +inline VariantRef VariantRefBase::getVariant() const { + return VariantRef(getPool(), getData()); +} + +template +inline VariantRef VariantRefBase::getOrCreateVariant() const { + return VariantRef(getPool(), getOrCreateData()); +} + +template template inline typename enable_if::value, ArrayRef>::type -VariantRef::to() const { - return ArrayRef(_pool, variantToArray(_data)); +VariantRefBase::to() const { + return ArrayRef(getPool(), variantToArray(getOrCreateData())); } +template template typename enable_if::value, ObjectRef>::type -VariantRef::to() const { - return ObjectRef(_pool, variantToObject(_data)); +VariantRefBase::to() const { + return ObjectRef(getPool(), variantToObject(getOrCreateData())); } +template template typename enable_if::value, VariantRef>::type -VariantRef::to() const { - variantSetNull(_data); +VariantRefBase::to() const { + variantSetNull(getOrCreateData()); return *this; } // Out of class definition to avoid #1560 -inline bool VariantRef::set(char value) const { +template +inline bool VariantRefBase::set(char value) const { return set(static_cast(value)); } +template +inline void convertToJson(const VariantRefBase& src, + VariantRef dst) { + dst.set(src.template as()); +} + // TODO: move somewhere else template bool CopyStringStoragePolicy::store(TAdaptedString str, MemoryPool* pool, diff --git a/src/ArduinoJson/Variant/VariantProxy.hpp b/src/ArduinoJson/Variant/VariantProxy.hpp index 3cba15e1..22d260f9 100644 --- a/src/ArduinoJson/Variant/VariantProxy.hpp +++ b/src/ArduinoJson/Variant/VariantProxy.hpp @@ -4,10 +4,8 @@ #pragma once -#include #include -#include -#include +#include #ifdef _MSC_VER # pragma warning(push) @@ -17,165 +15,33 @@ namespace ARDUINOJSON_NAMESPACE { template -class VariantProxy : public VariantShortcuts >, - public VariantOperators >, - public VariantTag { - friend class VariantAttorney; - +class VariantProxy : public VariantRefBase, + public VariantOperators > { public: - explicit FORCE_INLINE VariantProxy(TDataSource source) : _source(source) {} + explicit FORCE_INLINE VariantProxy(TDataSource source) + : VariantRefBase(source) {} - // Copy-constructor required because of user-defined copy-assignment operator - FORCE_INLINE VariantProxy(const VariantProxy& src) : _source(src._source) {} + // Copy-constructor required because of user-defined copy-assignment + // operator + FORCE_INLINE VariantProxy(const VariantProxy& src) + : VariantRefBase(src) {} FORCE_INLINE VariantProxy& operator=(const VariantProxy& src) { - getOrAddUpstreamVariant().set(src); + this->set(src); return *this; } template FORCE_INLINE VariantProxy& operator=(const T& src) { - getOrAddUpstreamVariant().set(src); + this->set(src); return *this; } template FORCE_INLINE VariantProxy& operator=(T* src) { - getOrAddUpstreamVariant().set(src); + this->set(src); return *this; } - - FORCE_INLINE void clear() const { - getUpstreamVariant().clear(); - } - - FORCE_INLINE bool isNull() const { - return getUpstreamVariantConst().isNull(); - } - - template - FORCE_INLINE typename enable_if::value && - !ConverterNeedsWriteableRef::value, - T>::type - as() const { - return getUpstreamVariantConst().template as(); - } - - template - FORCE_INLINE typename enable_if::value, T>::type - as() const { - return getUpstreamVariant().template as(); - } - - template - FORCE_INLINE typename enable_if::value, const char*>::type - ARDUINOJSON_DEPRECATED("Replace as() with as()") - as() const { - return as(); - } - - template - FORCE_INLINE operator T() const { - return as(); - } - - template - FORCE_INLINE typename VariantTo::type to() { - return getOrAddUpstreamVariant().template to(); - } - - template - FORCE_INLINE - typename enable_if::value, bool>::type - is() const { - return getUpstreamVariant().template is(); - } - - template - FORCE_INLINE - typename enable_if::value, bool>::type - is() const { - return getUpstreamVariantConst().template is(); - } - - FORCE_INLINE void shallowCopy(VariantConstRef value) { - getOrAddUpstreamVariant().shallowCopy(value); - } - - template - FORCE_INLINE bool set(const T& value) { - return getOrAddUpstreamVariant().set(value); - } - - template - FORCE_INLINE bool set(T* value) { - return getOrAddUpstreamVariant().set(value); - } - - FORCE_INLINE size_t size() const { - return getUpstreamVariantConst().size(); - } - - FORCE_INLINE size_t memoryUsage() const { - return getUpstreamVariantConst().memoryUsage(); - } - - FORCE_INLINE VariantRef add() const { - return getOrAddUpstreamVariant().add(); - } - - using ArrayShortcuts >::add; - - FORCE_INLINE void remove(size_t index) const { - getUpstreamVariant().remove(index); - } - // remove(char*) const - // remove(const char*) const - // remove(const __FlashStringHelper*) const - template - FORCE_INLINE typename enable_if::value>::type remove( - TChar* key) const { - getUpstreamVariant().remove(key); - } - // remove(const std::string&) const - // remove(const String&) const - template - FORCE_INLINE typename enable_if::value>::type remove( - const TString& key) const { - getUpstreamVariant().remove(key); - } - - protected: - FORCE_INLINE MemoryPool* getPool() const { - return _source.getPool(); - } - - FORCE_INLINE VariantData* getData() const { - return _source.getData(); - } - - FORCE_INLINE VariantData* getOrCreateData() const { - return _source.getOrCreateData(); - } - - private: - FORCE_INLINE VariantRef getUpstreamVariant() const { - return VariantRef(getPool(), getData()); - } - - FORCE_INLINE VariantConstRef getUpstreamVariantConst() const { - return VariantConstRef(getData()); - } - - FORCE_INLINE VariantRef getOrAddUpstreamVariant() const { - return VariantRef(getPool(), getOrCreateData()); - } - - friend void convertToJson(const VariantProxy& src, VariantRef dst) { - dst.set(src.getUpstreamVariantConst()); - } - - const TDataSource _source; }; } // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantRef.hpp b/src/ArduinoJson/Variant/VariantRef.hpp index 11b53c73..4f9005a6 100644 --- a/src/ArduinoJson/Variant/VariantRef.hpp +++ b/src/ArduinoJson/Variant/VariantRef.hpp @@ -4,310 +4,43 @@ #pragma once -#include -#include // for uint8_t - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace ARDUINOJSON_NAMESPACE { -// Forward declarations. -class ArrayRef; -class ObjectRef; - -// Contains the methods shared by VariantRef and VariantConstRef -template -class VariantRefBase : public VariantTag { +class VariantDataSource { public: - FORCE_INLINE bool isNull() const { - return variantIsNull(_data); - } + VariantDataSource() : _data(0), _pool(0) {} - FORCE_INLINE bool isUnbound() const { - return !_data; - } + VariantDataSource(MemoryPool* pool, VariantData* data) + : _data(data), _pool(pool) {} - FORCE_INLINE size_t memoryUsage() const { - return _data ? _data->memoryUsage() : 0; - } - - FORCE_INLINE size_t nesting() const { - return variantNesting(_data); - } - - size_t size() const { - return variantSize(_data); - } - - protected: - VariantRefBase(TData* data) : _data(data) {} - TData* _data; -}; - -class VariantConstRef : public VariantRefBase, - public VariantOperators, - public VariantShortcuts { - typedef VariantRefBase base_type; - - friend class VariantAttorney; - - public: - VariantConstRef() : base_type(0) {} - explicit VariantConstRef(const VariantData* data) : base_type(data) {} - - template - FORCE_INLINE - typename enable_if::value && !is_same::value, - T>::type - as() const { - return Converter::fromJson(*this); - } - - template - FORCE_INLINE typename enable_if::value, const char*>::type - ARDUINOJSON_DEPRECATED("Replace as() with as()") - as() const { - return as(); - } - - template - FORCE_INLINE typename enable_if::value, char>::type - ARDUINOJSON_DEPRECATED( - "Support for char is deprecated, use int8_t or uint8_t instead") - as() const { - return static_cast(as()); - } - - template - FORCE_INLINE - typename enable_if::value && !is_same::value, - bool>::type - is() const { - return Converter::checkJson(*this); - } - - template - FORCE_INLINE typename enable_if::value, bool>::type - ARDUINOJSON_DEPRECATED("Replace is() with is()") - is() const { - return is(); - } - - template - FORCE_INLINE typename enable_if::value, bool>::type - ARDUINOJSON_DEPRECATED( - "Support for char is deprecated, use int8_t or uint8_t instead") - is() const { - return is(); - } - - template - FORCE_INLINE operator T() const { - return as(); - } - - FORCE_INLINE VariantConstRef operator[](size_t index) const { - return VariantConstRef(variantGetElement(_data, index)); - } - - // operator[](const std::string&) const - // operator[](const String&) const - template - FORCE_INLINE - typename enable_if::value, VariantConstRef>::type - operator[](const TString& key) const { - return VariantConstRef(variantGetMember(_data, adaptString(key))); - } - - // operator[](char*) const - // operator[](const char*) const - // operator[](const __FlashStringHelper*) const - template - FORCE_INLINE - typename enable_if::value, VariantConstRef>::type - operator[](TChar* key) const { - return VariantConstRef(variantGetMember(_data, adaptString(key))); - } - - protected: - const VariantData* getData() const { - return _data; - } -}; - -// A variant that can be a any value serializable to a JSON value. -// -// It can be set to: -// - a boolean -// - a char, short, int or a long (signed or unsigned) -// - a string (const char*) -// - a reference to a ArrayRef or ObjectRef -class VariantRef : public VariantRefBase, - public VariantOperators, - public VariantShortcuts { - typedef VariantRefBase base_type; - - public: - // Intenal use only - FORCE_INLINE VariantRef(MemoryPool* pool, VariantData* data) - : base_type(data), _pool(pool) {} - - // Creates an uninitialized VariantRef - FORCE_INLINE VariantRef() : base_type(0), _pool(0) {} - - FORCE_INLINE void clear() const { - return variantSetNull(_data); - } - - template - FORCE_INLINE bool set(const T& value) const { - Converter::toJson(value, *this); - return _pool && !_pool->overflowed(); - } - - bool ARDUINOJSON_DEPRECATED( - "Support for char is deprecated, use int8_t or uint8_t instead") - set(char value) const; - - template - FORCE_INLINE bool set(T* value) const { - Converter::toJson(value, *this); - return _pool && !_pool->overflowed(); - } - - template - FORCE_INLINE - typename enable_if::value && !is_same::value, - T>::type - as() const { - return Converter::fromJson(*this); - } - - template - FORCE_INLINE typename enable_if::value, const char*>::type - ARDUINOJSON_DEPRECATED("Replace as() with as()") - as() const { - return as(); - } - - template - FORCE_INLINE typename enable_if::value, char>::type - ARDUINOJSON_DEPRECATED( - "Support for char is deprecated, use int8_t or uint8_t instead") - as() const { - return static_cast(as()); - } - - template - FORCE_INLINE - typename enable_if::value && !is_same::value, - bool>::type - is() const { - return Converter::checkJson(*this); - } - - template - FORCE_INLINE typename enable_if::value, bool>::type - ARDUINOJSON_DEPRECATED("Replace is() with is()") - is() const { - return is(); - } - - template - FORCE_INLINE typename enable_if::value, bool>::type - ARDUINOJSON_DEPRECATED( - "Support for char is deprecated, use int8_t or uint8_t instead") - is() const { - return is(); - } - - template - FORCE_INLINE operator T() const { - return as(); - } - - FORCE_INLINE operator VariantConstRef() const { - return VariantConstRef(_data); - } - - // Change the type of the variant - // - // ArrayRef to() - template - typename enable_if::value, ArrayRef>::type to() const; - // - // ObjectRef to() - template - typename enable_if::value, ObjectRef>::type to() const; - // - // ObjectRef to() - template - typename enable_if::value, VariantRef>::type to() - const; - - VariantRef add() const { - return VariantRef(_pool, variantAddElement(_data, _pool)); - } - - using ArrayShortcuts::add; - - FORCE_INLINE void remove(size_t index) const { - if (_data) - _data->remove(index); - } - // remove(char*) const - // remove(const char*) const - // remove(const __FlashStringHelper*) const - template - FORCE_INLINE typename enable_if::value>::type remove( - TChar* key) const { - if (_data) - _data->remove(adaptString(key)); - } - // remove(const std::string&) const - // remove(const String&) const - template - FORCE_INLINE typename enable_if::value>::type remove( - const TString& key) const { - if (_data) - _data->remove(adaptString(key)); - } - - inline void shallowCopy(VariantConstRef target) { - if (!_data) - return; - const VariantData* targetData = VariantAttorney::getData(target); - if (targetData) - *_data = *targetData; - else - _data->setNull(); - } - - MemoryPool* getPool() const { + FORCE_INLINE MemoryPool* getPool() const { return _pool; } - VariantData* getData() const { + FORCE_INLINE VariantData* getData() const { return _data; } - VariantData* getOrCreateData() const { + FORCE_INLINE VariantData* getOrCreateData() const { return _data; } private: + VariantData* _data; MemoryPool* _pool; }; +class VariantRef : public VariantRefBase, + public VariantOperators { + public: + VariantRef() : VariantRefBase(VariantDataSource()) {} + + VariantRef(MemoryPool* pool, VariantData* data) + : VariantRefBase(VariantDataSource(pool, data)) {} +}; + template <> struct Converter : private VariantAttorney { static void toJson(VariantRef src, VariantRef dst) { diff --git a/src/ArduinoJson/Variant/VariantRefBase.hpp b/src/ArduinoJson/Variant/VariantRefBase.hpp new file mode 100644 index 00000000..52ed96d5 --- /dev/null +++ b/src/ArduinoJson/Variant/VariantRefBase.hpp @@ -0,0 +1,215 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2022, Benoit BLANCHON +// MIT License + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace ARDUINOJSON_NAMESPACE { + +class VariantRef; + +template +class VariantRefBase : public VariantShortcuts >, + public VariantTag { + friend class VariantAttorney; + + public: + explicit FORCE_INLINE VariantRefBase(TDataSource source) : _source(source) {} + + FORCE_INLINE void clear() const { + variantSetNull(getData()); + } + + FORCE_INLINE bool isNull() const { + return variantIsNull(getData()); + } + + FORCE_INLINE bool isUnbound() const { + return !getData(); + } + + template + FORCE_INLINE typename enable_if::value && + !is_same::value && + !ConverterNeedsWriteableRef::value, + T>::type + as() const { + return Converter::fromJson(getVariantConst()); + } + + template + FORCE_INLINE typename enable_if::value, T>::type + as() const { + return Converter::fromJson(getVariant()); + } + + template + FORCE_INLINE typename enable_if::value, const char*>::type + ARDUINOJSON_DEPRECATED("Replace as() with as()") + as() const { + return as(); + } + + template + FORCE_INLINE typename enable_if::value, char>::type + ARDUINOJSON_DEPRECATED( + "Support for char is deprecated, use int8_t or uint8_t instead") + as() const { + return static_cast(as()); + } + + template + FORCE_INLINE operator T() const { + return as(); + } + + // Change the type of the variant + // + // ArrayRef to() + template + typename enable_if::value, ArrayRef>::type to() const; + // + // ObjectRef to() + template + typename enable_if::value, ObjectRef>::type to() const; + // + // VariantRef to() + template + typename enable_if::value, VariantRef>::type to() + const; + + template + FORCE_INLINE + typename enable_if::value, bool>::type + is() const { + return Converter::checkJson(getVariant()); + } + + template + FORCE_INLINE typename enable_if::value && + !is_same::value && + !is_same::value, + bool>::type + is() const { + return Converter::checkJson(getVariantConst()); + } + + template + FORCE_INLINE typename enable_if::value, bool>::type + ARDUINOJSON_DEPRECATED("Replace is() with is()") + is() const { + return is(); + } + + template + FORCE_INLINE typename enable_if::value, bool>::type + ARDUINOJSON_DEPRECATED( + "Support for char is deprecated, use int8_t or uint8_t instead") + is() const { + return is(); + } + + FORCE_INLINE void shallowCopy(VariantConstRef target) { + VariantData* data = getOrCreateData(); + if (!data) + return; + const VariantData* targetData = VariantAttorney::getData(target); + if (targetData) + *data = *targetData; + else + data->setNull(); + } + + template + FORCE_INLINE bool set(const T& value) const { + Converter::toJson(value, getOrCreateVariant()); + MemoryPool* pool = getPool(); + return pool && !pool->overflowed(); + } + + template + FORCE_INLINE bool set(T* value) const { + Converter::toJson(value, getOrCreateVariant()); + MemoryPool* pool = getPool(); + return pool && !pool->overflowed(); + } + + bool ARDUINOJSON_DEPRECATED( + "Support for char is deprecated, use int8_t or uint8_t instead") + set(char value) const; + + FORCE_INLINE size_t size() const { + return variantSize(getData()); + } + + FORCE_INLINE size_t memoryUsage() const { + VariantData* data = getData(); + return data ? data->memoryUsage() : 0; + } + + FORCE_INLINE size_t nesting() const { + return variantNesting(getData()); + } + + FORCE_INLINE VariantRef add() const; + + using ArrayShortcuts >::add; + + FORCE_INLINE void remove(size_t index) const { + VariantData* data = getData(); + if (data) + data->remove(index); + } + // remove(char*) const + // remove(const char*) const + // remove(const __FlashStringHelper*) const + template + FORCE_INLINE typename enable_if::value>::type remove( + TChar* key) const { + VariantData* data = getData(); + if (data) + data->remove(adaptString(key)); + } + // remove(const std::string&) const + // remove(const String&) const + template + FORCE_INLINE typename enable_if::value>::type remove( + const TString& key) const { + VariantData* data = getData(); + if (data) + data->remove(adaptString(key)); + } + + protected: + FORCE_INLINE MemoryPool* getPool() const { + return _source.getPool(); + } + + FORCE_INLINE VariantData* getData() const { + return _source.getData(); + } + + FORCE_INLINE VariantData* getOrCreateData() const { + return _source.getOrCreateData(); + } + + private: + FORCE_INLINE VariantRef getVariant() const; + + FORCE_INLINE VariantConstRef getVariantConst() const { + return VariantConstRef(getData()); + } + + FORCE_INLINE VariantRef getOrCreateVariant() const; + + TDataSource _source; +}; + +} // namespace ARDUINOJSON_NAMESPACE