Make MemberProxy and `ElementProxy similar

This commit is contained in:
Benoit Blanchon
2022-08-09 13:57:23 +02:00
parent f73be9cf0f
commit ffa7f8d22d
2 changed files with 115 additions and 142 deletions

View File

@ -16,51 +16,43 @@
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {
template <typename TArray> template <typename TUpstream>
class ElementProxy : public VariantOperators<ElementProxy<TArray> >, class ElementProxy //
public VariantShortcuts<ElementProxy<TArray> >, : public VariantOperators<ElementProxy<TUpstream> >,
public VariantTag { public VariantShortcuts<ElementProxy<TUpstream> >,
typedef ElementProxy<TArray> this_type; public VariantTag {
friend class VariantAttorney; friend class VariantAttorney;
public: public:
FORCE_INLINE ElementProxy(TArray array, size_t index) FORCE_INLINE ElementProxy(TUpstream upstream, size_t index)
: _array(array), _index(index) {} : _upstream(upstream), _index(index) {}
FORCE_INLINE ElementProxy(const ElementProxy& src) FORCE_INLINE ElementProxy(const ElementProxy& src)
: _array(src._array), _index(src._index) {} : _upstream(src._upstream), _index(src._index) {}
FORCE_INLINE this_type& operator=(const this_type& src) { FORCE_INLINE ElementProxy& operator=(const ElementProxy& src) {
getOrAddUpstreamElement().set(src.as<VariantConstRef>()); getOrAddUpstreamVariant().set(src);
return *this; return *this;
} }
// Replaces the value
//
// operator=(const TValue&)
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
// std::string, String, ArrayRef, ObjectRef
template <typename T> template <typename T>
FORCE_INLINE this_type& operator=(const T& src) { FORCE_INLINE ElementProxy& operator=(const T& src) {
getOrAddUpstreamElement().set(src); getOrAddUpstreamVariant().set(src);
return *this; return *this;
} }
//
// operator=(TValue)
// TValue = char*, const char*, const __FlashStringHelper*
template <typename T> template <typename T>
FORCE_INLINE this_type& operator=(T* src) { FORCE_INLINE ElementProxy& operator=(T* src) {
getOrAddUpstreamElement().set(src); getOrAddUpstreamVariant().set(src);
return *this; return *this;
} }
FORCE_INLINE void clear() const { FORCE_INLINE void clear() const {
getUpstreamElement().clear(); getUpstreamVariant().clear();
} }
FORCE_INLINE bool isNull() const { FORCE_INLINE bool isNull() const {
return getUpstreamElementConst().isNull(); return getUpstreamVariantConst().isNull();
} }
template <typename T> template <typename T>
@ -68,13 +60,13 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
!ConverterNeedsWriteableRef<T>::value, !ConverterNeedsWriteableRef<T>::value,
T>::type T>::type
as() const { as() const {
return getUpstreamElementConst().template as<T>(); return getUpstreamVariantConst().template as<T>();
} }
template <typename T> template <typename T>
FORCE_INLINE typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type FORCE_INLINE typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type
as() const { as() const {
return getUpstreamElement().template as<T>(); return getUpstreamVariant().template as<T>();
} }
template <typename T> template <typename T>
@ -89,62 +81,55 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
return as<T>(); return as<T>();
} }
template <typename T>
FORCE_INLINE typename VariantTo<T>::type to() {
return getOrAddUpstreamVariant().template to<T>();
}
template <typename T> template <typename T>
FORCE_INLINE FORCE_INLINE
typename enable_if<ConverterNeedsWriteableRef<T>::value, bool>::type typename enable_if<ConverterNeedsWriteableRef<T>::value, bool>::type
is() const { is() const {
return getUpstreamElement().template is<T>(); return getUpstreamVariant().template is<T>();
} }
template <typename T> template <typename T>
FORCE_INLINE FORCE_INLINE
typename enable_if<!ConverterNeedsWriteableRef<T>::value, bool>::type typename enable_if<!ConverterNeedsWriteableRef<T>::value, bool>::type
is() const { is() const {
return getUpstreamElementConst().template is<T>(); return getUpstreamVariantConst().template is<T>();
}
FORCE_INLINE void shallowCopy(VariantConstRef value) {
getOrAddUpstreamVariant().shallowCopy(value);
} }
template <typename T> template <typename T>
FORCE_INLINE typename VariantTo<T>::type to() const { FORCE_INLINE bool set(const T& value) {
return getOrAddUpstreamElement().template to<T>(); return getOrAddUpstreamVariant().set(value);
} }
FORCE_INLINE void shallowCopy(VariantConstRef value) const { template <typename T>
getOrAddUpstreamElement().shallowCopy(value); FORCE_INLINE bool set(T* value) {
} return getOrAddUpstreamVariant().set(value);
// Replaces the value
//
// bool set(const TValue&)
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
// std::string, String, ArrayRef, ObjectRef
template <typename TValue>
FORCE_INLINE bool set(const TValue& value) const {
return getOrAddUpstreamElement().set(value);
}
//
// bool set(TValue)
// TValue = char*, const char*, const __FlashStringHelper*
template <typename TValue>
FORCE_INLINE bool set(TValue* value) const {
return getOrAddUpstreamElement().set(value);
} }
FORCE_INLINE size_t size() const { FORCE_INLINE size_t size() const {
return getUpstreamElementConst().size(); return getUpstreamVariantConst().size();
} }
FORCE_INLINE size_t memoryUsage() const { FORCE_INLINE size_t memoryUsage() const {
return getUpstreamElementConst().memoryUsage(); return getUpstreamVariantConst().memoryUsage();
} }
VariantRef add() const { FORCE_INLINE VariantRef add() const {
return getOrAddUpstreamElement().add(); return getOrAddUpstreamVariant().add();
} }
using ArrayShortcuts<ElementProxy<TArray> >::add; using ArrayShortcuts<ElementProxy<TUpstream> >::add;
FORCE_INLINE void remove(size_t index) const { FORCE_INLINE void remove(size_t index) const {
getUpstreamElement().remove(index); getUpstreamVariant().remove(index);
} }
// remove(char*) const // remove(char*) const
// remove(const char*) const // remove(const char*) const
@ -152,48 +137,48 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
template <typename TChar> template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove( FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
TChar* key) const { TChar* key) const {
getUpstreamElement().remove(key); getUpstreamVariant().remove(key);
} }
// remove(const std::string&) const // remove(const std::string&) const
// remove(const String&) const // remove(const String&) const
template <typename TString> template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString& key) const { const TString& key) const {
getUpstreamElement().remove(key); getUpstreamVariant().remove(key);
} }
protected: protected:
FORCE_INLINE MemoryPool* getPool() const { FORCE_INLINE MemoryPool* getPool() const {
return VariantAttorney::getPool(_array); return VariantAttorney::getPool(_upstream);
} }
FORCE_INLINE VariantData* getData() const { FORCE_INLINE VariantData* getData() const {
return variantGetElement(VariantAttorney::getData(_array), _index); return variantGetElement(VariantAttorney::getData(_upstream), _index);
} }
FORCE_INLINE VariantData* getOrCreateData() const { FORCE_INLINE VariantData* getOrCreateData() const {
return variantGetOrAddElement(VariantAttorney::getOrCreateData(_array), return variantGetOrAddElement(VariantAttorney::getOrCreateData(_upstream),
_index, VariantAttorney::getPool(_array)); _index, VariantAttorney::getPool(_upstream));
} }
private: private:
FORCE_INLINE VariantRef getUpstreamElement() const { FORCE_INLINE VariantRef getUpstreamVariant() const {
return VariantRef(getPool(), getData()); return VariantRef(getPool(), getData());
} }
FORCE_INLINE VariantConstRef getUpstreamElementConst() const { FORCE_INLINE VariantConstRef getUpstreamVariantConst() const {
return VariantConstRef(getData()); return VariantConstRef(getData());
} }
FORCE_INLINE VariantRef getOrAddUpstreamElement() const { FORCE_INLINE VariantRef getOrAddUpstreamVariant() const {
return VariantRef(getPool(), getOrCreateData()); return VariantRef(getPool(), getOrCreateData());
} }
friend void convertToJson(const this_type& src, VariantRef dst) { friend void convertToJson(const ElementProxy& src, VariantRef dst) {
dst.set(src.getUpstreamElementConst()); dst.set(src.getUpstreamVariantConst());
} }
TArray _array; TUpstream _upstream;
const size_t _index; const size_t _index;
}; };

View File

@ -19,52 +19,43 @@
namespace ARDUINOJSON_NAMESPACE { namespace ARDUINOJSON_NAMESPACE {
template <typename TObject, typename TStringRef> template <typename TUpstream, typename TStringRef>
class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >, class MemberProxy //
public VariantShortcuts<MemberProxy<TObject, TStringRef> >, : public VariantOperators<MemberProxy<TUpstream, TStringRef> >,
public VariantTag { public VariantShortcuts<MemberProxy<TUpstream, TStringRef> >,
typedef MemberProxy<TObject, TStringRef> this_type; public VariantTag {
friend class VariantAttorney; friend class VariantAttorney;
public: public:
FORCE_INLINE MemberProxy(TObject variant, TStringRef key) FORCE_INLINE MemberProxy(TUpstream upstream, TStringRef key)
: _object(variant), _key(key) {} : _upstream(upstream), _key(key) {}
FORCE_INLINE MemberProxy(const MemberProxy& src) FORCE_INLINE MemberProxy(const MemberProxy& src)
: _object(src._object), _key(src._key) {} : _upstream(src._upstream), _key(src._key) {}
FORCE_INLINE operator VariantConstRef() const { FORCE_INLINE MemberProxy& operator=(const MemberProxy& src) {
return getUpstreamMemberConst(); getOrAddUpstreamVariant().set(src);
}
FORCE_INLINE this_type& operator=(const this_type& src) {
getOrAddUpstreamMember().set(src);
return *this; return *this;
} }
template <typename TValue> template <typename T>
FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type&>::type FORCE_INLINE MemberProxy& operator=(const T& src) {
operator=(const TValue& src) { getOrAddUpstreamVariant().set(src);
getOrAddUpstreamMember().set(src);
return *this; return *this;
} }
// operator=(char*) template <typename T>
// operator=(const char*) FORCE_INLINE MemberProxy& operator=(T* src) {
// operator=(const __FlashStringHelper*) getOrAddUpstreamVariant().set(src);
template <typename TChar>
FORCE_INLINE this_type& operator=(TChar* src) {
getOrAddUpstreamMember().set(src);
return *this; return *this;
} }
FORCE_INLINE void clear() const { FORCE_INLINE void clear() const {
getUpstreamMember().clear(); getUpstreamVariant().clear();
} }
FORCE_INLINE bool isNull() const { FORCE_INLINE bool isNull() const {
return getUpstreamMemberConst().isNull(); return getUpstreamVariantConst().isNull();
} }
template <typename T> template <typename T>
@ -72,13 +63,13 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
!ConverterNeedsWriteableRef<T>::value, !ConverterNeedsWriteableRef<T>::value,
T>::type T>::type
as() const { as() const {
return getUpstreamMemberConst().template as<T>(); return getUpstreamVariantConst().template as<T>();
} }
template <typename T> template <typename T>
FORCE_INLINE typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type FORCE_INLINE typename enable_if<ConverterNeedsWriteableRef<T>::value, T>::type
as() const { as() const {
return getUpstreamMember().template as<T>(); return getUpstreamVariant().template as<T>();
} }
template <typename T> template <typename T>
@ -93,30 +84,55 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return as<T>(); return as<T>();
} }
template <typename T>
FORCE_INLINE typename VariantTo<T>::type to() {
return getOrAddUpstreamVariant().template to<T>();
}
template <typename T> template <typename T>
FORCE_INLINE FORCE_INLINE
typename enable_if<ConverterNeedsWriteableRef<T>::value, bool>::type typename enable_if<ConverterNeedsWriteableRef<T>::value, bool>::type
is() const { is() const {
return getUpstreamMember().template is<T>(); return getUpstreamVariant().template is<T>();
} }
template <typename T> template <typename T>
FORCE_INLINE FORCE_INLINE
typename enable_if<!ConverterNeedsWriteableRef<T>::value, bool>::type typename enable_if<!ConverterNeedsWriteableRef<T>::value, bool>::type
is() const { is() const {
return getUpstreamMemberConst().template is<T>(); return getUpstreamVariantConst().template is<T>();
}
FORCE_INLINE void shallowCopy(VariantConstRef value) {
getOrAddUpstreamVariant().shallowCopy(value);
}
template <typename T>
FORCE_INLINE bool set(const T& value) {
return getOrAddUpstreamVariant().set(value);
}
template <typename T>
FORCE_INLINE bool set(T* value) {
return getOrAddUpstreamVariant().set(value);
} }
FORCE_INLINE size_t size() const { FORCE_INLINE size_t size() const {
return getUpstreamMemberConst().size(); return getUpstreamVariantConst().size();
} }
FORCE_INLINE size_t memoryUsage() const { FORCE_INLINE size_t memoryUsage() const {
return getUpstreamMemberConst().memoryUsage(); return getUpstreamVariantConst().memoryUsage();
} }
FORCE_INLINE VariantRef add() const {
return getOrAddUpstreamVariant().add();
}
using ArrayShortcuts<MemberProxy<TUpstream, TStringRef> >::add;
FORCE_INLINE void remove(size_t index) const { FORCE_INLINE void remove(size_t index) const {
getUpstreamMember().remove(index); getUpstreamVariant().remove(index);
} }
// remove(char*) const // remove(char*) const
// remove(const char*) const // remove(const char*) const
@ -124,77 +140,49 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
template <typename TChar> template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove( FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
TChar* key) const { TChar* key) const {
getUpstreamMember().remove(key); getUpstreamVariant().remove(key);
} }
// remove(const std::string&) const // remove(const std::string&) const
// remove(const String&) const // remove(const String&) const
template <typename TString> template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString& key) const { const TString& key) const {
getUpstreamMember().remove(key); getUpstreamVariant().remove(key);
} }
FORCE_INLINE void shallowCopy(VariantConstRef value) {
getOrAddUpstreamMember().shallowCopy(value);
}
template <typename TValue>
FORCE_INLINE typename VariantTo<TValue>::type to() {
return getOrAddUpstreamMember().template to<TValue>();
}
template <typename TValue>
FORCE_INLINE bool set(const TValue& value) {
return getOrAddUpstreamMember().set(value);
}
// set(char*) const
// set(const char*) const
// set(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE bool set(TChar* value) {
return getOrAddUpstreamMember().set(value);
}
FORCE_INLINE VariantRef add() const {
return getOrAddUpstreamMember().add();
}
using ArrayShortcuts<MemberProxy<TObject, TStringRef> >::add;
protected: protected:
FORCE_INLINE MemoryPool* getPool() const { FORCE_INLINE MemoryPool* getPool() const {
return VariantAttorney::getPool(_object); return VariantAttorney::getPool(_upstream);
} }
FORCE_INLINE VariantData* getData() const { FORCE_INLINE VariantData* getData() const {
return variantGetMember(VariantAttorney::getData(_object), return variantGetMember(VariantAttorney::getData(_upstream),
adaptString(_key)); adaptString(_key));
} }
FORCE_INLINE VariantData* getOrCreateData() const { FORCE_INLINE VariantData* getOrCreateData() const {
return variantGetOrAddMember(VariantAttorney::getOrCreateData(_object), return variantGetOrAddMember(VariantAttorney::getOrCreateData(_upstream),
_key, VariantAttorney::getPool(_object)); _key, VariantAttorney::getPool(_upstream));
} }
private: private:
FORCE_INLINE VariantRef getUpstreamMember() const { FORCE_INLINE VariantRef getUpstreamVariant() const {
return VariantRef(getPool(), getData()); return VariantRef(getPool(), getData());
} }
FORCE_INLINE VariantConstRef getUpstreamMemberConst() const { FORCE_INLINE VariantConstRef getUpstreamVariantConst() const {
return VariantConstRef(getData()); return VariantConstRef(getData());
} }
FORCE_INLINE VariantRef getOrAddUpstreamMember() const { FORCE_INLINE VariantRef getOrAddUpstreamVariant() const {
return VariantRef(getPool(), getOrCreateData()); return VariantRef(getPool(), getOrCreateData());
} }
friend void convertToJson(const this_type& src, VariantRef dst) { friend void convertToJson(const MemberProxy& src, VariantRef dst) {
dst.set(src.getUpstreamMemberConst()); dst.set(src.getUpstreamVariantConst());
} }
TObject _object; TUpstream _upstream;
TStringRef _key; TStringRef _key;
}; };