mirror of
https://github.com/nlohmann/json.git
synced 2026-10-03 13:10:33 +00:00
Make comparisons with scalars noexcept only when the conversion is
The comparison operators taking a scalar (==, !=, <, <=, >, >=, and C++20's <=>) convert the scalar to a basic_json and compare, but were unconditionally noexcept. When that conversion throws, the program called std::terminate instead of propagating the exception, e.g. when comparing a json with a string literal under memory pressure (std::bad_alloc) or with an enum value not mapped by NLOHMANN_JSON_SERIALIZE_ENUM_STRICT (out_of_range.410). clang-tidy 22.1 reports the latter as bugprone-exception-escape. Declare the 16 scalar overloads noexcept(std::is_nothrow_constructible<basic_json, ScalarType>::value): they stay noexcept for numbers, Booleans, nullptr, and plain enums, and are noexcept(false) for strings and enums whose to_json may throw. The comparisons of two basic_json values are unchanged. Restore the strict-enum comparisons removed from unit-conversions.cpp in the previous PR, check that comparing an unmapped strict enum now throws, and pin the new exception specifications in unit-noexcept.cpp. Document the exception safety of overload (2) on all seven operator pages. Ran make amalgamate. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -54,6 +54,15 @@ static_assert(noexcept(json(pod {})), "");
|
||||
static_assert(noexcept(std::declval<json>().get<pod>()), "");
|
||||
static_assert(!noexcept(std::declval<json>().get<pod_bis>()), "");
|
||||
static_assert(noexcept(json(pod{})), "");
|
||||
|
||||
// comparing with a scalar is noexcept exactly when converting the scalar is
|
||||
static_assert(noexcept(std::declval<const json&>() == 1), "");
|
||||
static_assert(noexcept(1 != std::declval<const json&>()), "");
|
||||
static_assert(noexcept(std::declval<const json&>() < 2.5), "");
|
||||
static_assert(noexcept(nullptr == std::declval<const json&>()), "");
|
||||
static_assert(!noexcept(std::declval<const json&>() == "foo"), "");
|
||||
static_assert(!noexcept("foo" >= std::declval<const json&>()), "");
|
||||
static_assert(noexcept(std::declval<const json&>() == std::declval<const json&>()), "");
|
||||
} // namespace
|
||||
|
||||
TEST_CASE("noexcept")
|
||||
|
||||
Reference in New Issue
Block a user