Make QPointer<T> constructible from QPointer<X>

QWeakPointer can do the same, so there's no reason to not allow it for
QPointer.

[ChangeLog][QtCore][QPointer] QPointer<T> can now be (move- and
copy-)constructed from QPointer<X>.

Fixes: QTBUG-112464
Change-Id: I77cf5d39974bf2b3ec849b4afc33e286e864821e
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
This commit is contained in:
Marc Mutz 2023-04-28 15:14:04 +02:00
parent 9b47c62682
commit 5f28d367d9
3 changed files with 50 additions and 0 deletions

View File

@ -97,6 +97,20 @@
pointed to.
*/
/*!
\fn template <class T> template <class X> QPointer<T>::QPointer(QPointer<X> &&other)
\fn template <class T> template <class X> QPointer<T>::QPointer(const QPointer<X> &other)
\since 6.6
Conversion constructor. Constructs a new QPointer by moving or copying from
\a other.
The moved-from QPointer is reset to nullptr.
\note These constructors participate in overload resolution only if \c{X*}
is convertible to \c{T*}.
*/
/*!
\fn template <class T> void QPointer<T>::swap(QPointer &other)
\since 5.6

View File

@ -18,6 +18,11 @@ class QPointer
{
static_assert(!std::is_pointer<T>::value, "QPointer's template type must not be a pointer type");
template <typename X>
using if_convertible = std::enable_if_t<std::is_convertible_v<X*, T*>, bool>;
template <typename X>
friend class QPointer;
using QObjectType =
typename std::conditional<std::is_const<T>::value, const QObject, QObject>::type;
QWeakPointer<QObjectType> wp;
@ -27,6 +32,11 @@ public:
// compiler-generated copy/move ctor/assignment operators are fine!
// compiler-generated dtor is fine!
template <typename X, if_convertible<X> = true>
QPointer(QPointer<X> &&other) noexcept : wp(std::move(other.wp)) {}
template <typename X, if_convertible<X> = true>
QPointer(const QPointer<X> &other) noexcept : wp(other.wp) {}
#ifdef Q_QDOC
// Stop qdoc from complaining about missing function
~QPointer();

View File

@ -19,6 +19,7 @@ public:
private slots:
void constructors();
void conversion();
void destructor();
void assignment_operators();
void equality_operators();
@ -44,6 +45,31 @@ void tst_QPointer::constructors()
QCOMPARE(p3, QPointer<QObject>(this));
}
void tst_QPointer::conversion()
{
// copy-conversion:
{
QFile file;
QPointer<QFile> pf = &file;
QCOMPARE_EQ(pf, &file);
QPointer<QIODevice> pio = pf;
QCOMPARE_EQ(pio, &file);
QCOMPARE_EQ(pio.get(), &file);
QCOMPARE_EQ(pio, pf);
QCOMPARE_EQ(pio.get(), pf.get());
}
// move-conversion:
{
QFile file;
QPointer<QFile> pf = &file;
QCOMPARE_EQ(pf, &file);
QPointer<QIODevice> pio = std::move(pf);
QCOMPARE_EQ(pf, nullptr);
QCOMPARE_EQ(pio, &file);
QCOMPARE_EQ(pio.get(), &file);
}
}
void tst_QPointer::destructor()
{
// Make two QPointer's to the same object