Skip to content

Commit ef75793

Browse files
committed
Fixed JsonVariant::as<unsigned>() (fixes #1601)
1 parent fc4f175 commit ef75793

File tree

5 files changed

+105
-1
lines changed

5 files changed

+105
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ HEAD
1212
* Added support for `std::string_view` (issue #1578, PR #1554 by @0xFEEDC0DE64)
1313
* Fixed warning `definition of implicit copy constructor for 'MsgPackDeserializer' is deprecated because it has a user-declared copy assignment operator`
1414
* Added `JsonArray::clear()` (issue #1597)
15+
* Fixed `JsonVariant::as<unsigned>()` (issue #1601)
1516

1617
v6.18.0 (2021-05-05)
1718
-------

extras/tests/JsonVariant/as.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ TEST_CASE("JsonVariant::as()") {
6161
REQUIRE(variant.as<std::string>() == "true");
6262
}
6363

64+
SECTION("set(42)") {
65+
variant.set(42);
66+
67+
REQUIRE(variant.as<bool>() == true);
68+
REQUIRE(variant.as<double>() == 42.0);
69+
REQUIRE(variant.as<int>() == 42);
70+
REQUIRE(variant.as<unsigned int>() == 42U); // issue #1601
71+
REQUIRE(variant.as<std::string>() == "42");
72+
}
73+
6474
SECTION("set(42L)") {
6575
variant.set(42L);
6676

extras/tests/Numbers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# MIT License
44

55
add_executable(NumbersTests
6+
convertNumber.cpp
67
parseFloat.cpp
78
parseDouble.cpp
89
parseInteger.cpp
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// ArduinoJson - https://arduinojson.org
2+
// Copyright Benoit Blanchon 2014-2021
3+
// MIT License
4+
5+
#include <stdint.h>
6+
#include <ArduinoJson.hpp>
7+
#include <catch.hpp>
8+
9+
using namespace ARDUINOJSON_NAMESPACE;
10+
11+
TEST_CASE("canConvertNumber<TOut, TIn>()") {
12+
SECTION("int8_t -> int8_t") {
13+
CHECK((canConvertNumber<int8_t, int8_t>(0)) == true);
14+
CHECK((canConvertNumber<int8_t, int8_t>(127)) == true);
15+
CHECK((canConvertNumber<int8_t, int8_t>(-128)) == true);
16+
}
17+
18+
SECTION("int8_t -> int16_t") {
19+
CHECK((canConvertNumber<int16_t, int8_t>(0)) == true);
20+
CHECK((canConvertNumber<int16_t, int8_t>(127)) == true);
21+
CHECK((canConvertNumber<int16_t, int8_t>(-128)) == true);
22+
}
23+
24+
SECTION("int8_t -> uint8_t") {
25+
CHECK((canConvertNumber<uint8_t, int8_t>(0)) == true);
26+
CHECK((canConvertNumber<uint8_t, int8_t>(127)) == true);
27+
CHECK((canConvertNumber<uint8_t, int8_t>(-128)) == false);
28+
}
29+
30+
SECTION("int8_t -> uint16_t") {
31+
CHECK((canConvertNumber<uint16_t, int8_t>(0)) == true);
32+
CHECK((canConvertNumber<uint16_t, int8_t>(127)) == true);
33+
CHECK((canConvertNumber<uint16_t, int8_t>(-128)) == false);
34+
}
35+
36+
SECTION("int16_t -> int8_t") {
37+
CHECK((canConvertNumber<int8_t, int16_t>(0)) == true);
38+
CHECK((canConvertNumber<int8_t, int16_t>(127)) == true);
39+
CHECK((canConvertNumber<int8_t, int16_t>(128)) == false);
40+
CHECK((canConvertNumber<int8_t, int16_t>(-128)) == true);
41+
CHECK((canConvertNumber<int8_t, int16_t>(-129)) == false);
42+
}
43+
44+
SECTION("int16_t -> uint8_t") {
45+
CHECK((canConvertNumber<uint8_t, int16_t>(0)) == true);
46+
CHECK((canConvertNumber<uint8_t, int16_t>(255)) == true);
47+
CHECK((canConvertNumber<uint8_t, int16_t>(256)) == false);
48+
CHECK((canConvertNumber<uint8_t, int16_t>(-1)) == false);
49+
}
50+
51+
SECTION("uint8_t -> int8_t") {
52+
CHECK((canConvertNumber<int8_t, uint8_t>(0)) == true);
53+
CHECK((canConvertNumber<int8_t, uint8_t>(127)) == true);
54+
CHECK((canConvertNumber<int8_t, uint8_t>(128)) == false);
55+
CHECK((canConvertNumber<int8_t, uint8_t>(255)) == false);
56+
}
57+
58+
SECTION("uint8_t -> int16_t") {
59+
CHECK((canConvertNumber<int16_t, uint8_t>(0)) == true);
60+
CHECK((canConvertNumber<int16_t, uint8_t>(127)) == true);
61+
CHECK((canConvertNumber<int16_t, uint8_t>(128)) == true);
62+
CHECK((canConvertNumber<int16_t, uint8_t>(255)) == true);
63+
}
64+
65+
SECTION("uint8_t -> uint8_t") {
66+
CHECK((canConvertNumber<uint8_t, uint8_t>(0)) == true);
67+
CHECK((canConvertNumber<uint8_t, uint8_t>(127)) == true);
68+
CHECK((canConvertNumber<uint8_t, uint8_t>(128)) == true);
69+
CHECK((canConvertNumber<uint8_t, uint8_t>(255)) == true);
70+
}
71+
72+
SECTION("uint8_t -> uint16_t") {
73+
CHECK((canConvertNumber<uint16_t, uint8_t>(0)) == true);
74+
CHECK((canConvertNumber<uint16_t, uint8_t>(127)) == true);
75+
CHECK((canConvertNumber<uint16_t, uint8_t>(128)) == true);
76+
CHECK((canConvertNumber<uint16_t, uint8_t>(255)) == true);
77+
}
78+
}

src/ArduinoJson/Numbers/convertNumber.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,23 @@ canConvertNumber(TIn) {
7171
}
7272

7373
// int32 -> uint32
74+
// int32 -> uint64
7475
template <typename TOut, typename TIn>
7576
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
76-
is_integral<TOut>::value && is_unsigned<TOut>::value,
77+
is_integral<TOut>::value && is_unsigned<TOut>::value &&
78+
sizeof(TOut) >= sizeof(TIn),
79+
bool>::type
80+
canConvertNumber(TIn value) {
81+
if (value < 0)
82+
return false;
83+
return TOut(value) <= numeric_limits<TOut>::highest();
84+
}
85+
86+
// int32 -> uint16
87+
template <typename TOut, typename TIn>
88+
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
89+
is_integral<TOut>::value && is_unsigned<TOut>::value &&
90+
sizeof(TOut) < sizeof(TIn),
7791
bool>::type
7892
canConvertNumber(TIn value) {
7993
if (value < 0)

0 commit comments

Comments
 (0)