diff --git a/include/nlohmann/detail/output/serializer.hpp b/include/nlohmann/detail/output/serializer.hpp index 9dabecfd9..e0b5dcc71 100644 --- a/include/nlohmann/detail/output/serializer.hpp +++ b/include/nlohmann/detail/output/serializer.hpp @@ -126,11 +126,7 @@ class serializer // variable to hold indentation for recursive calls const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize((std::max)(indent_string.size() * 2, static_cast(new_indent)), indent_char); - JSON_ASSERT(indent_string.size() >= new_indent); - } + reserve_indent(new_indent); // first n-1 elements auto i = val.m_data.m_value.object->cbegin(); @@ -200,11 +196,7 @@ class serializer // variable to hold indentation for recursive calls const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize((std::max)(indent_string.size() * 2, static_cast(new_indent)), indent_char); - JSON_ASSERT(indent_string.size() >= new_indent); - } + reserve_indent(new_indent); // first n-1 elements for (auto i = val.m_data.m_value.array->cbegin(); @@ -262,11 +254,7 @@ class serializer // variable to hold indentation for recursive calls const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize((std::max)(indent_string.size() * 2, static_cast(new_indent)), indent_char); - JSON_ASSERT(indent_string.size() >= new_indent); - } + reserve_indent(new_indent); o->write_characters(indent_string.c_str(), new_indent); @@ -376,6 +364,25 @@ class serializer } } + /*! + @brief grow the indentation string so it can hold at least @a new_indent characters + + The indentation string is grown by doubling its size, but at least to + @a new_indent characters, so that it can be used as a source for writing + @a new_indent indentation characters. The newly added characters use the + configured @ref indent_char. + + @param[in] new_indent the required number of indentation characters + */ + void reserve_indent(const std::size_t new_indent) + { + if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) + { + indent_string.resize((std::max)(indent_string.size() * 2, new_indent), indent_char); + } + JSON_ASSERT(indent_string.size() >= new_indent); + } + JSON_PRIVATE_UNLESS_TESTED: /*! @brief dump escaped string diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 662c9afb0..7408238c2 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -19300,11 +19300,7 @@ class serializer // variable to hold indentation for recursive calls const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize((std::max)(indent_string.size() * 2, static_cast(new_indent)), indent_char); - JSON_ASSERT(indent_string.size() >= new_indent); - } + reserve_indent(new_indent); // first n-1 elements auto i = val.m_data.m_value.object->cbegin(); @@ -19374,11 +19370,7 @@ class serializer // variable to hold indentation for recursive calls const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize((std::max)(indent_string.size() * 2, static_cast(new_indent)), indent_char); - JSON_ASSERT(indent_string.size() >= new_indent); - } + reserve_indent(new_indent); // first n-1 elements for (auto i = val.m_data.m_value.array->cbegin(); @@ -19436,11 +19428,7 @@ class serializer // variable to hold indentation for recursive calls const auto new_indent = current_indent + indent_step; - if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) - { - indent_string.resize((std::max)(indent_string.size() * 2, static_cast(new_indent)), indent_char); - JSON_ASSERT(indent_string.size() >= new_indent); - } + reserve_indent(new_indent); o->write_characters(indent_string.c_str(), new_indent); @@ -19550,6 +19538,25 @@ class serializer } } + /*! + @brief grow the indentation string so it can hold at least @a new_indent characters + + The indentation string is grown by doubling its size, but at least to + @a new_indent characters, so that it can be used as a source for writing + @a new_indent indentation characters. The newly added characters use the + configured @ref indent_char. + + @param[in] new_indent the required number of indentation characters + */ + void reserve_indent(const std::size_t new_indent) + { + if (JSON_HEDLEY_UNLIKELY(indent_string.size() < new_indent)) + { + indent_string.resize((std::max)(indent_string.size() * 2, new_indent), indent_char); + } + JSON_ASSERT(indent_string.size() >= new_indent); + } + JSON_PRIVATE_UNLESS_TESTED: /*! @brief dump escaped string diff --git a/tests/src/unit-serialization.cpp b/tests/src/unit-serialization.cpp index c0f2a8e04..f55ed8470 100644 --- a/tests/src/unit-serialization.cpp +++ b/tests/src/unit-serialization.cpp @@ -311,14 +311,16 @@ TEST_CASE("dump for basic_json with long double number_float_t") SECTION("round-trip dump/parse") { constexpr std::array values = - {{ - 0.0L, -0.0L, 1.0L, -1.0L, - 0.5L, -0.5L, 1.5L, -2.25L, - 1.23e45L, 1.23e-45L, - (std::numeric_limits::min)(), - std::numeric_limits::lowest(), - (std::numeric_limits::max)() - }}; + { + { + 0.0L, -0.0L, 1.0L, -1.0L, + 0.5L, -0.5L, 1.5L, -2.25L, + 1.23e45L, 1.23e-45L, + (std::numeric_limits::min)(), + std::numeric_limits::lowest(), + (std::numeric_limits::max)() + } + }; for (long double v : values) {