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<T> is inserted into a QVariant. Change-Id: I29e12b8a6aa5f4aadbd62f92b89bc238f64b5725 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
This commit is contained in:
parent
668efc29fd
commit
579ea489a4
3
dist/changes-5.0.0
vendored
3
dist/changes-5.0.0
vendored
@ -168,6 +168,9 @@ information about a particular change.
|
|||||||
* Q_DECLARE_METATYPE(Foo*) now requires that Foo is fully defined. In
|
* Q_DECLARE_METATYPE(Foo*) now requires that Foo is fully defined. In
|
||||||
cases where a forward declared type should be used as a metatype,
|
cases where a forward declared type should be used as a metatype,
|
||||||
Q_DECLARE_OPAQUE_POINTER(Foo*) can be used to allow that.
|
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
|
- QItemEditorFactory
|
||||||
|
|
||||||
|
@ -247,7 +247,10 @@ public:
|
|||||||
NeedsDestruction = 0x2,
|
NeedsDestruction = 0x2,
|
||||||
MovableType = 0x4,
|
MovableType = 0x4,
|
||||||
PointerToQObject = 0x8,
|
PointerToQObject = 0x8,
|
||||||
IsEnumeration = 0x10
|
IsEnumeration = 0x10,
|
||||||
|
SharedPointerToQObject = 0x20,
|
||||||
|
WeakPointerToQObject = 0x40,
|
||||||
|
TrackingPointerToQObject = 0x80
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
|
Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
|
||||||
|
|
||||||
@ -415,6 +418,9 @@ template <> inline void qMetaTypeLoadHelper<void>(QDataStream &, void *) {}
|
|||||||
|
|
||||||
class QObject;
|
class QObject;
|
||||||
class QWidget;
|
class QWidget;
|
||||||
|
template <class T> class QSharedPointer;
|
||||||
|
template <class T> class QWeakPointer;
|
||||||
|
template <class T> class QPointer;
|
||||||
|
|
||||||
namespace QtPrivate
|
namespace QtPrivate
|
||||||
{
|
{
|
||||||
@ -465,6 +471,40 @@ namespace QtPrivate
|
|||||||
{
|
{
|
||||||
static inline const QMetaObject *value() { return &T::staticMetaObject; }
|
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>
|
template <typename T, bool = QtPrivate::IsPointerToTypeDerivedFromQObject<T>::Value>
|
||||||
@ -511,6 +551,9 @@ namespace QtPrivate {
|
|||||||
| (QTypeInfo<T>::isComplex ? QMetaType::NeedsConstruction : 0)
|
| (QTypeInfo<T>::isComplex ? QMetaType::NeedsConstruction : 0)
|
||||||
| (QTypeInfo<T>::isComplex ? QMetaType::NeedsDestruction : 0)
|
| (QTypeInfo<T>::isComplex ? QMetaType::NeedsDestruction : 0)
|
||||||
| (IsPointerToTypeDerivedFromQObject<T>::Value ? QMetaType::PointerToQObject : 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)
|
| (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 QQueue;
|
||||||
template <class T> class QStack;
|
template <class T> class QStack;
|
||||||
template <class T> class QSet;
|
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 QMap;
|
||||||
template <class T1, class T2> class QHash;
|
template <class T1, class T2> class QHash;
|
||||||
template <class T1, class T2> struct QPair;
|
template <class T1, class T2> struct QPair;
|
||||||
|
@ -1221,6 +1221,7 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
|
|||||||
*/
|
*/
|
||||||
QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
|
QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
|
||||||
{
|
{
|
||||||
|
Q_ASSERT(QMetaType::typeFlags(variant.userType()) & QMetaType::SharedPointerToQObject);
|
||||||
return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
|
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)
|
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());
|
return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1462,30 +1462,33 @@ void tst_QMetaType::automaticTemplateRegistration()
|
|||||||
|
|
||||||
#endif // Q_COMPILER_VARIADIC_MACROS
|
#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); \
|
SMARTPOINTER < ELEMENT_TYPE > sp(new ELEMENT_TYPE); \
|
||||||
|
sp.data()->setObjectName("Test name"); \
|
||||||
QVariant v = QVariant::fromValue(sp); \
|
QVariant v = QVariant::fromValue(sp); \
|
||||||
QCOMPARE(v.typeName(), #SMARTPOINTER "<" #ELEMENT_TYPE ">"); \
|
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, QObject, SharedPointerToQObject, qSharedPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QSharedPointer, QFile)
|
TEST_SMARTPOINTER(QSharedPointer, QFile, SharedPointerToQObject, qSharedPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QSharedPointer, QTemporaryFile)
|
TEST_SMARTPOINTER(QSharedPointer, QTemporaryFile, SharedPointerToQObject, qSharedPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QSharedPointer, MyObject)
|
TEST_SMARTPOINTER(QSharedPointer, MyObject, SharedPointerToQObject, qSharedPointerFromVariant)
|
||||||
|
|
||||||
TEST_SMARTPOINTER(QWeakPointer, QObject)
|
TEST_SMARTPOINTER(QWeakPointer, QObject, WeakPointerToQObject, qWeakPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QWeakPointer, QFile)
|
TEST_SMARTPOINTER(QWeakPointer, QFile, WeakPointerToQObject, qWeakPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QWeakPointer, QTemporaryFile)
|
TEST_SMARTPOINTER(QWeakPointer, QTemporaryFile, WeakPointerToQObject, qWeakPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QWeakPointer, MyObject)
|
TEST_SMARTPOINTER(QWeakPointer, MyObject, WeakPointerToQObject, qWeakPointerFromVariant)
|
||||||
|
|
||||||
TEST_SMARTPOINTER(QPointer, QObject)
|
TEST_SMARTPOINTER(QPointer, QObject, TrackingPointerToQObject, qPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QPointer, QFile)
|
TEST_SMARTPOINTER(QPointer, QFile, TrackingPointerToQObject, qPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QPointer, QTemporaryFile)
|
TEST_SMARTPOINTER(QPointer, QTemporaryFile, TrackingPointerToQObject, qPointerFromVariant)
|
||||||
TEST_SMARTPOINTER(QPointer, MyObject)
|
TEST_SMARTPOINTER(QPointer, MyObject, TrackingPointerToQObject, qPointerFromVariant)
|
||||||
|
|
||||||
#undef TEST_SMARTPOINTER
|
#undef TEST_SMARTPOINTER
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
Loading…
Reference in New Issue
Block a user