Merge branch 'claude/implement-5891-deff16' into claude/from-json-arith-array

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-24 07:20:56 +02:00
commit cf0c72cd95
5 files changed
+166 -172

No files matched your search

+34 -34
View File
@@ -688,40 +688,40 @@ class lexer : public lexer_base<BasicJsonType>
case 0x1E:
case 0x1F:
{
static const char* const control_character_messages[32] = // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
{
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000",
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001",
"invalid string: control character U+0002 (STX) must be escaped to \\u0002",
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003",
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004",
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005",
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006",
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007",
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b",
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t",
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n",
"invalid string: control character U+000B (VT) must be escaped to \\u000B",
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f",
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r",
"invalid string: control character U+000E (SO) must be escaped to \\u000E",
"invalid string: control character U+000F (SI) must be escaped to \\u000F",
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010",
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011",
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012",
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013",
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014",
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015",
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016",
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017",
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018",
"invalid string: control character U+0019 (EM) must be escaped to \\u0019",
"invalid string: control character U+001A (SUB) must be escaped to \\u001A",
"invalid string: control character U+001B (ESC) must be escaped to \\u001B",
"invalid string: control character U+001C (FS) must be escaped to \\u001C",
"invalid string: control character U+001D (GS) must be escaped to \\u001D",
"invalid string: control character U+001E (RS) must be escaped to \\u001E",
"invalid string: control character U+001F (US) must be escaped to \\u001F"
static const std::array<const char*, 32> control_character_messages = {{
"invalid string: control character U+0000 (NUL) must be escaped to \\u0000",
"invalid string: control character U+0001 (SOH) must be escaped to \\u0001",
"invalid string: control character U+0002 (STX) must be escaped to \\u0002",
"invalid string: control character U+0003 (ETX) must be escaped to \\u0003",
"invalid string: control character U+0004 (EOT) must be escaped to \\u0004",
"invalid string: control character U+0005 (ENQ) must be escaped to \\u0005",
"invalid string: control character U+0006 (ACK) must be escaped to \\u0006",
"invalid string: control character U+0007 (BEL) must be escaped to \\u0007",
"invalid string: control character U+0008 (BS) must be escaped to \\u0008 or \\b",
"invalid string: control character U+0009 (HT) must be escaped to \\u0009 or \\t",
"invalid string: control character U+000A (LF) must be escaped to \\u000A or \\n",
"invalid string: control character U+000B (VT) must be escaped to \\u000B",
"invalid string: control character U+000C (FF) must be escaped to \\u000C or \\f",
"invalid string: control character U+000D (CR) must be escaped to \\u000D or \\r",
"invalid string: control character U+000E (SO) must be escaped to \\u000E",
"invalid string: control character U+000F (SI) must be escaped to \\u000F",
"invalid string: control character U+0010 (DLE) must be escaped to \\u0010",
"invalid string: control character U+0011 (DC1) must be escaped to \\u0011",
"invalid string: control character U+0012 (DC2) must be escaped to \\u0012",
"invalid string: control character U+0013 (DC3) must be escaped to \\u0013",
"invalid string: control character U+0014 (DC4) must be escaped to \\u0014",
"invalid string: control character U+0015 (NAK) must be escaped to \\u0015",
"invalid string: control character U+0016 (SYN) must be escaped to \\u0016",
"invalid string: control character U+0017 (ETB) must be escaped to \\u0017",
"invalid string: control character U+0018 (CAN) must be escaped to \\u0018",
"invalid string: control character U+0019 (EM) must be escaped to \\u0019",
"invalid string: control character U+001A (SUB) must be escaped to \\u001A",
"invalid string: control character U+001B (ESC) must be escaped to \\u001B",
"invalid string: control character U+001C (FS) must be escaped to \\u001C",
"invalid string: control character U+001D (GS) must be escaped to \\u001D",
"invalid string: control character U+001E (RS) must be escaped to \\u001E",
"invalid string: control character U+001F (US) must be escaped to \\u001F"
}
};
error_message = control_character_messages[static_cast<std::size_t>(current)];
return token_type::parse_error;
@@ -325,7 +325,7 @@ class binary_writer
case value_t::discarded:
default:
throw_on_discarded(j, input_format_name(input_format_t::cbor));
throw_on_discarded(j, input_format_t::cbor);
}
}
@@ -539,7 +539,7 @@ class binary_writer
case value_t::discarded:
default:
throw_on_discarded(j, input_format_name(input_format_t::msgpack));
throw_on_discarded(j, input_format_t::msgpack);
}
}
@@ -713,7 +713,7 @@ class binary_writer
case value_t::discarded:
default:
throw_on_discarded(j, input_format_name(use_bjdata ? input_format_t::bjdata : input_format_t::ubjson));
throw_on_discarded(j, use_bjdata ? input_format_t::bjdata : input_format_t::ubjson);
}
}
@@ -739,11 +739,11 @@ class binary_writer
@brief throws because @a j is discarded and cannot be serialized
@throw type_error.321 always
*/
JSON_HEDLEY_NO_RETURN static void throw_on_discarded(const BasicJsonType& j, const char* format_name)
JSON_HEDLEY_NO_RETURN static void throw_on_discarded(const BasicJsonType& j, const input_format_t format)
{
static_cast<void>(j); // unused when JSON_NOEXCEPTION is defined
static_cast<void>(format_name);
JSON_THROW(type_error::create(exception_id::discarded_value_used, concat("cannot serialize discarded value to ", format_name), &j));
static_cast<void>(format);
JSON_THROW(type_error::create(exception_id::discarded_value_used, concat("cannot serialize discarded value to ", input_format_name(format)), &j));
}
/// how the range of integer type @a NumberType relates to that of @a TargetType
@@ -863,11 +863,11 @@ class binary_writer
}
/*!
@brief throws because the integer @a j is too large for @a format_name
@brief throws because the integer @a j is too large for @a format
@throw out_of_range.407 always
*/
JSON_HEDLEY_NO_RETURN JSON_HEDLEY_NEVER_INLINE
static void throw_integer_out_of_range(const BasicJsonType& j, const char* format_name, const char* range)
static void throw_integer_out_of_range(const BasicJsonType& j, const input_format_t format, const char* range)
{
// neither std::to_string(), which has no overload for integer types
// wider than 64 bits, nor dump(), which would also instantiate the
@@ -878,9 +878,9 @@ class binary_writer
? integer_to_string(j.m_data.m_value.number_unsigned, std::integral_constant<bool, unsigned_limits::is_signed>())
: integer_to_string(j.m_data.m_value.number_integer, std::integral_constant<bool, integer_limits::is_signed>());
static_cast<void>(number); // unused when JSON_NOEXCEPTION is defined
static_cast<void>(format_name);
static_cast<void>(format);
static_cast<void>(range);
JSON_THROW(out_of_range::create(exception_id::integer_too_large, concat("integer number ", number, " cannot be represented by ", format_name, " as it does not fit ", range), &j));
JSON_THROW(out_of_range::create(exception_id::integer_too_large, concat("integer number ", number, " cannot be represented by ", input_format_name(format), " as it does not fit ", range), &j));
}
// The exceptions below are thrown from functions of their own, out of line:
@@ -1731,14 +1731,14 @@ class binary_writer
case value_t::number_integer:
if (JSON_HEDLEY_UNLIKELY(!integer_fits<std::int64_t>(j.m_data.m_value.number_integer)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::bson), "int64");
throw_integer_out_of_range(j, input_format_t::bson, "int64");
}
return calc_bson_integer_size(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
case value_t::number_unsigned:
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::uint64_t>(j.m_data.m_value.number_unsigned)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::bson), "uint64");
throw_integer_out_of_range(j, input_format_t::bson, "uint64");
}
return calc_bson_unsigned_size(conditional_static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
@@ -1749,7 +1749,7 @@ class binary_writer
return 0ul;
case value_t::discarded:
throw_on_discarded(j, input_format_name(input_format_t::bson));
throw_on_discarded(j, input_format_t::bson);
// LCOV_EXCL_START
case value_t::object:
@@ -1978,7 +1978,7 @@ class binary_writer
return write_bson_null(name);
case value_t::discarded:
throw_on_discarded(j, input_format_name(input_format_t::bson));
throw_on_discarded(j, input_format_t::bson);
// LCOV_EXCL_START
case value_t::object:
@@ -2759,7 +2759,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::uint64_t>(j.m_data.m_value.number_unsigned)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::cbor), "uint64");
throw_integer_out_of_range(j, input_format_t::cbor, "uint64");
}
write_cbor_head(0x00, conditional_static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
return;
@@ -2769,7 +2769,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::uint64_t>(j.m_data.m_value.number_integer)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::cbor), "[-2^64, 2^64-1]");
throw_integer_out_of_range(j, input_format_t::cbor, "[-2^64, 2^64-1]");
}
// CBOR does not differentiate between positive signed
// integers and unsigned integers
@@ -2780,7 +2780,7 @@ class binary_writer
// a negative integer n is encoded as -1 - n
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::uint64_t>(-1 - j.m_data.m_value.number_integer)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::cbor), "[-2^64, 2^64-1]");
throw_integer_out_of_range(j, input_format_t::cbor, "[-2^64, 2^64-1]");
}
write_cbor_head(0x20, static_cast<std::uint64_t>(-1 - j.m_data.m_value.number_integer));
}
@@ -2856,7 +2856,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::uint64_t>(j.m_data.m_value.number_unsigned)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::msgpack), "uint64");
throw_integer_out_of_range(j, input_format_t::msgpack, "uint64");
}
write_msgpack_unsigned(static_cast<std::uint64_t>(j.m_data.m_value.number_unsigned));
return;
@@ -2866,7 +2866,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::uint64_t>(j.m_data.m_value.number_integer)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::msgpack), "[-2^63, 2^64-1]");
throw_integer_out_of_range(j, input_format_t::msgpack, "[-2^63, 2^64-1]");
}
// MessagePack does not differentiate between positive
// signed integers and unsigned integers.
@@ -2876,7 +2876,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!integer_fits_min<std::int64_t>(j.m_data.m_value.number_integer)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::msgpack), "[-2^63, 2^64-1]");
throw_integer_out_of_range(j, input_format_t::msgpack, "[-2^63, 2^64-1]");
}
if (j.m_data.m_value.number_integer >= -32)
{
@@ -3024,8 +3024,8 @@ class binary_writer
Walk::string(*this, key, context);
}
template < typename Walk, typename Key = typename BasicJsonType::object_t::key_type,
enable_if_t < !std::is_convertible<Key, string_t>::value, int > = 0 >
template<typename Walk, typename Key = typename BasicJsonType::object_t::key_type,
enable_if_t<negation<std::is_convertible<Key, string_t>>::value, int> = 0>
void write_object_key(const typename BasicJsonType::object_t::key_type& key, const BasicJsonType& /*context*/)
{
Walk::scalar(*this, BasicJsonType(key));
@@ -4279,7 +4279,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!integer_fits_max<std::int64_t>(j.m_data.m_value.number_unsigned)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::bon8), "int64");
throw_integer_out_of_range(j, input_format_t::bon8, "int64");
}
write_bon8_integer(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned));
string_open = false;
@@ -4290,7 +4290,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!integer_fits<std::int64_t>(j.m_data.m_value.number_integer)))
{
throw_integer_out_of_range(j, input_format_name(input_format_t::bon8), "int64");
throw_integer_out_of_range(j, input_format_t::bon8, "int64");
}
write_bon8_integer(static_cast<std::int64_t>(j.m_data.m_value.number_integer));
string_open = false;
@@ -4358,7 +4358,7 @@ class binary_writer
case value_t::discarded:
default:
throw_on_discarded(j, input_format_name(input_format_t::bon8));
throw_on_discarded(j, input_format_t::bon8);
}
}
+4 -3
View File
@@ -181,9 +181,10 @@ inline bool owns_memory(const value_t t) noexcept
@brief whether a value of the given type is neither an object nor an array
Unlike basic_json::is_primitive(), this includes value_t::discarded: it names
the types for which iterators, JSON Pointer resolution, and the serializer take
the "single value" path. Every enumerator is listed so that -Wswitch-enum flags
this function when a new type is added.
the types that iterators walk with a primitive_iterator_t (a single value, or no
value for null and discarded) and that JSON Pointer resolution and the
serializer treat as leaves. Every enumerator is listed so that -Wswitch-enum
flags this function when a new type is added.
*/
inline bool is_primitive(const value_t t) noexcept
{