QJsonObject: use new comparison helper macros

Replace public operators operator==(), operator!=() of
QJsonObject to friend methods comparesEqual().

Use QT_CORE_REMOVED_SINCE and removed_api.cpp to get rid of current
comparison methods and replace them with a friend.

Add friend method comparesEqual(QJsonObject, QJsonValue)
to the QJsonObject class, to support comparison between QJsonObject
and QJsonValue elements, see test-case valueEquals().

Task-number: QTBUG-120300
Change-Id: Ibab0b4b39966205447e31c41e94e7e1a4e31e553
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
bb10
Tatiana Borisova 2024-03-20 17:43:22 +01:00
parent f5d5a42dc3
commit 25652c2819
4 changed files with 66 additions and 19 deletions

View File

@ -978,6 +978,19 @@ bool QJsonDocument::operator==(const QJsonDocument &other) const
return comparesEqual(*this, other);
}
#include "qjsonobject.h"
bool QJsonObject::operator==(const QJsonObject &other) const
{
return comparesEqual(*this, other);
}
bool QJsonObject::operator!=(const QJsonObject &other) const
{
return !comparesEqual(*this, other);
}
#include "qjsonvalue.h"
bool QJsonValue::operator==(const QJsonValue &other) const

View File

@ -31,6 +31,10 @@ QT_BEGIN_NAMESPACE
\brief The QJsonObject class encapsulates a JSON object.
\compares equality
\compareswith equality QJsonValue
\endcompareswith
A JSON object is a list of key value pairs, where the keys are unique strings
and the values are represented by a QJsonValue.
@ -613,22 +617,24 @@ bool QJsonObject::containsImpl(T key) const
}
/*!
Returns \c true if \a other is equal to this object.
*/
bool QJsonObject::operator==(const QJsonObject &other) const
\fn bool QJsonObject::operator==(const QJsonObject &lhs, const QJsonObject &rhs)
Returns \c true if \a lhs object is equal to \a rhs, \c false otherwise.
*/
bool comparesEqual(const QJsonObject &lhs, const QJsonObject &rhs) noexcept
{
if (o == other.o)
if (lhs.o == rhs.o)
return true;
if (!o)
return !other.o->elements.size();
if (!other.o)
return !o->elements.size();
if (o->elements.size() != other.o->elements.size())
if (!lhs.o)
return !rhs.o->elements.size();
if (!rhs.o)
return !lhs.o->elements.size();
if (lhs.o->elements.size() != rhs.o->elements.size())
return false;
for (qsizetype i = 0, end = o->elements.size(); i < end; ++i) {
if (o->valueAt(i) != other.o->valueAt(i))
for (qsizetype i = 0, end = lhs.o->elements.size(); i < end; ++i) {
if (lhs.o->valueAt(i) != rhs.o->valueAt(i))
return false;
}
@ -636,12 +642,10 @@ bool QJsonObject::operator==(const QJsonObject &other) const
}
/*!
Returns \c true if \a other is not equal to this object.
*/
bool QJsonObject::operator!=(const QJsonObject &other) const
{
return !(*this == other);
}
\fn bool QJsonObject::operator!=(const QJsonObject &lhs, const QJsonObject &rhs)
Returns \c true if \a lhs object is not equal to \a rhs, \c false otherwise.
*/
/*!
Removes the (key, value) pair pointed to by the iterator \a it

View File

@ -72,9 +72,10 @@ public:
bool contains(QStringView key) const;
bool contains(QLatin1StringView key) const;
#if QT_CORE_REMOVED_SINCE(6, 8)
bool operator==(const QJsonObject &other) const;
bool operator!=(const QJsonObject &other) const;
#endif
class const_iterator;
class iterator
@ -236,6 +237,15 @@ public:
inline bool empty() const { return isEmpty(); }
private:
friend Q_CORE_EXPORT bool comparesEqual(const QJsonObject &lhs,
const QJsonObject &rhs) noexcept;
friend bool comparesEqual(const QJsonObject &lhs,
const QJsonValue &rhs) noexcept
{
return comparesEqual(lhs, rhs.toObject());
}
Q_DECLARE_EQUALITY_COMPARABLE(QJsonObject)
Q_DECLARE_EQUALITY_COMPARABLE(QJsonObject, QJsonValue)
friend class QJsonValue;
friend class QJsonDocument;
friend class QJsonPrivate::Value;

View File

@ -177,10 +177,12 @@ void tst_QtJson::compareCompiles()
{
QTestPrivate::testEqualityOperatorsCompile<QJsonArray>();
QTestPrivate::testEqualityOperatorsCompile<QJsonDocument>();
QTestPrivate::testEqualityOperatorsCompile<QJsonObject>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef>();
QTestPrivate::testEqualityOperatorsCompile<QJsonArray, QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonObject, QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef, QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValueConstRef>();
@ -823,9 +825,12 @@ void tst_QtJson::testObjectNested()
QJsonValue v = inner;
QCOMPARE(v.toObject(), inner);
QCOMPARE(v.toObject(otherObject), inner);
QT_TEST_EQUALITY_OPS(v.toObject(), inner, true);
QT_TEST_EQUALITY_OPS(v.toObject(otherObject), inner, true);
inner.insert("number", 999.);
outer.insert("nested", inner);
QT_TEST_EQUALITY_OPS(outer, inner, false);
// if we don't modify the original JsonObject, value()
// should return the same object (non-detached).
@ -835,6 +840,8 @@ void tst_QtJson::testObjectNested()
QCOMPARE(value.value("number").toDouble(), 999.);
QCOMPARE(v.toObject(), inner);
QCOMPARE(v.toObject(otherObject), inner);
QT_TEST_EQUALITY_OPS(v.toObject(), inner, true);
QT_TEST_EQUALITY_OPS(v.toObject(otherObject), inner, true);
QCOMPARE(v["number"].toDouble(), 999.);
// if we modify the original object, it should detach and not
@ -860,6 +867,7 @@ void tst_QtJson::testObjectNested()
QCOMPARE(outer.value("nested").toObject().value("nested").toObject(), twoDeep);
QCOMPARE(outer.value("nested").toObject().value("nested").toObject().value("boolean").toBool(),
true);
QT_TEST_EQUALITY_OPS(outer.value("nested").toObject().value("nested").toObject(), twoDeep, true);
}
void tst_QtJson::testArrayNested()
@ -885,6 +893,7 @@ void tst_QtJson::testArrayNested()
object.insert("boolean", true);
outer.append(object);
QCOMPARE(outer.last().toObject(), object);
QT_TEST_EQUALITY_OPS(outer.last().toObject(), object, true);
QCOMPARE(outer.last().toObject().value("boolean").toBool(), true);
// two deep arrays
@ -925,6 +934,7 @@ void tst_QtJson::testObjectNestedEmpty()
QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(value), false);
QCOMPARE(value.size(), 0);
QCOMPARE(value, inner);
QT_TEST_EQUALITY_OPS(value, inner, true);
QCOMPARE(value.size(), 0);
object.insert("count", 0.);
QCOMPARE(object.value("inner").toObject().size(), 0);
@ -1096,6 +1106,7 @@ void tst_QtJson::testObjectIteration()
{
QJsonObject object2 = object;
QCOMPARE(object, object2);
QT_TEST_EQUALITY_OPS(object, object2, true);
QJsonValue val = *object2.begin();
auto next = object2.erase(object2.begin());
@ -1116,6 +1127,7 @@ void tst_QtJson::testObjectIteration()
{
QJsonObject object2 = object;
QCOMPARE(object, object2);
QT_TEST_EQUALITY_OPS(object, object2, true);
QJsonValue val = *(object2.end() - 1);
auto next = object2.erase(object2.end() - 1);
@ -1135,6 +1147,7 @@ void tst_QtJson::testObjectIteration()
{
QJsonObject object2 = object;
QCOMPARE(object, object2);
QT_TEST_EQUALITY_OPS(object, object2, true);
QJsonObject::iterator it = object2.find(QString::number(5));
QJsonValue val = *it;
@ -2559,6 +2572,13 @@ void tst_QtJson::testCompaction()
}
QCOMPARE(obj.size(), 1);
QCOMPARE(obj.value(QLatin1String("foo")).toString(), QLatin1String("bar"));
QJsonObject obj2;
QT_TEST_EQUALITY_OPS(obj, obj2, false);
QT_TEST_EQUALITY_OPS(QJsonObject(), obj2, true);
obj2 = obj;
QT_TEST_EQUALITY_OPS(obj, obj2, true);
}
void tst_QtJson::testDebugStream()
@ -2883,7 +2903,7 @@ void tst_QtJson::valueEquals()
QCOMPARE(QJsonValue(QJsonObject()), QJsonValue(QJsonObject()));
QJsonObject nonEmptyObject;
nonEmptyObject.insert("Key", true);
QVERIFY(QJsonValue(QJsonObject()) != nonEmptyObject);
QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), nonEmptyObject, false);
QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(QJsonValue::Undefined), false);
QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(), false);
QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(true), false);