Add getMemberConst() and getElementConst() (6780,5602)

This commit is contained in:
Benoit Blanchon
2022-03-31 11:59:00 +02:00
parent 5fcdf1739e
commit c4d487b6cf
10 changed files with 164 additions and 59 deletions

View File

@@ -154,7 +154,8 @@ TEST_CASE("JsonVariant::operator[]") {
doc2.add(42); doc2.add(42);
var.link(doc2); var.link(doc2);
CHECK(var[0].as<int>() == 42); bool ok = var[0].as<int>() == 42;
CHECK(ok);
} }
SECTION("set value to linked array") { SECTION("set value to linked array") {

View File

@@ -87,10 +87,10 @@ class ArrayConstRef : public ArrayRefBase<const CollectionData>,
} }
FORCE_INLINE VariantConstRef operator[](size_t index) const { 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); return VariantConstRef(_data ? _data->getElement(index) : 0);
} }
}; };
@@ -151,6 +151,11 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
return VariantRef(_pool, _data ? _data->getElement(index) : 0); 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. // Removes element at specified position.
FORCE_INLINE void remove(iterator it) const { FORCE_INLINE void remove(iterator it) const {
if (!_data) if (!_data)

View File

@@ -65,8 +65,16 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
} }
template <typename T> template <typename T>
FORCE_INLINE typename enable_if<!is_same<T, char*>::value, T>::type as() FORCE_INLINE typename enable_if<!is_same<T, char*>::value &&
const { !ConverterNeedsWriteableRef<T>::value,
T>::type
as() const {
return getUpstreamElementConst().template as<T>();
}
template <typename T>
FORCE_INLINE typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type
as() const {
return getUpstreamElement().template as<T>(); return getUpstreamElement().template as<T>();
} }
@@ -115,7 +123,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
template <typename TVisitor> template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor& visitor) const { typename TVisitor::result_type accept(TVisitor& visitor) const {
return getUpstreamElement().accept(visitor); return getUpstreamElementConst().accept(visitor);
} }
FORCE_INLINE size_t size() const { FORCE_INLINE size_t size() const {
@@ -136,6 +144,16 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
return getUpstreamElement().getMember(key); return getUpstreamElement().getMember(key);
} }
template <typename TNestedKey>
VariantConstRef getMemberConst(TNestedKey* key) const {
return getUpstreamElementConst().getMemberConst(key);
}
template <typename TNestedKey>
VariantConstRef getMemberConst(const TNestedKey& key) const {
return getUpstreamElementConst().getMemberConst(key);
}
template <typename TNestedKey> template <typename TNestedKey>
VariantRef getOrAddMember(TNestedKey* key) const { VariantRef getOrAddMember(TNestedKey* key) const {
return getOrAddUpstreamElement().getOrAddMember(key); return getOrAddUpstreamElement().getOrAddMember(key);
@@ -154,6 +172,10 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
return getOrAddUpstreamElement().getElement(index); return getOrAddUpstreamElement().getElement(index);
} }
VariantConstRef getElementConst(size_t index) const {
return getUpstreamElementConst().getElementConst(index);
}
VariantRef getOrAddElement(size_t index) const { VariantRef getOrAddElement(size_t index) const {
return getOrAddUpstreamElement().getOrAddElement(index); return getOrAddUpstreamElement().getOrAddElement(index);
} }
@@ -182,6 +204,10 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
return _array.getElement(_index); return _array.getElement(_index);
} }
FORCE_INLINE VariantConstRef getUpstreamElementConst() const {
return _array.getElementConst(_index);
}
FORCE_INLINE VariantRef getOrAddUpstreamElement() const { FORCE_INLINE VariantRef getOrAddUpstreamElement() const {
return _array.getOrAddElement(_index); return _array.getOrAddElement(_index);
} }

View File

