Fixed invalid result from operator| (closes #981)

This commit is contained in:
Benoit Blanchon
2019-05-07 08:12:18 +02:00
parent 0588e578d5
commit eaf55e174b
3 changed files with 36 additions and 15 deletions

View File

@ -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)
------- -------

View File

@ -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|( T operator|(const T &defaultValue) const {
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);

View File

@ -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); // NOTE: changed the behavior to fix #981
int result = variant | 666; variant.set(666.0);
int result = variant | 42;
REQUIRE(result == 42); REQUIRE(result == 42);
} }