mirror of
https://github.com/nlohmann/json.git
synced 2026-11-12 15:10:47 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15348ea128 |
No files matched your search
@@ -905,6 +905,8 @@ void resume_array(const lockstep_path& /*path*/, const A& /*a*/, const B& /*b*/,
|
|||||||
template<typename BasicJsonType, typename ViewA, typename ViewB>
|
template<typename BasicJsonType, typename ViewA, typename ViewB>
|
||||||
bool floats_equal(const view_side<BasicJsonType, ViewA>& a, const view_side<BasicJsonType, ViewB>& b)
|
bool floats_equal(const view_side<BasicJsonType, ViewA>& a, const view_side<BasicJsonType, ViewB>& b)
|
||||||
{
|
{
|
||||||
|
// float_token_is_nan() reads at most the node length of the token, which is not null terminated
|
||||||
|
// NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
|
||||||
return (a.value_node()->extra == b.value_node()->extra && a.float_token() == b.float_token() && !(view_side<BasicJsonType, ViewA>::nav::editable() && float_token_is_nan(*a.value_node(), a.float_token().data()))) || std::equal_to<typename BasicJsonType::number_float_t>()(a.floating(), b.floating());
|
return (a.value_node()->extra == b.value_node()->extra && a.float_token() == b.float_token() && !(view_side<BasicJsonType, ViewA>::nav::editable() && float_token_is_nan(*a.value_node(), a.float_token().data()))) || std::equal_to<typename BasicJsonType::number_float_t>()(a.floating(), b.floating());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,8 @@ struct document_data
|
|||||||
{
|
{
|
||||||
const auto overlaps = [p, n](const char* b, std::size_t m) noexcept
|
const auto overlaps = [p, n](const char* b, std::size_t m) noexcept
|
||||||
{
|
{
|
||||||
// (std::less: a total order also for pointers into different objects)
|
// (std::less: a total order also for pointers into different objects; std::less<> needs C++14)
|
||||||
|
// NOLINTNEXTLINE(modernize-use-transparent-functors)
|
||||||
return n != 0 && m != 0 && std::less<const char*>()(p, b + m) && std::less<const char*>()(b, p + n);
|
return n != 0 && m != 0 && std::less<const char*>()(p, b + m) && std::less<const char*>()(b, p + n);
|
||||||
};
|
};
|
||||||
return overlaps(owned.data(), owned.capacity())
|
return overlaps(owned.data(), owned.capacity())
|
||||||
|
|||||||
Generated
+4
-1
@@ -502,7 +502,8 @@ struct document_data
|
|||||||
{
|
{
|
||||||
const auto overlaps = [p, n](const char* b, std::size_t m) noexcept
|
const auto overlaps = [p, n](const char* b, std::size_t m) noexcept
|
||||||
{
|
{
|
||||||
// (std::less: a total order also for pointers into different objects)
|
// (std::less: a total order also for pointers into different objects; std::less<> needs C++14)
|
||||||
|
// NOLINTNEXTLINE(modernize-use-transparent-functors)
|
||||||
return n != 0 && m != 0 && std::less<const char*>()(p, b + m) && std::less<const char*>()(b, p + n);
|
return n != 0 && m != 0 && std::less<const char*>()(p, b + m) && std::less<const char*>()(b, p + n);
|
||||||
};
|
};
|
||||||
return overlaps(owned.data(), owned.capacity())
|
return overlaps(owned.data(), owned.capacity())
|
||||||
@@ -4088,6 +4089,8 @@ void resume_array(const lockstep_path& /*path*/, const A& /*a*/, const B& /*b*/,
|
|||||||
template<typename BasicJsonType, typename ViewA, typename ViewB>
|
template<typename BasicJsonType, typename ViewA, typename ViewB>
|
||||||
bool floats_equal(const view_side<BasicJsonType, ViewA>& a, const view_side<BasicJsonType, ViewB>& b)
|
bool floats_equal(const view_side<BasicJsonType, ViewA>& a, const view_side<BasicJsonType, ViewB>& b)
|
||||||
{
|
{
|
||||||
|
// float_token_is_nan() reads at most the node length of the token, which is not null terminated
|
||||||
|
// NOLINTNEXTLINE(bugprone-suspicious-stringview-data-usage)
|
||||||
return (a.value_node()->extra == b.value_node()->extra && a.float_token() == b.float_token() && !(view_side<BasicJsonType, ViewA>::nav::editable() && float_token_is_nan(*a.value_node(), a.float_token().data()))) || std::equal_to<typename BasicJsonType::number_float_t>()(a.floating(), b.floating());
|
return (a.value_node()->extra == b.value_node()->extra && a.float_token() == b.float_token() && !(view_side<BasicJsonType, ViewA>::nav::editable() && float_token_is_nan(*a.value_node(), a.float_token().data()))) || std::equal_to<typename BasicJsonType::number_float_t>()(a.floating(), b.floating());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2682,25 +2682,27 @@ TEST_CASE("JSON patch - consecutive operations with paths that share a prefix")
|
|||||||
const json doc = json::parse(R"({"a": [{"b": [1, 2, 3]}, {"b": [4, 5, 6]}], "c": {"d": {"e": 7}}})");
|
const json doc = json::parse(R"({"a": [{"b": [1, 2, 3]}, {"b": [4, 5, 6]}], "c": {"d": {"e": 7}}})");
|
||||||
|
|
||||||
// an element inserted before the elements of an array moves them
|
// an element inserted before the elements of an array moves them
|
||||||
CHECK(doc.patch(json::parse(R"([
|
const json inserted = json::parse(R"([
|
||||||
{"op": "test", "path": "/a/0/b/2", "value": 3},
|
{"op": "test", "path": "/a/0/b/2", "value": 3},
|
||||||
{"op": "add", "path": "/a/0", "value": {"b": [9]}},
|
{"op": "add", "path": "/a/0", "value": {"b": [9]}},
|
||||||
{"op": "test", "path": "/a/1/b/2", "value": 3},
|
{"op": "test", "path": "/a/1/b/2", "value": 3},
|
||||||
{"op": "test", "path": "/a/0/b/0", "value": 9},
|
{"op": "test", "path": "/a/0/b/0", "value": 9},
|
||||||
{"op": "test", "path": "/a/2/b/0", "value": 4}
|
{"op": "test", "path": "/a/2/b/0", "value": 4}
|
||||||
])")) == json::parse(R"({"a": [{"b": [9]}, {"b": [1, 2, 3]}, {"b": [4, 5, 6]}], "c": {"d": {"e": 7}}})"));
|
])");
|
||||||
|
CHECK(doc.patch(inserted) == json::parse(R"({"a": [{"b": [9]}, {"b": [1, 2, 3]}, {"b": [4, 5, 6]}], "c": {"d": {"e": 7}}})"));
|
||||||
|
|
||||||
// an element removed from the front
|
// an element removed from the front
|
||||||
CHECK(doc.patch(json::parse(R"([
|
const json removed_front = json::parse(R"([
|
||||||
{"op": "test", "path": "/a/1/b/2", "value": 6},
|
{"op": "test", "path": "/a/1/b/2", "value": 6},
|
||||||
{"op": "remove", "path": "/a/0"},
|
{"op": "remove", "path": "/a/0"},
|
||||||
{"op": "test", "path": "/a/0/b/2", "value": 6},
|
{"op": "test", "path": "/a/0/b/2", "value": 6},
|
||||||
{"op": "replace", "path": "/a/0/b/2", "value": 60},
|
{"op": "replace", "path": "/a/0/b/2", "value": 60},
|
||||||
{"op": "test", "path": "/a/0/b/2", "value": 60}
|
{"op": "test", "path": "/a/0/b/2", "value": 60}
|
||||||
])")) == json::parse(R"({"a": [{"b": [4, 5, 60]}], "c": {"d": {"e": 7}}})"));
|
])");
|
||||||
|
CHECK(doc.patch(removed_front) == json::parse(R"({"a": [{"b": [4, 5, 60]}], "c": {"d": {"e": 7}}})"));
|
||||||
|
|
||||||
// a value replaced above the path that was resolved before
|
// a value replaced above the path that was resolved before
|
||||||
CHECK(doc.patch(json::parse(R"([
|
const json replaced_above = json::parse(R"([
|
||||||
{"op": "test", "path": "/c/d/e", "value": 7},
|
{"op": "test", "path": "/c/d/e", "value": 7},
|
||||||
{"op": "replace", "path": "/c/d", "value": {"e": 8, "f": {"g": 9}}},
|
{"op": "replace", "path": "/c/d", "value": {"e": 8, "f": {"g": 9}}},
|
||||||
{"op": "test", "path": "/c/d/e", "value": 8},
|
{"op": "test", "path": "/c/d/e", "value": 8},
|
||||||
@@ -2708,7 +2710,8 @@ TEST_CASE("JSON patch - consecutive operations with paths that share a prefix")
|
|||||||
{"op": "remove", "path": "/c/d/f"},
|
{"op": "remove", "path": "/c/d/f"},
|
||||||
{"op": "add", "path": "/c/d/f", "value": [1]},
|
{"op": "add", "path": "/c/d/f", "value": [1]},
|
||||||
{"op": "test", "path": "/c/d/f/0", "value": 1}
|
{"op": "test", "path": "/c/d/f/0", "value": 1}
|
||||||
])")) == json::parse(R"({"a": [{"b": [1, 2, 3]}, {"b": [4, 5, 6]}], "c": {"d": {"e": 8, "f": [1]}}})"));
|
])");
|
||||||
|
CHECK(doc.patch(replaced_above) == json::parse(R"({"a": [{"b": [1, 2, 3]}, {"b": [4, 5, 6]}], "c": {"d": {"e": 8, "f": [1]}}})"));
|
||||||
|
|
||||||
#if !defined(JSON_NOEXCEPTION)
|
#if !defined(JSON_NOEXCEPTION)
|
||||||
// a value removed above the path that was resolved before is gone
|
// a value removed above the path that was resolved before is gone
|
||||||
|
|||||||
@@ -916,14 +916,15 @@ TEST_CASE("json_view document_data::holds() (the debug check of read())")
|
|||||||
|
|
||||||
SECTION("owned text")
|
SECTION("owned text")
|
||||||
{
|
{
|
||||||
d->owned = "{\"a\":\"some text that does not fit a short string\"}";
|
d->owned = R"({"a":"some text that does not fit a short string"})";
|
||||||
const char* const b = d->owned.data();
|
const char* const b = d->owned.data();
|
||||||
CHECK(d->holds(b, 1));
|
CHECK(d->holds(b, 1));
|
||||||
CHECK(d->holds(b + 5, 3));
|
CHECK(d->holds(b + 5, 3));
|
||||||
CHECK(d->holds(b + d->owned.size() - 1, 1));
|
CHECK(d->holds(b + d->owned.size() - 1, 1));
|
||||||
// also after clear(), which keeps the buffer that the next parse writes
|
// also after clear(), which keeps the buffer that the next parse writes
|
||||||
d->owned.clear();
|
d->owned.clear();
|
||||||
CHECK(d->holds(b, 4));
|
// (b is only compared with the buffer, never read)
|
||||||
|
CHECK(d->holds(b, 4)); // NOLINT(clang-analyzer-cplusplus.InnerPointer)
|
||||||
CHECK(!d->holds(other.data(), other.size()));
|
CHECK(!d->holds(other.data(), other.size()));
|
||||||
CHECK(!d->holds(b, 0));
|
CHECK(!d->holds(b, 0));
|
||||||
}
|
}
|
||||||
@@ -946,7 +947,7 @@ TEST_CASE("json_view document_data::holds() (the debug check of read())")
|
|||||||
{
|
{
|
||||||
d->edits.reset(new document_data::edit_state()); // NOLINT(cppcoreguidelines-owning-memory)
|
d->edits.reset(new document_data::edit_state()); // NOLINT(cppcoreguidelines-owning-memory)
|
||||||
CHECK(!d->holds(other.data(), other.size()));
|
CHECK(!d->holds(other.data(), other.size()));
|
||||||
d->edits->texts.emplace_back(new char[16]); // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
d->edits->texts.emplace_back(new char[16]); // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays,cppcoreguidelines-owning-memory)
|
||||||
d->edits->text_cap = 16;
|
d->edits->text_cap = 16;
|
||||||
CHECK(d->holds(d->edits->texts.back().get() + 3, 3));
|
CHECK(d->holds(d->edits->texts.back().get() + 3, 3));
|
||||||
CHECK(!d->holds(other.data(), other.size()));
|
CHECK(!d->holds(other.data(), other.size()));
|
||||||
|
|||||||
@@ -494,7 +494,7 @@ TEST_CASE("walks over values nested around the recursion depth limit")
|
|||||||
for_each_value([](const std::string & kinds)
|
for_each_value([](const std::string & kinds)
|
||||||
{
|
{
|
||||||
const json a = build(kinds, 1);
|
const json a = build(kinds, 1);
|
||||||
const std::hash<json> hash;
|
const std::hash<json> hash{};
|
||||||
CHECK(hash(a) == hash(json(a)));
|
CHECK(hash(a) == hash(json(a)));
|
||||||
CHECK(hash(a) == hash(json::parse(expected_compact(kinds, "1"))));
|
CHECK(hash(a) == hash(json::parse(expected_compact(kinds, "1"))));
|
||||||
CHECK(hash(a) != hash(build(kinds, 2)));
|
CHECK(hash(a) != hash(build(kinds, 2)));
|
||||||
|
|||||||
Reference in new issue
Block a user