diff --git a/include/nlohmann/detail/view/serializer.hpp b/include/nlohmann/detail/view/serializer.hpp index ce9bb8e8f..38377e9c0 100644 --- a/include/nlohmann/detail/view/serializer.hpp +++ b/include/nlohmann/detail/view/serializer.hpp @@ -37,12 +37,10 @@ class output_buffer { public: output_buffer(StringType& out, std::size_t estimate) - : m_out(out) - { - m_out.resize((std::max)(estimate, static_cast(64))); - m_pos = &m_out[0]; - m_end = m_pos + m_out.size(); - } + : m_out(sized(out, estimate)) + , m_pos(&m_out[0]) + , m_end(m_pos + m_out.size()) + {} void finish() { @@ -78,17 +76,23 @@ class output_buffer } private: + static StringType& sized(StringType& out, std::size_t estimate) + { + out.resize((std::max)(estimate, static_cast(64))); + return out; + } + NLOHMANN_VIEW_NOINLINE void grow(std::size_t n) { - const std::size_t used = static_cast(m_pos - m_out.data()); + const auto used = static_cast(m_pos - m_out.data()); m_out.resize((std::max)(m_out.size() * 2, used + n + 256)); m_pos = &m_out[0] + used; m_end = &m_out[0] + m_out.size(); } StringType& m_out; - char* m_pos = nullptr; - char* m_end = nullptr; + char* m_pos; + char* m_end; }; /// how the view's dump() writes a value @@ -318,8 +322,15 @@ class view_serializer std::size_t i = 0; while (i < n) { - const std::size_t run = EnsureAscii ? (is_ascii_copyable(s[i]) ? find_ascii_copyable_run(s + i, n - i) : 0) - : string_bulk_run(s + i, n - i); + std::size_t run = 0; + if (!EnsureAscii) + { + run = string_bulk_run(s + i, n - i); + } + else if (is_ascii_copyable(s[i])) + { + run = find_ascii_copyable_run(s + i, n - i); + } if (run != 0) { m_out.put(reinterpret_cast(s + i), run); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) @@ -330,7 +341,11 @@ class view_serializer std::size_t len = 1; if (codepoint >= 0xC0) { - len = codepoint >= 0xF0 ? 4 : (codepoint >= 0xE0 ? 3 : 2); + len = 2; + if (codepoint >= 0xE0) + { + len = codepoint >= 0xF0 ? 4 : 3; + } codepoint &= 0xFFu >> (len + 1); for (std::size_t k = 1; k < len; ++k) { diff --git a/single_include/nlohmann/json_view.hpp b/single_include/nlohmann/json_view.hpp index 677430567..9d0ab3b2e 100644 --- a/single_include/nlohmann/json_view.hpp +++ b/single_include/nlohmann/json_view.hpp @@ -2610,12 +2610,10 @@ class output_buffer { public: output_buffer(StringType& out, std::size_t estimate) - : m_out(out) - { - m_out.resize((std::max)(estimate, static_cast(64))); - m_pos = &m_out[0]; - m_end = m_pos + m_out.size(); - } + : m_out(sized(out, estimate)) + , m_pos(&m_out[0]) + , m_end(m_pos + m_out.size()) + {} void finish() { @@ -2651,17 +2649,23 @@ class output_buffer } private: + static StringType& sized(StringType& out, std::size_t estimate) + { + out.resize((std::max)(estimate, static_cast(64))); + return out; + } + NLOHMANN_VIEW_NOINLINE void grow(std::size_t n) { - const std::size_t used = static_cast(m_pos - m_out.data()); + const auto used = static_cast(m_pos - m_out.data()); m_out.resize((std::max)(m_out.size() * 2, used + n + 256)); m_pos = &m_out[0] + used; m_end = &m_out[0] + m_out.size(); } StringType& m_out; - char* m_pos = nullptr; - char* m_end = nullptr; + char* m_pos; + char* m_end; }; /// how the view's dump() writes a value @@ -2891,8 +2895,15 @@ class view_serializer std::size_t i = 0; while (i < n) { - const std::size_t run = EnsureAscii ? (is_ascii_copyable(s[i]) ? find_ascii_copyable_run(s + i, n - i) : 0) - : string_bulk_run(s + i, n - i); + std::size_t run = 0; + if (!EnsureAscii) + { + run = string_bulk_run(s + i, n - i); + } + else if (is_ascii_copyable(s[i])) + { + run = find_ascii_copyable_run(s + i, n - i); + } if (run != 0) { m_out.put(reinterpret_cast(s + i), run); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) @@ -2903,7 +2914,11 @@ class view_serializer std::size_t len = 1; if (codepoint >= 0xC0) { - len = codepoint >= 0xF0 ? 4 : (codepoint >= 0xE0 ? 3 : 2); + len = 2; + if (codepoint >= 0xE0) + { + len = codepoint >= 0xF0 ? 4 : 3; + } codepoint &= 0xFFu >> (len + 1); for (std::size_t k = 1; k < len; ++k) { diff --git a/tests/src/unit-json_view.cpp b/tests/src/unit-json_view.cpp index 9fb9ff411..2c0076486 100644 --- a/tests/src/unit-json_view.cpp +++ b/tests/src/unit-json_view.cpp @@ -1141,7 +1141,7 @@ TEST_CASE("json_view dump") CHECK(d.root().dump(-1, ' ', false, json_view::number_format::source) == "[1.50,1E2,-0,-0.0,123456789012345678901234567890,18446744073709551615,-9223372036854775808,0.1,1e-7,5e-324]"); // random doubles, written as parse() and dump() would - std::mt19937_64 rng(1170); + std::mt19937_64 rng(1170); // NOLINT(cert-msc32-c,cert-msc51-cpp,bugprone-random-generator-seed) std::string many = "["; for (int i = 0; i < 5000; ++i) { @@ -1153,7 +1153,7 @@ TEST_CASE("json_view dump") many += (many.size() > 1 ? "," : "") + json(x).dump(); } } - many += "]"; + many += ']'; CHECK(json_document::parse(many).root().dump() == json::parse(many).dump()); using json_float = nlohmann::basic_json;