From df98274f6c05b7ff109317694058cb6dcf83ee47 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Fri, 23 Oct 2026 10:21:05 +0200 Subject: [PATCH] 1.2/1.3/1.5/2.5.1/2.5.2/2.5.5: share helpers in the view code (#5891) - detail::exception_id at every numeric id; throw_* helpers take it - hex_byte, hex4_lower, utf8_shape replace local hex/table code - throw_array_index_out_of_range/_past_end, throw_key_not_found - has_native_float_format replaces the hand-written IEEE check No change of messages, ids or output. Signed-off-by: Niels Lohmann --- include/nlohmann/detail/view/edit.hpp | 60 ++++++------------- include/nlohmann/detail/view/edit_storage.hpp | 4 +- include/nlohmann/detail/view/errors.hpp | 34 ++++++++--- include/nlohmann/detail/view/image.hpp | 8 +-- include/nlohmann/detail/view/iterator.hpp | 2 +- include/nlohmann/detail/view/pointer.hpp | 16 ++--- include/nlohmann/detail/view/serializer.hpp | 14 ++--- include/nlohmann/detail/view/value.hpp | 6 +- include/nlohmann/json_view.hpp | 38 ++++++------ 9 files changed, 88 insertions(+), 94 deletions(-) diff --git a/include/nlohmann/detail/view/edit.hpp b/include/nlohmann/detail/view/edit.hpp index ec18793c9..bad8d9da3 100644 --- a/include/nlohmann/detail/view/edit.hpp +++ b/include/nlohmann/detail/view/edit.hpp @@ -51,11 +51,6 @@ struct first_true : std::integral_constant < int, 1 + firs inline void check_utf8(const char* s, std::size_t n) { const auto* const p = reinterpret_cast(s); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) - const auto hex = [](unsigned char c) - { - constexpr const char* digits = "0123456789ABCDEF"; - return std::string{digits[c >> 4u], digits[c & 0xFu]}; - }; for (std::size_t i = 0; i < n;) { const unsigned char c = p[i]; @@ -64,39 +59,22 @@ inline void check_utf8(const char* s, std::size_t n) ++i; continue; } - std::size_t len = 0; - unsigned char lo = 0x80; - unsigned char hi = 0xBF; - if (c >= 0xC2 && c <= 0xDF) + const utf8_sequence_shape shape = utf8_shape(c); + const std::size_t len = shape.length; + if (len == 0) { - len = 2; - } - else if (c >= 0xE0 && c <= 0xEF) - { - len = 3; - lo = c == 0xE0 ? 0xA0 : 0x80; - hi = c == 0xED ? 0x9F : 0xBF; - } - else if (c >= 0xF0 && c <= 0xF4) - { - len = 4; - lo = c == 0xF0 ? 0x90 : 0x80; - hi = c == 0xF4 ? 0x8F : 0xBF; - } - else - { - throw_type_error(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex(c))); + throw_type_error(exception_id::invalid_utf8, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", hex_byte(c))); } for (std::size_t k = 1; k < len; ++k) { if (i + k == n) { - throw_type_error(316, concat("incomplete UTF-8 string; last byte: 0x", hex(p[n - 1]))); + throw_type_error(exception_id::invalid_utf8, concat("incomplete UTF-8 string; last byte: 0x", hex_byte(p[n - 1]))); } const unsigned char b = p[i + k]; - if (b < (k == 1 ? lo : 0x80) || b > (k == 1 ? hi : 0xBF)) + if (b < (k == 1 ? shape.second_lo : 0x80) || b > (k == 1 ? shape.second_hi : 0xBF)) { - throw_type_error(316, concat("invalid UTF-8 byte at index ", std::to_string(i + k), ": 0x", hex(b))); + throw_type_error(exception_id::invalid_utf8, concat("invalid UTF-8 byte at index ", std::to_string(i + k), ": 0x", hex_byte(b))); } } i += len; @@ -144,7 +122,7 @@ class editor node* const o = own(object); if (o->kind != static_cast(value_t::object) && o->kind != static_cast(value_t::null)) { - throw_type_error(305, "cannot use operator[] with a string argument with ", object.type_name()); + throw_type_error(exception_id::subscript_wrong_type, "cannot use operator[] with a string argument with ", object.type_name()); } check_utf8(key.data(), key.size()); const encoded e = encode(std::forward(value)); @@ -195,7 +173,7 @@ class editor node* const a = own(array); if (a->kind != static_cast(value_t::array)) { - throw_type_error(305, "cannot use operator[] with a numeric argument with ", array.type_name()); + throw_type_error(exception_id::subscript_wrong_type, "cannot use operator[] with a numeric argument with ", array.type_name()); } check_index(idx, a->len); const encoded e = encode(std::forward(value)); @@ -212,7 +190,7 @@ class editor node* const a = own(array); if (a->kind != static_cast(value_t::array) && a->kind != static_cast(value_t::null)) { - throw_type_error(308, "cannot use push_back() with ", array.type_name()); + throw_type_error(exception_id::push_back_wrong_type, "cannot use push_back() with ", array.type_name()); } const encoded e = encode(std::forward(value)); if (a->kind == static_cast(value_t::null)) @@ -236,7 +214,7 @@ class editor node* const a = own(array); if (a->kind != static_cast(value_t::array)) { - throw_type_error(309, "cannot use insert() with ", array.type_name()); + throw_type_error(exception_id::insert_wrong_type, "cannot use insert() with ", array.type_name()); } check_index(idx, a->len + 1); const encoded e = encode(std::forward(value)); @@ -256,7 +234,7 @@ class editor node* const o = own(object); if (o->kind != static_cast(value_t::object)) { - throw_type_error(307, "cannot use erase() with ", object.type_name()); + throw_type_error(exception_id::erase_wrong_type, "cannot use erase() with ", object.type_name()); } for (const node* k = nav::first(m_doc, o), *end = nav::end(m_doc, o); k != end; k = document_data::after(k + 1)) { @@ -274,7 +252,7 @@ class editor node* const a = own(array); if (a->kind != static_cast(value_t::array)) { - throw_type_error(307, "cannot use erase() with ", array.type_name()); + throw_type_error(exception_id::erase_wrong_type, "cannot use erase() with ", array.type_name()); } check_index(idx, a->len); node* const h = block_of(m_doc, a, 0); @@ -297,7 +275,7 @@ class editor { if (NLOHMANN_VIEW_UNLIKELY(v.m_doc != &m_doc || v.m_node == nullptr)) { - throw_invalid_iterator(202, "view does not belong to this document"); + throw_invalid_iterator(exception_id::iterator_from_other_value, "view does not belong to this document"); } edit_state_of(m_doc); return const_cast(v.m_node); // NOLINT(cppcoreguidelines-pro-type-const-cast): the nodes belong to this document @@ -307,7 +285,7 @@ class editor { if (idx >= limit) { - throw_out_of_range(401, concat("array index ", std::to_string(idx), " is out of range")); + throw_array_index_out_of_range(idx); } } @@ -448,7 +426,7 @@ class editor { if (NLOHMANN_VIEW_UNLIKELY(v.m_node == nullptr)) { - throw_type_error(302, "type must be a value, but is ", "discarded"); + throw_type_error(exception_id::type_mismatch, "type must be a value, but is ", "discarded"); } encoded r; if (!is_container(*v.m_node)) @@ -598,7 +576,7 @@ class editor { if (NLOHMANN_VIEW_UNLIKELY(len >= 0xFFFFFFFFu)) { - throw_out_of_range(416, "strings of 4 GiB or more are not supported by json_document"); // LCOV_EXCL_LINE + throw_out_of_range(exception_id::document_too_large, "strings of 4 GiB or more are not supported by json_document"); // LCOV_EXCL_LINE } node n = plain_node(value_t::string); n.flags = static_cast(n.flags | node_flags::edited); @@ -673,12 +651,12 @@ class editor return string_node(s.data(), s.size()); } case value_t::binary: - throw_type_error(319, "cannot store a binary value in a json_document", ""); + throw_type_error(exception_id::document_binary_value, "cannot store a binary value in a json_document", ""); case value_t::discarded: case value_t::object: case value_t::array: default: - throw_type_error(302, "type must be a value, but is ", "discarded"); + throw_type_error(exception_id::type_mismatch, "type must be a value, but is ", "discarded"); } } diff --git a/include/nlohmann/detail/view/edit_storage.hpp b/include/nlohmann/detail/view/edit_storage.hpp index 614a0fb0d..9a45bfebd 100644 --- a/include/nlohmann/detail/view/edit_storage.hpp +++ b/include/nlohmann/detail/view/edit_storage.hpp @@ -84,7 +84,7 @@ inline std::size_t text_capacity(std::size_t cap, std::size_t used, std::size_t constexpr std::size_t limit = 0xFFFFFFFFu; if (NLOHMANN_VIEW_UNLIKELY(used > limit || n > limit - used)) { - throw_out_of_range(416, "edits of 4 GiB or more are not supported by json_document"); + throw_out_of_range(exception_id::document_too_large, "edits of 4 GiB or more are not supported by json_document"); } const std::size_t needed = used + n; const std::size_t wanted = needed + (std::min)(limit - needed, std::size_t{256}); @@ -135,7 +135,7 @@ inline void reserve_moved(document_data& d) document_data::edit_state& e = edit_state_of(d); if (e.moved.size() >= 0xFFFFFFFFu) { - throw_out_of_range(416, "more than 4294967295 edited arrays and objects are not supported by json_document"); // LCOV_EXCL_LINE + throw_out_of_range(exception_id::document_too_large, "more than 4294967295 edited arrays and objects are not supported by json_document"); // LCOV_EXCL_LINE } if (e.moved.size() == e.moved.capacity() || e.moved_cap.size() == e.moved_cap.capacity()) { diff --git a/include/nlohmann/detail/view/errors.hpp b/include/nlohmann/detail/view/errors.hpp index ca790a13d..590bb2edb 100644 --- a/include/nlohmann/detail/view/errors.hpp +++ b/include/nlohmann/detail/view/errors.hpp @@ -25,32 +25,52 @@ namespace view // Exceptions are thrown out of line, so that the accessors that may throw stay // small enough to be inlined. -[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_type_error(int id, const char* prefix, const char* type) +[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_type_error(exception_id id, const char* prefix, const char* type) { NLOHMANN_VIEW_THROW(type_error::create(id, concat(prefix, type), nullptr)); } -[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_type_error(int id, const std::string& msg) +[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_type_error(exception_id id, const std::string& msg) { NLOHMANN_VIEW_THROW(type_error::create(id, msg, nullptr)); } -[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_out_of_range(int id, const std::string& msg) +[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_out_of_range(exception_id id, const std::string& msg) { NLOHMANN_VIEW_THROW(out_of_range::create(id, msg, nullptr)); } -[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_invalid_iterator(int id, const char* msg) +[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_invalid_iterator(exception_id id, const char* msg) { NLOHMANN_VIEW_THROW(invalid_iterator::create(id, msg, nullptr)); } /// a parse error without a position (as those of json_pointer) -[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_parse_error(int id, const std::string& msg) +[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_parse_error(exception_id id, const std::string& msg) { NLOHMANN_VIEW_THROW(parse_error::create(id, 0, msg, nullptr)); } +/// out_of_range.401: the array index @a idx is not below the size +template +[[noreturn]] NLOHMANN_VIEW_NOINLINE void throw_array_index_out_of_range(const Index idx) +{ + throw_out_of_range(exception_id::array_index_out_of_range, concat("array index ", std::to_string(idx), " is out of range")); +} + +/// out_of_range.402: the JSON Pointer token '-' of an array of @a size elements +[[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_array_index_past_end(std::size_t size) +{ + throw_out_of_range(exception_id::pointer_past_the_end_index, concat("array index '-' (", std::to_string(size), ") is out of range")); +} + +/// out_of_range.403: the object has no member @a key +template +[[noreturn]] NLOHMANN_VIEW_NOINLINE void throw_key_not_found(const Key& key) +{ + throw_out_of_range(exception_id::key_not_found, concat("key '", key, "' not found")); +} + /// SAX handler of the error replay: accepts every event without storing it, /// and throws the exception the parser reports template @@ -149,7 +169,7 @@ template if (f.code == error_code::input_too_large) { // (the limit is detail::view::max_input_size(): 4 GiB minus 16 bytes) - NLOHMANN_VIEW_THROW(out_of_range::create(416, "input of 4294967280 bytes or more is not supported by json_document", nullptr)); + NLOHMANN_VIEW_THROW(out_of_range::create(exception_id::document_too_large, "input of 4294967280 bytes or more is not supported by json_document", nullptr)); } throwing_sax sax; const bool accepted = BasicJsonType::sax_parse(src, src + size, &sax, input_format_t::json, true, ignore_comments, ignore_trailing_commas); @@ -169,7 +189,7 @@ template } } pos.chars_read_current_line = off + 1 - line_start; - NLOHMANN_VIEW_THROW(parse_error::create(101, pos, "syntax error while parsing value", nullptr)); + NLOHMANN_VIEW_THROW(parse_error::create(exception_id::syntax_error, pos, "syntax error while parsing value", nullptr)); // LCOV_EXCL_STOP } diff --git a/include/nlohmann/detail/view/image.hpp b/include/nlohmann/detail/view/image.hpp index 702a55530..af9994712 100644 --- a/include/nlohmann/detail/view/image.hpp +++ b/include/nlohmann/detail/view/image.hpp @@ -186,7 +186,7 @@ inline void compact_nodes(const document_data& d, std::size_t arena_size, std::v inline std::vector save_image(const document_data& d) { #if !NLOHMANN_VIEW_LITTLE_ENDIAN - throw_type_error(320, "json_document images need a little-endian target"); // LCOV_EXCL_LINE + throw_type_error(exception_id::document_image_unsupported, "json_document images need a little-endian target"); // LCOV_EXCL_LINE #endif const std::size_t arena_size = d.arena_size; std::vector compacted; @@ -203,7 +203,7 @@ inline std::vector save_image(const document_data& d) if (NLOHMANN_VIEW_UNLIKELY(text_size >= image_limit || total_arena >= image_limit || count >= image_limit)) { // LCOV_EXCL_START (4 GiB) - throw_out_of_range(416, "images of 4 GiB or more are not supported by json_document"); + throw_out_of_range(exception_id::document_too_large, "images of 4 GiB or more are not supported by json_document"); // LCOV_EXCL_STOP } image_header h{}; @@ -660,7 +660,7 @@ inline bool check_image(const node* nodes, std::size_t count, const unsigned cha [[noreturn]] NLOHMANN_VIEW_NOINLINE inline void throw_invalid_image(const char* what) { - throw_parse_error(116, concat("invalid json_document image: ", what)); + throw_parse_error(exception_id::invalid_document_image, concat("invalid json_document image: ", what)); } /// Read an image into d. The text and the decoded strings stay in the image; @@ -668,7 +668,7 @@ inline bool check_image(const node* nodes, std::size_t count, const unsigned cha inline void load_image(document_data& d, const std::uint8_t* image, std::size_t size, image_check check) { #if !NLOHMANN_VIEW_LITTLE_ENDIAN - throw_type_error(320, "json_document images need a little-endian target"); // LCOV_EXCL_LINE + throw_type_error(exception_id::document_image_unsupported, "json_document images need a little-endian target"); // LCOV_EXCL_LINE #endif if (image == nullptr || size < sizeof(image_header)) { diff --git a/include/nlohmann/detail/view/iterator.hpp b/include/nlohmann/detail/view/iterator.hpp index 12906e9c1..cf74d0bb0 100644 --- a/include/nlohmann/detail/view/iterator.hpp +++ b/include/nlohmann/detail/view/iterator.hpp @@ -110,7 +110,7 @@ class view_iterator { if (NLOHMANN_VIEW_UNLIKELY(m_value_offset == 0)) { - throw_invalid_iterator(207, "cannot use key() for non-object iterators"); + throw_invalid_iterator(exception_id::iterator_key_not_object, "cannot use key() for non-object iterators"); } return string_view_t(m_doc->str(*m_pos), m_pos->len); } diff --git a/include/nlohmann/detail/view/pointer.hpp b/include/nlohmann/detail/view/pointer.hpp index fb957b604..58a8ce043 100644 --- a/include/nlohmann/detail/view/pointer.hpp +++ b/include/nlohmann/detail/view/pointer.hpp @@ -86,15 +86,15 @@ template switch (status) { case index_status::leading_zero: - throw_parse_error(106, concat("array index '", s, "' must not begin with '0'")); + throw_parse_error(exception_id::pointer_index_leading_zero, concat("array index '", s, "' must not begin with '0'")); case index_status::not_number: - throw_parse_error(109, concat("array index '", s, "' is not a number")); + throw_parse_error(exception_id::pointer_index_not_a_number, concat("array index '", s, "' is not a number")); case index_status::too_large: - throw_out_of_range(410, concat("array index ", s, " exceeds size_type")); // LCOV_EXCL_LINE + throw_out_of_range(exception_id::value_out_of_range, concat("array index ", s, " exceeds size_type")); // LCOV_EXCL_LINE case index_status::unresolved: case index_status::ok: default: - throw_out_of_range(404, concat("unresolved reference token '", s, "'")); + throw_out_of_range(exception_id::pointer_unresolved, concat("unresolved reference token '", s, "'")); } } @@ -119,7 +119,7 @@ View resolve_pointer(View cur, const Tokens& tokens, pointer_mode mode) { if (mode == pointer_mode::checked) { - throw_out_of_range(403, concat("key '", token, "' not found")); + throw_key_not_found(token); } return View(); } @@ -131,7 +131,7 @@ View resolve_pointer(View cur, const Tokens& tokens, pointer_mode mode) { if (throwing) { - throw_out_of_range(402, concat("array index '-' (", std::to_string(cur.size()), ") is out of range")); + throw_array_index_past_end(cur.size()); } return View(); } @@ -150,7 +150,7 @@ View resolve_pointer(View cur, const Tokens& tokens, pointer_mode mode) { if (mode == pointer_mode::checked) { - throw_out_of_range(401, concat("array index ", std::to_string(idx), " is out of range")); + throw_array_index_out_of_range(idx); } return View(); } @@ -160,7 +160,7 @@ View resolve_pointer(View cur, const Tokens& tokens, pointer_mode mode) { if (throwing) { - throw_out_of_range(404, concat("unresolved reference token '", token, "'")); + throw_out_of_range(exception_id::pointer_unresolved, concat("unresolved reference token '", token, "'")); } return View(); } diff --git a/include/nlohmann/detail/view/serializer.hpp b/include/nlohmann/detail/view/serializer.hpp index 7d393d0f6..280304e90 100644 --- a/include/nlohmann/detail/view/serializer.hpp +++ b/include/nlohmann/detail/view/serializer.hpp @@ -890,21 +890,17 @@ class view_serializer m_out.put("null"); return; } - static constexpr bool is_ieee_single_or_double - = std::numeric_limits::is_iec559 - && ((std::numeric_limits::digits == 24 && std::numeric_limits::max_exponent == 128) - || (std::numeric_limits::digits == 53 && std::numeric_limits::max_exponent == 1024)); - write_float(x, std::integral_constant()); + write_float(x, std::integral_constant::value>()); } - void write_float(number_float_t x, std::true_type /*is_ieee_single_or_double*/) + void write_float(number_float_t x, std::true_type /*has_native_float_format*/) { std::array buf{}; const char* const end = ::nlohmann::detail::to_chars(buf.data(), buf.data() + buf.size(), x); m_out.put(buf.data(), static_cast(end - buf.data())); } - void write_float(number_float_t x, std::false_type /*is_ieee_single_or_double*/) + void write_float(number_float_t x, std::false_type /*has_native_float_format*/) { // other types (e.g. long double) are rare: the library writes them const string_t s = BasicJsonType(x).dump(); @@ -1031,8 +1027,8 @@ class view_serializer void write_u_escape(std::uint32_t u) { - static constexpr const char* hex = "0123456789abcdef"; - const std::array e = {{'\\', 'u', hex[(u >> 12u) & 0xFu], hex[(u >> 8u) & 0xFu], hex[(u >> 4u) & 0xFu], hex[u & 0xFu]}}; + std::array e = {{'\\', 'u', 0, 0, 0, 0}}; + hex4_lower(static_cast(u), &e[2]); m_out.put(e.data(), e.size()); } diff --git a/include/nlohmann/detail/view/value.hpp b/include/nlohmann/detail/view/value.hpp index 1f1eafde4..945071705 100644 --- a/include/nlohmann/detail/view/value.hpp +++ b/include/nlohmann/detail/view/value.hpp @@ -60,7 +60,7 @@ NLOHMANN_VIEW_ALWAYS_INLINE T arithmetic_value(const document_data& d, const nod case value_t::binary: case value_t::discarded: default: - throw_type_error(302, "type must be number, but is ", value_type_name(static_cast(n.kind))); + throw_type_error(exception_id::type_mismatch, "type must be number, but is ", value_type_name(static_cast(n.kind))); } } @@ -70,7 +70,7 @@ std::vector vector_value(const View& v) { if (NLOHMANN_VIEW_UNLIKELY(!v.is_array())) { - throw_type_error(302, "type must be array, but is ", v.type_name()); + throw_type_error(exception_id::type_mismatch, "type must be array, but is ", v.type_name()); } std::vector r; r.reserve(v.size()); @@ -88,7 +88,7 @@ Map map_value(const View& v) { if (NLOHMANN_VIEW_UNLIKELY(!v.is_object())) { - throw_type_error(302, "type must be object, but is ", v.type_name()); + throw_type_error(exception_id::type_mismatch, "type must be object, but is ", v.type_name()); } Map r; for (auto it = v.begin(); it != v.end(); ++it) diff --git a/include/nlohmann/json_view.hpp b/include/nlohmann/json_view.hpp index f0fc58dc9..a3bbdf50c 100644 --- a/include/nlohmann/json_view.hpp +++ b/include/nlohmann/json_view.hpp @@ -267,7 +267,7 @@ class basic_json_view { return {}; } - detail::view::throw_type_error(305, "cannot use operator[] with a string argument with ", type_name()); + detail::view::throw_type_error(detail::exception_id::subscript_wrong_type, "cannot use operator[] with a string argument with ", type_name()); } return lookup(key); } @@ -293,7 +293,7 @@ class basic_json_view { return {}; } - detail::view::throw_type_error(305, "cannot use operator[] with a numeric argument with ", type_name()); + detail::view::throw_type_error(detail::exception_id::subscript_wrong_type, "cannot use operator[] with a numeric argument with ", type_name()); } return idx < m_node->len ? basic_json_view(m_doc, navigation::value(detail::view::element_at(*m_doc, m_node, idx))) : basic_json_view(); } @@ -326,12 +326,12 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(!is_object())) { - detail::view::throw_type_error(304, "cannot use at() with ", type_name()); + detail::view::throw_type_error(detail::exception_id::at_wrong_type, "cannot use at() with ", type_name()); } const basic_json_view r = lookup(key); if (NLOHMANN_VIEW_UNLIKELY(r.is_discarded())) { - detail::view::throw_out_of_range(403, detail::concat("key '", std::string(key.data(), key.size()), "' not found")); + detail::view::throw_key_not_found(std::string(key.data(), key.size())); } return r; } @@ -352,11 +352,11 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(!is_array())) { - detail::view::throw_type_error(304, "cannot use at() with ", type_name()); + detail::view::throw_type_error(detail::exception_id::at_wrong_type, "cannot use at() with ", type_name()); } if (NLOHMANN_VIEW_UNLIKELY(idx >= m_node->len)) { - detail::view::throw_out_of_range(401, detail::concat("array index ", std::to_string(idx), " is out of range")); + detail::view::throw_array_index_out_of_range(idx); } return basic_json_view(m_doc, navigation::value(detail::view::element_at(*m_doc, m_node, idx))); } @@ -384,7 +384,7 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(!is_object())) { - detail::view::throw_type_error(306, "cannot use value() with ", type_name()); + detail::view::throw_type_error(detail::exception_id::value_wrong_type, "cannot use value() with ", type_name()); } const basic_json_view r = lookup(key); return r.is_discarded() ? default_value : r.template get(); @@ -403,7 +403,7 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(!is_structured())) { - detail::view::throw_type_error(306, "cannot use value() with ", type_name()); + detail::view::throw_type_error(detail::exception_id::value_wrong_type, "cannot use value() with ", type_name()); } const basic_json_view r = detail::view::resolve_pointer(*this, detail::json_pointer_access::reference_tokens(ptr), detail::view::pointer_mode::value); return r.is_discarded() ? default_value : r.template get(); @@ -421,7 +421,7 @@ class basic_json_view const iterator it = begin(); if (NLOHMANN_VIEW_UNLIKELY(it == end())) { - detail::view::throw_invalid_iterator(214, "cannot get value"); + detail::view::throw_invalid_iterator(detail::exception_id::iterator_value_unavailable, "cannot get value"); } return *it; } @@ -573,7 +573,7 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(!is_string())) { - detail::view::throw_type_error(302, "type must be string, but is ", type_name()); + detail::view::throw_type_error(detail::exception_id::type_mismatch, "type must be string, but is ", type_name()); } return {m_doc->str(*m_node), m_node->len}; } @@ -585,7 +585,7 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(!is_number())) { - detail::view::throw_type_error(302, "type must be number, but is ", type_name()); + detail::view::throw_type_error(detail::exception_id::type_mismatch, "type must be number, but is ", type_name()); } return {m_doc->str(*m_node), detail::view::number_length(*m_node)}; } @@ -795,7 +795,7 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(!is_boolean())) { - detail::view::throw_type_error(302, "type must be boolean, but is ", type_name()); + detail::view::throw_type_error(detail::exception_id::type_mismatch, "type must be boolean, but is ", type_name()); } return (m_node->flags & detail::view::node_flags::is_true) != 0; } @@ -805,7 +805,7 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(m_node == nullptr)) { - detail::view::throw_type_error(302, "type must be number, but is ", type_name()); + detail::view::throw_type_error(detail::exception_id::type_mismatch, "type must be number, but is ", type_name()); } return detail::view::arithmetic_value(*m_doc, *m_node); } @@ -814,7 +814,7 @@ class basic_json_view { if (NLOHMANN_VIEW_UNLIKELY(!is_null())) { - detail::view::throw_type_error(302, "type must be null, but is ", type_name()); + detail::view::throw_type_error(detail::exception_id::type_mismatch, "type must be null, but is ", type_name()); } return nullptr; } @@ -1123,7 +1123,7 @@ class basic_json_document { if (NLOHMANN_VIEW_UNLIKELY(!m_data || m_data->discarded)) { - detail::view::throw_type_error(320, "cannot save a discarded json_document"); + detail::view::throw_type_error(detail::exception_id::document_image_unsupported, "cannot save a discarded json_document"); } return detail::view::save_image(*m_data); } @@ -1224,7 +1224,7 @@ class basic_json_document const std::size_t idx = pointer_index(token); if (idx >= 0xFFFFFFFFu) { - detail::view::throw_out_of_range(401, detail::concat("array index ", std::to_string(idx), " is out of range")); + detail::view::throw_array_index_out_of_range(idx); } for (std::size_t i = 0; i < idx; ++i) { @@ -1280,7 +1280,7 @@ class basic_json_document { if (ptr.empty()) { - detail::view::throw_out_of_range(405, "JSON pointer has no parent"); + detail::view::throw_out_of_range(detail::exception_id::patch_on_root, "JSON pointer has no parent"); } const view_type parent = root().at(ptr.parent_pointer()); const auto& token = ptr.back(); @@ -1300,7 +1300,7 @@ class basic_json_document static_assert(Editable, "only an editable document can be edited: use basic_json_document (json_editable_document)"); if (NLOHMANN_VIEW_UNLIKELY(!m_data || m_data->discarded)) { - detail::view::throw_invalid_iterator(202, "view does not belong to this document"); + detail::view::throw_invalid_iterator(detail::exception_id::iterator_from_other_value, "view does not belong to this document"); } return detail::view::editor(*m_data); } @@ -1317,7 +1317,7 @@ class basic_json_document { if (idx < 0) { - detail::view::throw_out_of_range(401, detail::concat("array index ", std::to_string(idx), " is out of range")); + detail::view::throw_array_index_out_of_range(idx); } return static_cast(idx); }