From c109e260df919cda1db5b5a4f071fd1b022be8bb Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 30 Sep 2026 07:33:13 +0200 Subject: [PATCH] Only track the target key order in diff() for insertion-ordered objects common_keys_target_order and new_keys_form_suffix are only read when object_t keeps its members in insertion order; skip building them otherwise. Addresses review comment by @gregmarr. Signed-off-by: Niels Lohmann --- include/nlohmann/json.hpp | 26 +++++++++++++++++--------- single_include/nlohmann/json.hpp | 26 +++++++++++++++++--------- 2 files changed, 34 insertions(+), 18 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index 849ce2167..c304dd69e 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -6150,12 +6150,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // the same time, determine whether every added key comes // after every common key in target's order (a precondition // for the fast path below, which only ever appends new keys - // at the very end): for an object_t whose iteration order is - // a pure function of the key set (e.g. the default std::map, - // which always iterates in sorted key order), the order - // check further below is always true and this whole - // mechanism is effectively a no-op; it only matters for a - // reorderable object_t such as the one backing `ordered_json`. + // at the very end). Both are only needed for an object_t that + // keeps its members in insertion order, such as the one + // backing `ordered_json`; for any other object_t, the fast + // path is always taken and they are not computed. // patch ops for keys that were added (i.e., in target but not // in source); built here so the fast path below can reuse // them without a second source.find() per target key. Only @@ -6179,11 +6177,21 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } else { - common_keys_target_order.push_back(it.key()); - if (seen_new_key) +#ifdef JSON_HEDLEY_MSVC_VERSION +#pragma warning(push ) +#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr +#endif + if (detail::is_ordered_map::value) { - new_keys_form_suffix = false; + common_keys_target_order.push_back(it.key()); + if (seen_new_key) + { + new_keys_form_suffix = false; + } } +#ifdef JSON_HEDLEY_MSVC_VERSION +#pragma warning( pop ) +#endif } } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index fe53ef54e..c2ce801c6 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -32231,12 +32231,10 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec // the same time, determine whether every added key comes // after every common key in target's order (a precondition // for the fast path below, which only ever appends new keys - // at the very end): for an object_t whose iteration order is - // a pure function of the key set (e.g. the default std::map, - // which always iterates in sorted key order), the order - // check further below is always true and this whole - // mechanism is effectively a no-op; it only matters for a - // reorderable object_t such as the one backing `ordered_json`. + // at the very end). Both are only needed for an object_t that + // keeps its members in insertion order, such as the one + // backing `ordered_json`; for any other object_t, the fast + // path is always taken and they are not computed. // patch ops for keys that were added (i.e., in target but not // in source); built here so the fast path below can reuse // them without a second source.find() per target key. Only @@ -32260,11 +32258,21 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } else { - common_keys_target_order.push_back(it.key()); - if (seen_new_key) +#ifdef JSON_HEDLEY_MSVC_VERSION +#pragma warning(push ) +#pragma warning(disable : 4127) // ignore warning to replace if with if constexpr +#endif + if (detail::is_ordered_map::value) { - new_keys_form_suffix = false; + common_keys_target_order.push_back(it.key()); + if (seen_new_key) + { + new_keys_form_suffix = false; + } } +#ifdef JSON_HEDLEY_MSVC_VERSION +#pragma warning( pop ) +#endif } }