Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36da0e2f78 | ||
|
|
9da5272f6c |
No files matched your search
@@ -406,6 +406,7 @@ using array_t = ArrayType<basic_json, AllocatorType<basic_json>>;
|
|||||||
| `#!cpp operator<<(std::ostream&, const json_pointer&)` | streamability to `#!cpp std::ostream` |
|
| `#!cpp operator<<(std::ostream&, const json_pointer&)` | streamability to `#!cpp std::ostream` |
|
||||||
| [`to_string`](../../api/basic_json/to_string.md) | conversion of `StringType` to `#!cpp std::string` (the function returns a `#!cpp std::string`) |
|
| [`to_string`](../../api/basic_json/to_string.md) | conversion of `StringType` to `#!cpp std::string` (the function returns a `#!cpp std::string`) |
|
||||||
| exception messages | `data()` and `size()`, or `begin()` and `end()` |
|
| exception messages | `data()` and `size()`, or `begin()` and `end()` |
|
||||||
|
| [`basic_json_view::dump`](../../api/basic_json_view/dump.md) | `reserve(n)` and `resize(n)` (one argument); `capacity()` is **not** required |
|
||||||
|
|
||||||
### Compatible types
|
### Compatible types
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ class output_buffer
|
|||||||
: m_out(sized(out, estimate))
|
: m_out(sized(out, estimate))
|
||||||
, m_pos(&m_out[0])
|
, m_pos(&m_out[0])
|
||||||
, m_end(m_pos + m_out.size())
|
, m_end(m_pos + m_out.size())
|
||||||
|
, m_reserved((std::max)(estimate, m_out.size()))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void finish()
|
void finish()
|
||||||
@@ -116,11 +117,12 @@ class output_buffer
|
|||||||
const auto used = static_cast<std::size_t>(m_pos - m_out.data());
|
const auto used = static_cast<std::size_t>(m_pos - m_out.data());
|
||||||
// (a step does not go beyond the reserved estimate, so that a good
|
// (a step does not go beyond the reserved estimate, so that a good
|
||||||
// estimate is never copied to a larger allocation; not a clamp: the
|
// estimate is never copied to a larger allocation; not a clamp: the
|
||||||
// lower bound used + n + 256 can exceed capacity(), and then it must win)
|
// lower bound used + n + 256 can exceed m_reserved, and then it must win)
|
||||||
const std::size_t size = (std::max)((std::min)(m_out.size() + step, m_out.capacity()), used + n + 256);
|
const std::size_t size = (std::max)((std::min)(m_out.size() + step, m_reserved), used + n + 256);
|
||||||
if (size > m_out.capacity())
|
if (size > m_reserved)
|
||||||
{
|
{
|
||||||
m_out.reserve((std::max)(m_out.capacity() * 2, size));
|
m_reserved = (std::max)(m_reserved * 2, size);
|
||||||
|
m_out.reserve(m_reserved);
|
||||||
}
|
}
|
||||||
m_out.resize(size);
|
m_out.resize(size);
|
||||||
m_pos = &m_out[0] + used;
|
m_pos = &m_out[0] + used;
|
||||||
@@ -130,6 +132,9 @@ class output_buffer
|
|||||||
StringType& m_out;
|
StringType& m_out;
|
||||||
char* m_pos;
|
char* m_pos;
|
||||||
char* m_end;
|
char* m_end;
|
||||||
|
/// what was last passed to reserve(), a lower bound of the capacity
|
||||||
|
/// (StringType need not have a capacity() member)
|
||||||
|
std::size_t m_reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The length of the run at s that dump() writes unchanged without
|
/// The length of the run at s that dump() writes unchanged without
|
||||||
|
|||||||
Generated
+9
-4
@@ -8511,6 +8511,7 @@ class output_buffer
|
|||||||
: m_out(sized(out, estimate))
|
: m_out(sized(out, estimate))
|
||||||
, m_pos(&m_out[0])
|
, m_pos(&m_out[0])
|
||||||
, m_end(m_pos + m_out.size())
|
, m_end(m_pos + m_out.size())
|
||||||
|
, m_reserved((std::max)(estimate, m_out.size()))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void finish()
|
void finish()
|
||||||
@@ -8580,11 +8581,12 @@ class output_buffer
|
|||||||
const auto used = static_cast<std::size_t>(m_pos - m_out.data());
|
const auto used = static_cast<std::size_t>(m_pos - m_out.data());
|
||||||
// (a step does not go beyond the reserved estimate, so that a good
|
// (a step does not go beyond the reserved estimate, so that a good
|
||||||
// estimate is never copied to a larger allocation; not a clamp: the
|
// estimate is never copied to a larger allocation; not a clamp: the
|
||||||
// lower bound used + n + 256 can exceed capacity(), and then it must win)
|
// lower bound used + n + 256 can exceed m_reserved, and then it must win)
|
||||||
const std::size_t size = (std::max)((std::min)(m_out.size() + step, m_out.capacity()), used + n + 256);
|
const std::size_t size = (std::max)((std::min)(m_out.size() + step, m_reserved), used + n + 256);
|
||||||
if (size > m_out.capacity())
|
if (size > m_reserved)
|
||||||
{
|
{
|
||||||
m_out.reserve((std::max)(m_out.capacity() * 2, size));
|
m_reserved = (std::max)(m_reserved * 2, size);
|
||||||
|
m_out.reserve(m_reserved);
|
||||||
}
|
}
|
||||||
m_out.resize(size);
|
m_out.resize(size);
|
||||||
m_pos = &m_out[0] + used;
|
m_pos = &m_out[0] + used;
|
||||||
@@ -8594,6 +8596,9 @@ class output_buffer
|
|||||||
StringType& m_out;
|
StringType& m_out;
|
||||||
char* m_pos;
|
char* m_pos;
|
||||||
char* m_end;
|
char* m_end;
|
||||||
|
/// what was last passed to reserve(), a lower bound of the capacity
|
||||||
|
/// (StringType need not have a capacity() member)
|
||||||
|
std::size_t m_reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The length of the run at s that dump() writes unchanged without
|
/// The length of the run at s that dump() writes unchanged without
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "doctest_compatibility.h"
|
#include "doctest_compatibility.h"
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <nlohmann/json_view.hpp>
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -483,4 +484,56 @@ TEST_CASE("alternative string type")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("alternative string type with json_view")
|
||||||
|
{
|
||||||
|
// regression test for #5994: basic_json_view::dump() called
|
||||||
|
// StringType::capacity(), which alt_string (and the documented StringType
|
||||||
|
// requirements) do not provide
|
||||||
|
using alt_document = nlohmann::basic_json_document<alt_json, nlohmann::view_mode::read_only>;
|
||||||
|
using alt_editable_document = nlohmann::basic_json_document<alt_json, nlohmann::view_mode::editable>;
|
||||||
|
|
||||||
|
const char* text = R"({"a":[1,"x\u00e4"],"b":{"c":true,"d":null},"e":2.5})";
|
||||||
|
const alt_json j = alt_json::parse(text);
|
||||||
|
|
||||||
|
SECTION("read-only document")
|
||||||
|
{
|
||||||
|
const alt_document d = alt_document::parse(text);
|
||||||
|
CHECK(d.root().dump() == j.dump());
|
||||||
|
CHECK(d.root().dump(2) == j.dump(2));
|
||||||
|
CHECK(d.root().dump(-1, ' ', true) == j.dump(-1, ' ', true));
|
||||||
|
CHECK(d.root().materialize() == j);
|
||||||
|
CHECK(d.root().contains(alt_string("b")));
|
||||||
|
CHECK(d.root()[alt_string("b")][alt_string("c")].dump() == "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("long output")
|
||||||
|
{
|
||||||
|
// more than one growth step of the output buffer
|
||||||
|
alt_json big = alt_json::array();
|
||||||
|
for (int i = 0; i < 20000; ++i)
|
||||||
|
{
|
||||||
|
big.push_back(alt_json::parse(text));
|
||||||
|
}
|
||||||
|
const alt_string big_text = big.dump();
|
||||||
|
const alt_document d = alt_document::parse(big_text);
|
||||||
|
CHECK(d.root().dump() == big_text);
|
||||||
|
CHECK(d.root().dump(4) == big.dump(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("editable document")
|
||||||
|
{
|
||||||
|
alt_editable_document d = alt_editable_document::parse(text);
|
||||||
|
d.set(d.root(), "f", "new");
|
||||||
|
d.push_back(d.root()[alt_string("a")], 3);
|
||||||
|
alt_json expected = j;
|
||||||
|
expected["f"] = "new";
|
||||||
|
expected["a"].push_back(3);
|
||||||
|
CHECK(d.root().materialize() == expected);
|
||||||
|
CHECK(alt_json::parse(d.root().dump()) == expected);
|
||||||
|
|
||||||
|
const alt_editable_document loaded = alt_editable_document::load(d.save());
|
||||||
|
CHECK(loaded.root().materialize() == expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
DOCTEST_CLANG_SUPPRESS_WARNING_POP
|
||||||
Reference in new issue
Block a user