From 839cffd5212cc1437661e9c650eb2ff4b19fa4e8 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova Date: Wed, 20 Mar 2024 17:05:42 +0100 Subject: [PATCH] QJsonValue: use new comparison helper macros Replace public operators operator==(), operator!=() of QJsonValue/QJsonValueConstRef/QJsonValueRef classes 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. Delete non-exported public operators operator==(), operator!=() for QJsonValueConstRef/QJsonValueRef classes. Add comparison check to auto-test. Task-number: QTBUG-120300 Change-Id: I01434af4ce5a7589733db4a9b14f54ad42e852ed Reviewed-by: Ivan Solovev --- src/corelib/compat/removed_api.cpp | 12 +++ src/corelib/serialization/qjsonvalue.cpp | 42 +++++----- src/corelib/serialization/qjsonvalue.h | 59 ++++++++----- .../corelib/serialization/json/tst_qtjson.cpp | 84 +++++++++++-------- 4 files changed, 122 insertions(+), 75 deletions(-) diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index 3d597d3d90..c88fb046bc 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -978,6 +978,18 @@ bool QJsonDocument::operator==(const QJsonDocument &other) const return comparesEqual(*this, other); } +#include "qjsonvalue.h" + +bool QJsonValue::operator==(const QJsonValue &other) const +{ + return comparesEqual(*this, other); +} + +bool QJsonValue::operator!=(const QJsonValue &other) const +{ + return !comparesEqual(*this, other); +} + #if QT_CONFIG(processenvironment) #include "qprocess.h" // inlined API diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp index 2d114b9072..6c2656d89f 100644 --- a/src/corelib/serialization/qjsonvalue.cpp +++ b/src/corelib/serialization/qjsonvalue.cpp @@ -59,6 +59,10 @@ static QJsonValue::Type convertFromCborType(QCborValue::Type type) noexcept \brief The QJsonValue class encapsulates a value in JSON. + \compares equality + \compareswith equality QJsonValueConstRef QJsonValueRef + \endcompareswith + A value in JSON can be one of 6 basic types: JSON is a format to store structured data. It has 6 basic data types: @@ -823,35 +827,37 @@ const QJsonValue QJsonValue::operator[](qsizetype i) const } /*! - Returns \c true if the value is equal to \a other. - */ -bool QJsonValue::operator==(const QJsonValue &other) const + \fn bool QJsonValue::operator==(const QJsonValue &lhs, const QJsonValue &rhs) + + Returns \c true if the \a lhs value is equal to \a rhs value, \c false otherwise. +*/ +bool comparesEqual(const QJsonValue &lhs, const QJsonValue &rhs) noexcept { - if (value.type() != other.value.type()) { - if (isDouble() && other.isDouble()) { + if (lhs.value.type() != rhs.value.type()) { + if (lhs.isDouble() && rhs.isDouble()) { // One value Cbor integer, one Cbor double, should interact as doubles. - return toDouble() == other.toDouble(); + return lhs.toDouble() == rhs.toDouble(); } return false; } - switch (value.type()) { + switch (lhs.value.type()) { case QCborValue::Undefined: case QCborValue::Null: case QCborValue::True: case QCborValue::False: break; case QCborValue::Double: - return toDouble() == other.toDouble(); + return lhs.toDouble() == rhs.toDouble(); case QCborValue::Integer: - return QJsonPrivate::Value::valueHelper(value) - == QJsonPrivate::Value::valueHelper(other.value); + return QJsonPrivate::Value::valueHelper(lhs.value) + == QJsonPrivate::Value::valueHelper(rhs.value); case QCborValue::String: - return toString() == other.toString(); + return lhs.toString() == rhs.toString(); case QCborValue::Array: - return toArray() == other.toArray(); + return lhs.toArray() == rhs.toArray(); case QCborValue::Map: - return toObject() == other.toObject(); + return lhs.toObject() == rhs.toObject(); default: return false; } @@ -859,12 +865,10 @@ bool QJsonValue::operator==(const QJsonValue &other) const } /*! - Returns \c true if the value is not equal to \a other. - */ -bool QJsonValue::operator!=(const QJsonValue &other) const -{ - return !(*this == other); -} + \fn bool QJsonValue::operator!=(const QJsonValue &lhs, const QJsonValue &rhs) + + Returns \c true if the \a lhs value is not equal to \a rhs value, \c false otherwise. +*/ /*! \class QJsonValueRef diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h index b0b6b97fab..d71dadf837 100644 --- a/src/corelib/serialization/qjsonvalue.h +++ b/src/corelib/serialization/qjsonvalue.h @@ -4,10 +4,11 @@ #ifndef QJSONVALUE_H #define QJSONVALUE_H +#include +#include #include #include #include -#include QT_BEGIN_NAMESPACE @@ -92,10 +93,16 @@ public: const QJsonValue operator[](QLatin1StringView key) const; const QJsonValue operator[](qsizetype i) const; +#if QT_CORE_REMOVED_SINCE(6, 8) bool operator==(const QJsonValue &other) const; bool operator!=(const QJsonValue &other) const; +#endif private: + friend Q_CORE_EXPORT bool comparesEqual(const QJsonValue &lhs, + const QJsonValue &rhs) noexcept; + Q_DECLARE_EQUALITY_COMPARABLE(QJsonValue) + // avoid implicit conversions from char * to bool QJsonValue(const void *) = delete; friend class QJsonPrivate::Value; @@ -148,10 +155,20 @@ public: const QJsonValue operator[](QLatin1StringView key) const { return concrete(*this)[key]; } const QJsonValue operator[](qsizetype i) const { return concrete(*this)[i]; } - inline bool operator==(const QJsonValue &other) const { return concrete(*this) == other; } - inline bool operator!=(const QJsonValue &other) const { return concrete(*this) != other; } - protected: + friend bool comparesEqual(const QJsonValueConstRef &lhs, + const QJsonValueConstRef &rhs) noexcept + { + return comparesEqual(concrete(lhs), concrete(rhs)); + } + friend bool comparesEqual(const QJsonValueConstRef &lhs, + const QJsonValue &rhs) noexcept + { + return comparesEqual(concrete(lhs), rhs); + } + Q_DECLARE_EQUALITY_COMPARABLE(QJsonValueConstRef) + Q_DECLARE_EQUALITY_COMPARABLE(QJsonValueConstRef, QJsonValue) + Q_CORE_EXPORT static QJsonValue::Type concreteType(QJsonValueConstRef self) noexcept Q_DECL_PURE_FUNCTION; Q_CORE_EXPORT static bool @@ -257,10 +274,25 @@ public: const QJsonValue operator[](QLatin1StringView key) const { return QJsonValueConstRef::operator[](key); } const QJsonValue operator[](qsizetype i) const { return QJsonValueConstRef::operator[](i); } - inline bool operator==(const QJsonValue &other) const { return QJsonValueConstRef::operator==(other); } - inline bool operator!=(const QJsonValue &other) const { return QJsonValueConstRef::operator!=(other); } +#if QT_CORE_REMOVED_SINCE(6, 8) + inline bool operator==(const QJsonValue &other) const { return comparesEqual(*this, other); } + inline bool operator!=(const QJsonValue &other) const { return !comparesEqual(*this, other); } +#endif private: + friend bool comparesEqual(const QJsonValueRef &lhs, + const QJsonValueRef &rhs) noexcept + { + return comparesEqual(QJsonValue(lhs), QJsonValue(rhs)); + } + friend bool comparesEqual(const QJsonValueRef &lhs, + const QJsonValueConstRef &rhs) noexcept + { + return comparesEqual(QJsonValue(lhs), QJsonValue(rhs)); + } + Q_DECLARE_EQUALITY_COMPARABLE(QJsonValueRef) + Q_DECLARE_EQUALITY_COMPARABLE(QJsonValueRef, QJsonValueConstRef) + QJsonValue toValue() const; #else using QJsonValueConstRef::operator[]; @@ -282,21 +314,6 @@ inline QJsonValue QCborValueConstRef::toJsonValue() const return concrete().toJsonValue(); } -inline bool operator==(const QJsonValueConstRef &lhs, const QJsonValueRef &rhs) -{ return QJsonValue(lhs) == QJsonValue(rhs); } -inline bool operator!=(const QJsonValueConstRef &lhs, const QJsonValueRef &rhs) -{ return !(lhs == rhs); } - -inline bool operator==(const QJsonValueRef &lhs, const QJsonValueConstRef &rhs) -{ return QJsonValue(lhs) == QJsonValue(rhs); } -inline bool operator!=(const QJsonValueRef &lhs, const QJsonValueConstRef &rhs) -{ return !(lhs == rhs); } - -inline bool operator==(const QJsonValueRef &lhs, const QJsonValueRef &rhs) -{ return QJsonValue(lhs) == QJsonValue(rhs); } -inline bool operator!=(const QJsonValueRef &lhs, const QJsonValueRef &rhs) -{ return !(lhs == rhs); } - Q_CORE_EXPORT size_t qHash(const QJsonValue &value, size_t seed = 0); #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp index 52367eb192..3705084d26 100644 --- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp +++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp @@ -177,7 +177,13 @@ void tst_QtJson::compareCompiles() { QTestPrivate::testEqualityOperatorsCompile(); QTestPrivate::testEqualityOperatorsCompile(); + QTestPrivate::testEqualityOperatorsCompile(); + QTestPrivate::testEqualityOperatorsCompile(); + QTestPrivate::testEqualityOperatorsCompile(); QTestPrivate::testEqualityOperatorsCompile(); + QTestPrivate::testEqualityOperatorsCompile(); + QTestPrivate::testEqualityOperatorsCompile(); + QTestPrivate::testEqualityOperatorsCompile(); } void tst_QtJson::testValueSimple() @@ -519,6 +525,7 @@ void tst_QtJson::testObjectSimple() QJsonValue value(QLatin1String("foo")); object.insert("value", value); QCOMPARE(object.value("value"), value); + QT_TEST_EQUALITY_OPS(object.value("value"), value, true); int size = object.size(); object.remove("boolean"); @@ -527,6 +534,7 @@ void tst_QtJson::testObjectSimple() QJsonValue taken = object.take("value"); QCOMPARE(taken, value); + QT_TEST_EQUALITY_OPS(taken, value, true); QVERIFY2(!object.contains("value"), "key value should have been removed"); QString before = object.value("string").toString(); @@ -1049,6 +1057,12 @@ void tst_QtJson::testValueRefComparison() // val <> val CHECK(a0, a0, a1); + QT_TEST_EQUALITY_OPS(r0, r1, false); + QT_TEST_EQUALITY_OPS(r0, c0, true); + QT_TEST_EQUALITY_OPS(c0, r1, false); + QT_TEST_EQUALITY_OPS(a0, c0, true); + QT_TEST_EQUALITY_OPS(a0, r1, false); + #undef CHECK #undef CHECK_IMPL } @@ -2824,57 +2838,57 @@ void tst_QtJson::testDetachBug() void tst_QtJson::valueEquals() { QCOMPARE(QJsonValue(), QJsonValue()); - QVERIFY(QJsonValue() != QJsonValue(QJsonValue::Undefined)); - QVERIFY(QJsonValue() != QJsonValue(true)); - QVERIFY(QJsonValue() != QJsonValue(1.)); - QVERIFY(QJsonValue() != QJsonValue(QJsonArray())); - QVERIFY(QJsonValue() != QJsonValue(QJsonObject())); + QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonValue::Undefined), false); + QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(true), false); + QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(1.), false); + QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonArray()), false); + QT_TEST_EQUALITY_OPS(QJsonValue(), QJsonValue(QJsonObject()), false); QCOMPARE(QJsonValue(true), QJsonValue(true)); - QVERIFY(QJsonValue(true) != QJsonValue(false)); - QVERIFY(QJsonValue(true) != QJsonValue(QJsonValue::Undefined)); - QVERIFY(QJsonValue(true) != QJsonValue()); - QVERIFY(QJsonValue(true) != QJsonValue(1.)); - QVERIFY(QJsonValue(true) != QJsonValue(QJsonArray())); - QVERIFY(QJsonValue(true) != QJsonValue(QJsonObject())); + QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(false), false); + QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonValue::Undefined), false); + QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(), false); + QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(1.), false); + QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonArray()), false); + QT_TEST_EQUALITY_OPS(QJsonValue(true), QJsonValue(QJsonObject()), false); QCOMPARE(QJsonValue(1), QJsonValue(1)); - QVERIFY(QJsonValue(1) != QJsonValue(2)); + QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(2), false); QCOMPARE(QJsonValue(1), QJsonValue(1.)); - QVERIFY(QJsonValue(1) != QJsonValue(1.1)); - QVERIFY(QJsonValue(1) != QJsonValue(QJsonValue::Undefined)); - QVERIFY(QJsonValue(1) != QJsonValue()); - QVERIFY(QJsonValue(1) != QJsonValue(true)); - QVERIFY(QJsonValue(1) != QJsonValue(QJsonArray())); - QVERIFY(QJsonValue(1) != QJsonValue(QJsonObject())); + QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(1.1), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonValue::Undefined), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(true), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonArray()), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1), QJsonValue(QJsonObject()), false); QCOMPARE(QJsonValue(1.), QJsonValue(1.)); - QVERIFY(QJsonValue(1.) != QJsonValue(2.)); - QVERIFY(QJsonValue(1.) != QJsonValue(QJsonValue::Undefined)); - QVERIFY(QJsonValue(1.) != QJsonValue()); - QVERIFY(QJsonValue(1.) != QJsonValue(true)); - QVERIFY(QJsonValue(1.) != QJsonValue(QJsonArray())); - QVERIFY(QJsonValue(1.) != QJsonValue(QJsonObject())); + QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(2.), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonValue::Undefined), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(true), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonArray()), false); + QT_TEST_EQUALITY_OPS(QJsonValue(1.), QJsonValue(QJsonObject()), false); QCOMPARE(QJsonValue(QJsonArray()), QJsonValue(QJsonArray())); QJsonArray nonEmptyArray; nonEmptyArray.append(true); - QVERIFY(QJsonValue(QJsonArray()) != nonEmptyArray); - QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(QJsonValue::Undefined)); - QVERIFY(QJsonValue(QJsonArray()) != QJsonValue()); - QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(true)); - QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(1.)); - QVERIFY(QJsonValue(QJsonArray()) != QJsonValue(QJsonObject())); + QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), nonEmptyArray, false); + QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(QJsonValue::Undefined), false); + QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(), false); + QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(true), false); + QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(1.), false); + QT_TEST_EQUALITY_OPS(QJsonValue(QJsonArray()), QJsonValue(QJsonObject()), false); QCOMPARE(QJsonValue(QJsonObject()), QJsonValue(QJsonObject())); QJsonObject nonEmptyObject; nonEmptyObject.insert("Key", true); QVERIFY(QJsonValue(QJsonObject()) != nonEmptyObject); - QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(QJsonValue::Undefined)); - QVERIFY(QJsonValue(QJsonObject()) != QJsonValue()); - QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(true)); - QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(1.)); - QVERIFY(QJsonValue(QJsonObject()) != QJsonValue(QJsonArray())); + 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); + QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(1.), false); + QT_TEST_EQUALITY_OPS(QJsonValue(QJsonObject()), QJsonValue(QJsonArray()), false); QCOMPARE(QJsonValue("foo"), QJsonValue(QLatin1String("foo"))); QCOMPARE(QJsonValue("foo"), QJsonValue(QString("foo")));