diff options
author | Ivan Solovev <ivan.solovev@qt.io> | 2024-04-05 11:59:30 +0200 |
---|---|---|
committer | Ivan Solovev <ivan.solovev@qt.io> | 2024-05-10 15:33:39 +0200 |
commit | 2a847dd93b1b9cc363eefa27686d78a4bc399d1e (patch) | |
tree | 490d7b81768321102e01919a6a96c0712147a2ba | |
parent | fa0d77e290f5ccb5afa7d02716f8726aa6b810e6 (diff) |
QLine(F): use comparison helper macros
Also explicitly add QLineF vs QLine comparison. Previously such
comparison was implicitly converting QLine to QLineF, and doing the
fuzzy comparison.
The new operators are directly calling operator==(QPointF, QPoint),
which also does the fuzzy comparison, so the old behavior is preserved.
Remove the old relational operators using QT_CORE_REMOVED_SINCE, but
also wrap the new operators in !defined(QT_CORE_REMOVED_SINCE).
That is required, because on Windows the instantiation of
QMetaTypeInterface<QLine(F)> happens in removed_api.cpp (as both
qline.h and qmetatype.h are already included there). If we just add
removed member operators into removed_api.cpp, the metatype interface
will not be able to create an equals() function, because of the
ambiguity in equality operators (member vs friend). That's why we have
to exclude the new friend operators from removed_api.cpp.
Done-with: Fabian Kosmale <fabian.kosmale@qt.io>
Task-number: QTBUG-120308
Change-Id: Ibbf5ec077f69c75da0d36a8be5596acd0fcd44d0
Reviewed-by: Tatiana Borisova <tatiana.borisova@qt.io>
-rw-r--r-- | src/corelib/compat/removed_api.cpp | 2 | ||||
-rw-r--r-- | src/corelib/tools/qline.cpp | 22 | ||||
-rw-r--r-- | src/corelib/tools/qline.h | 34 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qline/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qline/tst_qline.cpp | 72 |
5 files changed, 118 insertions, 14 deletions
diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index 3c6123ed15..1b987f7886 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -1005,6 +1005,8 @@ bool QJsonValue::operator!=(const QJsonValue &other) const return !comparesEqual(*this, other); } +#include "qline.h" // inlined API + #include "qmimetype.h" bool QMimeType::operator==(const QMimeType &other) const diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index 9216b8875b..a1794f98f6 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -14,6 +14,9 @@ QT_BEGIN_NAMESPACE \class QLine \inmodule QtCore \ingroup painting + \compares equality + \compareswith equality QLineF + \endcompareswith \brief The QLine class provides a two-dimensional vector using integer precision. @@ -133,18 +136,18 @@ QT_BEGIN_NAMESPACE */ /*! - \fn bool QLine::operator!=(const QLine &line) const + \fn bool QLine::operator!=(const QLine &lhs, const QLine &rhs) - Returns \c true if the given \a line is not the same as \e this line. + Returns \c true if the line \a lhs is not the same as line \a rhs. A line is different from another line if any of their start or end points differ, or the internal order of the points is different. */ /*! - \fn bool QLine::operator==(const QLine &line) const + \fn bool QLine::operator==(const QLine &lhs, const QLine &rhs) - Returns \c true if the given \a line is the same as \e this line. + Returns \c true if the line \a lhs is the same as line \a rhs. A line is identical to another line if the start and end points are identical, and the internal order of the points is the same. @@ -288,6 +291,9 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) \class QLineF \inmodule QtCore \ingroup painting + \compares equality + \compareswith equality QLine + \endcompareswith \brief The QLineF class provides a two-dimensional vector using floating point precision. @@ -508,18 +514,18 @@ QDataStream &operator>>(QDataStream &stream, QLine &line) */ /*! - \fn bool QLineF::operator!=(const QLineF &line) const + \fn bool QLineF::operator!=(const QLineF &lhs, const QLineF &rhs) - Returns \c true if the given \a line is not the same as \e this line. + Returns \c true if the line \a lhs is not the same as line \a rhs. A line is different from another line if their start or end points differ, or the internal order of the points is different. */ /*! - \fn bool QLineF::operator==(const QLineF &line) const + \fn bool QLineF::operator==(const QLineF &lhs, const QLineF &rhs) - Returns \c true if the given \a line is the same as this line. + Returns \c true if the line \a lhs is the same as line \a rhs. A line is identical to another line if the start and end points are identical, and the internal order of the points is the same. diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h index e23ffbe9d5..45f0bae94f 100644 --- a/src/corelib/tools/qline.h +++ b/src/corelib/tools/qline.h @@ -48,12 +48,20 @@ public: inline void setPoints(const QPoint &p1, const QPoint &p2); inline void setLine(int x1, int y1, int x2, int y2); +#if QT_CORE_REMOVED_SINCE(6, 8) constexpr inline bool operator==(const QLine &d) const noexcept; - constexpr inline bool operator!=(const QLine &d) const noexcept { return !(*this == d); } + constexpr inline bool operator!=(const QLine &d) const noexcept { return !operator==(d); } +#endif [[nodiscard]] constexpr inline QLineF toLineF() const noexcept; private: + friend constexpr bool comparesEqual(const QLine &lhs, const QLine &rhs) noexcept + { return lhs.pt1 == rhs.pt1 && lhs.pt2 == rhs.pt2; } +#if !QT_CORE_REMOVED_SINCE(6, 8) + Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(QLine) +#endif + QPoint pt1, pt2; }; Q_DECLARE_TYPEINFO(QLine, Q_PRIMITIVE_TYPE); @@ -161,10 +169,12 @@ inline void QLine::setLine(int aX1, int aY1, int aX2, int aY2) pt2 = QPoint(aX2, aY2); } +#if QT_CORE_REMOVED_SINCE(6, 8) constexpr inline bool QLine::operator==(const QLine &d) const noexcept { - return pt1 == d.pt1 && pt2 == d.pt2; + return comparesEqual(*this, d); } +#endif #ifndef QT_NO_DEBUG_STREAM Q_CORE_EXPORT QDebug operator<<(QDebug d, const QLine &p); @@ -233,12 +243,24 @@ public: inline void setPoints(const QPointF &p1, const QPointF &p2); inline void setLine(qreal x1, qreal y1, qreal x2, qreal y2); +#if QT_CORE_REMOVED_SINCE(6, 8) constexpr inline bool operator==(const QLineF &d) const; - constexpr inline bool operator!=(const QLineF &d) const { return !(*this == d); } + constexpr inline bool operator!=(const QLineF &d) const { return !operator==(d); } +#endif constexpr QLine toLine() const; private: + friend constexpr bool comparesEqual(const QLineF &lhs, const QLineF &rhs) noexcept + { return lhs.pt1 == rhs.pt1 && lhs.pt2 == rhs.pt2; } +#if !QT_CORE_REMOVED_SINCE(6, 8) + Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(QLineF) +#endif + + friend constexpr bool comparesEqual(const QLineF &lhs, const QLine &rhs) noexcept + { return comparesEqual(lhs, rhs.toLineF()); } + Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(QLineF, QLine) + QPointF pt1, pt2; }; Q_DECLARE_TYPEINFO(QLineF, Q_PRIMITIVE_TYPE); @@ -383,12 +405,12 @@ inline void QLineF::setLine(qreal aX1, qreal aY1, qreal aX2, qreal aY2) pt2 = QPointF(aX2, aY2); } - +#if QT_CORE_REMOVED_SINCE(6, 8) constexpr inline bool QLineF::operator==(const QLineF &d) const { - return pt1 == d.pt1 && pt2 == d.pt2; + return comparesEqual(*this, d); } - +#endif #ifndef QT_NO_DEBUG_STREAM diff --git a/tests/auto/corelib/tools/qline/CMakeLists.txt b/tests/auto/corelib/tools/qline/CMakeLists.txt index 17a3a1bcef..7d9fdf51a9 100644 --- a/tests/auto/corelib/tools/qline/CMakeLists.txt +++ b/tests/auto/corelib/tools/qline/CMakeLists.txt @@ -14,6 +14,8 @@ endif() qt_internal_add_test(tst_qline SOURCES tst_qline.cpp + LIBRARIES + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/tools/qline/tst_qline.cpp b/tests/auto/corelib/tools/qline/tst_qline.cpp index 51f1f8ac79..80214707e4 100644 --- a/tests/auto/corelib/tools/qline/tst_qline.cpp +++ b/tests/auto/corelib/tools/qline/tst_qline.cpp @@ -4,6 +4,7 @@ #include <QTest> #include <qline.h> #include <qmath.h> +#include <private/qcomparisontesthelper_p.h> #include <array> @@ -11,6 +12,10 @@ class tst_QLine : public QObject { Q_OBJECT private slots: + void testComparisonCompiles(); + void testComparison_data(); + void testComparison(); + void testIntersection(); void testIntersection_data(); @@ -42,6 +47,73 @@ private slots: const qreal epsilon = sizeof(qreal) == sizeof(double) ? 1e-8 : 1e-4; +void tst_QLine::testComparisonCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile<QLine>(); + QTestPrivate::testEqualityOperatorsCompile<QLineF>(); + QTestPrivate::testEqualityOperatorsCompile<QLineF, QLine>(); +} + +void tst_QLine::testComparison_data() +{ + QTest::addColumn<double>("xa1"); + QTest::addColumn<double>("ya1"); + QTest::addColumn<double>("xa2"); + QTest::addColumn<double>("ya2"); + QTest::addColumn<double>("xb1"); + QTest::addColumn<double>("yb1"); + QTest::addColumn<double>("xb2"); + QTest::addColumn<double>("yb2"); + QTest::addColumn<bool>("result"); + QTest::addColumn<bool>("floatResult"); + QTest::addColumn<bool>("mixedResult"); + + auto row = [&](double xa1, double ya1, double xa2, double ya2, + double xb1, double yb1, double xb2, double yb2, + bool result, bool floatResult, bool mixedResult) + { + QString str; + QDebug dbg(&str); + dbg.nospace() << "[(" << xa1 << ", " << ya1 << "); (" << xa2 << ", " << ya2 << ")] vs [(" + << xb1 << ", " << yb1 << "); (" << xb2 << ", " << yb2 << ")]"; + QTest::addRow("%s", str.toLatin1().constData()) + << xa1 << ya1 << xa2 << ya2 << xb1 << yb1 << xb2 << yb2 + << result << floatResult << mixedResult; + }; + + constexpr static qreal qreal_min = std::numeric_limits<qreal>::min(); + + row(-1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, true, true, true); + row(-1.1, -0.9, 1.1, 0.9, -1.0, -1.0, 1.0, 1.0, true, false, false); + row(-1.0, -1.0, 1.0, 1.0, -0.9, -1.1, 0.9, 1.1, true, false, true); + row(-qreal_min, -1.0, 1.0, qreal_min, 0.0, -1.1, 0.9, 0.0, true, false, true); +} + +void tst_QLine::testComparison() +{ + QFETCH(double, xa1); + QFETCH(double, ya1); + QFETCH(double, xa2); + QFETCH(double, ya2); + QFETCH(double, xb1); + QFETCH(double, yb1); + QFETCH(double, xb2); + QFETCH(double, yb2); + QFETCH(bool, result); + QFETCH(bool, floatResult); + QFETCH(bool, mixedResult); + + const QLineF l1f(xa1, ya1, xa2, ya2); + const QLine l1 = l1f.toLine(); + + const QLineF l2f(xb1, yb1, xb2, yb2); + const QLine l2 = l2f.toLine(); + + QT_TEST_EQUALITY_OPS(l1, l2, result); + QT_TEST_EQUALITY_OPS(l1f, l2f, floatResult); + QT_TEST_EQUALITY_OPS(l1f, l2, mixedResult); +} + void tst_QLine::testSet() { { |