mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Implement VariantRefBase with a CRTP
				
					
				
			This commit is contained in:
		| @@ -9,7 +9,6 @@ HEAD | |||||||
| * Fix comparison operators for `JsonArray`, `JsonArrayConst`, `JsonObject`, and `JsonObjectConst` | * Fix comparison operators for `JsonArray`, `JsonArrayConst`, `JsonObject`, and `JsonObjectConst` | ||||||
| * Fix lax parsing of `true`, `false`, and `null` (issue #1781) | * Fix lax parsing of `true`, `false`, and `null` (issue #1781) | ||||||
| * Remove undocumented `accept()` functions | * Remove undocumented `accept()` functions | ||||||
| * Remove undocumented `ElementProxy` and `MemberProxy` classes |  | ||||||
| * Rename `addElement()` to `add()` | * Rename `addElement()` to `add()` | ||||||
| * Remove `getElement()`, `getOrAddElement()`, `getMember()`, and `getOrAddMember()` | * Remove `getElement()`, `getOrAddElement()`, `getMember()`, and `getOrAddMember()` | ||||||
| * Remove undocumented `JsonDocument::data()` and `JsonDocument::memoryPool()` | * Remove undocumented `JsonDocument::data()` and `JsonDocument::memoryPool()` | ||||||
|   | |||||||
| @@ -5,9 +5,7 @@ | |||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <catch.hpp> | #include <catch.hpp> | ||||||
|  |  | ||||||
| using namespace ARDUINOJSON_NAMESPACE; | typedef ARDUINOJSON_NAMESPACE::ElementProxy<JsonDocument&> ElementProxy; | ||||||
|  |  | ||||||
| typedef VariantProxy<ElementDataSource<JsonDocument&> > ElementProxy; |  | ||||||
|  |  | ||||||
| TEST_CASE("ElementProxy::add()") { | TEST_CASE("ElementProxy::add()") { | ||||||
|   DynamicJsonDocument doc(4096); |   DynamicJsonDocument doc(4096); | ||||||
|   | |||||||
| @@ -5,9 +5,8 @@ | |||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <catch.hpp> | #include <catch.hpp> | ||||||
|  |  | ||||||
| using namespace ARDUINOJSON_NAMESPACE; | typedef ARDUINOJSON_NAMESPACE::MemberProxy<JsonDocument&, const char*> | ||||||
|  |     MemberProxy; | ||||||
| typedef VariantProxy<MemberDataSource<JsonDocument&, const char*> > MemberProxy; |  | ||||||
|  |  | ||||||
| TEST_CASE("MemberProxy::add()") { | TEST_CASE("MemberProxy::add()") { | ||||||
|   DynamicJsonDocument doc(4096); |   DynamicJsonDocument doc(4096); | ||||||
|   | |||||||
| @@ -184,13 +184,12 @@ TEST_CASE("Polyfills/type_traits") { | |||||||
|     CHECK((is_convertible<VariantRef, JsonVariantConst>::value == true)); |     CHECK((is_convertible<VariantRef, JsonVariantConst>::value == true)); | ||||||
|     CHECK((is_convertible<VariantConstRef, JsonVariantConst>::value == true)); |     CHECK((is_convertible<VariantConstRef, JsonVariantConst>::value == true)); | ||||||
|     CHECK((is_convertible<ArrayRef, JsonVariantConst>::value == true)); |     CHECK((is_convertible<ArrayRef, JsonVariantConst>::value == true)); | ||||||
|     CHECK((is_convertible<VariantProxy<ElementDataSource<ArrayRef> >, |     CHECK((is_convertible<ElementProxy<ArrayRef>, JsonVariantConst>::value == | ||||||
|                           JsonVariantConst>::value == true)); |            true)); | ||||||
|     CHECK((is_convertible<ArrayConstRef, JsonVariantConst>::value == true)); |     CHECK((is_convertible<ArrayConstRef, JsonVariantConst>::value == true)); | ||||||
|     CHECK((is_convertible<ObjectRef, JsonVariantConst>::value == true)); |     CHECK((is_convertible<ObjectRef, JsonVariantConst>::value == true)); | ||||||
|     CHECK( |     CHECK((is_convertible<MemberProxy<ObjectRef, const char*>, | ||||||
|         (is_convertible<VariantProxy<MemberDataSource<ObjectRef, const char*> >, |                           JsonVariantConst>::value == true)); | ||||||
|                         JsonVariantConst>::value == true)); |  | ||||||
|     CHECK((is_convertible<ObjectConstRef, JsonVariantConst>::value == true)); |     CHECK((is_convertible<ObjectConstRef, JsonVariantConst>::value == true)); | ||||||
|     CHECK( |     CHECK( | ||||||
|         (is_convertible<DynamicJsonDocument, JsonVariantConst>::value == true)); |         (is_convertible<DynamicJsonDocument, JsonVariantConst>::value == true)); | ||||||
|   | |||||||
| @@ -13,21 +13,20 @@ inline ObjectRef ArrayRef::createNestedObject() const { | |||||||
|   return add().to<ObjectRef>(); |   return add().to<ObjectRef>(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| inline ArrayRef VariantRefBase<TDataSource>::createNestedArray() const { | inline ArrayRef VariantRefBase<TDerived>::createNestedArray() const { | ||||||
|   return add().template to<ArrayRef>(); |   return add().template to<ArrayRef>(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| inline ObjectRef VariantRefBase<TDataSource>::createNestedObject() const { | inline ObjectRef VariantRefBase<TDerived>::createNestedObject() const { | ||||||
|   return add().template to<ObjectRef>(); |   return add().template to<ObjectRef>(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| inline VariantProxy<ElementDataSource<VariantRefBase<TDataSource> > > | inline ElementProxy<TDerived> VariantRefBase<TDerived>::operator[]( | ||||||
| VariantRefBase<TDataSource>::operator[](size_t index) const { |     size_t index) const { | ||||||
|   return VariantProxy<ElementDataSource<VariantRefBase<TDataSource> > >( |   return ElementProxy<TDerived>(derived(), index); | ||||||
|       ElementDataSource<VariantRefBase<TDataSource> >(*this, index)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| }  // namespace ARDUINOJSON_NAMESPACE | }  // namespace ARDUINOJSON_NAMESPACE | ||||||
|   | |||||||
| @@ -184,10 +184,8 @@ class ArrayRef : public ArrayRefBase<CollectionData>, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Returns the element at specified index if the variant is an array. |   // Returns the element at specified index if the variant is an array. | ||||||
|   FORCE_INLINE VariantProxy<ElementDataSource<ArrayRef> > operator[]( |   FORCE_INLINE ElementProxy<ArrayRef> operator[](size_t index) const { | ||||||
|       size_t index) const { |     return ElementProxy<ArrayRef>(*this, index); | ||||||
|     return VariantProxy<ElementDataSource<ArrayRef> >( |  | ||||||
|         ElementDataSource<ArrayRef>(*this, index)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE ObjectRef createNestedObject() const; |   FORCE_INLINE ObjectRef createNestedObject() const; | ||||||
|   | |||||||
| @@ -4,16 +4,40 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <ArduinoJson/Variant/VariantProxy.hpp> | #include <ArduinoJson/Variant/VariantRefBase.hpp> | ||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| template <typename TUpstream> | template <typename TUpstream> | ||||||
| class ElementDataSource { | class ElementProxy : public VariantRefBase<ElementProxy<TUpstream> >, | ||||||
|  |                      public VariantOperators<ElementProxy<TUpstream> > { | ||||||
|  |   friend class VariantAttorney; | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   ElementDataSource(TUpstream upstream, size_t index) |   ElementProxy(TUpstream upstream, size_t index) | ||||||
|       : _upstream(upstream), _index(index) {} |       : _upstream(upstream), _index(index) {} | ||||||
|  |  | ||||||
|  |   ElementProxy(const ElementProxy& src) | ||||||
|  |       : _upstream(src._upstream), _index(src._index) {} | ||||||
|  |  | ||||||
|  |   FORCE_INLINE ElementProxy& operator=(const ElementProxy& src) { | ||||||
|  |     this->set(src); | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   template <typename T> | ||||||
|  |   FORCE_INLINE ElementProxy& operator=(const T& src) { | ||||||
|  |     this->set(src); | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   template <typename T> | ||||||
|  |   FORCE_INLINE ElementProxy& operator=(T* src) { | ||||||
|  |     this->set(src); | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|   FORCE_INLINE MemoryPool* getPool() const { |   FORCE_INLINE MemoryPool* getPool() const { | ||||||
|     return VariantAttorney::getPool(_upstream); |     return VariantAttorney::getPool(_upstream); | ||||||
|   } |   } | ||||||
| @@ -27,12 +51,6 @@ class ElementDataSource { | |||||||
|                                   _index, VariantAttorney::getPool(_upstream)); |                                   _index, VariantAttorney::getPool(_upstream)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  | ||||||
| #if defined _MSC_VER && _MSC_VER <= 1800  // Visual Studio 2013 or below |  | ||||||
|   // Prevent "assignment operator could not be generated" |  | ||||||
|   ElementDataSource& operator=(const ElementDataSource&); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   TUpstream _upstream; |   TUpstream _upstream; | ||||||
|   size_t _index; |   size_t _index; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -139,24 +139,20 @@ class JsonDocument : public VariantOperators<const JsonDocument&> { | |||||||
|   // operator[](const std::string&) |   // operator[](const std::string&) | ||||||
|   // operator[](const String&) |   // operator[](const String&) | ||||||
|   template <typename TString> |   template <typename TString> | ||||||
|   FORCE_INLINE typename enable_if< |   FORCE_INLINE typename enable_if<IsString<TString>::value, | ||||||
|       IsString<TString>::value, |                                   MemberProxy<JsonDocument&, TString> >::type | ||||||
|       VariantProxy<MemberDataSource<JsonDocument&, TString> > >::type |  | ||||||
|   operator[](const TString& key) { |   operator[](const TString& key) { | ||||||
|     return VariantProxy<MemberDataSource<JsonDocument&, TString> >( |     return MemberProxy<JsonDocument&, TString>(*this, key); | ||||||
|         MemberDataSource<JsonDocument&, TString>(*this, key)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // operator[](char*) |   // operator[](char*) | ||||||
|   // operator[](const char*) |   // operator[](const char*) | ||||||
|   // operator[](const __FlashStringHelper*) |   // operator[](const __FlashStringHelper*) | ||||||
|   template <typename TChar> |   template <typename TChar> | ||||||
|   FORCE_INLINE typename enable_if< |   FORCE_INLINE typename enable_if<IsString<TChar*>::value, | ||||||
|       IsString<TChar*>::value, |                                   MemberProxy<JsonDocument&, TChar*> >::type | ||||||
|       VariantProxy<MemberDataSource<JsonDocument&, TChar*> > >::type |  | ||||||
|   operator[](TChar* key) { |   operator[](TChar* key) { | ||||||
|     return VariantProxy<MemberDataSource<JsonDocument&, TChar*> >( |     return MemberProxy<JsonDocument&, TChar*>(*this, key); | ||||||
|         MemberDataSource<JsonDocument&, TChar*>(*this, key)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // operator[](const std::string&) const |   // operator[](const std::string&) const | ||||||
| @@ -178,10 +174,8 @@ class JsonDocument : public VariantOperators<const JsonDocument&> { | |||||||
|     return VariantConstRef(_data.getMember(adaptString(key))); |     return VariantConstRef(_data.getMember(adaptString(key))); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE VariantProxy<ElementDataSource<JsonDocument&> > operator[]( |   FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) { | ||||||
|       size_t index) { |     return ElementProxy<JsonDocument&>(*this, index); | ||||||
|     return VariantProxy<ElementDataSource<JsonDocument&> >( |  | ||||||
|         ElementDataSource<JsonDocument&>(*this, index)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE VariantConstRef operator[](size_t index) const { |   FORCE_INLINE VariantConstRef operator[](size_t index) const { | ||||||
|   | |||||||
| @@ -4,16 +4,41 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <ArduinoJson/Variant/VariantProxy.hpp> | #include <ArduinoJson/Variant/VariantRefBase.hpp> | ||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| template <typename TUpstream, typename TStringRef> | template <typename TUpstream, typename TStringRef> | ||||||
| class MemberDataSource { | class MemberProxy | ||||||
|  |     : public VariantRefBase<MemberProxy<TUpstream, TStringRef> >, | ||||||
|  |       public VariantOperators<MemberProxy<TUpstream, TStringRef> > { | ||||||
|  |   friend class VariantAttorney; | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   FORCE_INLINE MemberDataSource(TUpstream upstream, TStringRef key) |   FORCE_INLINE MemberProxy(TUpstream upstream, TStringRef key) | ||||||
|       : _upstream(upstream), _key(key) {} |       : _upstream(upstream), _key(key) {} | ||||||
|  |  | ||||||
|  |   MemberProxy(const MemberProxy& src) | ||||||
|  |       : _upstream(src._upstream), _key(src._key) {} | ||||||
|  |  | ||||||
|  |   FORCE_INLINE MemberProxy& operator=(const MemberProxy& src) { | ||||||
|  |     this->set(src); | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   template <typename T> | ||||||
|  |   FORCE_INLINE MemberProxy& operator=(const T& src) { | ||||||
|  |     this->set(src); | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   template <typename T> | ||||||
|  |   FORCE_INLINE MemberProxy& operator=(T* src) { | ||||||
|  |     this->set(src); | ||||||
|  |     return *this; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|   FORCE_INLINE MemoryPool* getPool() const { |   FORCE_INLINE MemoryPool* getPool() const { | ||||||
|     return VariantAttorney::getPool(_upstream); |     return VariantAttorney::getPool(_upstream); | ||||||
|   } |   } | ||||||
| @@ -30,11 +55,6 @@ class MemberDataSource { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
| #if defined _MSC_VER && _MSC_VER <= 1800  // Visual Studio 2013 or below |  | ||||||
|   // Prevent "assignment operator could not be generated" |  | ||||||
|   MemberDataSource& operator=(const MemberDataSource&); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   TUpstream _upstream; |   TUpstream _upstream; | ||||||
|   TStringRef _key; |   TStringRef _key; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -19,68 +19,63 @@ inline ArrayRef ObjectRef::createNestedArray(TChar* key) const { | |||||||
|   return operator[](key).template to<ArrayRef>(); |   return operator[](key).template to<ArrayRef>(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| template <typename TString> | template <typename TString> | ||||||
| inline ArrayRef VariantRefBase<TDataSource>::createNestedArray( | inline ArrayRef VariantRefBase<TDerived>::createNestedArray( | ||||||
|     const TString& key) const { |     const TString& key) const { | ||||||
|   return operator[](key).template to<ArrayRef>(); |   return operator[](key).template to<ArrayRef>(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| template <typename TChar> | template <typename TChar> | ||||||
| inline ArrayRef VariantRefBase<TDataSource>::createNestedArray( | inline ArrayRef VariantRefBase<TDerived>::createNestedArray(TChar* key) const { | ||||||
|     TChar* key) const { |  | ||||||
|   return operator[](key).template to<ArrayRef>(); |   return operator[](key).template to<ArrayRef>(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| template <typename TString> | template <typename TString> | ||||||
| inline ObjectRef VariantRefBase<TDataSource>::createNestedObject( | inline ObjectRef VariantRefBase<TDerived>::createNestedObject( | ||||||
|     const TString& key) const { |     const TString& key) const { | ||||||
|   return operator[](key).template to<ObjectRef>(); |   return operator[](key).template to<ObjectRef>(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| template <typename TChar> | template <typename TChar> | ||||||
| inline ObjectRef VariantRefBase<TDataSource>::createNestedObject( | inline ObjectRef VariantRefBase<TDerived>::createNestedObject( | ||||||
|     TChar* key) const { |     TChar* key) const { | ||||||
|   return operator[](key).template to<ObjectRef>(); |   return operator[](key).template to<ObjectRef>(); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| template <typename TString> | template <typename TString> | ||||||
| inline typename enable_if<IsString<TString>::value, bool>::type | inline typename enable_if<IsString<TString>::value, bool>::type | ||||||
| VariantRefBase<TDataSource>::containsKey(const TString& key) const { | VariantRefBase<TDerived>::containsKey(const TString& key) const { | ||||||
|   return variantGetMember(VariantAttorney::getData(*this), adaptString(key)) != |   return variantGetMember(VariantAttorney::getData(derived()), | ||||||
|          0; |                           adaptString(key)) != 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| template <typename TChar> | template <typename TChar> | ||||||
| inline typename enable_if<IsString<TChar*>::value, bool>::type | inline typename enable_if<IsString<TChar*>::value, bool>::type | ||||||
| VariantRefBase<TDataSource>::containsKey(TChar* key) const { | VariantRefBase<TDerived>::containsKey(TChar* key) const { | ||||||
|   return variantGetMember(VariantAttorney::getData(*this), adaptString(key)) != |   return variantGetMember(VariantAttorney::getData(derived()), | ||||||
|          0; |                           adaptString(key)) != 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| template <typename TString> | template <typename TString> | ||||||
| inline typename enable_if<IsString<TString*>::value, | inline typename enable_if<IsString<TString*>::value, | ||||||
|                           VariantProxy<MemberDataSource< |                           MemberProxy<TDerived, TString*> >::type | ||||||
|                               VariantRefBase<TDataSource>, TString*> > >::type | VariantRefBase<TDerived>::operator[](TString* key) const { | ||||||
| VariantRefBase<TDataSource>::operator[](TString* key) const { |   return MemberProxy<TDerived, TString*>(derived(), key); | ||||||
|   return VariantProxy<MemberDataSource<VariantRefBase, TString*> >( |  | ||||||
|       MemberDataSource<VariantRefBase, TString*>(*this, key)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| template <typename TString> | template <typename TString> | ||||||
| inline typename enable_if<IsString<TString>::value, | inline typename enable_if<IsString<TString>::value, | ||||||
|                           VariantProxy<MemberDataSource< |                           MemberProxy<TDerived, TString> >::type | ||||||
|                               VariantRefBase<TDataSource>, TString> > >::type | VariantRefBase<TDerived>::operator[](const TString& key) const { | ||||||
| VariantRefBase<TDataSource>::operator[](const TString& key) const { |   return MemberProxy<TDerived, TString>(derived(), key); | ||||||
|   return VariantProxy<MemberDataSource<VariantRefBase, TString> >( |  | ||||||
|       MemberDataSource<VariantRefBase, TString>(*this, key)); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| }  // namespace ARDUINOJSON_NAMESPACE | }  // namespace ARDUINOJSON_NAMESPACE | ||||||
|   | |||||||
| @@ -176,21 +176,17 @@ class ObjectRef : public ObjectRefBase<CollectionData>, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename TString> |   template <typename TString> | ||||||
|   FORCE_INLINE typename enable_if< |   FORCE_INLINE typename enable_if<IsString<TString>::value, | ||||||
|       IsString<TString>::value, |                                   MemberProxy<ObjectRef, TString> >::type | ||||||
|       VariantProxy<MemberDataSource<ObjectRef, TString> > >::type |  | ||||||
|   operator[](const TString& key) const { |   operator[](const TString& key) const { | ||||||
|     return VariantProxy<MemberDataSource<ObjectRef, TString> >( |     return MemberProxy<ObjectRef, TString>(*this, key); | ||||||
|         MemberDataSource<ObjectRef, TString>(*this, key)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename TChar> |   template <typename TChar> | ||||||
|   FORCE_INLINE typename enable_if< |   FORCE_INLINE typename enable_if<IsString<TChar*>::value, | ||||||
|       IsString<TChar*>::value, |                                   MemberProxy<ObjectRef, TChar*> >::type | ||||||
|       VariantProxy<MemberDataSource<ObjectRef, TChar*> > >::type |  | ||||||
|   operator[](TChar* key) const { |   operator[](TChar* key) const { | ||||||
|     return VariantProxy<MemberDataSource<ObjectRef, TChar*> >( |     return MemberProxy<ObjectRef, TChar*>(*this, key); | ||||||
|         MemberDataSource<ObjectRef, TChar*>(*this, key)); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE void remove(iterator it) const { |   FORCE_INLINE void remove(iterator it) const { | ||||||
|   | |||||||
| @@ -104,52 +104,51 @@ inline bool VariantData::copyFrom(const VariantData& src, MemoryPool* pool) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TSource> | template <typename TDerived> | ||||||
| inline VariantRef VariantRefBase<TSource>::add() const { | inline VariantRef VariantRefBase<TDerived>::add() const { | ||||||
|   return VariantRef(getPool(), variantAddElement(getOrCreateData(), getPool())); |   return VariantRef(getPool(), variantAddElement(getOrCreateData(), getPool())); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TSource> | template <typename TDerived> | ||||||
| inline VariantRef VariantRefBase<TSource>::getVariant() const { | inline VariantRef VariantRefBase<TDerived>::getVariant() const { | ||||||
|   return VariantRef(getPool(), getData()); |   return VariantRef(getPool(), getData()); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TSource> | template <typename TDerived> | ||||||
| inline VariantRef VariantRefBase<TSource>::getOrCreateVariant() const { | inline VariantRef VariantRefBase<TDerived>::getOrCreateVariant() const { | ||||||
|   return VariantRef(getPool(), getOrCreateData()); |   return VariantRef(getPool(), getOrCreateData()); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TSource> | template <typename TDerived> | ||||||
| template <typename T> | template <typename T> | ||||||
| inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type | inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type | ||||||
| VariantRefBase<TSource>::to() const { | VariantRefBase<TDerived>::to() const { | ||||||
|   return ArrayRef(getPool(), variantToArray(getOrCreateData())); |   return ArrayRef(getPool(), variantToArray(getOrCreateData())); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TSource> | template <typename TDerived> | ||||||
| template <typename T> | template <typename T> | ||||||
| typename enable_if<is_same<T, ObjectRef>::value, ObjectRef>::type | typename enable_if<is_same<T, ObjectRef>::value, ObjectRef>::type | ||||||
| VariantRefBase<TSource>::to() const { | VariantRefBase<TDerived>::to() const { | ||||||
|   return ObjectRef(getPool(), variantToObject(getOrCreateData())); |   return ObjectRef(getPool(), variantToObject(getOrCreateData())); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TSource> | template <typename TDerived> | ||||||
| template <typename T> | template <typename T> | ||||||
| typename enable_if<is_same<T, VariantRef>::value, VariantRef>::type | typename enable_if<is_same<T, VariantRef>::value, VariantRef>::type | ||||||
| VariantRefBase<TSource>::to() const { | VariantRefBase<TDerived>::to() const { | ||||||
|   variantSetNull(getOrCreateData()); |   variantSetNull(getOrCreateData()); | ||||||
|   return *this; |   return *this; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Out of class definition to avoid #1560 | // Out of class definition to avoid #1560 | ||||||
| template <typename TSource> | template <typename TDerived> | ||||||
| inline bool VariantRefBase<TSource>::set(char value) const { | inline bool VariantRefBase<TDerived>::set(char value) const { | ||||||
|   return set(static_cast<signed char>(value)); |   return set(static_cast<signed char>(value)); | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TDataSource> | template <typename TDerived> | ||||||
| inline void convertToJson(const VariantRefBase<TDataSource>& src, | inline void convertToJson(const VariantRefBase<TDerived>& src, VariantRef dst) { | ||||||
|                           VariantRef dst) { |  | ||||||
|   dst.set(src.template as<VariantConstRef>()); |   dst.set(src.template as<VariantConstRef>()); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,51 +0,0 @@ | |||||||
| // ArduinoJson - https://arduinojson.org |  | ||||||
| // Copyright © 2014-2022, Benoit BLANCHON |  | ||||||
| // MIT License |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include <ArduinoJson/Variant/VariantOperators.hpp> |  | ||||||
| #include <ArduinoJson/Variant/VariantRefBase.hpp> |  | ||||||
|  |  | ||||||
| #ifdef _MSC_VER |  | ||||||
| #  pragma warning(push) |  | ||||||
| #  pragma warning(disable : 4522) |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { |  | ||||||
|  |  | ||||||
| template <typename TDataSource> |  | ||||||
| class VariantProxy : public VariantRefBase<TDataSource>, |  | ||||||
|                      public VariantOperators<VariantProxy<TDataSource> > { |  | ||||||
|  public: |  | ||||||
|   explicit FORCE_INLINE VariantProxy(TDataSource source) |  | ||||||
|       : VariantRefBase<TDataSource>(source) {} |  | ||||||
|  |  | ||||||
|   // Copy-constructor required because of user-defined copy-assignment |  | ||||||
|   // operator |  | ||||||
|   FORCE_INLINE VariantProxy(const VariantProxy& src) |  | ||||||
|       : VariantRefBase<TDataSource>(src) {} |  | ||||||
|  |  | ||||||
|   FORCE_INLINE VariantProxy& operator=(const VariantProxy& src) { |  | ||||||
|     this->set(src); |  | ||||||
|     return *this; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   template <typename T> |  | ||||||
|   FORCE_INLINE VariantProxy& operator=(const T& src) { |  | ||||||
|     this->set(src); |  | ||||||
|     return *this; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   template <typename T> |  | ||||||
|   FORCE_INLINE VariantProxy& operator=(T* src) { |  | ||||||
|     this->set(src); |  | ||||||
|     return *this; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| }  // namespace ARDUINOJSON_NAMESPACE |  | ||||||
|  |  | ||||||
| #ifdef _MSC_VER |  | ||||||
| #  pragma warning(pop) |  | ||||||
| #endif |  | ||||||
| @@ -8,13 +8,16 @@ | |||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| class VariantDataSource { | class VariantRef : public VariantRefBase<VariantRef>, | ||||||
|  |                    public VariantOperators<VariantRef> { | ||||||
|  |   friend class VariantAttorney; | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   VariantDataSource() : _data(0), _pool(0) {} |   VariantRef() : _data(0), _pool(0) {} | ||||||
|  |  | ||||||
|   VariantDataSource(MemoryPool* pool, VariantData* data) |   VariantRef(MemoryPool* pool, VariantData* data) : _data(data), _pool(pool) {} | ||||||
|       : _data(data), _pool(pool) {} |  | ||||||
|  |  | ||||||
|  |  private: | ||||||
|   FORCE_INLINE MemoryPool* getPool() const { |   FORCE_INLINE MemoryPool* getPool() const { | ||||||
|     return _pool; |     return _pool; | ||||||
|   } |   } | ||||||
| @@ -27,20 +30,10 @@ class VariantDataSource { | |||||||
|     return _data; |     return _data; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  | ||||||
|   VariantData* _data; |   VariantData* _data; | ||||||
|   MemoryPool* _pool; |   MemoryPool* _pool; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class VariantRef : public VariantRefBase<VariantDataSource>, |  | ||||||
|                    public VariantOperators<VariantRef> { |  | ||||||
|  public: |  | ||||||
|   VariantRef() : VariantRefBase<VariantDataSource>(VariantDataSource()) {} |  | ||||||
|  |  | ||||||
|   VariantRef(MemoryPool* pool, VariantData* data) |  | ||||||
|       : VariantRefBase<VariantDataSource>(VariantDataSource(pool, data)) {} |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| template <> | template <> | ||||||
| struct Converter<VariantRef> : private VariantAttorney { | struct Converter<VariantRef> : private VariantAttorney { | ||||||
|   static void toJson(VariantRef src, VariantRef dst) { |   static void toJson(VariantRef src, VariantRef dst) { | ||||||
|   | |||||||
| @@ -15,21 +15,16 @@ namespace ARDUINOJSON_NAMESPACE { | |||||||
| class VariantRef; | class VariantRef; | ||||||
|  |  | ||||||
| template <typename> | template <typename> | ||||||
| class ElementDataSource; | class ElementProxy; | ||||||
|  |  | ||||||
| template <typename, typename> | template <typename, typename> | ||||||
| class MemberDataSource; | class MemberProxy; | ||||||
|  |  | ||||||
| template <typename> | template <typename TDerived> | ||||||
| class VariantProxy; |  | ||||||
|  |  | ||||||
| template <typename TDataSource> |  | ||||||
| class VariantRefBase : public VariantTag { | class VariantRefBase : public VariantTag { | ||||||
|   friend class VariantAttorney; |   friend class VariantAttorney; | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   explicit FORCE_INLINE VariantRefBase(TDataSource source) : _source(source) {} |  | ||||||
|  |  | ||||||
|   FORCE_INLINE void clear() const { |   FORCE_INLINE void clear() const { | ||||||
|     variantSetNull(getData()); |     variantSetNull(getData()); | ||||||
|   } |   } | ||||||
| @@ -206,8 +201,7 @@ class VariantRefBase : public VariantTag { | |||||||
|  |  | ||||||
|   FORCE_INLINE ArrayRef createNestedArray() const; |   FORCE_INLINE ArrayRef createNestedArray() const; | ||||||
|   FORCE_INLINE ObjectRef createNestedObject() const; |   FORCE_INLINE ObjectRef createNestedObject() const; | ||||||
|   FORCE_INLINE VariantProxy<ElementDataSource<VariantRefBase> > operator[]( |   FORCE_INLINE ElementProxy<TDerived> operator[](size_t index) const; | ||||||
|       size_t index) const; |  | ||||||
|  |  | ||||||
|   template <typename TString> |   template <typename TString> | ||||||
|   FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type |   FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type | ||||||
| @@ -218,15 +212,13 @@ class VariantRefBase : public VariantTag { | |||||||
|   containsKey(TChar* key) const; |   containsKey(TChar* key) const; | ||||||
|  |  | ||||||
|   template <typename TString> |   template <typename TString> | ||||||
|   FORCE_INLINE typename enable_if< |   FORCE_INLINE typename enable_if<IsString<TString>::value, | ||||||
|       IsString<TString>::value, |                                   MemberProxy<TDerived, TString> >::type | ||||||
|       VariantProxy<MemberDataSource<VariantRefBase, TString> > >::type |  | ||||||
|   operator[](const TString& key) const; |   operator[](const TString& key) const; | ||||||
|  |  | ||||||
|   template <typename TChar> |   template <typename TChar> | ||||||
|   FORCE_INLINE typename enable_if< |   FORCE_INLINE typename enable_if<IsString<TChar*>::value, | ||||||
|       IsString<TChar*>::value, |                                   MemberProxy<TDerived, TChar*> >::type | ||||||
|       VariantProxy<MemberDataSource<VariantRefBase, TChar*> > >::type |  | ||||||
|   operator[](TChar* key) const; |   operator[](TChar* key) const; | ||||||
|  |  | ||||||
|   template <typename TString> |   template <typename TString> | ||||||
| @@ -241,17 +233,25 @@ class VariantRefBase : public VariantTag { | |||||||
|   template <typename TChar> |   template <typename TChar> | ||||||
|   ObjectRef createNestedObject(TChar* key) const; |   ObjectRef createNestedObject(TChar* key) const; | ||||||
|  |  | ||||||
|  protected: |  private: | ||||||
|  |   TDerived& derived() { | ||||||
|  |     return static_cast<TDerived&>(*this); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const TDerived& derived() const { | ||||||
|  |     return static_cast<const TDerived&>(*this); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE MemoryPool* getPool() const { |   FORCE_INLINE MemoryPool* getPool() const { | ||||||
|     return _source.getPool(); |     return VariantAttorney::getPool(derived()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE VariantData* getData() const { |   FORCE_INLINE VariantData* getData() const { | ||||||
|     return _source.getData(); |     return VariantAttorney::getData(derived()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE VariantData* getOrCreateData() const { |   FORCE_INLINE VariantData* getOrCreateData() const { | ||||||
|     return _source.getOrCreateData(); |     return VariantAttorney::getOrCreateData(derived()); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
| @@ -262,8 +262,6 @@ class VariantRefBase : public VariantTag { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE VariantRef getOrCreateVariant() const; |   FORCE_INLINE VariantRef getOrCreateVariant() const; | ||||||
|  |  | ||||||
|   TDataSource _source; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace ARDUINOJSON_NAMESPACE | }  // namespace ARDUINOJSON_NAMESPACE | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user