From 4b8ceb41aed352f10d36db5284453f425dbc5f3f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Fri, 30 Dec 2011 12:00:09 +0100 Subject: Store the is-a QObject fact with the metatype declaration. This is a source incompatible change for Q_DECLARE_METATYPE(T*), which now requires T to be fully defined. The consequences of this are: * Forward declared types can no longer be declared as a metatype. (though this is a very uncommon thing to do). There is a trivial workaround where necessary. Change-Id: Id74c40088b8c0b466fcd7c55abd616f69acc82c8 Reviewed-by: Lars Knoll --- src/corelib/io/qtextstream.h | 7 ++++++ src/corelib/kernel/qmetatype.cpp | 6 +++-- src/corelib/kernel/qmetatype.h | 47 +++++++++++++++++++++++++++++++++++++--- 3 files changed, 55 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h index 329dc4b644..ba25a2b6f2 100644 --- a/src/corelib/io/qtextstream.h +++ b/src/corelib/io/qtextstream.h @@ -208,6 +208,13 @@ typedef QTextStream & (*QTextStreamFunction)(QTextStream &);// manipulator funct typedef void (QTextStream::*QTSMFI)(int); // manipulator w/int argument typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument + +namespace QtPrivate { +template <> struct IsPointerToTypeDerivedFromQObject { + enum { Value = false }; +}; +} + class Q_CORE_EXPORT QTextStreamManipulator { public: diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 44fa450f5f..1c106f4f36 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1670,11 +1670,13 @@ class Flags template::IsAccepted> struct FlagsImpl { - static quint32 Flags(const int) + static quint32 Flags(const int type) { return (!QTypeInfo::isStatic * QMetaType::MovableType) | (QTypeInfo::isComplex * QMetaType::NeedsConstruction) - | (QTypeInfo::isComplex * QMetaType::NeedsDestruction); + | (QTypeInfo::isComplex * QMetaType::NeedsDestruction) + | (type == QMetaType::QObjectStar ? QMetaType::PointerToQObject : 0) + | (type == QMetaType::QWidgetStar ? QMetaType::PointerToQObject : 0); } }; template diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index e81dbb69d1..7c38d1cd13 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -207,7 +207,8 @@ public: enum TypeFlag { NeedsConstruction = 0x1, NeedsDestruction = 0x2, - MovableType = 0x4 + MovableType = 0x4, + PointerToQObject = 0x8 }; Q_DECLARE_FLAGS(TypeFlags, TypeFlag) @@ -315,6 +316,9 @@ struct QMetaTypeId2 static inline int qt_metatype_id() { return QMetaTypeId::qt_metatype_id(); } }; +class QObject; +class QWidget; + namespace QtPrivate { template ::Defined> struct QMetaTypeIdHelper { @@ -325,6 +329,43 @@ namespace QtPrivate { static inline int qt_metatype_id() { return -1; } }; + + template + struct IsPointerToTypeDerivedFromQObject + { + enum { Value = false }; + }; + + // Specialize to avoid sizeof(void) warning + template<> + struct IsPointerToTypeDerivedFromQObject + { + enum { Value = false }; + }; + template<> + struct IsPointerToTypeDerivedFromQObject + { + enum { Value = true }; + }; + template<> + struct IsPointerToTypeDerivedFromQObject + { + enum { Value = true }; + }; + + template + struct IsPointerToTypeDerivedFromQObject + { + typedef qint8 yes_type; + typedef qint64 no_type; + +#ifndef QT_NO_QOBJECT + static yes_type checkType(QObject* ); +#endif + static no_type checkType(...); + Q_STATIC_ASSERT_X(sizeof(T), "Type argument of Q_DECLARE_METATYPE(T*) must be fully defined"); + enum { Value = sizeof(checkType(static_cast(0))) == sizeof(yes_type) }; + }; } template @@ -354,6 +395,8 @@ int qRegisterMetaType(const char *typeName flags |= QMetaType::NeedsConstruction; flags |= QMetaType::NeedsDestruction; } + if (QtPrivate::IsPointerToTypeDerivedFromQObject::Value) + flags |= QMetaType::PointerToQObject; return QMetaType::registerType(typeName, reinterpret_cast(dptr), reinterpret_cast(cptr), @@ -459,8 +502,6 @@ QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER) #undef QT_FORWARD_DECLARE_STATIC_TYPES_ITER -class QWidget; -class QObject; template class QList; template class QMap; template class QHash; -- cgit v1.2.3