diff --git a/CHANGELOG.md b/CHANGELOG.md index cd67e2f4..1f8062be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ HEAD * Added support for `std::string_view` (issue #1578, PR #1554 by @0xFEEDC0DE64) * Fixed warning `definition of implicit copy constructor for 'MsgPackDeserializer' is deprecated because it has a user-declared copy assignment operator` * Added `JsonArray::clear()` (issue #1597) +* Fixed `JsonVariant::as()` (issue #1601) v6.18.0 (2021-05-05) ------- diff --git a/extras/tests/JsonVariant/as.cpp b/extras/tests/JsonVariant/as.cpp index 843f17dd..add6b10c 100644 --- a/extras/tests/JsonVariant/as.cpp +++ b/extras/tests/JsonVariant/as.cpp @@ -61,6 +61,16 @@ TEST_CASE("JsonVariant::as()") { REQUIRE(variant.as() == "true"); } + SECTION("set(42)") { + variant.set(42); + + REQUIRE(variant.as() == true); + REQUIRE(variant.as() == 42.0); + REQUIRE(variant.as() == 42); + REQUIRE(variant.as() == 42U); // issue #1601 + REQUIRE(variant.as() == "42"); + } + SECTION("set(42L)") { variant.set(42L); diff --git a/extras/tests/Numbers/CMakeLists.txt b/extras/tests/Numbers/CMakeLists.txt index 7e799a3a..7d11034f 100644 --- a/extras/tests/Numbers/CMakeLists.txt +++ b/extras/tests/Numbers/CMakeLists.txt @@ -3,6 +3,7 @@ # MIT License add_executable(NumbersTests + convertNumber.cpp parseFloat.cpp parseDouble.cpp parseInteger.cpp diff --git a/extras/tests/Numbers/convertNumber.cpp b/extras/tests/Numbers/convertNumber.cpp new file mode 100644 index 00000000..0fdc20db --- /dev/null +++ b/extras/tests/Numbers/convertNumber.cpp @@ -0,0 +1,78 @@ +// ArduinoJson - https://arduinojson.org +// Copyright Benoit Blanchon 2014-2021 +// MIT License + +#include +#include +#include + +using namespace ARDUINOJSON_NAMESPACE; + +TEST_CASE("canConvertNumber()") { + SECTION("int8_t -> int8_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(-128)) == true); + } + + SECTION("int8_t -> int16_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(-128)) == true); + } + + SECTION("int8_t -> uint8_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(-128)) == false); + } + + SECTION("int8_t -> uint16_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(-128)) == false); + } + + SECTION("int16_t -> int8_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(128)) == false); + CHECK((canConvertNumber(-128)) == true); + CHECK((canConvertNumber(-129)) == false); + } + + SECTION("int16_t -> uint8_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(255)) == true); + CHECK((canConvertNumber(256)) == false); + CHECK((canConvertNumber(-1)) == false); + } + + SECTION("uint8_t -> int8_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(128)) == false); + CHECK((canConvertNumber(255)) == false); + } + + SECTION("uint8_t -> int16_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(128)) == true); + CHECK((canConvertNumber(255)) == true); + } + + SECTION("uint8_t -> uint8_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(128)) == true); + CHECK((canConvertNumber(255)) == true); + } + + SECTION("uint8_t -> uint16_t") { + CHECK((canConvertNumber(0)) == true); + CHECK((canConvertNumber(127)) == true); + CHECK((canConvertNumber(128)) == true); + CHECK((canConvertNumber(255)) == true); + } +} diff --git a/src/ArduinoJson/Numbers/convertNumber.hpp b/src/ArduinoJson/Numbers/convertNumber.hpp index 8f2cd592..3087459f 100644 --- a/src/ArduinoJson/Numbers/convertNumber.hpp +++ b/src/ArduinoJson/Numbers/convertNumber.hpp @@ -71,9 +71,23 @@ canConvertNumber(TIn) { } // int32 -> uint32 +// int32 -> uint64 template typename enable_if::value && is_signed::value && - is_integral::value && is_unsigned::value, + is_integral::value && is_unsigned::value && + sizeof(TOut) >= sizeof(TIn), + bool>::type +canConvertNumber(TIn value) { + if (value < 0) + return false; + return TOut(value) <= numeric_limits::highest(); +} + +// int32 -> uint16 +template +typename enable_if::value && is_signed::value && + is_integral::value && is_unsigned::value && + sizeof(TOut) < sizeof(TIn), bool>::type canConvertNumber(TIn value) { if (value < 0)