소스 검색

Fixed invalid result from operator| (closes #981)

Benoit Blanchon 6 년 전
부모
커밋
eaf55e174b
3개의 변경된 파일36개의 추가작업 그리고 15개의 파일을 삭제
  1. 26 0
      CHANGELOG.md
  2. 1 13
      src/ArduinoJson/Operators/VariantOr.hpp
  3. 9 2
      test/JsonVariant/or.cpp

+ 26 - 0
CHANGELOG.md

@@ -1,6 +1,32 @@
 ArduinoJson: change log
 ArduinoJson: change log
 =======================
 =======================
 
 
+HEAD
+----
+
+* Fixed invalid result from `operator|` (issue #981)
+
+> ### BREAKING CHANGE
+> 
+> This version slightly changes the behavior of the | operator when the 
+> variant contains a float and the user requests an integer.
+>
+> Older versions returned the floating point value truncated.
+> Now, it returns the default value.
+> 
+> ```c++
+> // suppose variant contains 1.2
+> int value = variant | 3;
+> 
+> // old behavior:
+> value == 1
+> 
+> // new behavior
+> value == 3
+> ```
+> 
+> If you need the old behavior, you must add `if (variant.is<float>())`.
+
 v6.10.1 (2019-04-23)
 v6.10.1 (2019-04-23)
 -------
 -------
 
 

+ 1 - 13
src/ArduinoJson/Operators/VariantOr.hpp

@@ -15,8 +15,7 @@ class VariantOr {
  public:
  public:
   // 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>
-  typename enable_if<!is_integral<T>::value, T>::type operator|(
-      const T &defaultValue) const {
+  T operator|(const T &defaultValue) const {
     if (impl()->template is<T>())
     if (impl()->template is<T>())
       return impl()->template as<T>();
       return impl()->template as<T>();
     else
     else
@@ -30,17 +29,6 @@ class VariantOr {
     return value ? value : defaultValue;
     return value ? value : defaultValue;
   }
   }
 
 
-  // Returns the default value if the VariantRef is undefined of incompatible
-  // Special case for integers: we also accept double
-  template <typename Integer>
-  typename enable_if<is_integral<Integer>::value, Integer>::type operator|(
-      const Integer &defaultValue) const {
-    if (impl()->template is<double>())
-      return impl()->template as<Integer>();
-    else
-      return defaultValue;
-  }
-
  private:
  private:
   const TImpl *impl() const {
   const TImpl *impl() const {
     return static_cast<const TImpl *>(this);
     return static_cast<const TImpl *>(this);

+ 9 - 2
test/JsonVariant/or.cpp

@@ -51,6 +51,12 @@ TEST_CASE("JsonVariant::operator|()") {
     REQUIRE(result == "default");
     REQUIRE(result == "default");
   }
   }
 
 
+  SECTION("int | uint8_t (out of range)") {
+    variant.set(666);
+    uint8_t result = variant | static_cast<uint8_t>(42);
+    REQUIRE(result == 42);
+  }
+
   SECTION("int | int") {
   SECTION("int | int") {
     variant.set(0);
     variant.set(0);
     int result = variant | 666;
     int result = variant | 666;
@@ -58,8 +64,9 @@ TEST_CASE("JsonVariant::operator|()") {
   }
   }
 
 
   SECTION("double | int") {
   SECTION("double | int") {
-    variant.set(42.0);
-    int result = variant | 666;
+    // NOTE: changed the behavior to fix #981
+    variant.set(666.0);
+    int result = variant | 42;
     REQUIRE(result == 42);
     REQUIRE(result == 42);
   }
   }