From 3bb9467073f366bfb2b46c9c6a0c1fe11219da60 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Tue, 13 Jul 2021 15:27:27 +0200 Subject: [PATCH] :recycle: move capacity check to set_parent function --- include/nlohmann/json.hpp | 53 ++++++++++++-------------------- single_include/nlohmann/json.hpp | 53 ++++++++++++-------------------- 2 files changed, 38 insertions(+), 68 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index ae77747b5..d18f082b4 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -1304,9 +1304,21 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return it; } - reference set_parent(reference j) + reference set_parent(reference j, std::size_t old_capacity = -1) { #if JSON_DIAGNOSTICS + if (old_capacity != -1) + { + // see https://github.com/nlohmann/json/issues/2838 + JSON_ASSERT(type() == value_t::array); + if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity)) + { + // capacity has changed: update all parents + set_parents(); + return j; + } + } + j.m_parent = this; #else static_cast(j); @@ -5371,18 +5383,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } // add element to array (move semantics) - const auto capacity = m_value.array->capacity(); + const auto old_capacity = m_value.array->capacity(); m_value.array->push_back(std::move(val)); - if (capacity == m_value.array->capacity()) - { - // capacity has not changed: updating parent of last element is sufficient - set_parent(m_value.array->back()); - } - else - { - // capacity has changed: update all elements' parents - set_parents(); - } + set_parent(m_value.array->back(), old_capacity); // if val is moved from, basic_json move constructor marks it null so we do not call the destructor } @@ -5417,18 +5420,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } // add element to array - const auto capacity = m_value.array->capacity(); + const auto old_capacity = m_value.array->capacity(); m_value.array->push_back(val); - if (capacity == m_value.array->capacity()) - { - // capacity has not changed: updating parent of last element is sufficient - set_parent(m_value.array->back()); - } - else - { - // capacity has changed: update all elements' parents - set_parents(); - } + set_parent(m_value.array->back(), old_capacity); } /*! @@ -5582,18 +5576,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } // add element to array (perfect forwarding) - const auto capacity = m_value.array->capacity(); + const auto old_capacity = m_value.array->capacity(); m_value.array->emplace_back(std::forward(args)...); - - if (capacity == m_value.array->capacity()) - { - // capacity has not changed: updating parent of last element is sufficient - return set_parent(m_value.array->back()); - } - - // capacity has changed: update all elements' parents - set_parents(); - return m_value.array->back(); + return set_parent(m_value.array->back(), old_capacity); } /*! diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 2500eb9cb..3b5a7a75d 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -18339,9 +18339,21 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec return it; } - reference set_parent(reference j) + reference set_parent(reference j, std::size_t old_capacity = -1) { #if JSON_DIAGNOSTICS + if (old_capacity != -1) + { + // see https://github.com/nlohmann/json/issues/2838 + JSON_ASSERT(type() == value_t::array); + if (JSON_HEDLEY_UNLIKELY(m_value.array->capacity() != old_capacity)) + { + // capacity has changed: update all parents + set_parents(); + return j; + } + } + j.m_parent = this; #else static_cast(j); @@ -22406,18 +22418,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } // add element to array (move semantics) - const auto capacity = m_value.array->capacity(); + const auto old_capacity = m_value.array->capacity(); m_value.array->push_back(std::move(val)); - if (capacity == m_value.array->capacity()) - { - // capacity has not changed: updating parent of last element is sufficient - set_parent(m_value.array->back()); - } - else - { - // capacity has changed: update all elements' parents - set_parents(); - } + set_parent(m_value.array->back(), old_capacity); // if val is moved from, basic_json move constructor marks it null so we do not call the destructor } @@ -22452,18 +22455,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } // add element to array - const auto capacity = m_value.array->capacity(); + const auto old_capacity = m_value.array->capacity(); m_value.array->push_back(val); - if (capacity == m_value.array->capacity()) - { - // capacity has not changed: updating parent of last element is sufficient - set_parent(m_value.array->back()); - } - else - { - // capacity has changed: update all elements' parents - set_parents(); - } + set_parent(m_value.array->back(), old_capacity); } /*! @@ -22617,18 +22611,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec } // add element to array (perfect forwarding) - const auto capacity = m_value.array->capacity(); + const auto old_capacity = m_value.array->capacity(); m_value.array->emplace_back(std::forward(args)...); - - if (capacity == m_value.array->capacity()) - { - // capacity has not changed: updating parent of last element is sufficient - return set_parent(m_value.array->back()); - } - - // capacity has changed: update all elements' parents - set_parents(); - return m_value.array->back(); + return set_parent(m_value.array->back(), old_capacity); } /*!