@@ -140,14 +140,14 @@ class JsonDocument : public Visitable,
// containsKey(const __FlashStringHelper*) const // containsKey(const __FlashStringHelper*) const
template <typename TChar> template <typename TChar>
bool containsKey(TChar* key) const { bool containsKey(TChar* key) const {
return !getMember(key).isUnbound(); return !getMemberConst(key).isUnbound();
} }
// containsKey(const std::string&) const // containsKey(const std::string&) const
// containsKey(const String&) const // containsKey(const String&) const
template <typename TString> template <typename TString>
bool containsKey(const TString& key) const { bool containsKey(const TString& key) const {
return !getMember(key).isUnbound(); return !getMemberConst(key).isUnbound();
} }
// operator[](const std::string&) // operator[](const std::string&)
@@ -175,7 +175,7 @@ class JsonDocument : public Visitable,
FORCE_INLINE FORCE_INLINE
typename enable_if<IsString<TString>::value, VariantConstRef>::type typename enable_if<IsString<TString>::value, VariantConstRef>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return getMember(key); return getMemberConst(key);
} }
// operator[](char*) const // operator[](char*) const
@@ -185,7 +185,7 @@ class JsonDocument : public Visitable,
FORCE_INLINE FORCE_INLINE
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return getMember(key); return getMemberConst(key);
} }
FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) { FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
@@ -193,14 +193,14 @@ class JsonDocument : public Visitable,
} }
FORCE_INLINE VariantConstRef operator[](size_t index) const { FORCE_INLINE VariantConstRef operator[](size_t index) const {
return getElement(index); return getElementConst(index);
} }
FORCE_INLINE VariantRef getElement(size_t index) { FORCE_INLINE VariantRef getElement(size_t index) {
return VariantRef(&_pool, _data.getElement(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)); return VariantConstRef(_data.getElement(index));
} }
@@ -208,20 +208,20 @@ class JsonDocument : public Visitable,
return VariantRef(&_pool, _data.getOrAddElement(index, &_pool)); return VariantRef(&_pool, _data.getOrAddElement(index, &_pool));
} }
// JsonVariantConst getMember(char*) const // JsonVariantConst getMemberConst(char*) const
// JsonVariantConst getMember(const char*) const // JsonVariantConst getMemberConst(const char*) const
// JsonVariantConst getMember(const __FlashStringHelper*) const // JsonVariantConst getMemberConst(const __FlashStringHelper*) const
template <typename TChar> template <typename TChar>
FORCE_INLINE VariantConstRef getMember(TChar* key) const { FORCE_INLINE VariantConstRef getMemberConst(TChar* key) const {
return VariantConstRef(_data.getMember(adaptString(key))); return VariantConstRef(_data.getMember(adaptString(key)));
} }
// JsonVariantConst getMember(const std::string&) const // JsonVariantConst getMemberConst(const std::string&) const
// JsonVariantConst getMember(const String&) const // JsonVariantConst getMemberConst(const String&) const
template <typename TString> template <typename TString>
FORCE_INLINE FORCE_INLINE
typename enable_if<IsString<TString>::value, VariantConstRef>::type typename enable_if<IsString<TString>::value, VariantConstRef>::type
getMember(const TString& key) const { getMemberConst(const TString& key) const {
return VariantConstRef(_data.getMember(adaptString(key))); return VariantConstRef(_data.getMember(adaptString(key)));
} }

View File

