Add qobject_cast operators for std::shared_ptr
Mimicking what we currently have for QSharedPointer, but also adding * snake_case version (matching the ones in std) * rvalue-overloaded versions (matching the C++2a overloads). [ChangeLog][QtCore][QSharedPointer] Overloads of qSharedPointerObjectCast have been added to work on std::shared_ptr. Change-Id: I26ddffd82b000bf876e7c141fdce86a7b8c1d75a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
23c2da3cc2
commit
d4435a37ca
@ -1299,6 +1299,57 @@
|
||||
\sa QSharedPointer::objectCast(), qSharedPointerCast(), qSharedPointerConstCast()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
|
||||
\relates QSharedPointer
|
||||
\since 5.14
|
||||
|
||||
Returns a shared pointer to the pointer held by \a src, using a
|
||||
\l qobject_cast() to type \tt X to obtain an internal pointer of the
|
||||
appropriate type. If the \tt qobject_cast fails, the object
|
||||
returned will be null.
|
||||
|
||||
Note that \tt X must have the same cv-qualifiers (\tt const and
|
||||
\tt volatile) that \tt T has, or the code will fail to
|
||||
compile. Use const_pointer_cast to cast away the constness.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
|
||||
\relates QSharedPointer
|
||||
\since 5.14
|
||||
|
||||
Same as qSharedPointerObjectCast(). This function is provided for STL
|
||||
compatibility.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <class X, class T> std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
|
||||
\relates QSharedPointer
|
||||
\since 5.14
|
||||
|
||||
Returns a shared pointer to the pointer held by \a src, using a
|
||||
\l qobject_cast() to type \tt X to obtain an internal pointer of the
|
||||
appropriate type.
|
||||
|
||||
If the \tt qobject_cast succeeds, the function will return a valid shared
|
||||
pointer, and \a src is reset to null. If the \tt qobject_cast fails, the
|
||||
object returned will be null, and \a src will not be modified.
|
||||
|
||||
Note that \tt X must have the same cv-qualifiers (\tt const and
|
||||
\tt volatile) that \tt T has, or the code will fail to
|
||||
compile. Use const_pointer_cast to cast away the constness.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <class X, class T> std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
|
||||
\relates QSharedPointer
|
||||
\since 5.14
|
||||
|
||||
Same as qSharedPointerObjectCast(). This function is provided for STL
|
||||
compatibility.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn template <class X> template <class T> QSharedPointer<X> qSharedPointerObjectCast(const QWeakPointer<T> &src)
|
||||
\relates QSharedPointer
|
||||
|
@ -67,6 +67,8 @@ QT_END_NAMESPACE
|
||||
#endif
|
||||
#include <QtCore/qhashfunctions.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
||||
@ -996,6 +998,46 @@ qSharedPointerFromVariant(const QVariant &variant)
|
||||
return qSharedPointerObjectCast<T>(QtSharedPointer::sharedPointerFromVariant_internal(variant));
|
||||
}
|
||||
|
||||
// std::shared_ptr helpers
|
||||
|
||||
template <typename X, class T>
|
||||
std::shared_ptr<X> qobject_pointer_cast(const std::shared_ptr<T> &src)
|
||||
{
|
||||
using element_type = typename std::shared_ptr<X>::element_type;
|
||||
return std::shared_ptr<X>(src, qobject_cast<element_type *>(src.get()));
|
||||
}
|
||||
|
||||
template <typename X, class T>
|
||||
std::shared_ptr<X> qobject_pointer_cast(std::shared_ptr<T> &&src)
|
||||
{
|
||||
using element_type = typename std::shared_ptr<X>::element_type;
|
||||
auto castResult = qobject_cast<element_type *>(src.get());
|
||||
if (castResult) {
|
||||
auto result = std::shared_ptr<X>(std::move(src), castResult);
|
||||
#if __cplusplus <= 201703L
|
||||
// C++2a's move aliasing constructor will leave src empty.
|
||||
// Before C++2a we don't really know if the compiler has support for it.
|
||||
// The move aliasing constructor is the resolution for LWG2996,
|
||||
// which does not impose a feature-testing macro. So: clear src.
|
||||
src.reset();
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
return std::shared_ptr<X>();
|
||||
}
|
||||
|
||||
template <typename X, class T>
|
||||
std::shared_ptr<X> qSharedPointerObjectCast(const std::shared_ptr<T> &src)
|
||||
{
|
||||
return qobject_pointer_cast<X>(src);
|
||||
}
|
||||
|
||||
template <typename X, class T>
|
||||
std::shared_ptr<X> qSharedPointerObjectCast(std::shared_ptr<T> &&src)
|
||||
{
|
||||
return qobject_pointer_cast<X>(std::move(src));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
template<typename T> Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_MOVABLE_TYPE);
|
||||
|
@ -78,6 +78,7 @@ private slots:
|
||||
void sharedPointerFromQObjectWithWeak();
|
||||
void weakQObjectFromSharedPointer();
|
||||
void objectCast();
|
||||
void objectCastStdSharedPtr();
|
||||
void differentPointers();
|
||||
void virtualBaseDifferentPointers();
|
||||
#ifndef QTEST_NO_RTTI
|
||||
@ -1113,6 +1114,60 @@ void tst_QSharedPointer::objectCast()
|
||||
safetyCheck();
|
||||
}
|
||||
|
||||
|
||||
void tst_QSharedPointer::objectCastStdSharedPtr()
|
||||
{
|
||||
{
|
||||
OtherObject *data = new OtherObject;
|
||||
std::shared_ptr<QObject> baseptr = std::shared_ptr<QObject>(data);
|
||||
QVERIFY(baseptr.get() == data);
|
||||
|
||||
// perform successful object cast
|
||||
std::shared_ptr<OtherObject> ptr = qobject_pointer_cast<OtherObject>(baseptr);
|
||||
QVERIFY(ptr.get());
|
||||
QVERIFY(ptr.get() == data);
|
||||
|
||||
QVERIFY(baseptr.get() == data);
|
||||
}
|
||||
|
||||
{
|
||||
OtherObject *data = new OtherObject;
|
||||
std::shared_ptr<QObject> baseptr = std::shared_ptr<QObject>(data);
|
||||
QVERIFY(baseptr.get() == data);
|
||||
|
||||
// perform successful object cast
|
||||
std::shared_ptr<OtherObject> ptr = qobject_pointer_cast<OtherObject>(std::move(baseptr));
|
||||
QVERIFY(ptr.get());
|
||||
QVERIFY(ptr.get() == data);
|
||||
|
||||
QVERIFY(!baseptr.get());
|
||||
}
|
||||
|
||||
{
|
||||
QObject *data = new QObject;
|
||||
std::shared_ptr<QObject> baseptr = std::shared_ptr<QObject>(data);
|
||||
QVERIFY(baseptr.get() == data);
|
||||
|
||||
// perform unsuccessful object cast
|
||||
std::shared_ptr<OtherObject> ptr = qobject_pointer_cast<OtherObject>(baseptr);
|
||||
QVERIFY(!ptr.get());
|
||||
|
||||
QVERIFY(baseptr.get() == data);
|
||||
}
|
||||
|
||||
{
|
||||
QObject *data = new QObject;
|
||||
std::shared_ptr<QObject> baseptr = std::shared_ptr<QObject>(data);
|
||||
QVERIFY(baseptr.get() == data);
|
||||
|
||||
// perform unsuccessful object cast
|
||||
std::shared_ptr<OtherObject> ptr = qobject_pointer_cast<OtherObject>(std::move(baseptr));
|
||||
QVERIFY(!ptr.get());
|
||||
|
||||
QVERIFY(baseptr.get() == data);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QSharedPointer::differentPointers()
|
||||
{
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user