diff --git a/src/ArduinoJson/Array/ArrayRef.hpp b/src/ArduinoJson/Array/ArrayRef.hpp index 2737c571..e890bc95 100644 --- a/src/ArduinoJson/Array/ArrayRef.hpp +++ b/src/ArduinoJson/Array/ArrayRef.hpp @@ -106,10 +106,10 @@ class ArrayConstRef : public ArrayRefBase, } FORCE_INLINE VariantConstRef operator[](size_t index) const { - return getElement(index); + return getElementConst(index); } - FORCE_INLINE VariantConstRef getElement(size_t index) const { + FORCE_INLINE VariantConstRef getElementConst(size_t index) const { return VariantConstRef(_data ? _data->getElement(index) : 0); } }; @@ -170,6 +170,11 @@ class ArrayRef : public ArrayRefBase, return VariantRef(_pool, _data ? _data->getElement(index) : 0); } + // Gets the value at the specified index. + FORCE_INLINE VariantConstRef getElementConst(size_t index) const { + return VariantConstRef(_data ? _data->getElement(index) : 0); + } + // Removes element at specified position. FORCE_INLINE void remove(iterator it) const { if (!_data) diff --git a/src/ArduinoJson/Array/ElementProxy.hpp b/src/ArduinoJson/Array/ElementProxy.hpp index 821cfba3..fe2d71cc 100644 --- a/src/ArduinoJson/Array/ElementProxy.hpp +++ b/src/ArduinoJson/Array/ElementProxy.hpp @@ -61,12 +61,20 @@ class ElementProxy : public VariantOperators >, } FORCE_INLINE bool isNull() const { - return getUpstreamElement().isNull(); + return getUpstreamElementConst().isNull(); } template - FORCE_INLINE typename enable_if::value, T>::type as() - const { + FORCE_INLINE typename enable_if::value && + !ConverterNeedsWriteableRef::value, + T>::type + as() const { + return getUpstreamElementConst().template as(); + } + + template + FORCE_INLINE typename enable_if::value, T>::type + as() const { return getUpstreamElement().template as(); } @@ -79,14 +87,23 @@ class ElementProxy : public VariantOperators >, template FORCE_INLINE operator T() const { - return getUpstreamElement(); + return as(); } template - FORCE_INLINE bool is() const { + FORCE_INLINE + typename enable_if::value, bool>::type + is() const { return getUpstreamElement().template is(); } + template + FORCE_INLINE + typename enable_if::value, bool>::type + is() const { + return getUpstreamElementConst().template is(); + } + template FORCE_INLINE typename VariantTo::type to() const { return getOrAddUpstreamElement().template to(); @@ -111,15 +128,15 @@ class ElementProxy : public VariantOperators >, template typename TVisitor::result_type accept(TVisitor& visitor) const { - return getUpstreamElement().accept(visitor); + return getUpstreamElementConst().accept(visitor); } FORCE_INLINE size_t size() const { - return getUpstreamElement().size(); + return getUpstreamElementConst().size(); } FORCE_INLINE size_t memoryUsage() const { - return getUpstreamElement().memoryUsage(); + return getUpstreamElementConst().memoryUsage(); } template @@ -132,6 +149,16 @@ class ElementProxy : public VariantOperators >, return getUpstreamElement().getMember(key); } + template + VariantConstRef getMemberConst(TNestedKey* key) const { + return getUpstreamElementConst().getMemberConst(key); + } + + template + VariantConstRef getMemberConst(const TNestedKey& key) const { + return getUpstreamElementConst().getMemberConst(key); + } + template VariantRef getOrAddMember(TNestedKey* key) const { return getOrAddUpstreamElement().getOrAddMember(key); @@ -150,6 +177,10 @@ class ElementProxy : public VariantOperators >, return getOrAddUpstreamElement().getElement(index); } + VariantConstRef getElementConst(size_t index) const { + return getUpstreamElementConst().getElementConst(index); + } + VariantRef getOrAddElement(size_t index) const { return getOrAddUpstreamElement().getOrAddElement(index); } @@ -178,12 +209,16 @@ class ElementProxy : public VariantOperators >, return _array.getElement(_index); } + FORCE_INLINE VariantConstRef getUpstreamElementConst() const { + return _array.getElementConst(_index); + } + FORCE_INLINE VariantRef getOrAddUpstreamElement() const { return _array.getOrAddElement(_index); } friend void convertToJson(const this_type& src, VariantRef dst) { - dst.set(src.getUpstreamElement()); + dst.set(src.getUpstreamElementConst()); } TArray _array; diff --git a/src/ArduinoJson/Document/JsonDocument.hpp b/src/ArduinoJson/Document/JsonDocument.hpp index d9c4eb5b..d1d7cb63 100644 --- a/src/ArduinoJson/Document/JsonDocument.hpp +++ b/src/ArduinoJson/Document/JsonDocument.hpp @@ -140,14 +140,14 @@ class JsonDocument : public Visitable, // containsKey(const __FlashStringHelper*) const template bool containsKey(TChar* key) const { - return !getMember(key).isUnbound(); + return !getMemberConst(key).isUnbound(); } // containsKey(const std::string&) const // containsKey(const String&) const template bool containsKey(const TString& key) const { - return !getMember(key).isUnbound(); + return !getMemberConst(key).isUnbound(); } // operator[](const std::string&) @@ -175,7 +175,7 @@ class JsonDocument : public Visitable, FORCE_INLINE typename enable_if::value, VariantConstRef>::type operator[](const TString& key) const { - return getMember(key); + return getMemberConst(key); } // operator[](char*) const @@ -185,7 +185,7 @@ class JsonDocument : public Visitable, FORCE_INLINE typename enable_if::value, VariantConstRef>::type operator[](TChar* key) const { - return getMember(key); + return getMemberConst(key); } FORCE_INLINE ElementProxy operator[](size_t index) { @@ -193,14 +193,14 @@ class JsonDocument : public Visitable, } FORCE_INLINE VariantConstRef operator[](size_t index) const { - return getElement(index); + return getElementConst(index); } FORCE_INLINE VariantRef getElement(size_t index) { return VariantRef(&_pool, _data.getElement(index)); } - FORCE_INLINE VariantConstRef getElement(size_t index) const { + FORCE_INLINE VariantConstRef getElementConst(size_t index) const { return VariantConstRef(_data.getElement(index)); } @@ -208,20 +208,20 @@ class JsonDocument : public Visitable, return VariantRef(&_pool, _data.getOrAddElement(index, &_pool)); } - // JsonVariantConst getMember(char*) const - // JsonVariantConst getMember(const char*) const - // JsonVariantConst getMember(const __FlashStringHelper*) const + // JsonVariantConst getMemberConst(char*) const + // JsonVariantConst getMemberConst(const char*) const + // JsonVariantConst getMemberConst(const __FlashStringHelper*) const template - FORCE_INLINE VariantConstRef getMember(TChar* key) const { + FORCE_INLINE VariantConstRef getMemberConst(TChar* key) const { return VariantConstRef(_data.getMember(adaptString(key))); } - // JsonVariantConst getMember(const std::string&) const - // JsonVariantConst getMember(const String&) const + // JsonVariantConst getMemberConst(const std::string&) const + // JsonVariantConst getMemberConst(const String&) const template FORCE_INLINE typename enable_if::value, VariantConstRef>::type - getMember(const TString& key) const { + getMemberConst(const TString& key) const { return VariantConstRef(_data.getMember(adaptString(key))); } diff --git a/src/ArduinoJson/Object/MemberProxy.hpp b/src/ArduinoJson/Object/MemberProxy.hpp index 9a1bc83f..b0cbd9d2 100644 --- a/src/ArduinoJson/Object/MemberProxy.hpp +++ b/src/ArduinoJson/Object/MemberProxy.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -35,7 +36,7 @@ class MemberProxy : public VariantOperators >, : _object(src._object), _key(src._key) {} FORCE_INLINE operator VariantConstRef() const { - return getUpstreamMember(); + return getUpstreamMemberConst(); } FORCE_INLINE this_type &operator=(const this_type &src) { @@ -64,12 +65,20 @@ class MemberProxy : public VariantOperators >, } FORCE_INLINE bool isNull() const { - return getUpstreamMember().isNull(); + return getUpstreamMemberConst().isNull(); } template - FORCE_INLINE typename enable_if::value, T>::type as() - const { + FORCE_INLINE typename enable_if::value && + !ConverterNeedsWriteableRef::value, + T>::type + as() const { + return getUpstreamMemberConst().template as(); + } + + template + FORCE_INLINE typename enable_if::value, T>::type + as() const { return getUpstreamMember().template as(); } @@ -82,20 +91,29 @@ class MemberProxy : public VariantOperators >, template FORCE_INLINE operator T() const { - return getUpstreamMember(); + return as(); } - template - FORCE_INLINE bool is() const { - return getUpstreamMember().template is(); + template + FORCE_INLINE + typename enable_if::value, bool>::type + is() const { + return getUpstreamMember().template is(); + } + + template + FORCE_INLINE + typename enable_if::value, bool>::type + is() const { + return getUpstreamMemberConst().template is(); } FORCE_INLINE size_t size() const { - return getUpstreamMember().size(); + return getUpstreamMemberConst().size(); } FORCE_INLINE size_t memoryUsage() const { - return getUpstreamMember().memoryUsage(); + return getUpstreamMemberConst().memoryUsage(); } FORCE_INLINE void remove(size_t index) const { @@ -137,7 +155,7 @@ class MemberProxy : public VariantOperators >, template typename TVisitor::result_type accept(TVisitor &visitor) const { - return getUpstreamMember().accept(visitor); + return getUpstreamMemberConst().accept(visitor); } FORCE_INLINE VariantRef addElement() const { @@ -148,6 +166,10 @@ class MemberProxy : public VariantOperators >, return getUpstreamMember().getElement(index); } + FORCE_INLINE VariantConstRef getElementConst(size_t index) const { + return getUpstreamMemberConst().getElementConst(index); + } + FORCE_INLINE VariantRef getOrAddElement(size_t index) const { return getOrAddUpstreamMember().getOrAddElement(index); } @@ -167,6 +189,21 @@ class MemberProxy : public VariantOperators >, return getUpstreamMember().getMember(key); } + // getMemberConst(char*) const + // getMemberConst(const char*) const + // getMemberConst(const __FlashStringHelper*) const + template + FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const { + return getUpstreamMemberConst().getMemberConst(key); + } + + // getMemberConst(const std::string&) const + // getMemberConst(const String&) const + template + FORCE_INLINE VariantConstRef getMemberConst(const TString &key) const { + return getUpstreamMemberConst().getMemberConst(key); + } + // getOrAddMember(char*) const // getOrAddMember(const char*) const // getOrAddMember(const __FlashStringHelper*) const @@ -187,12 +224,16 @@ class MemberProxy : public VariantOperators >, return _object.getMember(_key); } + FORCE_INLINE VariantConstRef getUpstreamMemberConst() const { + return _object.getMemberConst(_key); + } + FORCE_INLINE VariantRef getOrAddUpstreamMember() const { return _object.getOrAddMember(_key); } friend void convertToJson(const this_type &src, VariantRef dst) { - dst.set(src.getUpstreamMember()); + dst.set(src.getUpstreamMemberConst()); } TObject _object; diff --git a/src/ArduinoJson/Object/ObjectImpl.hpp b/src/ArduinoJson/Object/ObjectImpl.hpp index 66793a77..ba327628 100644 --- a/src/ArduinoJson/Object/ObjectImpl.hpp +++ b/src/ArduinoJson/Object/ObjectImpl.hpp @@ -40,14 +40,14 @@ template template inline typename enable_if::value, bool>::type ObjectShortcuts::containsKey(const TString& key) const { - return !impl()->getMember(key).isUnbound(); + return !impl()->getMemberConst(key).isUnbound(); } template template inline typename enable_if::value, bool>::type ObjectShortcuts::containsKey(TChar* key) const { - return !impl()->getMember(key).isUnbound(); + return !impl()->getMemberConst(key).isUnbound(); } template diff --git a/src/ArduinoJson/Object/ObjectRef.hpp b/src/ArduinoJson/Object/ObjectRef.hpp index 4b368a8a..934452c1 100644 --- a/src/ArduinoJson/Object/ObjectRef.hpp +++ b/src/ArduinoJson/Object/ObjectRef.hpp @@ -81,7 +81,7 @@ class ObjectConstRef : public ObjectRefBase, // containsKey(const String&) const template FORCE_INLINE bool containsKey(const TString& key) const { - return !getMember(key).isUnbound(); + return !getMemberConst(key).isUnbound(); } // containsKey(char*) const @@ -89,22 +89,22 @@ class ObjectConstRef : public ObjectRefBase, // containsKey(const __FlashStringHelper*) const template FORCE_INLINE bool containsKey(TChar* key) const { - return !getMember(key).isUnbound(); + return !getMemberConst(key).isUnbound(); } - // getMember(const std::string&) const - // getMember(const String&) const + // getMemberConst(const std::string&) const + // getMemberConst(const String&) const template - FORCE_INLINE VariantConstRef getMember(const TString& key) const { - return get_impl(adaptString(key)); + FORCE_INLINE VariantConstRef getMemberConst(const TString& key) const { + return VariantConstRef(objectGetMember(_data, adaptString(key))); } - // getMember(char*) const - // getMember(const char*) const - // getMember(const __FlashStringHelper*) const + // getMemberConst(char*) const + // getMemberConst(const char*) const + // getMemberConst(const __FlashStringHelper*) const template - FORCE_INLINE VariantConstRef getMember(TChar* key) const { - return get_impl(adaptString(key)); + FORCE_INLINE VariantConstRef getMemberConst(TChar* key) const { + return VariantConstRef(objectGetMember(_data, adaptString(key))); } // operator[](const std::string&) const @@ -113,7 +113,7 @@ class ObjectConstRef : public ObjectRefBase, FORCE_INLINE typename enable_if::value, VariantConstRef>::type operator[](const TString& key) const { - return get_impl(adaptString(key)); + return getMemberConst(key); } // operator[](char*) const @@ -123,7 +123,7 @@ class ObjectConstRef : public ObjectRefBase, FORCE_INLINE typename enable_if::value, VariantConstRef>::type operator[](TChar* key) const { - return get_impl(adaptString(key)); + return getMemberConst(key); } FORCE_INLINE bool operator==(ObjectConstRef rhs) const { @@ -143,10 +143,6 @@ class ObjectConstRef : public ObjectRefBase, } private: - template - FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const { - return VariantConstRef(objectGetMember(_data, key)); - } }; class ObjectRef : public ObjectRefBase, @@ -207,6 +203,21 @@ class ObjectRef : public ObjectRefBase, return VariantRef(_pool, objectGetMember(_data, adaptString(key))); } + // getMemberConst(const std::string&) const + // getMemberConst(const String&) const + template + FORCE_INLINE VariantConstRef getMemberConst(const TString& key) const { + return VariantConstRef(objectGetMember(_data, adaptString(key))); + } + + // getMemberConst(char*) const + // getMemberConst(const char*) const + // getMemberConst(const __FlashStringHelper*) const + template + FORCE_INLINE VariantConstRef getMemberConst(TChar* key) const { + return VariantConstRef(objectGetMember(_data, adaptString(key))); + } + // getOrAddMember(const std::string&) const // getOrAddMember(const String&) const template diff --git a/src/ArduinoJson/Variant/Converter.hpp b/src/ArduinoJson/Variant/Converter.hpp index f9ce9ab7..72f9dfd4 100644 --- a/src/ArduinoJson/Variant/Converter.hpp +++ b/src/ArduinoJson/Variant/Converter.hpp @@ -14,4 +14,7 @@ template class InvalidConversion; // Error here? See https://arduinojson.org/v6/invalid-conversion/ // clang-format on +template +struct ConverterNeedsWriteableRef; + } // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantRef.hpp b/src/ArduinoJson/Variant/VariantRef.hpp index fb80de23..a26e62a3 100644 --- a/src/ArduinoJson/Variant/VariantRef.hpp +++ b/src/ArduinoJson/Variant/VariantRef.hpp @@ -123,27 +123,27 @@ class VariantConstRef : public VariantRefBase, return as(); } - FORCE_INLINE VariantConstRef getElement(size_t index) const { + FORCE_INLINE VariantConstRef getElementConst(size_t index) const { return VariantConstRef(_data != 0 ? _data->getElement(index) : 0); } FORCE_INLINE VariantConstRef operator[](size_t index) const { - return getElement(index); + return getElementConst(index); } - // getMember(const std::string&) const - // getMember(const String&) const + // getMemberConst(const std::string&) const + // getMemberConst(const String&) const template - FORCE_INLINE VariantConstRef getMember(const TString &key) const { + FORCE_INLINE VariantConstRef getMemberConst(const TString &key) const { return VariantConstRef( objectGetMember(variantAsObject(_data), adaptString(key))); } - // getMember(char*) const - // getMember(const char*) const - // getMember(const __FlashStringHelper*) const + // getMemberConst(char*) const + // getMemberConst(const char*) const + // getMemberConst(const __FlashStringHelper*) const template - FORCE_INLINE VariantConstRef getMember(TChar *key) const { + FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const { const CollectionData *obj = variantAsObject(_data); return VariantConstRef(obj ? obj->getMember(adaptString(key)) : 0); } @@ -154,7 +154,7 @@ class VariantConstRef : public VariantRefBase, FORCE_INLINE typename enable_if::value, VariantConstRef>::type operator[](const TString &key) const { - return getMember(key); + return getMemberConst(key); } // operator[](char*) const @@ -164,7 +164,7 @@ class VariantConstRef : public VariantRefBase, FORCE_INLINE typename enable_if::value, VariantConstRef>::type operator[](TChar *key) const { - return getMember(key); + return getMemberConst(key); } }; @@ -292,6 +292,10 @@ class VariantRef : public VariantRefBase, return VariantRef(_pool, _data != 0 ? _data->getElement(index) : 0); } + FORCE_INLINE VariantConstRef getElementConst(size_t index) const { + return VariantConstRef(_data != 0 ? _data->getElement(index) : 0); + } + FORCE_INLINE VariantRef getOrAddElement(size_t index) const { return VariantRef(_pool, variantGetOrAddElement(_data, index, _pool)); } @@ -313,6 +317,22 @@ class VariantRef : public VariantRefBase, _data != 0 ? _data->getMember(adaptString(key)) : 0); } + // getMemberConst(const char*) const + // getMemberConst(const __FlashStringHelper*) const + template + FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const { + return VariantConstRef(_data ? _data->getMember(adaptString(key)) : 0); + } + + // getMemberConst(const std::string&) const + // getMemberConst(const String&) const + template + FORCE_INLINE + typename enable_if::value, VariantConstRef>::type + getMemberConst(const TString &key) const { + return VariantConstRef(_data ? _data->getMember(adaptString(key)) : 0); + } + // getOrAddMember(char*) const // getOrAddMember(const char*) const // getOrAddMember(const __FlashStringHelper*) const