diff --git a/CHANGELOG.md b/CHANGELOG.md index 673975f8..27e60f49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ 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 `JsonDocument::data()` and `JsonDocument::memoryPool()` diff --git a/extras/tests/JsonDocument/ElementProxy.cpp b/extras/tests/JsonDocument/ElementProxy.cpp index 277b62c5..62dcc091 100644 --- a/extras/tests/JsonDocument/ElementProxy.cpp +++ b/extras/tests/JsonDocument/ElementProxy.cpp @@ -7,10 +7,12 @@ using namespace ARDUINOJSON_NAMESPACE; +typedef VariantProxy > ElementProxy; + TEST_CASE("ElementProxy::add()") { DynamicJsonDocument doc(4096); doc.add(); - ElementProxy ep = doc[0]; + ElementProxy ep = doc[0]; SECTION("add(int)") { ep.add(42); @@ -36,7 +38,7 @@ TEST_CASE("ElementProxy::add()") { TEST_CASE("ElementProxy::clear()") { DynamicJsonDocument doc(4096); doc.add(); - ElementProxy ep = doc[0]; + ElementProxy ep = doc[0]; SECTION("size goes back to zero") { ep.add(42); @@ -96,7 +98,7 @@ TEST_CASE("ElementProxy::operator==()") { TEST_CASE("ElementProxy::remove()") { DynamicJsonDocument doc(4096); doc.add(); - ElementProxy ep = doc[0]; + ElementProxy ep = doc[0]; SECTION("remove(int)") { ep.add(1); @@ -143,7 +145,7 @@ TEST_CASE("ElementProxy::remove()") { TEST_CASE("ElementProxy::set()") { DynamicJsonDocument doc(4096); - ElementProxy ep = doc[0]; + ElementProxy ep = doc[0]; SECTION("set(int)") { ep.set(42); @@ -169,7 +171,7 @@ TEST_CASE("ElementProxy::set()") { TEST_CASE("ElementProxy::size()") { DynamicJsonDocument doc(4096); doc.add(); - ElementProxy ep = doc[0]; + ElementProxy ep = doc[0]; SECTION("returns 0") { REQUIRE(ep.size() == 0); @@ -191,7 +193,7 @@ TEST_CASE("ElementProxy::size()") { TEST_CASE("ElementProxy::memoryUsage()") { DynamicJsonDocument doc(4096); doc.add(); - ElementProxy ep = doc[0]; + ElementProxy ep = doc[0]; SECTION("returns 0 for null") { REQUIRE(ep.memoryUsage() == 0); @@ -205,7 +207,7 @@ TEST_CASE("ElementProxy::memoryUsage()") { TEST_CASE("ElementProxy::operator[]") { DynamicJsonDocument doc(4096); - ElementProxy ep = doc[1]; + ElementProxy ep = doc[1]; SECTION("set member") { ep["world"] = 42; @@ -224,7 +226,7 @@ TEST_CASE("ElementProxy cast to JsonVariantConst") { DynamicJsonDocument doc(4096); doc[0] = "world"; - const ElementProxy ep = doc[0]; + const ElementProxy ep = doc[0]; JsonVariantConst var = ep; @@ -235,7 +237,7 @@ TEST_CASE("ElementProxy cast to JsonVariant") { DynamicJsonDocument doc(4096); doc[0] = "world"; - ElementProxy ep = doc[0]; + ElementProxy ep = doc[0]; JsonVariant var = ep; diff --git a/extras/tests/JsonDocument/MemberProxy.cpp b/extras/tests/JsonDocument/MemberProxy.cpp index 99ff62d5..58958a1e 100644 --- a/extras/tests/JsonDocument/MemberProxy.cpp +++ b/extras/tests/JsonDocument/MemberProxy.cpp @@ -7,9 +7,11 @@ using namespace ARDUINOJSON_NAMESPACE; +typedef VariantProxy > MemberProxy; + TEST_CASE("MemberProxy::add()") { DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; SECTION("add(int)") { mp.add(42); @@ -26,7 +28,7 @@ TEST_CASE("MemberProxy::add()") { TEST_CASE("MemberProxy::clear()") { DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; SECTION("size goes back to zero") { mp.add(42); @@ -85,7 +87,7 @@ TEST_CASE("MemberProxy::operator==()") { TEST_CASE("MemberProxy::containsKey()") { DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; SECTION("containsKey(const char*)") { mp["key"] = "value"; @@ -136,7 +138,7 @@ TEST_CASE("MemberProxy::operator|()") { TEST_CASE("MemberProxy::remove()") { DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; SECTION("remove(int)") { mp.add(1); @@ -183,7 +185,7 @@ TEST_CASE("MemberProxy::remove()") { TEST_CASE("MemberProxy::set()") { DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; SECTION("set(int)") { mp.set(42); @@ -208,7 +210,7 @@ TEST_CASE("MemberProxy::set()") { TEST_CASE("MemberProxy::size()") { DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; SECTION("returns 0") { REQUIRE(mp.size() == 0); @@ -231,7 +233,7 @@ TEST_CASE("MemberProxy::size()") { TEST_CASE("MemberProxy::memoryUsage()") { DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; SECTION("returns 0 when null") { REQUIRE(mp.memoryUsage() == 0); @@ -245,7 +247,7 @@ TEST_CASE("MemberProxy::memoryUsage()") { TEST_CASE("MemberProxy::operator[]") { DynamicJsonDocument doc(4096); - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; SECTION("set member") { mp["world"] = 42; @@ -264,7 +266,7 @@ TEST_CASE("MemberProxy cast to JsonVariantConst") { DynamicJsonDocument doc(4096); doc["hello"] = "world"; - const MemberProxy mp = doc["hello"]; + const MemberProxy mp = doc["hello"]; JsonVariantConst var = mp; @@ -275,7 +277,7 @@ TEST_CASE("MemberProxy cast to JsonVariant") { DynamicJsonDocument doc(4096); doc["hello"] = "world"; - MemberProxy mp = doc["hello"]; + MemberProxy mp = doc["hello"]; JsonVariant var = mp; diff --git a/extras/tests/Misc/TypeTraits.cpp b/extras/tests/Misc/TypeTraits.cpp index 5f861afa..9002e6b4 100644 --- a/extras/tests/Misc/TypeTraits.cpp +++ b/extras/tests/Misc/TypeTraits.cpp @@ -184,12 +184,13 @@ TEST_CASE("Polyfills/type_traits") { CHECK((is_convertible::value == true)); CHECK((is_convertible::value == true)); CHECK((is_convertible::value == true)); - CHECK((is_convertible, JsonVariantConst>::value == - true)); + CHECK((is_convertible >, + JsonVariantConst>::value == true)); CHECK((is_convertible::value == true)); CHECK((is_convertible::value == true)); - CHECK((is_convertible, - JsonVariantConst>::value == true)); + CHECK( + (is_convertible >, + JsonVariantConst>::value == true)); CHECK((is_convertible::value == true)); CHECK( (is_convertible::value == true)); diff --git a/src/ArduinoJson/Array/ArrayImpl.hpp b/src/ArduinoJson/Array/ArrayImpl.hpp index 7d3ad9b1..18fd58e0 100644 --- a/src/ArduinoJson/Array/ArrayImpl.hpp +++ b/src/ArduinoJson/Array/ArrayImpl.hpp @@ -20,9 +20,10 @@ inline ObjectRef ArrayShortcuts::createNestedObject() const { } template -inline ElementProxy ArrayShortcuts::operator[]( - size_t index) const { - return ElementProxy(*impl(), index); +inline VariantProxy > +ArrayShortcuts::operator[](size_t index) const { + return VariantProxy >( + ElementDataSource(*impl(), index)); } } // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Array/ArrayRef.hpp b/src/ArduinoJson/Array/ArrayRef.hpp index 2b75e422..41d19f1e 100644 --- a/src/ArduinoJson/Array/ArrayRef.hpp +++ b/src/ArduinoJson/Array/ArrayRef.hpp @@ -17,8 +17,6 @@ namespace ARDUINOJSON_NAMESPACE { class ObjectRef; -template -class ElementProxy; template class ArrayRefBase { diff --git a/src/ArduinoJson/Array/ArrayShortcuts.hpp b/src/ArduinoJson/Array/ArrayShortcuts.hpp index 77c8a2d9..717a20b5 100644 --- a/src/ArduinoJson/Array/ArrayShortcuts.hpp +++ b/src/ArduinoJson/Array/ArrayShortcuts.hpp @@ -11,14 +11,19 @@ namespace ARDUINOJSON_NAMESPACE { // Forward declarations. class ArrayRef; class ObjectRef; + template -class ElementProxy; +class ElementDataSource; + +template +class VariantProxy; template class ArrayShortcuts { public: // Returns the element at specified index if the variant is an array. - FORCE_INLINE ElementProxy operator[](size_t index) const; + FORCE_INLINE VariantProxy > operator[]( + size_t index) const; FORCE_INLINE ObjectRef createNestedObject() const; diff --git a/src/ArduinoJson/Array/ElementProxy.hpp b/src/ArduinoJson/Array/ElementProxy.hpp index 651b37b1..0995b310 100644 --- a/src/ArduinoJson/Array/ElementProxy.hpp +++ b/src/ArduinoJson/Array/ElementProxy.hpp @@ -4,150 +4,16 @@ #pragma once -#include -#include -#include -#include - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4522) -#endif +#include namespace ARDUINOJSON_NAMESPACE { template -class ElementProxy // - : public VariantOperators >, - public VariantShortcuts >, - public VariantTag { - friend class VariantAttorney; - +class ElementDataSource { public: - FORCE_INLINE ElementProxy(TUpstream upstream, size_t index) + ElementDataSource(TUpstream upstream, size_t index) : _upstream(upstream), _index(index) {} - FORCE_INLINE ElementProxy(const ElementProxy& src) - : _upstream(src._upstream), _index(src._index) {} - - FORCE_INLINE ElementProxy& operator=(const ElementProxy& src) { - getOrAddUpstreamVariant().set(src); - return *this; - } - - template - FORCE_INLINE ElementProxy& operator=(const T& src) { - getOrAddUpstreamVariant().set(src); - return *this; - } - - template - FORCE_INLINE ElementProxy& operator=(T* src) { - getOrAddUpstreamVariant().set(src); - return *this; - } - - FORCE_INLINE void clear() const { - getUpstreamVariant().clear(); - } - - FORCE_INLINE bool isNull() const { - return getUpstreamVariantConst().isNull(); - } - - template - FORCE_INLINE typename enable_if::value && - !ConverterNeedsWriteableRef::value, - T>::type - as() const { - return getUpstreamVariantConst().template as(); - } - - template - FORCE_INLINE typename enable_if::value, T>::type - as() const { - return getUpstreamVariant().template as(); - } - - template - FORCE_INLINE typename enable_if::value, const char*>::type - ARDUINOJSON_DEPRECATED("Replace as() with as()") - as() const { - return as(); - } - - template - FORCE_INLINE operator T() const { - return as(); - } - - template - FORCE_INLINE typename VariantTo::type to() { - return getOrAddUpstreamVariant().template to(); - } - - template - FORCE_INLINE - typename enable_if::value, bool>::type - is() const { - return getUpstreamVariant().template is(); - } - - template - FORCE_INLINE - typename enable_if::value, bool>::type - is() const { - return getUpstreamVariantConst().template is(); - } - - FORCE_INLINE void shallowCopy(VariantConstRef value) { - getOrAddUpstreamVariant().shallowCopy(value); - } - - template - FORCE_INLINE bool set(const T& value) { - return getOrAddUpstreamVariant().set(value); - } - - template - FORCE_INLINE bool set(T* value) { - return getOrAddUpstreamVariant().set(value); - } - - FORCE_INLINE size_t size() const { - return getUpstreamVariantConst().size(); - } - - FORCE_INLINE size_t memoryUsage() const { - return getUpstreamVariantConst().memoryUsage(); - } - - FORCE_INLINE VariantRef add() const { - return getOrAddUpstreamVariant().add(); - } - - using ArrayShortcuts >::add; - - FORCE_INLINE void remove(size_t index) const { - getUpstreamVariant().remove(index); - } - // remove(char*) const - // remove(const char*) const - // remove(const __FlashStringHelper*) const - template - FORCE_INLINE typename enable_if::value>::type remove( - TChar* key) const { - getUpstreamVariant().remove(key); - } - // remove(const std::string&) const - // remove(const String&) const - template - FORCE_INLINE typename enable_if::value>::type remove( - const TString& key) const { - getUpstreamVariant().remove(key); - } - - protected: FORCE_INLINE MemoryPool* getPool() const { return VariantAttorney::getPool(_upstream); } @@ -162,28 +28,13 @@ class ElementProxy // } private: - FORCE_INLINE VariantRef getUpstreamVariant() const { - return VariantRef(getPool(), getData()); - } - - FORCE_INLINE VariantConstRef getUpstreamVariantConst() const { - return VariantConstRef(getData()); - } - - FORCE_INLINE VariantRef getOrAddUpstreamVariant() const { - return VariantRef(getPool(), getOrCreateData()); - } - - friend void convertToJson(const ElementProxy& src, VariantRef dst) { - dst.set(src.getUpstreamVariantConst()); - } +#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; - const size_t _index; + size_t _index; }; } // namespace ARDUINOJSON_NAMESPACE - -#ifdef _MSC_VER -# pragma warning(pop) -#endif diff --git a/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp b/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp index 569fa2c5..0112f749 100644 --- a/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp +++ b/src/ArduinoJson/Deserialization/Readers/VariantReader.hpp @@ -9,15 +9,9 @@ namespace ARDUINOJSON_NAMESPACE { -template -struct Reader, void> : Reader { - explicit Reader(const ElementProxy& x) - : Reader(x.template as()) {} -}; - -template -struct Reader, void> : Reader { - explicit Reader(const MemberProxy& x) +template +struct Reader, void> : Reader { + explicit Reader(const VariantProxy& x) : Reader(x.template as()) {} }; diff --git a/src/ArduinoJson/Document/JsonDocument.hpp b/src/ArduinoJson/Document/JsonDocument.hpp index d8e0a291..b7b178b8 100644 --- a/src/ArduinoJson/Document/JsonDocument.hpp +++ b/src/ArduinoJson/Document/JsonDocument.hpp @@ -139,20 +139,24 @@ class JsonDocument : public VariantOperators { // operator[](const std::string&) // operator[](const String&) template - FORCE_INLINE typename enable_if::value, - MemberProxy >::type + FORCE_INLINE typename enable_if< + IsString::value, + VariantProxy > >::type operator[](const TString& key) { - return MemberProxy(*this, key); + return VariantProxy >( + MemberDataSource(*this, key)); } // operator[](char*) // operator[](const char*) // operator[](const __FlashStringHelper*) template - FORCE_INLINE typename enable_if::value, - MemberProxy >::type + FORCE_INLINE typename enable_if< + IsString::value, + VariantProxy > >::type operator[](TChar* key) { - return MemberProxy(*this, key); + return VariantProxy >( + MemberDataSource(*this, key)); } // operator[](const std::string&) const @@ -174,8 +178,10 @@ class JsonDocument : public VariantOperators { return VariantConstRef(_data.getMember(adaptString(key))); } - FORCE_INLINE ElementProxy operator[](size_t index) { - return ElementProxy(*this, index); + FORCE_INLINE VariantProxy > operator[]( + size_t index) { + return VariantProxy >( + ElementDataSource(*this, index)); } FORCE_INLINE VariantConstRef operator[](size_t index) const { diff --git a/src/ArduinoJson/Object/MemberProxy.hpp b/src/ArduinoJson/Object/MemberProxy.hpp index 68f12b0c..df11a9d9 100644 --- a/src/ArduinoJson/Object/MemberProxy.hpp +++ b/src/ArduinoJson/Object/MemberProxy.hpp @@ -4,153 +4,16 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4522) -#endif +#include namespace ARDUINOJSON_NAMESPACE { template -class MemberProxy // - : public VariantOperators >, - public VariantShortcuts >, - public VariantTag { - friend class VariantAttorney; - +class MemberDataSource { public: - FORCE_INLINE MemberProxy(TUpstream upstream, TStringRef key) + FORCE_INLINE MemberDataSource(TUpstream upstream, TStringRef key) : _upstream(upstream), _key(key) {} - FORCE_INLINE MemberProxy(const MemberProxy& src) - : _upstream(src._upstream), _key(src._key) {} - - FORCE_INLINE MemberProxy& operator=(const MemberProxy& src) { - getOrAddUpstreamVariant().set(src); - return *this; - } - - template - FORCE_INLINE MemberProxy& operator=(const T& src) { - getOrAddUpstreamVariant().set(src); - return *this; - } - - template - FORCE_INLINE MemberProxy& operator=(T* src) { - getOrAddUpstreamVariant().set(src); - return *this; - } - - FORCE_INLINE void clear() const { - getUpstreamVariant().clear(); - } - - FORCE_INLINE bool isNull() const { - return getUpstreamVariantConst().isNull(); - } - - template - FORCE_INLINE typename enable_if::value && - !ConverterNeedsWriteableRef::value, - T>::type - as() const { - return getUpstreamVariantConst().template as(); - } - - template - FORCE_INLINE typename enable_if::value, T>::type - as() const { - return getUpstreamVariant().template as(); - } - - template - FORCE_INLINE typename enable_if::value, const char*>::type - ARDUINOJSON_DEPRECATED("Replace as() with as()") - as() const { - return as(); - } - - template - FORCE_INLINE operator T() const { - return as(); - } - - template - FORCE_INLINE typename VariantTo::type to() { - return getOrAddUpstreamVariant().template to(); - } - - template - FORCE_INLINE - typename enable_if::value, bool>::type - is() const { - return getUpstreamVariant().template is(); - } - - template - FORCE_INLINE - typename enable_if::value, bool>::type - is() const { - return getUpstreamVariantConst().template is(); - } - - FORCE_INLINE void shallowCopy(VariantConstRef value) { - getOrAddUpstreamVariant().shallowCopy(value); - } - - template - FORCE_INLINE bool set(const T& value) { - return getOrAddUpstreamVariant().set(value); - } - - template - FORCE_INLINE bool set(T* value) { - return getOrAddUpstreamVariant().set(value); - } - - FORCE_INLINE size_t size() const { - return getUpstreamVariantConst().size(); - } - - FORCE_INLINE size_t memoryUsage() const { - return getUpstreamVariantConst().memoryUsage(); - } - - FORCE_INLINE VariantRef add() const { - return getOrAddUpstreamVariant().add(); - } - - using ArrayShortcuts >::add; - - FORCE_INLINE void remove(size_t index) const { - getUpstreamVariant().remove(index); - } - // remove(char*) const - // remove(const char*) const - // remove(const __FlashStringHelper*) const - template - FORCE_INLINE typename enable_if::value>::type remove( - TChar* key) const { - getUpstreamVariant().remove(key); - } - // remove(const std::string&) const - // remove(const String&) const - template - FORCE_INLINE typename enable_if::value>::type remove( - const TString& key) const { - getUpstreamVariant().remove(key); - } - - protected: FORCE_INLINE MemoryPool* getPool() const { return VariantAttorney::getPool(_upstream); } @@ -166,28 +29,13 @@ class MemberProxy // } private: - FORCE_INLINE VariantRef getUpstreamVariant() const { - return VariantRef(getPool(), getData()); - } - - FORCE_INLINE VariantConstRef getUpstreamVariantConst() const { - return VariantConstRef(getData()); - } - - FORCE_INLINE VariantRef getOrAddUpstreamVariant() const { - return VariantRef(getPool(), getOrCreateData()); - } - - friend void convertToJson(const MemberProxy& src, VariantRef dst) { - dst.set(src.getUpstreamVariantConst()); - } +#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; }; } // namespace ARDUINOJSON_NAMESPACE - -#ifdef _MSC_VER -# pragma warning(pop) -#endif diff --git a/src/ArduinoJson/Object/ObjectImpl.hpp b/src/ArduinoJson/Object/ObjectImpl.hpp index 22d462aa..88c27c71 100644 --- a/src/ArduinoJson/Object/ObjectImpl.hpp +++ b/src/ArduinoJson/Object/ObjectImpl.hpp @@ -54,18 +54,22 @@ ObjectShortcuts::containsKey(TChar* key) const { template template -inline typename enable_if::value, - MemberProxy >::type +inline typename enable_if< + IsString::value, + VariantProxy > >::type ObjectShortcuts::operator[](TString* key) const { - return MemberProxy(*impl(), key); + return VariantProxy >( + MemberDataSource(*impl(), key)); } template template -inline typename enable_if::value, - MemberProxy >::type -ObjectShortcuts::operator[](const TString& key) const { - return MemberProxy(*impl(), key); +inline + typename enable_if::value, + VariantProxy > >::type + ObjectShortcuts::operator[](const TString& key) const { + return VariantProxy >( + MemberDataSource(*impl(), key)); } } // namespace ARDUINOJSON_NAMESPACE diff --git a/src/ArduinoJson/Object/ObjectShortcuts.hpp b/src/ArduinoJson/Object/ObjectShortcuts.hpp index 3644a393..d40e9a2a 100644 --- a/src/ArduinoJson/Object/ObjectShortcuts.hpp +++ b/src/ArduinoJson/Object/ObjectShortcuts.hpp @@ -9,8 +9,11 @@ #include namespace ARDUINOJSON_NAMESPACE { +template +class VariantProxy; + template -class MemberProxy; +class MemberDataSource; template class ObjectShortcuts { @@ -31,16 +34,18 @@ class ObjectShortcuts { // operator[](const std::string&) const // operator[](const String&) const template - FORCE_INLINE typename enable_if::value, - MemberProxy >::type + FORCE_INLINE typename enable_if< + IsString::value, + VariantProxy > >::type operator[](const TString& key) const; // operator[](char*) const // operator[](const char*) const // operator[](const __FlashStringHelper*) const template - FORCE_INLINE typename enable_if::value, - MemberProxy >::type + FORCE_INLINE typename enable_if< + IsString::value, + VariantProxy > >::type operator[](TChar* key) const; // createNestedArray(const std::string&) const diff --git a/src/ArduinoJson/Variant/VariantProxy.hpp b/src/ArduinoJson/Variant/VariantProxy.hpp new file mode 100644 index 00000000..3cba15e1 --- /dev/null +++ b/src/ArduinoJson/Variant/VariantProxy.hpp @@ -0,0 +1,185 @@ +// ArduinoJson - https://arduinojson.org +// Copyright © 2014-2022, Benoit BLANCHON +// MIT License + +#pragma once + +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4522) +#endif + +namespace ARDUINOJSON_NAMESPACE { + +template +class VariantProxy : public VariantShortcuts >, + public VariantOperators >, + public VariantTag { + friend class VariantAttorney; + + public: + explicit FORCE_INLINE VariantProxy(TDataSource source) : _source(source) {} + + // Copy-constructor required because of user-defined copy-assignment operator + FORCE_INLINE VariantProxy(const VariantProxy& src) : _source(src._source) {} + + FORCE_INLINE VariantProxy& operator=(const VariantProxy& src) { + getOrAddUpstreamVariant().set(src); + return *this; + } + + template + FORCE_INLINE VariantProxy& operator=(const T& src) { + getOrAddUpstreamVariant().set(src); + return *this; + } + + template + FORCE_INLINE VariantProxy& operator=(T* src) { + getOrAddUpstreamVariant().set(src); + return *this; + } + + FORCE_INLINE void clear() const { + getUpstreamVariant().clear(); + } + + FORCE_INLINE bool isNull() const { + return getUpstreamVariantConst().isNull(); + } + + template + FORCE_INLINE typename enable_if::value && + !ConverterNeedsWriteableRef::value, + T>::type + as() const { + return getUpstreamVariantConst().template as(); + } + + template + FORCE_INLINE typename enable_if::value, T>::type + as() const { + return getUpstreamVariant().template as(); + } + + template + FORCE_INLINE typename enable_if::value, const char*>::type + ARDUINOJSON_DEPRECATED("Replace as() with as()") + as() const { + return as(); + } + + template + FORCE_INLINE operator T() const { + return as(); + } + + template + FORCE_INLINE typename VariantTo::type to() { + return getOrAddUpstreamVariant().template to(); + } + + template + FORCE_INLINE + typename enable_if::value, bool>::type + is() const { + return getUpstreamVariant().template is(); + } + + template + FORCE_INLINE + typename enable_if::value, bool>::type + is() const { + return getUpstreamVariantConst().template is(); + } + + FORCE_INLINE void shallowCopy(VariantConstRef value) { + getOrAddUpstreamVariant().shallowCopy(value); + } + + template + FORCE_INLINE bool set(const T& value) { + return getOrAddUpstreamVariant().set(value); + } + + template + FORCE_INLINE bool set(T* value) { + return getOrAddUpstreamVariant().set(value); + } + + FORCE_INLINE size_t size() const { + return getUpstreamVariantConst().size(); + } + + FORCE_INLINE size_t memoryUsage() const { + return getUpstreamVariantConst().memoryUsage(); + } + + FORCE_INLINE VariantRef add() const { + return getOrAddUpstreamVariant().add(); + } + + using ArrayShortcuts >::add; + + FORCE_INLINE void remove(size_t index) const { + getUpstreamVariant().remove(index); + } + // remove(char*) const + // remove(const char*) const + // remove(const __FlashStringHelper*) const + template + FORCE_INLINE typename enable_if::value>::type remove( + TChar* key) const { + getUpstreamVariant().remove(key); + } + // remove(const std::string&) const + // remove(const String&) const + template + FORCE_INLINE typename enable_if::value>::type remove( + const TString& key) const { + getUpstreamVariant().remove(key); + } + + protected: + FORCE_INLINE MemoryPool* getPool() const { + return _source.getPool(); + } + + FORCE_INLINE VariantData* getData() const { + return _source.getData(); + } + + FORCE_INLINE VariantData* getOrCreateData() const { + return _source.getOrCreateData(); + } + + private: + FORCE_INLINE VariantRef getUpstreamVariant() const { + return VariantRef(getPool(), getData()); + } + + FORCE_INLINE VariantConstRef getUpstreamVariantConst() const { + return VariantConstRef(getData()); + } + + FORCE_INLINE VariantRef getOrAddUpstreamVariant() const { + return VariantRef(getPool(), getOrCreateData()); + } + + friend void convertToJson(const VariantProxy& src, VariantRef dst) { + dst.set(src.getUpstreamVariantConst()); + } + + const TDataSource _source; +}; + +} // namespace ARDUINOJSON_NAMESPACE + +#ifdef _MSC_VER +# pragma warning(pop) +#endif