@@ -6,6 +6,7 @@
#include <ArduinoJson/Configuration.hpp> #include <ArduinoJson/Configuration.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp> #include <ArduinoJson/Polyfills/type_traits.hpp>
#include <ArduinoJson/Variant/Converter.hpp>
#include <ArduinoJson/Variant/VariantOperators.hpp> #include <ArduinoJson/Variant/VariantOperators.hpp>
#include <ArduinoJson/Variant/VariantRef.hpp> #include <ArduinoJson/Variant/VariantRef.hpp>
#include <ArduinoJson/Variant/VariantShortcuts.hpp> #include <ArduinoJson/Variant/VariantShortcuts.hpp>
@@ -68,8 +69,16 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
} }
template <typename T> template <typename T>
FORCE_INLINE typename enable_if<!is_same<T, char *>::value, T>::type as() FORCE_INLINE typename enable_if<!is_same<T, char *>::value &&
const { !ConverterNeedsWriteableRef<T>::value,
T>::type
as() const {
return getUpstreamMemberConst().template as<T>();
}
template <typename T>
FORCE_INLINE typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type
as() const {
return getUpstreamMember().template as<T>(); return getUpstreamMember().template as<T>();
} }
@@ -141,7 +150,7 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
template <typename TVisitor> template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor &visitor) const { typename TVisitor::result_type accept(TVisitor &visitor) const {
return getUpstreamMember().accept(visitor); return getUpstreamMemberConst().accept(visitor);
} }
FORCE_INLINE VariantRef addElement() const { FORCE_INLINE VariantRef addElement() const {
@@ -152,6 +161,10 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return getUpstreamMember().getElement(index); return getUpstreamMember().getElement(index);
} }
FORCE_INLINE VariantConstRef getElementConst(size_t index) const {
return getUpstreamMemberConst().getElementConst(index);
}
FORCE_INLINE VariantRef getOrAddElement(size_t index) const { FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
return getOrAddUpstreamMember().getOrAddElement(index); return getOrAddUpstreamMember().getOrAddElement(index);
} }
@@ -171,6 +184,21 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return getUpstreamMember().getMember(key); return getUpstreamMember().getMember(key);
} }
// getMemberConst(char*) const
// getMemberConst(const char*) const
// getMemberConst(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const {
return getUpstreamMember().getMemberConst(key);
}
// getMemberConst(const std::string&) const
// getMemberConst(const String&) const
template <typename TString>
FORCE_INLINE VariantConstRef getMemberConst(const TString &key) const {
return getUpstreamMember().getMemberConst(key);
}
// getOrAddMember(char*) const // getOrAddMember(char*) const
// getOrAddMember(const char*) const // getOrAddMember(const char*) const
// getOrAddMember(const __FlashStringHelper*) const // getOrAddMember(const __FlashStringHelper*) const
@@ -191,6 +219,10 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return _object.getMember(_key); return _object.getMember(_key);
} }
FORCE_INLINE VariantConstRef getUpstreamMemberConst() const {
return _object.getMemberConst(_key);
}
FORCE_INLINE VariantRef getOrAddUpstreamMember() const { FORCE_INLINE VariantRef getOrAddUpstreamMember() const {
return _object.getOrAddMember(_key); return _object.getOrAddMember(_key);
} }

View File

@@ -40,14 +40,14 @@ template <typename TObject>
template <typename TString> template <typename TString>
inline typename enable_if<IsString<TString>::value, bool>::type inline typename enable_if<IsString<TString>::value, bool>::type
ObjectShortcuts<TObject>::containsKey(const TString& key) const { ObjectShortcuts<TObject>::containsKey(const TString& key) const {
return !impl()->getMember(key).isUnbound(); return !impl()->getMemberConst(key).isUnbound();
} }
template <typename TObject> template <typename TObject>
template <typename TChar> template <typename TChar>
inline typename enable_if<IsString<TChar*>::value, bool>::type inline typename enable_if<IsString<TChar*>::value, bool>::type
ObjectShortcuts<TObject>::containsKey(TChar* key) const { ObjectShortcuts<TObject>::containsKey(TChar* key) const {
return !impl()->getMember(key).isUnbound(); return !impl()->getMemberConst(key).isUnbound();
} }
template <typename TObject> template <typename TObject>

View File

