QSize(F): use comparison helper macros

Also explicitly add QSizeF vs QSize comparison. Previously such
comparison was implicitly converting QSize to QSizeF, and doing the
fuzzy comparison. We have to keep the old behavior to avoid
breaking user code, so use fuzzy comparison in the new operators
as well.

As a drive-by: put all the hidden friends in the private section.

Done-with: Ivan Solovev <ivan.solovev@qt.io>
Task-number: QTBUG-120308
Change-Id: Ia52adc97c557e475b19f5c16f9dd8c992637280e
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
bb10
Tatiana Borisova 2024-04-16 14:49:59 +02:00 committed by Ivan Solovev
parent 6f2ef2eacb
commit c2826805de
6 changed files with 108 additions and 14 deletions

View File

@ -266,15 +266,15 @@ QSize QSize::scaled(const QSize &s, Qt::AspectRatioMode mode) const noexcept
*/
/*!
\fn bool QSize::operator==(const QSize &s1, const QSize &s2)
\fn bool QSize::operator==(const QSize &lhs, const QSize &rhs)
Returns \c true if \a s1 and \a s2 are equal; otherwise returns \c false.
Returns \c true if \a lhs and \a rhs are equal; otherwise returns \c false.
*/
/*!
\fn bool QSize::operator!=(const QSize &s1, const QSize &s2)
\fn bool QSize::operator!=(const QSize &lhs, const QSize &rhs)
Returns \c true if \a s1 and \a s2 are different; otherwise returns \c false.
Returns \c true if \a lhs and \a rhs are different; otherwise returns \c false.
*/
/*!
@ -714,9 +714,9 @@ QSizeF QSizeF::scaled(const QSizeF &s, Qt::AspectRatioMode mode) const noexcept
*/
/*!
\fn bool QSizeF::operator==(const QSizeF &s1, const QSizeF &s2)
\fn bool QSizeF::operator==(const QSizeF &lhs, const QSizeF &rhs)
Returns \c true if \a s1 and \a s2 are approximately equal; otherwise
Returns \c true if \a lhs and \a rhs are approximately equal; otherwise
returns false.
\warning This function does not check for strict equality; instead,
@ -726,9 +726,9 @@ QSizeF QSizeF::scaled(const QSizeF &s, Qt::AspectRatioMode mode) const noexcept
*/
/*!
\fn bool QSizeF::operator!=(const QSizeF &s1, const QSizeF &s2)
\fn bool QSizeF::operator!=(const QSizeF &lhs, const QSizeF &rhs)
Returns \c true if \a s1 and \a s2 are sufficiently different; otherwise
Returns \c true if \a lhs and \a rhs are sufficiently different; otherwise
returns \c false.
\warning This function does not check for strict inequality; instead,

View File

@ -59,10 +59,10 @@ public:
constexpr inline QSize &operator*=(qreal c) noexcept;
inline QSize &operator/=(qreal c);
friend inline constexpr bool operator==(const QSize &s1, const QSize &s2) noexcept
private:
friend constexpr bool comparesEqual(const QSize &s1, const QSize &s2) noexcept
{ return s1.wd == s2.wd && s1.ht == s2.ht; }
friend inline constexpr bool operator!=(const QSize &s1, const QSize &s2) noexcept
{ return s1.wd != s2.wd || s1.ht != s2.ht; }
Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(QSize)
friend inline constexpr QSize operator+(const QSize &s1, const QSize &s2) noexcept
{ return QSize(s1.wd + s2.wd, s1.ht + s2.ht); }
friend inline constexpr QSize operator-(const QSize &s1, const QSize &s2) noexcept
@ -75,6 +75,7 @@ public:
{ Q_ASSERT(!qFuzzyIsNull(c)); return QSize(qRound(s.wd / c), qRound(s.ht / c)); }
friend inline constexpr size_t qHash(const QSize &, size_t) noexcept;
public:
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
[[nodiscard]] CGSize toCGSize() const noexcept;
#endif
@ -242,16 +243,19 @@ public:
constexpr inline QSizeF &operator*=(qreal c) noexcept;
inline QSizeF &operator/=(qreal c);
private:
QT_WARNING_PUSH
QT_WARNING_DISABLE_FLOAT_COMPARE
friend constexpr inline bool operator==(const QSizeF &s1, const QSizeF &s2)
friend constexpr bool comparesEqual(const QSizeF &s1, const QSizeF &s2) noexcept
{
return ((!s1.wd || !s2.wd) ? qFuzzyIsNull(s1.wd - s2.wd) : qFuzzyCompare(s1.wd, s2.wd))
&& ((!s1.ht || !s2.ht) ? qFuzzyIsNull(s1.ht - s2.ht) : qFuzzyCompare(s1.ht, s2.ht));
}
QT_WARNING_POP
friend constexpr inline bool operator!=(const QSizeF &s1, const QSizeF &s2)
{ return !(s1 == s2); }
Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(QSizeF)
friend constexpr bool comparesEqual(const QSizeF &lhs, const QSize &rhs) noexcept
{ return comparesEqual(lhs, rhs.toSizeF()); }
Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(QSizeF, QSize)
friend constexpr inline QSizeF operator+(const QSizeF &s1, const QSizeF &s2) noexcept
{ return QSizeF(s1.wd + s2.wd, s1.ht + s2.ht); }
friend constexpr inline QSizeF operator-(const QSizeF &s1, const QSizeF &s2) noexcept
@ -263,6 +267,7 @@ public:
friend inline QSizeF operator/(const QSizeF &s, qreal c)
{ Q_ASSERT(!qFuzzyIsNull(c)); return QSizeF(s.wd / c, s.ht / c); }
public:
constexpr inline QSize toSize() const noexcept;
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)

View File

@ -14,4 +14,6 @@ endif()
qt_internal_add_test(tst_qsize
SOURCES
tst_qsize.cpp
LIBRARIES
Qt::TestPrivate
)

View File

@ -24,6 +24,7 @@ CHECK(const &&);
#undef CHECK
#include <QTest>
#include <QtTest/private/qcomparisontesthelper_p.h>
#include <qsize.h>
#include <array>
@ -34,6 +35,10 @@ class tst_QSize : public QObject
{
Q_OBJECT
private slots:
void compareCompiles();
void compare_data();
void compare();
void getSetCheck();
void scale();
@ -55,6 +60,38 @@ private slots:
void structuredBinding();
};
void tst_QSize::compareCompiles()
{
QTestPrivate::testEqualityOperatorsCompile<QSize>();
}
void tst_QSize::compare_data()
{
QTest::addColumn<QSize>("lhs");
QTest::addColumn<QSize>("rhs");
QTest::addColumn<bool>("result");
auto row = [](QSize lhs, QSize rhs, bool res) {
QTest::addRow("(%d, %d) vs (%d, %d)", lhs.width(), lhs.height(), rhs.width(), rhs.height())
<< lhs << rhs << res;
};
row(QSize(0, 0), QSize(0, 0), true);
row(QSize(1, 0), QSize(0, 1), false);
row(QSize(-1, -1), QSize(-1, -1), true);
row(QSize(-1, -1), QSize(1, 1), false);
row(QSize(INT_MIN, INT_MAX), QSize(INT_MAX, INT_MIN), false);
}
void tst_QSize::compare()
{
QFETCH(QSize, lhs);
QFETCH(QSize, rhs);
QFETCH(bool, result);
QT_TEST_EQUALITY_OPS(lhs, rhs, result);
}
// Testing get/set functions
void tst_QSize::getSetCheck()
{

View File

@ -14,4 +14,6 @@ endif()
qt_internal_add_test(tst_qsizef
SOURCES
tst_qsizef.cpp
LIBRARIES
Qt::TestPrivate
)

View File

@ -24,14 +24,21 @@ CHECK(const &&);
#undef CHECK
#include <QTest>
#include <QtTest/private/qcomparisontesthelper_p.h>
#include <qsize.h>
Q_DECLARE_METATYPE(QMarginsF)
static constexpr qreal qreal_min = std::numeric_limits<qreal>::min();
class tst_QSizeF : public QObject
{
Q_OBJECT
private slots:
void compareCompiles();
void compare_data();
void compare();
void isNull_data();
void isNull();
@ -52,6 +59,47 @@ private slots:
void structuredBinding();
};
void tst_QSizeF::compareCompiles()
{
QTestPrivate::testEqualityOperatorsCompile<QSizeF>();
QTestPrivate::testEqualityOperatorsCompile<QSizeF, QSize>();
}
void tst_QSizeF::compare_data()
{
QTest::addColumn<QSizeF>("lhs");
QTest::addColumn<QSizeF>("rhs");
QTest::addColumn<bool>("result");
QTest::addColumn<bool>("mixedResult");
auto row = [&](QSizeF lhs, QSizeF rhs, bool res, bool mixedRes) {
QString str;
QDebug dbg(&str);
dbg.nospace() << "(" << lhs.width() << ", " << lhs.height() << ") vs "
<< "(" << rhs.width() << ", " << rhs.height() << ")";
QTest::addRow("%s", str.toLatin1().constData()) << lhs << rhs << res << mixedRes;
};
row(QSizeF(0.0, 0.0), QSizeF(0.0, 0.0), true, true);
row(QSizeF(1.0, 2.0), QSizeF(1.0, 2.0), true, true);
row(QSizeF(1.0, -1.0), QSizeF(-1.0, 1.0), false, false);
row(QSizeF(0.1, 1.1), QSizeF(0.1, 1.1), true, false);
row(QSizeF(qreal_min, 0.0), QSizeF(0.0, -qreal_min), true, true);
}
void tst_QSizeF::compare()
{
QFETCH(QSizeF, lhs);
QFETCH(QSizeF, rhs);
QFETCH(bool, result);
QFETCH(bool, mixedResult);
QT_TEST_EQUALITY_OPS(lhs, rhs, result);
const QSize rhsFixed = rhs.toSize();
QT_TEST_EQUALITY_OPS(lhs, rhsFixed, mixedResult);
}
void tst_QSizeF::isNull_data()
{
QTest::addColumn<qreal>("width");