From 10ec0f21b0418dbffccd09504238c6816b16fa4d Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 23 Oct 2020 10:22:14 +0200 Subject: [PATCH] Fixed `operator|(MemberProxy, JsonObject)` (fixes #1415) --- CHANGELOG.md | 1 + extras/tests/JsonDocument/MemberProxy.cpp | 11 +++++++++++ src/ArduinoJson/Array/ElementProxy.hpp | 5 ++++- src/ArduinoJson/Object/MemberProxy.hpp | 5 ++++- src/ArduinoJson/Variant/VariantOperators.hpp | 14 ++++++++++++-- src/ArduinoJson/Variant/VariantRef.hpp | 6 ++---- src/ArduinoJson/Variant/VariantTag.hpp | 16 ++++++++++++++++ 7 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 src/ArduinoJson/Variant/VariantTag.hpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 13224494..98254812 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ HEAD ---- * Fixed error `ambiguous overload for 'operator|'` (issue #1411) +* Fixed `operator|(MemberProxy, JsonObject)` (issue #1415) v6.17.0 (2020-10-19) ------- diff --git a/extras/tests/JsonDocument/MemberProxy.cpp b/extras/tests/JsonDocument/MemberProxy.cpp index ded18157..ecb41c5c 100644 --- a/extras/tests/JsonDocument/MemberProxy.cpp +++ b/extras/tests/JsonDocument/MemberProxy.cpp @@ -121,6 +121,17 @@ TEST_CASE("MemberProxy::operator|()") { REQUIRE(sensor == std::string("gps")); } + + SECTION("Issue #1415") { + JsonObject object = doc.to(); + object["hello"] = "world"; + + StaticJsonDocument<0> emptyDoc; + JsonObject anotherObject = object["hello"] | emptyDoc.to(); + + REQUIRE(anotherObject.isNull() == false); + REQUIRE(anotherObject.size() == 0); + } } TEST_CASE("MemberProxy::remove()") { diff --git a/src/ArduinoJson/Array/ElementProxy.hpp b/src/ArduinoJson/Array/ElementProxy.hpp index 6d47ef37..41166b6a 100644 --- a/src/ArduinoJson/Array/ElementProxy.hpp +++ b/src/ArduinoJson/Array/ElementProxy.hpp @@ -19,10 +19,13 @@ namespace ARDUINOJSON_NAMESPACE { template class ElementProxy : public VariantOperators >, public VariantShortcuts >, - public Visitable { + public Visitable, + public VariantTag { typedef ElementProxy this_type; public: + typedef VariantRef variant_type; + FORCE_INLINE ElementProxy(TArray array, size_t index) : _array(array), _index(index) {} diff --git a/src/ArduinoJson/Object/MemberProxy.hpp b/src/ArduinoJson/Object/MemberProxy.hpp index a9ee6034..1963deae 100644 --- a/src/ArduinoJson/Object/MemberProxy.hpp +++ b/src/ArduinoJson/Object/MemberProxy.hpp @@ -21,10 +21,13 @@ namespace ARDUINOJSON_NAMESPACE { template class MemberProxy : public VariantOperators >, public VariantShortcuts >, - public Visitable { + public Visitable, + public VariantTag { typedef MemberProxy this_type; public: + typedef VariantRef variant_type; + FORCE_INLINE MemberProxy(TObject variant, TStringRef key) : _object(variant), _key(key) {} diff --git a/src/ArduinoJson/Variant/VariantOperators.hpp b/src/ArduinoJson/Variant/VariantOperators.hpp index b08d92f4..df4e9df2 100644 --- a/src/ArduinoJson/Variant/VariantOperators.hpp +++ b/src/ArduinoJson/Variant/VariantOperators.hpp @@ -9,6 +9,7 @@ #include #include #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -17,15 +18,24 @@ CompareResult compare(const T1 &lhs, const T2 &rhs); // VariantCompare.cpp template struct VariantOperators { - // Returns the default value if the VariantRef is undefined of incompatible + // Returns the default value if the VariantRef is undefined or incompatible template - friend typename enable_if::value, T>::type operator|( + friend typename enable_if::value, T>::type operator|( const TVariant &variant, T defaultValue) { if (variant.template is()) return variant.template as(); else return defaultValue; } + // Returns the default value if the VariantRef is undefined or incompatible + template + friend typename enable_if::value, typename T::variant_type>::type + operator|(const TVariant &variant, T defaultValue) { + if (variant) + return variant; + else + return defaultValue; + } // value == TVariant template diff --git a/src/ArduinoJson/Variant/VariantRef.hpp b/src/ArduinoJson/Variant/VariantRef.hpp index c82ec1ea..a8b9067a 100644 --- a/src/ArduinoJson/Variant/VariantRef.hpp +++ b/src/ArduinoJson/Variant/VariantRef.hpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace ARDUINOJSON_NAMESPACE { @@ -23,12 +24,9 @@ namespace ARDUINOJSON_NAMESPACE { class ArrayRef; class ObjectRef; -template -class MemberProxy; - // Contains the methods shared by VariantRef and VariantConstRef template -class VariantRefBase { +class VariantRefBase : public VariantTag { public: // Tells wether the variant has the specified type. // Returns true if the variant has type type T, false otherwise. diff --git a/src/ArduinoJson/Variant/VariantTag.hpp b/src/ArduinoJson/Variant/VariantTag.hpp new file mode 100644 index 00000000..e9a08aec --- /dev/null +++ b/src/ArduinoJson/Variant/VariantTag.hpp @@ -0,0 +1,16 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2020 +// MIT License + +#pragma once + +#include + +namespace ARDUINOJSON_NAMESPACE { + +struct VariantTag {}; + +template +struct IsVariant : is_base_of {}; + +} // namespace ARDUINOJSON_NAMESPACE