From 5c3738b9b11cf46f4a6cc13dc03ff557b418a432 Mon Sep 17 00:00:00 2001 From: Jonas Wittbrodt Date: Wed, 25 Aug 2021 12:53:49 +0200 Subject: [PATCH] add explicit conversion of null into float NaN --- .../nlohmann/detail/conversions/from_json.hpp | 30 +++++++++++++++-- test/src/unit-conversions.cpp | 33 +++++++++++++++---- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index c7bd018e3..61c95cbe0 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -57,8 +57,21 @@ void get_arithmetic_value(const BasicJsonType& j, ArithmeticType& val) val = static_cast(*j.template get_ptr()); break; } - case value_t::null: + { + if(std::numeric_limits::has_quiet_NaN) + { + val = std::numeric_limits::quiet_NaN(); + break; + } + else if(std::numeric_limits::has_signaling_NaN) + { + val = std::numeric_limits::signaling_NaN(); + break; + } + // [[fallthrough]]; + } + case value_t::object: case value_t::array: case value_t::string: @@ -349,8 +362,21 @@ void from_json(const BasicJsonType& j, ArithmeticType& val) val = static_cast(*j.template get_ptr()); break; } - case value_t::null: + { + if(std::numeric_limits::has_quiet_NaN) + { + val = std::numeric_limits::quiet_NaN(); + break; + } + else if(std::numeric_limits::has_signaling_NaN) + { + val = std::numeric_limits::signaling_NaN(); + break; + } + // [[fallthrough]]; + } + case value_t::object: case value_t::array: case value_t::string: diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp index bc1ad24d6..c7dba44f3 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -1207,10 +1207,31 @@ TEST_CASE("value conversion") CHECK(json(n).m_value.number_float == Approx(j.m_value.number_float)); } - SECTION("exception in case of a non-string type") + SECTION("null as NaN") { - CHECK_THROWS_AS(json(json::value_t::null).get(), - json::type_error&); + json jNull(nullptr); + SECTION("number_float_t") + { + auto n = jNull.get(); + CHECK(std::isnan(n)); + } + + SECTION("float") + { + auto n = jNull.get(); + CHECK(std::isnan(n)); + } + + SECTION("double") + { + auto n = jNull.get(); + CHECK(std::isnan(n)); + } + } + SECTION("exception in case of a non-numeric type") + { + // CHECK_THROWS_AS(json(json::value_t::null).get(), + // json::type_error&); CHECK_THROWS_AS(json(json::value_t::object).get(), json::type_error&); CHECK_THROWS_AS(json(json::value_t::array).get(), @@ -1220,9 +1241,9 @@ TEST_CASE("value conversion") CHECK_THROWS_AS(json(json::value_t::boolean).get(), json::type_error&); - CHECK_THROWS_WITH( - json(json::value_t::null).get(), - "[json.exception.type_error.302] type must be number, but is null"); + // CHECK_THROWS_WITH( + // json(json::value_t::null).get(), + // "[json.exception.type_error.302] type must be number, but is null"); CHECK_THROWS_WITH( json(json::value_t::object).get(), "[json.exception.type_error.302] type must be number, but is object");