summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.0.03
-rw-r--r--src/corelib/kernel/qmetatype.h48
-rw-r--r--src/corelib/tools/qsharedpointer.cpp2
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp31
4 files changed, 66 insertions, 18 deletions
diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0
index 7ddb17f4d1..76cdd0abcb 100644
--- a/dist/changes-5.0.0
+++ b/dist/changes-5.0.0
@@ -168,6 +168,9 @@ information about a particular change.
* Q_DECLARE_METATYPE(Foo*) now requires that Foo is fully defined. In
cases where a forward declared type should be used as a metatype,
Q_DECLARE_OPAQUE_POINTER(Foo*) can be used to allow that.
+ * Similarly, Q_DECLARE_METATYPE(QSharedPointer<Foo>), and
+ Q_DECLARE_METATYPE(QWeakPointer<Foo>) require Foo to be fully defined. Again
+ though, Q_DECLARE_OPAQUE_POINTER(Foo*) can be used to allow that.
- QItemEditorFactory
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index da6d02cddf..1a57cac7f1 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -247,7 +247,10 @@ public:
NeedsDestruction = 0x2,
MovableType = 0x4,
PointerToQObject = 0x8,
- IsEnumeration = 0x10
+ IsEnumeration = 0x10,
+ SharedPointerToQObject = 0x20,
+ WeakPointerToQObject = 0x40,
+ TrackingPointerToQObject = 0x80
};
Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
@@ -415,6 +418,9 @@ template <> inline void qMetaTypeLoadHelper<void>(QDataStream &, void *) {}
class QObject;
class QWidget;
+template <class T> class QSharedPointer;
+template <class T> class QWeakPointer;
+template <class T> class QPointer;
namespace QtPrivate
{
@@ -465,6 +471,40 @@ namespace QtPrivate
{
static inline const QMetaObject *value() { return &T::staticMetaObject; }
};
+
+ template<typename T>
+ struct IsSharedPointerToTypeDerivedFromQObject
+ {
+ enum { Value = false };
+ };
+
+ template<typename T>
+ struct IsSharedPointerToTypeDerivedFromQObject<QSharedPointer<T> > : IsPointerToTypeDerivedFromQObject<T*>
+ {
+ };
+
+ template<typename T>
+ struct IsWeakPointerToTypeDerivedFromQObject
+ {
+ enum { Value = false };
+ };
+
+ template<typename T>
+ struct IsWeakPointerToTypeDerivedFromQObject<QWeakPointer<T> > : IsPointerToTypeDerivedFromQObject<T*>
+ {
+ };
+
+ template<typename T>
+ struct IsTrackingPointerToTypeDerivedFromQObject
+ {
+ enum { Value = false };
+ };
+
+ template<typename T>
+ struct IsTrackingPointerToTypeDerivedFromQObject<QPointer<T> >
+ {
+ enum { Value = true };
+ };
}
template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value>
@@ -511,6 +551,9 @@ namespace QtPrivate {
| (QTypeInfo<T>::isComplex ? QMetaType::NeedsConstruction : 0)
| (QTypeInfo<T>::isComplex ? QMetaType::NeedsDestruction : 0)
| (IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : 0)
+ | (IsSharedPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::SharedPointerToQObject : 0)
+ | (IsWeakPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::WeakPointerToQObject : 0)
+ | (IsTrackingPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::TrackingPointerToQObject : 0)
| (Q_IS_ENUM(T) ? QMetaType::IsEnumeration : 0)
};
};
@@ -677,9 +720,6 @@ template <class T> class QVector;
template <class T> class QQueue;
template <class T> class QStack;
template <class T> class QSet;
-template <class T> class QSharedPointer;
-template <class T> class QWeakPointer;
-template <class T> class QPointer;
template <class T1, class T2> class QMap;
template <class T1, class T2> class QHash;
template <class T1, class T2> struct QPair;
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index 73a1e6c607..673b90c99a 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -1221,6 +1221,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
*/
QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
{
+ Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::SharedPointerToQObject);
return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
}
@@ -1231,6 +1232,7 @@ QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const
*/
QWeakPointer<QObject> QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant)
{
+ Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::WeakPointerToQObject || QMetaType::typeFlags(variant.userType()) & QMetaType::TrackingPointerToQObject);
return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
}
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 861cedf416..f1053ad2b4 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -1462,30 +1462,33 @@ void tst_QMetaType::automaticTemplateRegistration()
#endif // Q_COMPILER_VARIADIC_MACROS
-#define TEST_SMARTPOINTER(SMARTPOINTER, ELEMENT_TYPE) \
+#define TEST_SMARTPOINTER(SMARTPOINTER, ELEMENT_TYPE, FLAG_TEST, FROMVARIANTFUNCTION) \
{ \
SMARTPOINTER < ELEMENT_TYPE > sp(new ELEMENT_TYPE); \
+ sp.data()->setObjectName("Test name"); \
QVariant v = QVariant::fromValue(sp); \
QCOMPARE(v.typeName(), #SMARTPOINTER "<" #ELEMENT_TYPE ">"); \
+ QVERIFY(QMetaType::typeFlags(::qMetaTypeId<SMARTPOINTER < ELEMENT_TYPE > >()) & QMetaType::FLAG_TEST); \
+ SMARTPOINTER < QObject > extractedPtr = FROMVARIANTFUNCTION<QObject>(v); \
+ QCOMPARE(extractedPtr.data()->objectName(), sp.data()->objectName()); \
}
- TEST_SMARTPOINTER(QSharedPointer, QObject)
- TEST_SMARTPOINTER(QSharedPointer, QFile)
- TEST_SMARTPOINTER(QSharedPointer, QTemporaryFile)
- TEST_SMARTPOINTER(QSharedPointer, MyObject)
+ TEST_SMARTPOINTER(QSharedPointer, QObject, SharedPointerToQObject, qSharedPointerFromVariant)
+ TEST_SMARTPOINTER(QSharedPointer, QFile, SharedPointerToQObject, qSharedPointerFromVariant)
+ TEST_SMARTPOINTER(QSharedPointer, QTemporaryFile, SharedPointerToQObject, qSharedPointerFromVariant)
+ TEST_SMARTPOINTER(QSharedPointer, MyObject, SharedPointerToQObject, qSharedPointerFromVariant)
- TEST_SMARTPOINTER(QWeakPointer, QObject)
- TEST_SMARTPOINTER(QWeakPointer, QFile)
- TEST_SMARTPOINTER(QWeakPointer, QTemporaryFile)
- TEST_SMARTPOINTER(QWeakPointer, MyObject)
+ TEST_SMARTPOINTER(QWeakPointer, QObject, WeakPointerToQObject, qWeakPointerFromVariant)
+ TEST_SMARTPOINTER(QWeakPointer, QFile, WeakPointerToQObject, qWeakPointerFromVariant)
+ TEST_SMARTPOINTER(QWeakPointer, QTemporaryFile, WeakPointerToQObject, qWeakPointerFromVariant)
+ TEST_SMARTPOINTER(QWeakPointer, MyObject, WeakPointerToQObject, qWeakPointerFromVariant)
- TEST_SMARTPOINTER(QPointer, QObject)
- TEST_SMARTPOINTER(QPointer, QFile)
- TEST_SMARTPOINTER(QPointer, QTemporaryFile)
- TEST_SMARTPOINTER(QPointer, MyObject)
+ TEST_SMARTPOINTER(QPointer, QObject, TrackingPointerToQObject, qPointerFromVariant)
+ TEST_SMARTPOINTER(QPointer, QFile, TrackingPointerToQObject, qPointerFromVariant)
+ TEST_SMARTPOINTER(QPointer, QTemporaryFile, TrackingPointerToQObject, qPointerFromVariant)
+ TEST_SMARTPOINTER(QPointer, MyObject, TrackingPointerToQObject, qPointerFromVariant)
#undef TEST_SMARTPOINTER
-
}
template <typename T>