@@ -81,7 +81,7 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
// containsKey(const String&) const // containsKey(const String&) const
template <typename TString> template <typename TString>
FORCE_INLINE bool containsKey(const TString& key) const { FORCE_INLINE bool containsKey(const TString& key) const {
return !getMember(key).isUnbound(); return !getMemberConst(key).isUnbound();
} }
// containsKey(char*) const // containsKey(char*) const
@@ -89,22 +89,22 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
// containsKey(const __FlashStringHelper*) const // containsKey(const __FlashStringHelper*) const
template <typename TChar> template <typename TChar>
FORCE_INLINE bool containsKey(TChar* key) const { FORCE_INLINE bool containsKey(TChar* key) const {
return !getMember(key).isUnbound(); return !getMemberConst(key).isUnbound();
} }
// getMember(const std::string&) const // getMemberConst(const std::string&) const
// getMember(const String&) const // getMemberConst(const String&) const
template <typename TString> template <typename TString>
FORCE_INLINE VariantConstRef getMember(const TString& key) const { FORCE_INLINE VariantConstRef getMemberConst(const TString& key) const {
return get_impl(adaptString(key)); return VariantConstRef(objectGetMember(_data, adaptString(key)));
} }
// getMember(char*) const // getMemberConst(char*) const
// getMember(const char*) const // getMemberConst(const char*) const
// getMember(const __FlashStringHelper*) const // getMemberConst(const __FlashStringHelper*) const
template <typename TChar> template <typename TChar>
FORCE_INLINE VariantConstRef getMember(TChar* key) const { FORCE_INLINE VariantConstRef getMemberConst(TChar* key) const {
return get_impl(adaptString(key)); return VariantConstRef(objectGetMember(_data, adaptString(key)));
} }
// operator[](const std::string&) const // operator[](const std::string&) const
@@ -113,7 +113,7 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
FORCE_INLINE FORCE_INLINE
typename enable_if<IsString<TString>::value, VariantConstRef>::type typename enable_if<IsString<TString>::value, VariantConstRef>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return get_impl(adaptString(key)); return getMemberConst(key);
} }
// operator[](char*) const // operator[](char*) const
@@ -123,7 +123,7 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
FORCE_INLINE FORCE_INLINE
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return get_impl(adaptString(key)); return getMemberConst(key);
} }
FORCE_INLINE bool operator==(ObjectConstRef rhs) const { FORCE_INLINE bool operator==(ObjectConstRef rhs) const {
@@ -131,10 +131,6 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
} }
private: private:
template <typename TAdaptedString>
FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const {
return VariantConstRef(objectGetMember(_data, key));
}
}; };
class ObjectRef : public ObjectRefBase<CollectionData>, class ObjectRef : public ObjectRefBase<CollectionData>,
@@ -195,6 +191,21 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
return VariantRef(_pool, objectGetMember(_data, adaptString(key))); return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
} }
// getMemberConst(const std::string&) const
// getMemberConst(const String&) const
template <typename TString>
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 <typename TChar>
FORCE_INLINE VariantConstRef getMemberConst(TChar* key) const {
return VariantConstRef(objectGetMember(_data, adaptString(key)));
}
// getOrAddMember(const std::string&) const // getOrAddMember(const std::string&) const
// getOrAddMember(const String&) const // getOrAddMember(const String&) const
template <typename TString> template <typename TString>

View File

@@ -14,4 +14,7 @@ template <typename T1, typename T2>
class InvalidConversion; // Error here? See https://arduinojson.org/v6/invalid-conversion/ class InvalidConversion; // Error here? See https://arduinojson.org/v6/invalid-conversion/
// clang-format on // clang-format on
template <typename T>
struct ConverterNeedsWriteableRef;
} // namespace ARDUINOJSON_NAMESPACE } // namespace ARDUINOJSON_NAMESPACE

View File

