From: Stephen Kelly Date: Thu, 24 May 2012 12:35:45 +0000 (+0200) Subject: Record if a metatype is a smart pointer to a QObject derived. X-Git-Tag: 071012110112~326 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=579ea489a40ae0240f22c3d31bde1fc2cd8aaf15;p=profile%2Fivi%2Fqtbase.git Record if a metatype is a smart pointer to a QObject derived. This allows QVariant/QMetaType software (such as QtDeclarative) to deal with smart pointers in a similar way to how they can deal with naked pointers (accessing properties etc). This also adds a requirement that T be fully defined when QSharedPointer is inserted into a QVariant. Change-Id: I29e12b8a6aa5f4aadbd62f92b89bc238f64b5725 Reviewed-by: Jędrzej Nowacki --- diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 7ddb17f..76cdd0a 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), and + Q_DECLARE_METATYPE(QWeakPointer) 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 da6d02c..1a57cac 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(QDataStream &, void *) {} class QObject; class QWidget; +template class QSharedPointer; +template class QWeakPointer; +template class QPointer; namespace QtPrivate { @@ -465,6 +471,40 @@ namespace QtPrivate { static inline const QMetaObject *value() { return &T::staticMetaObject; } }; + + template + struct IsSharedPointerToTypeDerivedFromQObject + { + enum { Value = false }; + }; + + template + struct IsSharedPointerToTypeDerivedFromQObject > : IsPointerToTypeDerivedFromQObject + { + }; + + template + struct IsWeakPointerToTypeDerivedFromQObject + { + enum { Value = false }; + }; + + template + struct IsWeakPointerToTypeDerivedFromQObject > : IsPointerToTypeDerivedFromQObject + { + }; + + template + struct IsTrackingPointerToTypeDerivedFromQObject + { + enum { Value = false }; + }; + + template + struct IsTrackingPointerToTypeDerivedFromQObject > + { + enum { Value = true }; + }; } template ::Value> @@ -511,6 +551,9 @@ namespace QtPrivate { | (QTypeInfo::isComplex ? QMetaType::NeedsConstruction : 0) | (QTypeInfo::isComplex ? QMetaType::NeedsDestruction : 0) | (IsPointerToTypeDerivedFromQObject::Value ? QMetaType::PointerToQObject : 0) + | (IsSharedPointerToTypeDerivedFromQObject::Value ? QMetaType::SharedPointerToQObject : 0) + | (IsWeakPointerToTypeDerivedFromQObject::Value ? QMetaType::WeakPointerToQObject : 0) + | (IsTrackingPointerToTypeDerivedFromQObject::Value ? QMetaType::TrackingPointerToQObject : 0) | (Q_IS_ENUM(T) ? QMetaType::IsEnumeration : 0) }; }; @@ -677,9 +720,6 @@ template class QVector; template class QQueue; template class QStack; template class QSet; -template class QSharedPointer; -template class QWeakPointer; -template class QPointer; template class QMap; template class QHash; template struct QPair; diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 73a1e6c..673b90c 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -1221,6 +1221,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge */ QSharedPointer QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant) { + Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::SharedPointerToQObject); return *reinterpret_cast*>(variant.constData()); } @@ -1231,6 +1232,7 @@ QSharedPointer QtSharedPointer::sharedPointerFromVariant_internal(const */ QWeakPointer QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant) { + Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::WeakPointerToQObject || QMetaType::typeFlags(variant.userType()) & QMetaType::TrackingPointerToQObject); return *reinterpret_cast*>(variant.constData()); } diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 861cedf..f1053ad 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 >()) & QMetaType::FLAG_TEST); \ + SMARTPOINTER < QObject > extractedPtr = FROMVARIANTFUNCTION(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