From 908038c0279db81e722e9d1f9318967da7581498 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 15 Oct 2026 08:16:23 +0200 Subject: [PATCH] Look up the key only once in the callback parser's key() Signed-off-by: Niels Lohmann --- include/nlohmann/detail/input/json_sax.hpp | 9 ++++++--- single_include/nlohmann/json.hpp | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/include/nlohmann/detail/input/json_sax.hpp b/include/nlohmann/detail/input/json_sax.hpp index 161568ded..b7e08c870 100644 --- a/include/nlohmann/detail/input/json_sax.hpp +++ b/include/nlohmann/detail/input/json_sax.hpp @@ -674,16 +674,19 @@ class json_sax_dom_callback_parser if (keep && ref_stack.back()) { auto& obj = *ref_stack.back()->m_data.m_value.object; - const auto it = obj.find(val); - if (it != obj.end()) + // a single lookup: insert the placeholder, or find the existing member + const auto inserted = obj.emplace(val, discarded); + const auto it = inserted.first; + if (!inserted.second) { // this is a duplicate key (legal in JSON); remember its // current value so it can be restored later if the new // value is rejected by the callback, instead of being // erased together with the discarded placeholder duplicate_key_stash.emplace_back(&(it->second), it->second); + it->second = discarded; } - object_element = &(obj[val] = discarded); + object_element = &(it->second); } return true; diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index a35f9e32c..cd5189628 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -13850,16 +13850,19 @@ class json_sax_dom_callback_parser if (keep && ref_stack.back()) { auto& obj = *ref_stack.back()->m_data.m_value.object; - const auto it = obj.find(val); - if (it != obj.end()) + // a single lookup: insert the placeholder, or find the existing member + const auto inserted = obj.emplace(val, discarded); + const auto it = inserted.first; + if (!inserted.second) { // this is a duplicate key (legal in JSON); remember its // current value so it can be restored later if the new // value is rejected by the callback, instead of being // erased together with the discarded placeholder duplicate_key_stash.emplace_back(&(it->second), it->second); + it->second = discarded; } - object_element = &(obj[val] = discarded); + object_element = &(it->second); } return true;