diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2019-06-06 12:52:15 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2019-06-11 18:44:58 +0200 |
commit | 242bc539ab6d9e76e1f67f2a51918c79970c2788 (patch) | |
tree | 459db17c263ed777c901e8194dc11c31b7ea6081 | |
parent | fafae936a68bac1231b2de69b58e8248ae5dca2f (diff) |
QWeakPointer: use an alternative work-round for internalData() users
The previous work-around fails, probably because of
cross-dependencies. E.g. we have this in QtScXml:
In file included from /home/qt/work/install/include/QtCore/qsharedpointer.h:48:0,
from ../../src/scxml/qscxmltabledata_p.h:55,
from ../../src/scxml/qscxmltabledata.cpp:40:
/home/qt/work/install/include/QtCore/qsharedpointer_impl.h:687:12: error: ‘QPointer’ does not name a type; did you mean ‘pointer’?
friend QPointer<X>
^~~~~~~~
pointer
/home/qt/work/install/include/QtCore/qsharedpointer_impl.h:689:23: error: ‘QSmartPointerConvertFunctor’ in namespace ‘QtPrivate’ does not name a template type
friend QtPrivate::QSmartPointerConvertFunctor<QWeakPointer>;
^~~~~~~~~~~~~~~~~~~~~~~~~~~
To fix, grand friendship only to a non-template class with a templated
static method that returns internalData(). This fixes most users,
except in qmetatype.h, which does not include qsharedpointer.h. In
order to use the non-template class in there, we need to delay its
name lookup to instantiation time. We do this by artificially making
it a dependent name, by using a class template that inherits from
our befrieded class.
Change-Id: I12b427f1fe9503df819ea5436d780972d6402e68
Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
-rw-r--r-- | src/corelib/kernel/qmetatype.h | 7 | ||||
-rw-r--r-- | src/corelib/kernel/qpointer.h | 3 | ||||
-rw-r--r-- | src/corelib/tools/qsharedpointer_impl.h | 28 |
3 files changed, 25 insertions, 13 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 154ccf62bb..fef25a32c4 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1715,12 +1715,17 @@ namespace QtPrivate { } }; + // hack to delay name lookup to instantiation time by making + // EnableInternalData a dependent name: + template <typename T> + struct EnableInternalDataWrap; + template<typename T> struct QSmartPointerConvertFunctor<QWeakPointer<T> > { QObject* operator()(const QWeakPointer<T> &p) const { - return p.internalData(); + return QtPrivate::EnableInternalDataWrap<T>::internalData(p); } }; } diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h index 80faef2990..7052bcf0d4 100644 --- a/src/corelib/kernel/qpointer.h +++ b/src/corelib/kernel/qpointer.h @@ -143,7 +143,8 @@ template<typename T> QPointer<T> qPointerFromVariant(const QVariant &variant) { - return QPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).internalData())); + const auto wp = QtSharedPointer::weakPointerFromVariant_internal(variant); + return QPointer<T>{qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(wp))}; } template <class T> diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 55f0f17c52..f352e433c5 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -107,6 +107,10 @@ template <class X, class T> QSharedPointer<X> qSharedPointerObjectCast(const QSharedPointer<T> &ptr); #endif +namespace QtPrivate { +struct EnableInternalData; +} + namespace QtSharedPointer { template <class T> class ExternalRefCount; @@ -672,21 +676,12 @@ public: #endif private: - + friend struct QtPrivate::EnableInternalData; #if defined(Q_NO_TEMPLATE_FRIENDS) public: #else template <class X> friend class QSharedPointer; template <class X> friend class QPointer; -# ifndef QT_NO_QOBJECT - template<typename X> - friend QWeakPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<X*>::Value, X>::type> - qWeakPointerFromVariant(const QVariant &variant); -# endif - template<typename X> - friend QPointer<X> - qPointerFromVariant(const QVariant &variant); - friend QtPrivate::QSmartPointerConvertFunctor<QWeakPointer>; #endif template <class X> @@ -721,6 +716,17 @@ public: T *value; }; +namespace QtPrivate { +struct EnableInternalData { + template <typename T> + static T *internalData(const QWeakPointer<T> &p) noexcept { return p.internalData(); } +}; +// hack to delay name lookup to instantiation time by making +// EnableInternalData a dependent name: +template <typename T> +struct EnableInternalDataWrap : EnableInternalData {}; +} + template <class T> class QEnableSharedFromThis { @@ -996,7 +1002,7 @@ template<typename T> QWeakPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type> qWeakPointerFromVariant(const QVariant &variant) { - return QWeakPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).internalData())); + return QWeakPointer<T>(qobject_cast<T*>(QtPrivate::EnableInternalData::internalData(QtSharedPointer::weakPointerFromVariant_internal(variant)))); } template<typename T> QSharedPointer<typename std::enable_if<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::type> |