From 890c270b9b27de5075bda668dbe8117649673b05 Mon Sep 17 00:00:00 2001 From: Rym Bouabid Date: Wed, 20 Mar 2024 12:44:44 +0100 Subject: [PATCH] QPointer: Use new comparison helper macros Provide the new comparesEqual() helper function as an implementation of (in)equality operators. Use QT_DECLARE_EQUALITY_OPERATORS_HELPER macro instead of Q_DECLARE_EQUALITY_COMPARABLE for the comparison between QPointer and QPointer to avoid creating the reversed version of the operators in C++17 mode. Use new \compares command in the documentation to describe the comparison operators provided by QPointer. Task-number: QTBUG-120306 Change-Id: Iff24d3ef5c790de7f06ab825f853e06186fa1471 Reviewed-by: Ivan Solovev --- src/corelib/kernel/qpointer.h | 33 ++++++------- src/corelib/kernel/qpointer.qdoc | 48 +++++++++++-------- .../corelib/kernel/qpointer/CMakeLists.txt | 1 + .../corelib/kernel/qpointer/tst_qpointer.cpp | 44 +++++++++-------- 4 files changed, 66 insertions(+), 60 deletions(-) diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h index 39e4ba3e0f..8875eef5c3 100644 --- a/src/corelib/kernel/qpointer.h +++ b/src/corelib/kernel/qpointer.h @@ -4,6 +4,7 @@ #ifndef QPOINTER_H #define QPOINTER_H +#include #include #include @@ -90,27 +91,21 @@ public: friend void swap(QPointer &lhs, QPointer &rhs) noexcept { lhs.swap(rhs); } -#define DECLARE_COMPARE_SET(T1, A1, T2, A2) \ - friend bool operator==(T1, T2) noexcept \ - { return A1 == A2; } \ - friend bool operator!=(T1, T2) noexcept \ - { return A1 != A2; } +private: + template + friend bool comparesEqual(const QPointer &lhs, const QPointer &rhs) noexcept + { return lhs.data() == rhs.data(); } + QT_DECLARE_EQUALITY_OPERATORS_HELPER(QPointer, QPointer, /* non-constexpr */, + template ) -#define DECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2) \ - template \ - friend bool operator==(T1, T2) noexcept \ - { return A1 == A2; } \ - template \ - friend bool operator!=(T1, T2) noexcept \ - { return A1 != A2; } + template + friend bool comparesEqual(const QPointer &lhs, X *rhs) noexcept + { return lhs.data() == rhs; } + Q_DECLARE_EQUALITY_COMPARABLE(QPointer, X*, template ) - DECLARE_TEMPLATE_COMPARE_SET(const QPointer &p1, p1.data(), const QPointer &p2, p2.data()) - DECLARE_TEMPLATE_COMPARE_SET(const QPointer &p1, p1.data(), X *ptr, ptr) - DECLARE_TEMPLATE_COMPARE_SET(X *ptr, ptr, const QPointer &p2, p2.data()) - DECLARE_COMPARE_SET(const QPointer &p1, p1.data(), std::nullptr_t, nullptr) - DECLARE_COMPARE_SET(std::nullptr_t, nullptr, const QPointer &p2, p2.data()) -#undef DECLARE_COMPARE_SET -#undef DECLARE_TEMPLATE_COMPARE_SET + friend bool comparesEqual(const QPointer &lhs, std::nullptr_t) noexcept + { return lhs.data() == nullptr; } + Q_DECLARE_EQUALITY_COMPARABLE(QPointer, std::nullptr_t) }; template Q_DECLARE_TYPEINFO_BODY(QPointer, Q_RELOCATABLE_TYPE); diff --git a/src/corelib/kernel/qpointer.qdoc b/src/corelib/kernel/qpointer.qdoc index 9e4c9b2658..63a2a72e6f 100644 --- a/src/corelib/kernel/qpointer.qdoc +++ b/src/corelib/kernel/qpointer.qdoc @@ -8,6 +8,12 @@ \ingroup objectmodel + \compares equality + \compareswith equality QPointer X* std::nullptr_t + Where X and T are compatible types, which means that they are either the same (except + for their cv-qualifiers), or one is a base type of the other. + \endcompareswith + A guarded pointer, QPointer, behaves like a normal C++ pointer \c{T *}, except that it is automatically cleared when the referenced object is destroyed (unlike normal C++ pointers, which @@ -202,38 +208,38 @@ */ /*! - \fn template template bool QPointer::operator==(X *o, const QPointer &p) + \fn template template bool QPointer::operator==(X* const &lhs, const QPointer &rhs) - Equality operator. Returns \c true if \a o and the guarded - pointer \a p are pointing to the same object, otherwise + Equality operator. Returns \c true if \a lhs and the guarded + pointer \a rhs are pointing to the same object, otherwise returns \c false. */ /*! - \fn template template bool QPointer::operator==(const QPointer &p, X *o) + \fn template template bool QPointer::operator==(const QPointer &lhs, X* const &rhs) - Equality operator. Returns \c true if \a o and the guarded - pointer \a p are pointing to the same object, otherwise + Equality operator. Returns \c true if \a rhs and the guarded + pointer \a lhs are pointing to the same object, otherwise returns \c false. */ /*! - \fn template template bool QPointer::operator==(const QPointer &p1, const QPointer &p2) + \fn template template bool QPointer::operator==(const QPointer &lhs, const QPointer &rhs) - Equality operator. Returns \c true if the guarded pointers \a p1 and \a p2 + Equality operator. Returns \c true if the guarded pointers \a lhs and \a rhs are pointing to the same object, otherwise returns \c false. */ /*! - \fn template bool QPointer::operator==(std::nullptr_t, const QPointer &rhs) + \fn template bool QPointer::operator==(std::nullptr_t const &lhs, const QPointer &rhs) Equality operator. Returns \c true if the pointer guarded by \a rhs is \nullptr, otherwise returns \c false. */ /*! - \fn template bool QPointer::operator==(const QPointer &lhs, std::nullptr_t) + \fn template bool QPointer::operator==(const QPointer &lhs, std::nullptr_t const &rhs) Equality operator. Returns \c true if the pointer guarded by \a lhs is \nullptr, otherwise @@ -241,35 +247,35 @@ */ /*! - \fn template template bool QPointer::operator!=(const QPointer &p, X *o) + \fn template template bool QPointer::operator!=(const QPointer &lhs, X* const &rhs) - Inequality operator. Returns \c true if \a o and the guarded - pointer \a p are not pointing to the same object, otherwise + Inequality operator. Returns \c true if \a rhs and the guarded + pointer \a lhs are not pointing to the same object, otherwise returns \c false. */ /*! - \fn template template bool QPointer::operator!=(X *o, const QPointer &p) + \fn template template bool QPointer::operator!=(X* const &lhs, const QPointer &rhs) - Inequality operator. Returns \c true if \a o and the guarded - pointer \a p are not pointing to the same object, otherwise + Inequality operator. Returns \c true if \a lhs and the guarded + pointer \a rhs are not pointing to the same object, otherwise returns \c false. */ /*! - \fn template template bool QPointer::operator!=(const QPointer &p1, const QPointer &p2) + \fn template template bool QPointer::operator!=(const QPointer &lhs, const QPointer &rhs) - Inequality operator. Returns \c true if the guarded pointers \a p1 and - \a p2 are not pointing to the same object, otherwise + Inequality operator. Returns \c true if the guarded pointers \a lhs and + \a rhs are not pointing to the same object, otherwise returns \c false. */ /*! - \fn template bool QPointer::operator!=(std::nullptr_t, const QPointer &rhs) + \fn template bool QPointer::operator!=(std::nullptr_t const &lhs, const QPointer &rhs) Inequality operator. Returns \c true if the pointer guarded by \a rhs is a valid (ie not \nullptr) pointer, otherwise returns \c false. */ /*! - \fn template bool QPointer::operator!=(const QPointer &lhs, std::nullptr_t) + \fn template bool QPointer::operator!=(const QPointer &lhs, std::nullptr_t const &rhs) Inequality operator. Returns \c true if the pointer guarded by \a lhs is a valid (ie not \nullptr) pointer, otherwise diff --git a/tests/auto/corelib/kernel/qpointer/CMakeLists.txt b/tests/auto/corelib/kernel/qpointer/CMakeLists.txt index b1570b8cef..0b2c4b7e45 100644 --- a/tests/auto/corelib/kernel/qpointer/CMakeLists.txt +++ b/tests/auto/corelib/kernel/qpointer/CMakeLists.txt @@ -20,6 +20,7 @@ qt_internal_add_test(tst_qpointer tst_qpointer.cpp LIBRARIES Qt::Gui + Qt::TestPrivate ) ## Scopes: diff --git a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp index 7365fee819..b88f1b5b0f 100644 --- a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp +++ b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include +#include #include #include @@ -23,6 +24,7 @@ private slots: void conversion(); void destructor(); void assignment_operators(); + void compareCompiles(); void equality_operators(); void swap(); void isNull(); @@ -203,12 +205,21 @@ void tst_QPointer::assignment_operators() delete object; } +void tst_QPointer::compareCompiles() +{ + QTestPrivate::testEqualityOperatorsCompile>(); + QTestPrivate::testEqualityOperatorsCompile, QObject*>(); + QTestPrivate::testEqualityOperatorsCompile, QWidget*>(); + QTestPrivate::testEqualityOperatorsCompile, QPointer>(); + QTestPrivate::testEqualityOperatorsCompile, std::nullptr_t>(); +} + void tst_QPointer::equality_operators() { QPointer p1; QPointer p2; - QVERIFY(p1 == p2); + QT_TEST_EQUALITY_OPS(p1, p2, true); QObject *object = nullptr; #ifndef QT_NO_WIDGETS @@ -216,16 +227,15 @@ void tst_QPointer::equality_operators() #endif p1 = object; - QVERIFY(p1 == p2); - QVERIFY(p1 == object); + QT_TEST_EQUALITY_OPS(p1, p2, true); + QT_TEST_EQUALITY_OPS(p1, object, true); p2 = object; - QVERIFY(p2 == p1); - QVERIFY(p2 == object); - + QT_TEST_EQUALITY_OPS(p2, p1, true); + QT_TEST_EQUALITY_OPS(p2, object, true); p1 = this; - QVERIFY(p1 != p2); + QT_TEST_EQUALITY_OPS(p1, p2, false); p2 = p1; - QVERIFY(p1 == p2); + QT_TEST_EQUALITY_OPS(p1, p2, true); // compare to zero p1 = nullptr; @@ -233,19 +243,13 @@ void tst_QPointer::equality_operators() QVERIFY(0 == p1); QVERIFY(p2 != 0); QVERIFY(0 != p2); - QVERIFY(p1 == nullptr); - QVERIFY(nullptr == p1); - QVERIFY(p2 != nullptr); - QVERIFY(nullptr != p2); - QVERIFY(p1 == object); - QVERIFY(object == p1); - QVERIFY(p2 != object); - QVERIFY(object != p2); + QT_TEST_EQUALITY_OPS(p1, nullptr, true); + QT_TEST_EQUALITY_OPS(p2, nullptr, false); + QT_TEST_EQUALITY_OPS(p1, object, true); + QT_TEST_EQUALITY_OPS(p2, object, false); #ifndef QT_NO_WIDGETS - QVERIFY(p1 == widget); - QVERIFY(widget == p1); - QVERIFY(p2 != widget); - QVERIFY(widget != p2); + QT_TEST_EQUALITY_OPS(p1, widget, true); + QT_TEST_EQUALITY_OPS(p2, widget, false); #endif }