From 6964ce689d9aa8bb28691f71fa0a718523923775 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sat, 10 Oct 2026 21:17:31 +0000 Subject: [PATCH] Merge the array and object branches of the BON8 iterative writer write_bon8_iterative and write_bon8_value_or_push handled arrays and objects in separate branches that repeated the end-of-container check, the 0xFE closer and the marker computation. Share those parts and branch only where arrays and objects really differ. The output is unchanged. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Hz7VJi1FTKr6gpseLErbbS Signed-off-by: Niels Lohmann --- .../nlohmann/detail/output/binary_writer.hpp | 62 +++++++------------ single_include/nlohmann/json.hpp | 62 +++++++------------ 2 files changed, 46 insertions(+), 78 deletions(-) diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index 55fd8ccb7..81767c769 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -2710,21 +2710,13 @@ class binary_writer */ void write_bon8_value_or_push(const BasicJsonType& j, bool& string_open, std::vector& stack) { - if (j.is_array()) + if (j.is_array() || j.is_object()) { - const auto N = j.m_data.m_value.array->size(); - write_bon8_marker(static_cast(N <= 4 ? 0x80 + N : 0x85), string_open); - if (N != 0) - { - stack.emplace_back(&j); - } - return; - } - - if (j.is_object()) - { - const auto N = j.m_data.m_value.object->size(); - write_bon8_marker(static_cast(N <= 4 ? 0x86 + N : 0x8B), string_open); + // arrays use the markers 0x80..0x85, objects 0x86..0x8B; the last + // one stands for more than four elements, closed later with 0xFE + const auto N = j.size(); + const std::size_t base = j.is_array() ? 0x80 : 0x86; + write_bon8_marker(static_cast(base + (N <= 4 ? N : 5)), string_open); if (N != 0) { stack.emplace_back(&j); @@ -2752,43 +2744,35 @@ class binary_writer while (!stack.empty()) { const binary_container_frame current = stack.back(); + const bool is_array = current.value->is_array(); + const bool at_end = is_array + ? current.array_it == current.value->m_data.m_value.array->cend() + : current.object_it == current.value->m_data.m_value.object->cend(); - if (current.value->is_array()) + if (at_end) { - const auto& array = *current.value->m_data.m_value.array; - if (current.array_it == array.cend()) + if (current.value->size() > 4) { - if (array.size() > 4) - { - write_bon8_marker(0xFE, string_open); - } - stack.pop_back(); - continue; + write_bon8_marker(0xFE, string_open); } + stack.pop_back(); + continue; + } - // read the child before pushing: entering it can move every frame - const BasicJsonType* child = &(*current.array_it); + // read the child before pushing: entering it can move every frame + const BasicJsonType* child = nullptr; + if (is_array) + { + child = &(*current.array_it); ++stack.back().array_it; - write_bon8_value_or_push(*child, string_open, stack); } else { - const auto& object = *current.value->m_data.m_value.object; - if (current.object_it == object.cend()) - { - if (object.size() > 4) - { - write_bon8_marker(0xFE, string_open); - } - stack.pop_back(); - continue; - } - write_bon8_string(current.object_it->first, string_open, *current.value); - const BasicJsonType* child = &(current.object_it->second); + child = &(current.object_it->second); ++stack.back().object_it; - write_bon8_value_or_push(*child, string_open, stack); } + write_bon8_value_or_push(*child, string_open, stack); } } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index e4cdf09b0..2eb1c44f4 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -24327,21 +24327,13 @@ class binary_writer */ void write_bon8_value_or_push(const BasicJsonType& j, bool& string_open, std::vector& stack) { - if (j.is_array()) + if (j.is_array() || j.is_object()) { - const auto N = j.m_data.m_value.array->size(); - write_bon8_marker(static_cast(N <= 4 ? 0x80 + N : 0x85), string_open); - if (N != 0) - { - stack.emplace_back(&j); - } - return; - } - - if (j.is_object()) - { - const auto N = j.m_data.m_value.object->size(); - write_bon8_marker(static_cast(N <= 4 ? 0x86 + N : 0x8B), string_open); + // arrays use the markers 0x80..0x85, objects 0x86..0x8B; the last + // one stands for more than four elements, closed later with 0xFE + const auto N = j.size(); + const std::size_t base = j.is_array() ? 0x80 : 0x86; + write_bon8_marker(static_cast(base + (N <= 4 ? N : 5)), string_open); if (N != 0) { stack.emplace_back(&j); @@ -24369,43 +24361,35 @@ class binary_writer while (!stack.empty()) { const binary_container_frame current = stack.back(); + const bool is_array = current.value->is_array(); + const bool at_end = is_array + ? current.array_it == current.value->m_data.m_value.array->cend() + : current.object_it == current.value->m_data.m_value.object->cend(); - if (current.value->is_array()) + if (at_end) { - const auto& array = *current.value->m_data.m_value.array; - if (current.array_it == array.cend()) + if (current.value->size() > 4) { - if (array.size() > 4) - { - write_bon8_marker(0xFE, string_open); - } - stack.pop_back(); - continue; + write_bon8_marker(0xFE, string_open); } + stack.pop_back(); + continue; + } - // read the child before pushing: entering it can move every frame - const BasicJsonType* child = &(*current.array_it); + // read the child before pushing: entering it can move every frame + const BasicJsonType* child = nullptr; + if (is_array) + { + child = &(*current.array_it); ++stack.back().array_it; - write_bon8_value_or_push(*child, string_open, stack); } else { - const auto& object = *current.value->m_data.m_value.object; - if (current.object_it == object.cend()) - { - if (object.size() > 4) - { - write_bon8_marker(0xFE, string_open); - } - stack.pop_back(); - continue; - } - write_bon8_string(current.object_it->first, string_open, *current.value); - const BasicJsonType* child = &(current.object_it->second); + child = &(current.object_it->second); ++stack.back().object_it; - write_bon8_value_or_push(*child, string_open, stack); } + write_bon8_value_or_push(*child, string_open, stack); } }