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 <ivan.solovev@qt.io>
bb10
Tatiana Borisova 2024-03-20 17:05:42 +01:00
parent e73295f908
commit 839cffd521
4 changed files with 122 additions and 75 deletions

View File

@ -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

View File

@ -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

View File

@ -4,10 +4,11 @@
#ifndef QJSONVALUE_H
#define QJSONVALUE_H
#include <QtCore/qcborvalue.h>
#include <QtCore/qcompare.h>
#include <QtCore/qglobal.h>
#include <QtCore/qstring.h>
#include <QtCore/qshareddata.h>
#include <QtCore/qcborvalue.h>
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)

View File

@ -177,7 +177,13 @@ void tst_QtJson::compareCompiles()
{
QTestPrivate::testEqualityOperatorsCompile<QJsonArray>();
QTestPrivate::testEqualityOperatorsCompile<QJsonDocument>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef>();
QTestPrivate::testEqualityOperatorsCompile<QJsonArray, QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueConstRef, QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValue>();
QTestPrivate::testEqualityOperatorsCompile<QJsonValueRef, QJsonValueConstRef>();
}
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")));