Add comparisons to json_view

basic_json_view gains operator== and operator!= with other views and with
basic_json values. Two views are equal if the values parse() would
produce for them are equal by basic_json's operator==: numbers compare by
value across their types, and objects by their members, with duplicate
keys resolved as parse() resolves them (the last value, at the position of
the first key). Objects are compared in member order if the object type
keeps an order (ordered_json), by key otherwise, as basic_json does.
Discarded views compare as discarded basic_json values do, which follows
JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON. Nothing is materialized except
single numbers, and the walk is iterative.

Tests compare the results for pairs of 1,200 generated documents (also
written differently: sorted keys, canonical numbers) with those of
basic_json, for json and ordered_json, plus numbers, duplicate keys,
member order, discarded values, and 100,000 levels of nesting.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-09-29 14:02:59 +02:00
parent ecce914701
commit 401af52511
5 changed files with 819 additions and 0 deletions
+46
View File
@@ -47,6 +47,7 @@
#endif
#include <nlohmann/detail/view/builder.hpp>
#include <nlohmann/detail/view/compare.hpp>
#include <nlohmann/detail/view/document_data.hpp>
#include <nlohmann/detail/view/errors.hpp>
#include <nlohmann/detail/view/input.hpp>
@@ -603,6 +604,44 @@ class basic_json_view
}
#endif
////////////////
// comparison //
////////////////
/// whether the values parse() would produce for two views are equal, as
/// by BasicJsonType's operator== (numbers by value, objects by their
/// members with duplicate keys resolved as parse() resolves them)
friend bool operator==(const basic_json_view& a, const basic_json_view& b)
{
return detail::view::equal<BasicJsonType>(side(a), side(b));
}
friend bool operator!=(const basic_json_view& a, const basic_json_view& b)
{
return !(a == b);
}
/// whether the value parse() would produce for a view equals a value
friend bool operator==(const basic_json_view& a, const BasicJsonType& j)
{
return detail::view::equal<BasicJsonType>(side(a), json_side_t(j));
}
friend bool operator==(const BasicJsonType& j, const basic_json_view& a)
{
return a == j;
}
friend bool operator!=(const basic_json_view& a, const BasicJsonType& j)
{
return !(a == j);
}
friend bool operator!=(const BasicJsonType& j, const basic_json_view& a)
{
return !(a == j);
}
/////////////////
// materialize //
/////////////////
@@ -635,6 +674,13 @@ class basic_json_view
: m_doc(d), m_node(n)
{}
using json_side_t = detail::view::json_side<BasicJsonType, string_view_t>;
static detail::view::view_side<BasicJsonType, basic_json_view> side(const basic_json_view& v) noexcept
{
return detail::view::view_side<BasicJsonType, basic_json_view>(v);
}
/// the number of source bytes of this value (estimated for values with
/// decoded strings)
std::size_t source_extent() const noexcept