diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2019-04-30 12:39:22 +0200 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2019-05-01 18:37:32 +0000 |
commit | d4435a37cae43abfbdb247b7d4a3a950aced2751 (patch) | |
tree | 41c567e46b9e2a914b69743480b3c771f5c7b5e0 /src/corelib | |
parent | 23c2da3cc23a2e04a0b3b3c8ad7fa9cc6126ff23 (diff) |
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>
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/tools/qsharedpointer.cpp | 51 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 42 |
2 files changed, 93 insertions, 0 deletions
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 62b76c5bb7..0aedf4c6d6 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -1300,6 +1300,57 @@ */ /*! + \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 \relates QWeakPointer diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 81d8dcd839..0851121ff2 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -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); |