Skip to content

Commit

Permalink
QJsonValue: use new comparison helper macros
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
qt-tatiana committed Mar 22, 2024
1 parent e73295f commit 839cffd
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 75 deletions.
12 changes: 12 additions & 0 deletions src/corelib/compat/removed_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
42 changes: 23 additions & 19 deletions src/corelib/serialization/qjsonvalue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -823,48 +827,48 @@ 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;
}
return true;
}

/*!
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
Expand Down
59 changes: 38 additions & 21 deletions src/corelib/serialization/qjsonvalue.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -92,10 +93,16 @@ class Q_CORE_EXPORT QJsonValue
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;
Expand Down Expand Up @@ -148,10 +155,20 @@ class QJsonValueConstRef
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
Expand Down Expand Up @@ -257,10 +274,25 @@ class QT6_ONLY(Q_CORE_EXPORT) QJsonValueRef : public QJsonValueConstRef
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[];
Expand All @@ -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)
Expand Down
84 changes: 49 additions & 35 deletions tests/auto/corelib/serialization/json/tst_qtjson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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");
Expand All @@ -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();
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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")));
Expand Down

0 comments on commit 839cffd

Please sign in to comment.