diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index cd6bfd17..b092c8cc 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -22,6 +22,16 @@ namespace nlohmann { namespace detail { +template +void from_json(const BasicJsonType& j, typename std::nullptr_t& n) +{ + if (JSON_UNLIKELY(not j.is_null())) + { + JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()))); + } + n = nullptr; +} + // overloads for basic_json template parameters template::value and diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 1ee2323c..51f16def 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -952,6 +952,16 @@ namespace nlohmann { namespace detail { +template +void from_json(const BasicJsonType& j, typename std::nullptr_t& n) +{ + if (JSON_UNLIKELY(not j.is_null())) + { + JSON_THROW(type_error::create(302, "type must be null, but is " + std::string(j.type_name()))); + } + n = nullptr; +} + // overloads for basic_json template parameters template::value and diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp index 548d0d9b..7a502089 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -433,6 +433,48 @@ TEST_CASE("value conversion") #endif } + SECTION("get null (implicit)") + { + std::nullptr_t n; + json j(n); + + std::nullptr_t n2 = j; + CHECK(n2 == n); + } + + SECTION("get null (explicit)") + { + std::nullptr_t n; + json j(n); + + auto n2 = j.get(); + CHECK(n2 == n); + + CHECK_THROWS_AS(json(json::value_t::string).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(), json::type_error&); + CHECK_THROWS_AS(json(json::value_t::boolean).get(), json::type_error&); + CHECK_THROWS_AS(json(json::value_t::number_integer).get(), json::type_error&); + CHECK_THROWS_AS(json(json::value_t::number_unsigned).get(), json::type_error&); + CHECK_THROWS_AS(json(json::value_t::number_float).get(), json::type_error&); + + CHECK_THROWS_WITH(json(json::value_t::string).get(), + "[json.exception.type_error.302] type must be null, but is string"); + CHECK_THROWS_WITH(json(json::value_t::object).get(), + "[json.exception.type_error.302] type must be null, but is object"); + CHECK_THROWS_WITH(json(json::value_t::array).get(), + "[json.exception.type_error.302] type must be null, but is array"); + CHECK_THROWS_WITH(json(json::value_t::boolean).get(), + "[json.exception.type_error.302] type must be null, but is boolean"); + CHECK_THROWS_WITH(json(json::value_t::number_integer).get(), + "[json.exception.type_error.302] type must be null, but is number"); + CHECK_THROWS_WITH(json(json::value_t::number_unsigned).get(), + "[json.exception.type_error.302] type must be null, but is number"); + CHECK_THROWS_WITH(json(json::value_t::number_float).get(), + "[json.exception.type_error.302] type must be null, but is number"); + + } + SECTION("get a string (implicit)") { json::string_t s_reference{"Hello world"};