From 390ebc91b9021f98b1c127a039a59304ee4974d3 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Fri, 23 Oct 2026 10:20:17 +0200 Subject: [PATCH] 2.2.4: factor primitive reset and range check in erase()/range ctor (#5891) Signed-off-by: Niels Lohmann --- include/nlohmann/json.hpp | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 4e7aaf5a3..189c96c79 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -2563,8 +2563,7 @@ public: case value_t::string: case value_t::binary: { - if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin() - || !last.m_it.primitive_iterator.is_end())) + if (JSON_HEDLEY_UNLIKELY(!primitive_range_is_complete(first, last))) { detail::throw_literal(detail::exception_id::iterator_range_out_of_range, "iterators out of range", first.m_object); } @@ -3073,6 +3072,23 @@ public: swap(*stored, other); } + /// whether [first, last) spans the whole of a primitive value + template + JSON_HEDLEY_ALWAYS_INLINE + static bool primitive_range_is_complete(const IteratorType& first, const IteratorType& last) noexcept + { + return first.m_it.primitive_iterator.is_begin() && last.m_it.primitive_iterator.is_end(); + } + + /// destroy the current (primitive) value and become null + void reset_to_null_impl() + { + m_data.m_value.destroy(m_data.m_type); + m_data.m_value = {}; + m_data.m_type = value_t::null; + assert_invariant(); + } + /// @throw out_of_range.401 always, as @a idx is out of range of @a j JSON_HEDLEY_NO_RETURN JSON_HEDLEY_NEVER_INLINE static void throw_array_index_out_of_range(size_type idx, const basic_json& j) @@ -4074,10 +4090,7 @@ public: detail::throw_literal(detail::exception_id::iterator_out_of_range, "iterator out of range", this); } - m_data.m_value.destroy(m_data.m_type); - m_data.m_value = {}; - m_data.m_type = value_t::null; - assert_invariant(); + reset_to_null_impl(); break; } @@ -4127,16 +4140,12 @@ public: case value_t::string: case value_t::binary: { - if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin() - || !last.m_it.primitive_iterator.is_end())) + if (JSON_HEDLEY_UNLIKELY(!primitive_range_is_complete(first, last))) { detail::throw_literal(detail::exception_id::iterator_range_out_of_range, "iterators out of range", this); } - m_data.m_value.destroy(m_data.m_type); - m_data.m_value = {}; - m_data.m_type = value_t::null; - assert_invariant(); + reset_to_null_impl(); break; }