QJsonDocument: use new comparison helper macros

Replace public operators operator==(), operator!=() of
QJsonDocument 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.

Task-number: QTBUG-120300
Change-Id: I7b61765c34406b7a9fb7dd8b1fc554c87af6a3f3
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Tatiana Borisova 2024-03-18 17:12:11 +01:00
parent 043ceca40f
commit e2bd247081
4 changed files with 47 additions and 15 deletions

View File

@ -971,6 +971,13 @@ bool QJsonArray::operator!=(const QJsonArray &other) const
return !comparesEqual(*this, other); return !comparesEqual(*this, other);
} }
#include "qjsondocument.h"
bool QJsonDocument::operator==(const QJsonDocument &other) const
{
return comparesEqual(*this, other);
}
#if QT_CONFIG(processenvironment) #if QT_CONFIG(processenvironment)
#include "qprocess.h" // inlined API #include "qprocess.h" // inlined API

View File

@ -30,6 +30,8 @@ QT_BEGIN_NAMESPACE
\brief The QJsonDocument class provides a way to read and write JSON documents. \brief The QJsonDocument class provides a way to read and write JSON documents.
\compares equality
QJsonDocument is a class that wraps a complete JSON document and can read QJsonDocument is a class that wraps a complete JSON document and can read
this document from, and write it to, a UTF-8 encoded text-based this document from, and write it to, a UTF-8 encoded text-based
representation. representation.
@ -456,20 +458,22 @@ const QJsonValue QJsonDocument::operator[](qsizetype i) const
} }
/*! /*!
Returns \c true if the \a other document is equal to this document. \fn bool QJsonDocument::operator==(const QJsonDocument &lhs, const QJsonDocument &rhs)
*/
bool QJsonDocument::operator==(const QJsonDocument &other) const Returns \c true if the \a lhs document is equal to \a rhs document, \c false otherwise.
*/
bool comparesEqual(const QJsonDocument &lhs, const QJsonDocument &rhs) noexcept
{ {
if (d && other.d) if (lhs.d && rhs.d)
return d->value == other.d->value; return lhs.d->value == rhs.d->value;
return !d == !other.d; return !lhs.d == !rhs.d;
} }
/*! /*!
\fn bool QJsonDocument::operator!=(const QJsonDocument &other) const \fn bool QJsonDocument::operator!=(const QJsonDocument &lhs, const QJsonDocument &rhs)
returns \c true if \a other is not equal to this document Returns \c true if the \a lhs document is not equal to \a rhs document, \c false otherwise.
*/ */
/*! /*!
returns \c true if this document is null. returns \c true if this document is null.

View File

@ -4,6 +4,7 @@
#ifndef QJSONDOCUMENT_H #ifndef QJSONDOCUMENT_H
#define QJSONDOCUMENT_H #define QJSONDOCUMENT_H
#include <QtCore/qcompare.h>
#include <QtCore/qjsonvalue.h> #include <QtCore/qjsonvalue.h>
#include <QtCore/qscopedpointer.h> #include <QtCore/qscopedpointer.h>
@ -98,16 +99,19 @@ public:
const QJsonValue operator[](QStringView key) const; const QJsonValue operator[](QStringView key) const;
const QJsonValue operator[](QLatin1StringView key) const; const QJsonValue operator[](QLatin1StringView key) const;
const QJsonValue operator[](qsizetype i) const; const QJsonValue operator[](qsizetype i) const;
#if QT_CORE_REMOVED_SINCE(6, 8)
bool operator==(const QJsonDocument &other) const; bool operator==(const QJsonDocument &other) const;
bool operator!=(const QJsonDocument &other) const { return !(*this == other); } bool operator!=(const QJsonDocument &other) const { return !operator==(other); }
#endif
bool isNull() const; bool isNull() const;
private: private:
friend class QJsonValue; friend class QJsonValue;
friend class QJsonPrivate::Parser; friend class QJsonPrivate::Parser;
friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &); friend Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonDocument &);
friend Q_CORE_EXPORT bool comparesEqual(const QJsonDocument &lhs,
const QJsonDocument &rhs) noexcept;
Q_DECLARE_EQUALITY_COMPARABLE(QJsonDocument)
QJsonDocument(const QCborValue &data); QJsonDocument(const QCborValue &data);

View File

@ -176,6 +176,7 @@ void tst_QtJson::initTestCase()
void tst_QtJson::compareCompiles() void tst_QtJson::compareCompiles()
{ {
QTestPrivate::testEqualityOperatorsCompile<QJsonArray>(); QTestPrivate::testEqualityOperatorsCompile<QJsonArray>();
QTestPrivate::testEqualityOperatorsCompile<QJsonDocument>();
QTestPrivate::testEqualityOperatorsCompile<QJsonArray, QJsonValue>(); QTestPrivate::testEqualityOperatorsCompile<QJsonArray, QJsonValue>();
} }
@ -381,6 +382,7 @@ void tst_QtJson::testNumbers_2()
QVERIFY2(floatValues[power] == floatValues_1[power], QString("floatValues[%1] != floatValues_1[%1]").arg(power).toLatin1()); QVERIFY2(floatValues[power] == floatValues_1[power], QString("floatValues[%1] != floatValues_1[%1]").arg(power).toLatin1());
} }
QT_TEST_EQUALITY_OPS(jDocument1, jDocument2, true);
// The last value is below min denorm and should round to 0, everything else should contain a value // The last value is below min denorm and should round to 0, everything else should contain a value
QVERIFY2(floatValues_1[1075] == 0, "Value after min denorm should round to 0"); QVERIFY2(floatValues_1[1075] == 0, "Value after min denorm should round to 0");
@ -412,6 +414,10 @@ void tst_QtJson::testNumbers_3()
QJsonDocument jDocument2(QJsonDocument::fromJson(ba)); QJsonDocument jDocument2(QJsonDocument::fromJson(ba));
QT_TEST_EQUALITY_OPS(jDocument1, jDocument2, true);
QT_TEST_EQUALITY_OPS(jDocument1, QJsonDocument(), false);
QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(), true);
double d1_1(jDocument2.object().value("d1").toDouble()); double d1_1(jDocument2.object().value("d1").toDouble());
double d2_1(jDocument2.object().value("d2").toDouble()); double d2_1(jDocument2.object().value("d2").toDouble());
QVERIFY(d1_1 != d2_1); QVERIFY(d1_1 != d2_1);
@ -429,7 +435,8 @@ void tst_QtJson::testNumbers_4()
array << QJsonValue(-9223372036854775808.0); array << QJsonValue(-9223372036854775808.0);
array << QJsonValue(+18446744073709551616.0); array << QJsonValue(+18446744073709551616.0);
array << QJsonValue(-18446744073709551616.0); array << QJsonValue(-18446744073709551616.0);
const QByteArray json(QJsonDocument(array).toJson()); QJsonDocument doc1 = QJsonDocument(array);
const QByteArray json(doc1.toJson());
const QByteArray expected = const QByteArray expected =
"[\n" "[\n"
" 1000000000000000,\n" " 1000000000000000,\n"
@ -450,7 +457,8 @@ void tst_QtJson::testNumbers_4()
array2 << QJsonValue(Q_INT64_C(-9007199254740992)); array2 << QJsonValue(Q_INT64_C(-9007199254740992));
array2 << QJsonValue(Q_INT64_C(+9223372036854775807)); array2 << QJsonValue(Q_INT64_C(+9223372036854775807));
array2 << QJsonValue(Q_INT64_C(-9223372036854775807)); array2 << QJsonValue(Q_INT64_C(-9223372036854775807));
const QByteArray json2(QJsonDocument(array2).toJson()); QJsonDocument doc2 = QJsonDocument(array2);
const QByteArray json2(doc2.toJson());
const QByteArray expected2 = const QByteArray expected2 =
"[\n" "[\n"
" 1000000000000000,\n" " 1000000000000000,\n"
@ -461,6 +469,8 @@ void tst_QtJson::testNumbers_4()
" -9223372036854775807\n" " -9223372036854775807\n"
"]\n"; "]\n";
QCOMPARE(json2, expected2); QCOMPARE(json2, expected2);
QT_TEST_EQUALITY_OPS(doc1, doc2, false);
} }
void tst_QtJson::testNumberComparisons() void tst_QtJson::testNumberComparisons()
@ -886,6 +896,7 @@ void tst_QtJson::testArrayNestedEmpty()
QJsonValue val = object.value("inner"); QJsonValue val = object.value("inner");
QJsonArray value = object.value("inner").toArray(); QJsonArray value = object.value("inner").toArray();
QVERIFY(QJsonDocument(value).isArray()); QVERIFY(QJsonDocument(value).isArray());
QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(value), false);
QCOMPARE(value.size(), 0); QCOMPARE(value.size(), 0);
QCOMPARE(value, inner); QCOMPARE(value, inner);
QCOMPARE(value.size(), 0); QCOMPARE(value.size(), 0);
@ -903,6 +914,7 @@ void tst_QtJson::testObjectNestedEmpty()
object.insert("inner2", inner2); object.insert("inner2", inner2);
QJsonObject value = object.value("inner").toObject(); QJsonObject value = object.value("inner").toObject();
QVERIFY(QJsonDocument(value).isObject()); QVERIFY(QJsonDocument(value).isObject());
QT_TEST_EQUALITY_OPS(QJsonDocument(), QJsonDocument(value), false);
QCOMPARE(value.size(), 0); QCOMPARE(value.size(), 0);
QCOMPARE(value, inner); QCOMPARE(value, inner);
QCOMPARE(value.size(), 0); QCOMPARE(value.size(), 0);
@ -1338,6 +1350,8 @@ void tst_QtJson::testDocument()
QCOMPARE(doc5.isObject(), false); QCOMPARE(doc5.isObject(), false);
QCOMPARE(doc5.array().size(), 1); QCOMPARE(doc5.array().size(), 1);
QCOMPARE(doc5.array().at(0), QJsonValue(23)); QCOMPARE(doc5.array().at(0), QJsonValue(23));
QT_TEST_EQUALITY_OPS(doc2, doc3, true);
} }
void tst_QtJson::nullValues() void tst_QtJson::nullValues()
@ -3374,7 +3388,7 @@ void tst_QtJson::documentFromVariant()
// As JSON arrays they should be equal. // As JSON arrays they should be equal.
QCOMPARE(da1.array(), da2.array()); QCOMPARE(da1.array(), da2.array());
QT_TEST_EQUALITY_OPS(da1, da2, true);
QMap <QString, QVariant> map; QMap <QString, QVariant> map;
map["key"] = string; map["key"] = string;
@ -3390,6 +3404,7 @@ void tst_QtJson::documentFromVariant()
// As JSON objects they should be equal. // As JSON objects they should be equal.
QCOMPARE(do1.object(), do2.object()); QCOMPARE(do1.object(), do2.object());
QT_TEST_EQUALITY_OPS(do1, do2, true);
} }
void tst_QtJson::parseErrorOffset_data() void tst_QtJson::parseErrorOffset_data()
@ -3488,6 +3503,7 @@ void tst_QtJson::streamSerializationQJsonDocument()
QDataStream load(buffer); QDataStream load(buffer);
load >> output; load >> output;
QCOMPARE(output, document); QCOMPARE(output, document);
QT_TEST_EQUALITY_OPS(output, document, true);
} }
void tst_QtJson::streamSerializationQJsonArray_data() void tst_QtJson::streamSerializationQJsonArray_data()
@ -3877,6 +3893,7 @@ void tst_QtJson::noLeakOnNameClash()
QVERIFY2(!expected.isNull(), qPrintable(error.errorString())); QVERIFY2(!expected.isNull(), qPrintable(error.errorString()));
QCOMPARE(doc, expected); QCOMPARE(doc, expected);
QT_TEST_EQUALITY_OPS(doc, expected, true);
// It should not leak. // It should not leak.
// In particular it should not forget to deref the container for the inner objects. // In particular it should not forget to deref the container for the inner objects.