mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 00:32:37 +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 lax parsing of `true`, `false`, and `null` (issue #1781) | ||||
| * Remove undocumented `accept()` functions | ||||
| * Remove undocumented `ElementProxy` and `MemberProxy` classes | ||||
| * Rename `addElement()` to `add()` | ||||
| * Remove `getElement()`, `getOrAddElement()`, `getMember()`, and `getOrAddMember()` | ||||
| * Remove undocumented `JsonDocument::data()` and `JsonDocument::memoryPool()` | ||||
|   | ||||
| @@ -5,9 +5,7 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| typedef VariantProxy<ElementDataSource<JsonDocument&> > ElementProxy; | ||||
| typedef ARDUINOJSON_NAMESPACE::ElementProxy<JsonDocument&> ElementProxy; | ||||
|  | ||||
| TEST_CASE("ElementProxy::add()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   | ||||
| @@ -5,9 +5,8 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| typedef VariantProxy<MemberDataSource<JsonDocument&, const char*> > MemberProxy; | ||||
| typedef ARDUINOJSON_NAMESPACE::MemberProxy<JsonDocument&, const char*> | ||||
|     MemberProxy; | ||||
|  | ||||
| TEST_CASE("MemberProxy::add()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   | ||||
| @@ -184,13 +184,12 @@ TEST_CASE("Polyfills/type_traits") { | ||||
|     CHECK((is_convertible<VariantRef, JsonVariantConst>::value == true)); | ||||
|     CHECK((is_convertible<VariantConstRef, JsonVariantConst>::value == true)); | ||||
|     CHECK((is_convertible<ArrayRef, JsonVariantConst>::value == true)); | ||||
|     CHECK((is_convertible<VariantProxy<ElementDataSource<ArrayRef> >, | ||||
|                           JsonVariantConst>::value == true)); | ||||
|     CHECK((is_convertible<ElementProxy<ArrayRef>, JsonVariantConst>::value == | ||||
|            true)); | ||||
|     CHECK((is_convertible<ArrayConstRef, JsonVariantConst>::value == true)); | ||||
|     CHECK((is_convertible<ObjectRef, JsonVariantConst>::value == true)); | ||||
|     CHECK( | ||||
|         (is_convertible<VariantProxy<MemberDataSource<ObjectRef, const char*> >, | ||||
|                         JsonVariantConst>::value == true)); | ||||
|     CHECK((is_convertible<MemberProxy<ObjectRef, const char*>, | ||||
|                           JsonVariantConst>::value == true)); | ||||
|     CHECK((is_convertible<ObjectConstRef, JsonVariantConst>::value == true)); | ||||
|     CHECK( | ||||
|         (is_convertible<DynamicJsonDocument, JsonVariantConst>::value == true)); | ||||
|   | ||||
| @@ -13,21 +13,20 @@ inline ObjectRef ArrayRef::createNestedObject() const { | ||||
|   return add().to<ObjectRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| inline ArrayRef VariantRefBase<TDataSource>::createNestedArray() const { | ||||
| template <typename TDerived> | ||||
| inline ArrayRef VariantRefBase<TDerived>::createNestedArray() const { | ||||
|   return add().template to<ArrayRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| inline ObjectRef VariantRefBase<TDataSource>::createNestedObject() const { | ||||
| template <typename TDerived> | ||||
| inline ObjectRef VariantRefBase<TDerived>::createNestedObject() const { | ||||
|   return add().template to<ObjectRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| inline VariantProxy<ElementDataSource<VariantRefBase<TDataSource> > > | ||||
| VariantRefBase<TDataSource>::operator[](size_t index) const { | ||||
|   return VariantProxy<ElementDataSource<VariantRefBase<TDataSource> > >( | ||||
|       ElementDataSource<VariantRefBase<TDataSource> >(*this, index)); | ||||
| template <typename TDerived> | ||||
| inline ElementProxy<TDerived> VariantRefBase<TDerived>::operator[]( | ||||
|     size_t index) const { | ||||
|   return ElementProxy<TDerived>(derived(), index); | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -184,10 +184,8 @@ class ArrayRef : public ArrayRefBase<CollectionData>, | ||||
|   } | ||||
|  | ||||
|   // Returns the element at specified index if the variant is an array. | ||||
|   FORCE_INLINE VariantProxy<ElementDataSource<ArrayRef> > operator[]( | ||||
|       size_t index) const { | ||||
|     return VariantProxy<ElementDataSource<ArrayRef> >( | ||||
|         ElementDataSource<ArrayRef>(*this, index)); | ||||
|   FORCE_INLINE ElementProxy<ArrayRef> operator[](size_t index) const { | ||||
|     return ElementProxy<ArrayRef>(*this, index); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE ObjectRef createNestedObject() const; | ||||
|   | ||||
| @@ -4,16 +4,40 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Variant/VariantProxy.hpp> | ||||
| #include <ArduinoJson/Variant/VariantRefBase.hpp> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename TUpstream> | ||||
| class ElementDataSource { | ||||
| class ElementProxy : public VariantRefBase<ElementProxy<TUpstream> >, | ||||
|                      public VariantOperators<ElementProxy<TUpstream> > { | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   ElementDataSource(TUpstream upstream, size_t index) | ||||
|   ElementProxy(TUpstream upstream, size_t 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 { | ||||
|     return VariantAttorney::getPool(_upstream); | ||||
|   } | ||||
| @@ -27,12 +51,6 @@ class ElementDataSource { | ||||
|                                   _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; | ||||
|   size_t _index; | ||||
| }; | ||||
|   | ||||
| @@ -139,24 +139,20 @@ class JsonDocument : public VariantOperators<const JsonDocument&> { | ||||
|   // operator[](const std::string&) | ||||
|   // operator[](const String&) | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE typename enable_if< | ||||
|       IsString<TString>::value, | ||||
|       VariantProxy<MemberDataSource<JsonDocument&, TString> > >::type | ||||
|   FORCE_INLINE typename enable_if<IsString<TString>::value, | ||||
|                                   MemberProxy<JsonDocument&, TString> >::type | ||||
|   operator[](const TString& key) { | ||||
|     return VariantProxy<MemberDataSource<JsonDocument&, TString> >( | ||||
|         MemberDataSource<JsonDocument&, TString>(*this, key)); | ||||
|     return MemberProxy<JsonDocument&, TString>(*this, key); | ||||
|   } | ||||
|  | ||||
|   // operator[](char*) | ||||
|   // operator[](const char*) | ||||
|   // operator[](const __FlashStringHelper*) | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE typename enable_if< | ||||
|       IsString<TChar*>::value, | ||||
|       VariantProxy<MemberDataSource<JsonDocument&, TChar*> > >::type | ||||
|   FORCE_INLINE typename enable_if<IsString<TChar*>::value, | ||||
|                                   MemberProxy<JsonDocument&, TChar*> >::type | ||||
|   operator[](TChar* key) { | ||||
|     return VariantProxy<MemberDataSource<JsonDocument&, TChar*> >( | ||||
|         MemberDataSource<JsonDocument&, TChar*>(*this, key)); | ||||
|     return MemberProxy<JsonDocument&, TChar*>(*this, key); | ||||
|   } | ||||
|  | ||||
|   // operator[](const std::string&) const | ||||
| @@ -178,10 +174,8 @@ class JsonDocument : public VariantOperators<const JsonDocument&> { | ||||
|     return VariantConstRef(_data.getMember(adaptString(key))); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantProxy<ElementDataSource<JsonDocument&> > operator[]( | ||||
|       size_t index) { | ||||
|     return VariantProxy<ElementDataSource<JsonDocument&> >( | ||||
|         ElementDataSource<JsonDocument&>(*this, index)); | ||||
|   FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) { | ||||
|     return ElementProxy<JsonDocument&>(*this, index); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantConstRef operator[](size_t index) const { | ||||
|   | ||||
| @@ -4,16 +4,41 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Variant/VariantProxy.hpp> | ||||
| #include <ArduinoJson/Variant/VariantRefBase.hpp> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename TUpstream, typename TStringRef> | ||||
| class MemberDataSource { | ||||
| class MemberProxy | ||||
|     : public VariantRefBase<MemberProxy<TUpstream, TStringRef> >, | ||||
|       public VariantOperators<MemberProxy<TUpstream, TStringRef> > { | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   FORCE_INLINE MemberDataSource(TUpstream upstream, TStringRef key) | ||||
|   FORCE_INLINE MemberProxy(TUpstream upstream, TStringRef 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 { | ||||
|     return VariantAttorney::getPool(_upstream); | ||||
|   } | ||||
| @@ -30,11 +55,6 @@ class MemberDataSource { | ||||
|   } | ||||
|  | ||||
|  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; | ||||
|   TStringRef _key; | ||||
| }; | ||||
|   | ||||
| @@ -19,68 +19,63 @@ inline ArrayRef ObjectRef::createNestedArray(TChar* key) const { | ||||
|   return operator[](key).template to<ArrayRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| template <typename TString> | ||||
| inline ArrayRef VariantRefBase<TDataSource>::createNestedArray( | ||||
| inline ArrayRef VariantRefBase<TDerived>::createNestedArray( | ||||
|     const TString& key) const { | ||||
|   return operator[](key).template to<ArrayRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| template <typename TChar> | ||||
| inline ArrayRef VariantRefBase<TDataSource>::createNestedArray( | ||||
|     TChar* key) const { | ||||
| inline ArrayRef VariantRefBase<TDerived>::createNestedArray(TChar* key) const { | ||||
|   return operator[](key).template to<ArrayRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| template <typename TString> | ||||
| inline ObjectRef VariantRefBase<TDataSource>::createNestedObject( | ||||
| inline ObjectRef VariantRefBase<TDerived>::createNestedObject( | ||||
|     const TString& key) const { | ||||
|   return operator[](key).template to<ObjectRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| template <typename TChar> | ||||
| inline ObjectRef VariantRefBase<TDataSource>::createNestedObject( | ||||
| inline ObjectRef VariantRefBase<TDerived>::createNestedObject( | ||||
|     TChar* key) const { | ||||
|   return operator[](key).template to<ObjectRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| template <typename TString> | ||||
| inline typename enable_if<IsString<TString>::value, bool>::type | ||||
| VariantRefBase<TDataSource>::containsKey(const TString& key) const { | ||||
|   return variantGetMember(VariantAttorney::getData(*this), adaptString(key)) != | ||||
|          0; | ||||
| VariantRefBase<TDerived>::containsKey(const TString& key) const { | ||||
|   return variantGetMember(VariantAttorney::getData(derived()), | ||||
|                           adaptString(key)) != 0; | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| template <typename TChar> | ||||
| inline typename enable_if<IsString<TChar*>::value, bool>::type | ||||
| VariantRefBase<TDataSource>::containsKey(TChar* key) const { | ||||
|   return variantGetMember(VariantAttorney::getData(*this), adaptString(key)) != | ||||
|          0; | ||||
| VariantRefBase<TDerived>::containsKey(TChar* key) const { | ||||
|   return variantGetMember(VariantAttorney::getData(derived()), | ||||
|                           adaptString(key)) != 0; | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| template <typename TString> | ||||
| inline typename enable_if<IsString<TString*>::value, | ||||
|                           VariantProxy<MemberDataSource< | ||||
|                               VariantRefBase<TDataSource>, TString*> > >::type | ||||
| VariantRefBase<TDataSource>::operator[](TString* key) const { | ||||
|   return VariantProxy<MemberDataSource<VariantRefBase, TString*> >( | ||||
|       MemberDataSource<VariantRefBase, TString*>(*this, key)); | ||||
|                           MemberProxy<TDerived, TString*> >::type | ||||
| VariantRefBase<TDerived>::operator[](TString* key) const { | ||||
|   return MemberProxy<TDerived, TString*>(derived(), key); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| template <typename TString> | ||||
| inline typename enable_if<IsString<TString>::value, | ||||
|                           VariantProxy<MemberDataSource< | ||||
|                               VariantRefBase<TDataSource>, TString> > >::type | ||||
| VariantRefBase<TDataSource>::operator[](const TString& key) const { | ||||
|   return VariantProxy<MemberDataSource<VariantRefBase, TString> >( | ||||
|       MemberDataSource<VariantRefBase, TString>(*this, key)); | ||||
|                           MemberProxy<TDerived, TString> >::type | ||||
| VariantRefBase<TDerived>::operator[](const TString& key) const { | ||||
|   return MemberProxy<TDerived, TString>(derived(), key); | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -176,21 +176,17 @@ class ObjectRef : public ObjectRefBase<CollectionData>, | ||||
|   } | ||||
|  | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE typename enable_if< | ||||
|       IsString<TString>::value, | ||||
|       VariantProxy<MemberDataSource<ObjectRef, TString> > >::type | ||||
|   FORCE_INLINE typename enable_if<IsString<TString>::value, | ||||
|                                   MemberProxy<ObjectRef, TString> >::type | ||||
|   operator[](const TString& key) const { | ||||
|     return VariantProxy<MemberDataSource<ObjectRef, TString> >( | ||||
|         MemberDataSource<ObjectRef, TString>(*this, key)); | ||||
|     return MemberProxy<ObjectRef, TString>(*this, key); | ||||
|   } | ||||
|  | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE typename enable_if< | ||||
|       IsString<TChar*>::value, | ||||
|       VariantProxy<MemberDataSource<ObjectRef, TChar*> > >::type | ||||
|   FORCE_INLINE typename enable_if<IsString<TChar*>::value, | ||||
|                                   MemberProxy<ObjectRef, TChar*> >::type | ||||
|   operator[](TChar* key) const { | ||||
|     return VariantProxy<MemberDataSource<ObjectRef, TChar*> >( | ||||
|         MemberDataSource<ObjectRef, TChar*>(*this, key)); | ||||
|     return MemberProxy<ObjectRef, TChar*>(*this, key); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE void remove(iterator it) const { | ||||
|   | ||||
| @@ -104,52 +104,51 @@ inline bool VariantData::copyFrom(const VariantData& src, MemoryPool* pool) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| template <typename TSource> | ||||
| inline VariantRef VariantRefBase<TSource>::add() const { | ||||
| template <typename TDerived> | ||||
| inline VariantRef VariantRefBase<TDerived>::add() const { | ||||
|   return VariantRef(getPool(), variantAddElement(getOrCreateData(), getPool())); | ||||
| } | ||||
|  | ||||
| template <typename TSource> | ||||
| inline VariantRef VariantRefBase<TSource>::getVariant() const { | ||||
| template <typename TDerived> | ||||
| inline VariantRef VariantRefBase<TDerived>::getVariant() const { | ||||
|   return VariantRef(getPool(), getData()); | ||||
| } | ||||
|  | ||||
| template <typename TSource> | ||||
| inline VariantRef VariantRefBase<TSource>::getOrCreateVariant() const { | ||||
| template <typename TDerived> | ||||
| inline VariantRef VariantRefBase<TDerived>::getOrCreateVariant() const { | ||||
|   return VariantRef(getPool(), getOrCreateData()); | ||||
| } | ||||
|  | ||||
| template <typename TSource> | ||||
| template <typename TDerived> | ||||
| template <typename T> | ||||
| inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type | ||||
| VariantRefBase<TSource>::to() const { | ||||
| VariantRefBase<TDerived>::to() const { | ||||
|   return ArrayRef(getPool(), variantToArray(getOrCreateData())); | ||||
| } | ||||
|  | ||||
| template <typename TSource> | ||||
| template <typename TDerived> | ||||
| template <typename T> | ||||
| typename enable_if<is_same<T, ObjectRef>::value, ObjectRef>::type | ||||
| VariantRefBase<TSource>::to() const { | ||||
| VariantRefBase<TDerived>::to() const { | ||||
|   return ObjectRef(getPool(), variantToObject(getOrCreateData())); | ||||
| } | ||||
|  | ||||
| template <typename TSource> | ||||
| template <typename TDerived> | ||||
| template <typename T> | ||||
| typename enable_if<is_same<T, VariantRef>::value, VariantRef>::type | ||||
| VariantRefBase<TSource>::to() const { | ||||
| VariantRefBase<TDerived>::to() const { | ||||
|   variantSetNull(getOrCreateData()); | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| // Out of class definition to avoid #1560 | ||||
| template <typename TSource> | ||||
| inline bool VariantRefBase<TSource>::set(char value) const { | ||||
| template <typename TDerived> | ||||
| inline bool VariantRefBase<TDerived>::set(char value) const { | ||||
|   return set(static_cast<signed char>(value)); | ||||
| } | ||||
|  | ||||
| template <typename TDataSource> | ||||
| inline void convertToJson(const VariantRefBase<TDataSource>& src, | ||||
|                           VariantRef dst) { | ||||
| template <typename TDerived> | ||||
| inline void convertToJson(const VariantRefBase<TDerived>& src, VariantRef dst) { | ||||
|   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 { | ||||
|  | ||||
| class VariantDataSource { | ||||
| class VariantRef : public VariantRefBase<VariantRef>, | ||||
|                    public VariantOperators<VariantRef> { | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   VariantDataSource() : _data(0), _pool(0) {} | ||||
|   VariantRef() : _data(0), _pool(0) {} | ||||
|  | ||||
|   VariantDataSource(MemoryPool* pool, VariantData* data) | ||||
|       : _data(data), _pool(pool) {} | ||||
|   VariantRef(MemoryPool* pool, VariantData* data) : _data(data), _pool(pool) {} | ||||
|  | ||||
|  private: | ||||
|   FORCE_INLINE MemoryPool* getPool() const { | ||||
|     return _pool; | ||||
|   } | ||||
| @@ -27,20 +30,10 @@ class VariantDataSource { | ||||
|     return _data; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   VariantData* _data; | ||||
|   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 <> | ||||
| struct Converter<VariantRef> : private VariantAttorney { | ||||
|   static void toJson(VariantRef src, VariantRef dst) { | ||||
|   | ||||
| @@ -15,21 +15,16 @@ namespace ARDUINOJSON_NAMESPACE { | ||||
| class VariantRef; | ||||
|  | ||||
| template <typename> | ||||
| class ElementDataSource; | ||||
| class ElementProxy; | ||||
|  | ||||
| template <typename, typename> | ||||
| class MemberDataSource; | ||||
| class MemberProxy; | ||||
|  | ||||
| template <typename> | ||||
| class VariantProxy; | ||||
|  | ||||
| template <typename TDataSource> | ||||
| template <typename TDerived> | ||||
| class VariantRefBase : public VariantTag { | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   explicit FORCE_INLINE VariantRefBase(TDataSource source) : _source(source) {} | ||||
|  | ||||
|   FORCE_INLINE void clear() const { | ||||
|     variantSetNull(getData()); | ||||
|   } | ||||
| @@ -206,8 +201,7 @@ class VariantRefBase : public VariantTag { | ||||
|  | ||||
|   FORCE_INLINE ArrayRef createNestedArray() const; | ||||
|   FORCE_INLINE ObjectRef createNestedObject() const; | ||||
|   FORCE_INLINE VariantProxy<ElementDataSource<VariantRefBase> > operator[]( | ||||
|       size_t index) const; | ||||
|   FORCE_INLINE ElementProxy<TDerived> operator[](size_t index) const; | ||||
|  | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type | ||||
| @@ -218,15 +212,13 @@ class VariantRefBase : public VariantTag { | ||||
|   containsKey(TChar* key) const; | ||||
|  | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE typename enable_if< | ||||
|       IsString<TString>::value, | ||||
|       VariantProxy<MemberDataSource<VariantRefBase, TString> > >::type | ||||
|   FORCE_INLINE typename enable_if<IsString<TString>::value, | ||||
|                                   MemberProxy<TDerived, TString> >::type | ||||
|   operator[](const TString& key) const; | ||||
|  | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE typename enable_if< | ||||
|       IsString<TChar*>::value, | ||||
|       VariantProxy<MemberDataSource<VariantRefBase, TChar*> > >::type | ||||
|   FORCE_INLINE typename enable_if<IsString<TChar*>::value, | ||||
|                                   MemberProxy<TDerived, TChar*> >::type | ||||
|   operator[](TChar* key) const; | ||||
|  | ||||
|   template <typename TString> | ||||
| @@ -241,17 +233,25 @@ class VariantRefBase : public VariantTag { | ||||
|   template <typename TChar> | ||||
|   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 { | ||||
|     return _source.getPool(); | ||||
|     return VariantAttorney::getPool(derived()); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantData* getData() const { | ||||
|     return _source.getData(); | ||||
|     return VariantAttorney::getData(derived()); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantData* getOrCreateData() const { | ||||
|     return _source.getOrCreateData(); | ||||
|     return VariantAttorney::getOrCreateData(derived()); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
| @@ -262,8 +262,6 @@ class VariantRefBase : public VariantTag { | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantRef getOrCreateVariant() const; | ||||
|  | ||||
|   TDataSource _source; | ||||
| }; | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
		Reference in New Issue
	
	Block a user