Răsfoiți Sursa

Added `operator|(JsonVariantConst, JsonVariantConst)`

Benoit Blanchon 5 ani în urmă
părinte
comite
726f8be341

+ 1 - 0
CHANGELOG.md

@@ -8,6 +8,7 @@ HEAD
 * Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358)
 * Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358)
 * Added `DeserializationError::EmptyInput` which tells if the input was empty
 * Added `DeserializationError::EmptyInput` which tells if the input was empty
 * Added `DeserializationError::f_str()` which returns a `const __FlashStringHelper*` (issue #846)
 * Added `DeserializationError::f_str()` which returns a `const __FlashStringHelper*` (issue #846)
+* Added `operator|(JsonVariantConst, JsonVariantConst)`
 * Moved float convertion tables to PROGMEM
 * Moved float convertion tables to PROGMEM
 * Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368)
 * Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368)
 * Fixed error `No such file or directory #include <WString.h>` (issue #1381)
 * Fixed error `No such file or directory #include <WString.h>` (issue #1381)

+ 50 - 1
extras/tests/JsonVariant/or.cpp

@@ -7,7 +7,7 @@
 
 
 TEST_CASE("JsonVariant::operator|()") {
 TEST_CASE("JsonVariant::operator|()") {
   DynamicJsonDocument doc(4096);
   DynamicJsonDocument doc(4096);
-  JsonVariant variant = doc.to<JsonVariant>();
+  JsonVariant variant = doc["value"].to<JsonVariant>();
 
 
   SECTION("undefined") {
   SECTION("undefined") {
     SECTION("undefined | const char*") {
     SECTION("undefined | const char*") {
@@ -24,6 +24,27 @@ TEST_CASE("JsonVariant::operator|()") {
       bool result = variant | true;
       bool result = variant | true;
       REQUIRE(result == true);
       REQUIRE(result == true);
     }
     }
+
+    SECTION("undefined | ElementProxy") {
+      doc["array"][0] = 42;
+
+      JsonVariantConst result = variant | doc["array"][0];
+      REQUIRE(result == 42);
+    }
+
+    SECTION("undefined | MemberProxy") {
+      doc["other"] = 42;
+
+      JsonVariantConst result = variant | doc["other"];
+      REQUIRE(result == 42);
+    }
+
+    SECTION("ElementProxy | ElementProxy") {
+      doc["array"][0] = 42;
+
+      JsonVariantConst result = doc["array"][1] | doc["array"][0];
+      REQUIRE(result == 42);
+    }
   }
   }
 
 
   SECTION("null") {
   SECTION("null") {
@@ -43,6 +64,20 @@ TEST_CASE("JsonVariant::operator|()") {
       bool result = variant | true;
       bool result = variant | true;
       REQUIRE(result == true);
       REQUIRE(result == true);
     }
     }
+
+    SECTION("null | ElementProxy") {
+      doc["array"][0] = 42;
+
+      JsonVariantConst result = variant | doc["array"][0];
+      REQUIRE(result == 42);
+    }
+
+    SECTION("null | MemberProxy") {
+      doc["other"] = 42;
+
+      JsonVariantConst result = variant | doc["other"];
+      REQUIRE(result == 42);
+    }
   }
   }
 
 
   SECTION("int | const char*") {
   SECTION("int | const char*") {
@@ -57,6 +92,20 @@ TEST_CASE("JsonVariant::operator|()") {
     REQUIRE(result == 42);
     REQUIRE(result == 42);
   }
   }
 
 
+  SECTION("int | ElementProxy") {
+    variant.set(42);
+    doc["array"][0] = 666;
+    JsonVariantConst result = variant | doc["array"][0];
+    REQUIRE(result == 42);
+  }
+
+  SECTION("int | MemberProxy") {
+    variant.set(42);
+    doc["other"] = 666;
+    JsonVariantConst result = variant | doc["other"];
+    REQUIRE(result == 42);
+  }
+
   SECTION("int | int") {
   SECTION("int | int") {
     variant.set(0);
     variant.set(0);
     int result = variant | 666;
     int result = variant | 666;

+ 5 - 0
src/ArduinoJson/Variant/VariantImpl.hpp

@@ -139,4 +139,9 @@ template <typename TString>
 inline VariantRef VariantRef::getOrAddMember(const TString &key) const {
 inline VariantRef VariantRef::getOrAddMember(const TString &key) const {
   return VariantRef(_pool, variantGetOrAddMember(_data, key, _pool));
   return VariantRef(_pool, variantGetOrAddMember(_data, key, _pool));
 }
 }
+
+inline VariantConstRef operator|(VariantConstRef preferedValue,
+                                 VariantConstRef defaultValue) {
+  return preferedValue ? preferedValue : defaultValue;
+}
 }  // namespace ARDUINOJSON_NAMESPACE
 }  // namespace ARDUINOJSON_NAMESPACE

+ 5 - 3
src/ArduinoJson/Variant/VariantOperators.hpp

@@ -19,7 +19,8 @@ template <typename TVariant>
 struct VariantOperators {
 struct VariantOperators {
   // Returns the default value if the VariantRef is undefined of incompatible
   // Returns the default value if the VariantRef is undefined of incompatible
   template <typename T>
   template <typename T>
-  friend T operator|(const TVariant &variant, const T &defaultValue) {
+  friend typename enable_if<!IsVisitable<T>::value, T>::type operator|(
+      const TVariant &variant, const T &defaultValue) {
     if (variant.template is<T>())
     if (variant.template is<T>())
       return variant.template as<T>();
       return variant.template as<T>();
     else
     else
@@ -28,8 +29,9 @@ struct VariantOperators {
 
 
   // Returns the default value if the VariantRef is undefined of incompatible
   // Returns the default value if the VariantRef is undefined of incompatible
   // Special case for string: null is treated as undefined
   // Special case for string: null is treated as undefined
-  friend const char *operator|(const TVariant &variant,
-                               const char *defaultValue) {
+  template <typename T>
+  friend typename enable_if<is_same<T, const char *>::value, T>::type operator|(
+      const TVariant &variant, T defaultValue) {
     const char *value = variant.template as<const char *>();
     const char *value = variant.template as<const char *>();
     return value ? value : defaultValue;
     return value ? value : defaultValue;
   }
   }