@@ -124,7 +124,7 @@ VariantRef::to() const {
return *this; return *this;
} }
inline VariantConstRef VariantConstRef::getElement(size_t index) const { inline VariantConstRef VariantConstRef::getElementConst(size_t index) const {
return ArrayConstRef(_data != 0 ? _data->resolve()->asArray() : 0)[index]; return ArrayConstRef(_data != 0 ? _data->resolve()->asArray() : 0)[index];
} }
@@ -133,8 +133,11 @@ inline VariantRef VariantRef::addElement() const {
} }
inline VariantRef VariantRef::getElement(size_t index) const { inline VariantRef VariantRef::getElement(size_t index) const {
return VariantRef(_pool, return VariantRef(_pool, _data != 0 ? _data->getElement(index) : 0);
_data != 0 ? _data->resolve()->getElement(index) : 0); }
inline VariantConstRef VariantRef::getElementConst(size_t index) const {
return VariantConstRef(_data != 0 ? _data->resolve()->getElement(index) : 0);
} }
inline VariantRef VariantRef::getOrAddElement(size_t index) const { inline VariantRef VariantRef::getOrAddElement(size_t index) const {
@@ -143,16 +146,26 @@ inline VariantRef VariantRef::getOrAddElement(size_t index) const {
template <typename TChar> template <typename TChar>
inline VariantRef VariantRef::getMember(TChar *key) const { inline VariantRef VariantRef::getMember(TChar *key) const {
return VariantRef( // TODO: this returns a mutable reference to a linked return VariantRef(_pool, _data != 0 ? _data->getMember(adaptString(key)) : 0);
// object
_pool, _data != 0 ? _data->resolve()->getMember(adaptString(key)) : 0);
} }
template <typename TString> template <typename TString>
inline typename enable_if<IsString<TString>::value, VariantRef>::type inline typename enable_if<IsString<TString>::value, VariantRef>::type
VariantRef::getMember(const TString &key) const { VariantRef::getMember(const TString &key) const {
return VariantRef( // TODO: idem return VariantRef(_pool, _data != 0 ? _data->getMember(adaptString(key)) : 0);
_pool, _data != 0 ? _data->resolve()->getMember(adaptString(key)) : 0); }
template <typename TChar>
inline VariantConstRef VariantRef::getMemberConst(TChar *key) const {
return VariantConstRef(
_data != 0 ? _data->resolve()->getMember(adaptString(key)) : 0);
}
template <typename TString>
inline typename enable_if<IsString<TString>::value, VariantConstRef>::type
VariantRef::getMemberConst(const TString &key) const {
return VariantConstRef(
_data != 0 ? _data->resolve()->getMember(adaptString(key)) : 0);
} }
template <typename TChar> template <typename TChar>

View File

@@ -174,6 +174,8 @@ class VariantRef : public VariantRefBase<VariantData>,
FORCE_INLINE VariantRef getElement(size_t) const; FORCE_INLINE VariantRef getElement(size_t) const;
FORCE_INLINE class VariantConstRef getElementConst(size_t) const;
FORCE_INLINE VariantRef getOrAddElement(size_t) const; FORCE_INLINE VariantRef getOrAddElement(size_t) const;
// getMember(const char*) const // getMember(const char*) const
@@ -187,6 +189,18 @@ class VariantRef : public VariantRefBase<VariantData>,
FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
getMember(const TString &) const; getMember(const TString &) const;
// getMemberConst(const char*) const
// getMemberConst(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE class VariantConstRef getMemberConst(TChar *) const;
// getMemberConst(const std::string&) const
// getMemberConst(const String&) const
template <typename TString>
FORCE_INLINE
typename enable_if<IsString<TString>::value, class VariantConstRef>::type
getMemberConst(const TString &) const;
// getOrAddMember(char*) const // getOrAddMember(char*) const
// getOrAddMember(const char*) const // getOrAddMember(const char*) const
// getOrAddMember(const __FlashStringHelper*) const // getOrAddMember(const __FlashStringHelper*) const
@@ -293,25 +307,25 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
return as<T>(); return as<T>();
} }
FORCE_INLINE VariantConstRef getElement(size_t) const; FORCE_INLINE VariantConstRef getElementConst(size_t) const;
FORCE_INLINE VariantConstRef operator[](size_t index) const { FORCE_INLINE VariantConstRef operator[](size_t index) const {
return getElement(index); return getElementConst(index);
} }
// getMember(const std::string&) const // getMemberConst(const std::string&) const
// getMember(const String&) const // getMemberConst(const String&) const
template <typename TString> template <typename TString>
FORCE_INLINE VariantConstRef getMember(const TString &key) const { FORCE_INLINE VariantConstRef getMemberConst(const TString &key) const {
return VariantConstRef( return VariantConstRef(
objectGetMember(variantAsObject(_data), adaptString(key))); objectGetMember(variantAsObject(_data), adaptString(key)));
} }
// getMember(char*) const // getMemberConst(char*) const
// getMember(const char*) const // getMemberConst(const char*) const
// getMember(const __FlashStringHelper*) const // getMemberConst(const __FlashStringHelper*) const
template <typename TChar> template <typename TChar>
FORCE_INLINE VariantConstRef getMember(TChar *key) const { FORCE_INLINE VariantConstRef getMemberConst(TChar *key) const {
const CollectionData *obj = variantAsObject(_data); const CollectionData *obj = variantAsObject(_data);
return VariantConstRef(obj ? obj->getMember(adaptString(key)) : 0); return VariantConstRef(obj ? obj->getMember(adaptString(key)) : 0);
} }
@@ -332,7 +346,7 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
FORCE_INLINE FORCE_INLINE
typename enable_if<IsString<TChar *>::value, VariantConstRef>::type typename enable_if<IsString<TChar *>::value, VariantConstRef>::type
operator[](TChar *key) const { operator[](TChar *key) const {
return getMember(key); return getMemberConst(key);
} }
}; };