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<T> and QPointer<X> 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 <ivan.solovev@qt.io>bb10
parent
99475db542
commit
890c270b9b
|
|
@ -4,6 +4,7 @@
|
|||
#ifndef QPOINTER_H
|
||||
#define QPOINTER_H
|
||||
|
||||
#include <QtCore/qcompare.h>
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
#include <QtCore/qtypeinfo.h>
|
||||
|
||||
|
|
@ -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 <typename X>
|
||||
friend bool comparesEqual(const QPointer &lhs, const QPointer<X> &rhs) noexcept
|
||||
{ return lhs.data() == rhs.data(); }
|
||||
QT_DECLARE_EQUALITY_OPERATORS_HELPER(QPointer, QPointer<X>, /* non-constexpr */,
|
||||
template <typename X>)
|
||||
|
||||
#define DECLARE_TEMPLATE_COMPARE_SET(T1, A1, T2, A2) \
|
||||
template <typename X> \
|
||||
friend bool operator==(T1, T2) noexcept \
|
||||
{ return A1 == A2; } \
|
||||
template <typename X> \
|
||||
friend bool operator!=(T1, T2) noexcept \
|
||||
{ return A1 != A2; }
|
||||
template <typename X>
|
||||
friend bool comparesEqual(const QPointer &lhs, X *rhs) noexcept
|
||||
{ return lhs.data() == rhs; }
|
||||
Q_DECLARE_EQUALITY_COMPARABLE(QPointer, X*, template <typename X>)
|
||||
|
||||
DECLARE_TEMPLATE_COMPARE_SET(const QPointer &p1, p1.data(), const QPointer<X> &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 <class T> Q_DECLARE_TYPEINFO_BODY(QPointer<T>, Q_RELOCATABLE_TYPE);
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@
|
|||
|
||||
\ingroup objectmodel
|
||||
|
||||
\compares equality
|
||||
\compareswith equality QPointer<X> 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<T>, 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 <typename T> template<typename X> bool QPointer<T>::operator==(X *o, const QPointer<T> &p)
|
||||
\fn template <typename T> template<typename X> bool QPointer<T>::operator==(X* const &lhs, const QPointer<T> &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 <typename T> template<typename X> bool QPointer<T>::operator==(const QPointer<T> &p, X *o)
|
||||
\fn template <typename T> template<typename X> bool QPointer<T>::operator==(const QPointer<T> &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 <typename T> template<typename X> bool QPointer<T>::operator==(const QPointer<T> &p1, const QPointer<X> &p2)
|
||||
\fn template <typename T> template<typename X> bool QPointer<T>::operator==(const QPointer<T> &lhs, const QPointer<X> &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 <typename T> bool QPointer<T>::operator==(std::nullptr_t, const QPointer<T> &rhs)
|
||||
\fn template <typename T> bool QPointer<T>::operator==(std::nullptr_t const &lhs, const QPointer<T> &rhs)
|
||||
|
||||
Equality operator. Returns \c true if the pointer guarded by \a rhs
|
||||
is \nullptr, otherwise
|
||||
returns \c false.
|
||||
*/
|
||||
/*!
|
||||
\fn template <typename T> bool QPointer<T>::operator==(const QPointer<T> &lhs, std::nullptr_t)
|
||||
\fn template <typename T> bool QPointer<T>::operator==(const QPointer<T> &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 <typename T> template<typename X> bool QPointer<T>::operator!=(const QPointer<T> &p, X *o)
|
||||
\fn template <typename T> template<typename X> bool QPointer<T>::operator!=(const QPointer<T> &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 <typename T> template<typename X> bool QPointer<T>::operator!=(X *o, const QPointer<T> &p)
|
||||
\fn template <typename T> template<typename X> bool QPointer<T>::operator!=(X* const &lhs, const QPointer<T> &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 <typename T> template<typename X> bool QPointer<T>::operator!=(const QPointer<T> &p1, const QPointer<X> &p2)
|
||||
\fn template <typename T> template<typename X> bool QPointer<T>::operator!=(const QPointer<T> &lhs, const QPointer<X> &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 <typename T> bool QPointer<T>::operator!=(std::nullptr_t, const QPointer<T> &rhs)
|
||||
\fn template <typename T> bool QPointer<T>::operator!=(std::nullptr_t const &lhs, const QPointer<T> &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 <typename T> bool QPointer<T>::operator!=(const QPointer<T> &lhs, std::nullptr_t)
|
||||
\fn template <typename T> bool QPointer<T>::operator!=(const QPointer<T> &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
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ qt_internal_add_test(tst_qpointer
|
|||
tst_qpointer.cpp
|
||||
LIBRARIES
|
||||
Qt::Gui
|
||||
Qt::TestPrivate
|
||||
)
|
||||
|
||||
## Scopes:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include <QTest>
|
||||
#include <QtTest/private/qcomparisontesthelper_p.h>
|
||||
#include <QRunnable>
|
||||
#include <QThreadPool>
|
||||
|
||||
|
|
@ -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<QPointer<QObject>>();
|
||||
QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, QObject*>();
|
||||
QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, QWidget*>();
|
||||
QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, QPointer<QWidget>>();
|
||||
QTestPrivate::testEqualityOperatorsCompile<QPointer<QObject>, std::nullptr_t>();
|
||||
}
|
||||
|
||||
void tst_QPointer::equality_operators()
|
||||
{
|
||||
QPointer<QObject> p1;
|
||||
QPointer<QObject> 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
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue