فهرست منبع

Fixed `operator|(MemberProxy, JsonObject)` (fixes #1415)

Benoit Blanchon 5 سال پیش
والد
کامیت
10ec0f21b0

+ 1 - 0
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)
 -------

+ 11 - 0
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<JsonObject>();
+    object["hello"] = "world";
+
+    StaticJsonDocument<0> emptyDoc;
+    JsonObject anotherObject = object["hello"] | emptyDoc.to<JsonObject>();
+
+    REQUIRE(anotherObject.isNull() == false);
+    REQUIRE(anotherObject.size() == 0);
+  }
 }
 
 TEST_CASE("MemberProxy::remove()") {

+ 4 - 1
src/ArduinoJson/Array/ElementProxy.hpp

@@ -19,10 +19,13 @@ namespace ARDUINOJSON_NAMESPACE {
 template <typename TArray>
 class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
                      public VariantShortcuts<ElementProxy<TArray> >,
-                     public Visitable {
+                     public Visitable,
+                     public VariantTag {
   typedef ElementProxy<TArray> this_type;
 
  public:
+  typedef VariantRef variant_type;
+
   FORCE_INLINE ElementProxy(TArray array, size_t index)
       : _array(array), _index(index) {}
 

+ 4 - 1
src/ArduinoJson/Object/MemberProxy.hpp

@@ -21,10 +21,13 @@ namespace ARDUINOJSON_NAMESPACE {
 template <typename TObject, typename TStringRef>
 class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
                     public VariantShortcuts<MemberProxy<TObject, TStringRef> >,
-                    public Visitable {
+                    public Visitable,
+                    public VariantTag {
   typedef MemberProxy<TObject, TStringRef> this_type;
 
  public:
+  typedef VariantRef variant_type;
+
   FORCE_INLINE MemberProxy(TObject variant, TStringRef key)
       : _object(variant), _key(key) {}
 

+ 12 - 2
src/ArduinoJson/Variant/VariantOperators.hpp

@@ -9,6 +9,7 @@
 #include <ArduinoJson/Polyfills/attributes.hpp>
 #include <ArduinoJson/Polyfills/type_traits.hpp>
 #include <ArduinoJson/Variant/VariantAs.hpp>
+#include <ArduinoJson/Variant/VariantTag.hpp>
 
 namespace ARDUINOJSON_NAMESPACE {
 
@@ -17,15 +18,24 @@ CompareResult compare(const T1 &lhs, const T2 &rhs);  // VariantCompare.cpp
 
 template <typename TVariant>
 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 <typename T>
-  friend typename enable_if<!IsVisitable<T>::value, T>::type operator|(
+  friend typename enable_if<!IsVariant<T>::value, T>::type operator|(
       const TVariant &variant, T defaultValue) {
     if (variant.template is<T>())
       return variant.template as<T>();
     else
       return defaultValue;
   }
+  // Returns the default value if the VariantRef is undefined or incompatible
+  template <typename T>
+  friend typename enable_if<IsVariant<T>::value, typename T::variant_type>::type
+  operator|(const TVariant &variant, T defaultValue) {
+    if (variant)
+      return variant;
+    else
+      return defaultValue;
+  }
 
   // value == TVariant
   template <typename T>

+ 2 - 4
src/ArduinoJson/Variant/VariantRef.hpp

@@ -16,6 +16,7 @@
 #include <ArduinoJson/Variant/VariantOperators.hpp>
 #include <ArduinoJson/Variant/VariantRef.hpp>
 #include <ArduinoJson/Variant/VariantShortcuts.hpp>
+#include <ArduinoJson/Variant/VariantTag.hpp>
 
 namespace ARDUINOJSON_NAMESPACE {
 
@@ -23,12 +24,9 @@ namespace ARDUINOJSON_NAMESPACE {
 class ArrayRef;
 class ObjectRef;
 
-template <typename, typename>
-class MemberProxy;
-
 // Contains the methods shared by VariantRef and VariantConstRef
 template <typename TData>
-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.

+ 16 - 0
src/ArduinoJson/Variant/VariantTag.hpp

@@ -0,0 +1,16 @@
+// ArduinoJson - arduinojson.org
+// Copyright Benoit Blanchon 2014-2020
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Namespace.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+struct VariantTag {};
+
+template <typename T>
+struct IsVariant : is_base_of<VariantTag, T> {};
+
+}  // namespace ARDUINOJSON_NAMESPACE