summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qpointer.h8
-rw-r--r--src/corelib/tools/qsharedpointer.cpp20
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h20
-rw-r--r--tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp37
-rw-r--r--tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp71
5 files changed, 155 insertions, 1 deletions
diff --git a/src/corelib/kernel/qpointer.h b/src/corelib/kernel/qpointer.h
index 88d8225621..ef1d4dc1d5 100644
--- a/src/corelib/kernel/qpointer.h
+++ b/src/corelib/kernel/qpointer.h
@@ -50,6 +50,7 @@ QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
+class QVariant;
class QPointerBase
{
@@ -184,6 +185,13 @@ inline bool operator!= (int i, const QPointer<T> &p)
{ Q_ASSERT(i == 0); return !i && !p.isNull(); }
#endif
+template<typename T>
+QPointer<T>
+qPointerFromVariant(const QVariant &variant)
+{
+ return QPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).data()));
+}
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp
index 8ca153f433..73a1e6c607 100644
--- a/src/corelib/tools/qsharedpointer.cpp
+++ b/src/corelib/tools/qsharedpointer.cpp
@@ -1214,6 +1214,26 @@ QtSharedPointer::ExternalRefCountData *QtSharedPointer::ExternalRefCountData::ge
return x;
}
+/**
+ \internal
+ Returns a QSharedPointer<QObject> if the variant contains
+ a QSharedPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
+*/
+QSharedPointer<QObject> QtSharedPointer::sharedPointerFromVariant_internal(const QVariant &variant)
+{
+ return *reinterpret_cast<const QSharedPointer<QObject>*>(variant.constData());
+}
+
+/**
+ \internal
+ Returns a QWeakPointer<QObject> if the variant contains
+ a QWeakPointer<T> where T inherits QObject. Otherwise the behaviour is undefined.
+*/
+QWeakPointer<QObject> QtSharedPointer::weakPointerFromVariant_internal(const QVariant &variant)
+{
+ return *reinterpret_cast<const QWeakPointer<QObject>*>(variant.constData());
+}
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 46cd1cc0a7..9d9698b8ca 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -87,6 +87,8 @@ template<typename T> inline void qt_sharedpointer_cast_check(T *) { }
template <class T> class QWeakPointer;
template <class T> class QSharedPointer;
+class QVariant;
+
template <class X, class T>
QSharedPointer<X> qSharedPointerCast(const QSharedPointer<T> &ptr);
template <class X, class T>
@@ -258,6 +260,9 @@ namespace QtSharedPointer {
~ExternalRefCountWithContiguousData() Q_DECL_EQ_DELETE;
Q_DISABLE_COPY(ExternalRefCountWithContiguousData)
};
+
+ Q_CORE_EXPORT QWeakPointer<QObject> weakPointerFromVariant_internal(const QVariant &variant);
+ Q_CORE_EXPORT QSharedPointer<QObject> sharedPointerFromVariant_internal(const QVariant &variant);
} // namespace QtSharedPointer
template <class T> class QSharedPointer
@@ -816,8 +821,21 @@ qobject_cast(const QWeakPointer<T> &src)
{
return qSharedPointerObjectCast<typename QtSharedPointer::RemovePointer<X>::Type, T>(src);
}
-#endif
+template<typename T>
+QWeakPointer<typename QtPrivate::QEnableIf<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::Type>
+qWeakPointerFromVariant(const QVariant &variant)
+{
+ return QWeakPointer<T>(qobject_cast<T*>(QtSharedPointer::weakPointerFromVariant_internal(variant).data()));
+}
+template<typename T>
+QSharedPointer<typename QtPrivate::QEnableIf<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, T>::Type>
+qSharedPointerFromVariant(const QVariant &variant)
+{
+ return qSharedPointerObjectCast<T>(QtSharedPointer::sharedPointerFromVariant_internal(variant));
+}
+
+#endif
template<typename T> Q_DECLARE_TYPEINFO_BODY(QWeakPointer<T>, Q_MOVABLE_TYPE);
template<typename T> Q_DECLARE_TYPEINFO_BODY(QSharedPointer<T>, Q_MOVABLE_TYPE);
diff --git a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp
index 3540df17ac..fd20a1cf5d 100644
--- a/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp
+++ b/tests/auto/corelib/kernel/qpointer/tst_qpointer.cpp
@@ -63,6 +63,8 @@ private slots:
void disconnect();
void castDuringDestruction();
void threadSafety();
+
+ void qvariantCast();
};
void tst_QPointer::constructors()
@@ -348,6 +350,41 @@ void tst_QPointer::threadSafety()
owner.wait();
}
+void tst_QPointer::qvariantCast()
+{
+ QPointer<QFile> tracking = new QFile;
+ tracking->setObjectName("A test name");
+ QVariant v = QVariant::fromValue(tracking);
+
+ {
+ QPointer<QObject> other = qPointerFromVariant<QObject>(v);
+ QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QPointer<QIODevice> other = qPointerFromVariant<QIODevice>(v);
+ QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QPointer<QFile> other = qPointerFromVariant<QFile>(v);
+ QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QPointer<QThread> other = qPointerFromVariant<QThread>(v);
+ QVERIFY(!other);
+ }
+ {
+ QPointer<QFile> toBeDeleted = new QFile;
+ QVariant deletedVariant = QVariant::fromValue(toBeDeleted);
+ delete toBeDeleted;
+ QPointer<QObject> deleted = qPointerFromVariant<QObject>(deletedVariant);
+ QVERIFY(!deleted);
+ }
+
+ // Intentionally does not compile.
+// QPointer<int> sop = qPointerFromVariant<int>(v);
+}
+
+
QTEST_MAIN(tst_QPointer)
#include "tst_qpointer.moc"
diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
index 70caad856b..6896b328d0 100644
--- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
+++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp
@@ -105,6 +105,8 @@ private slots:
void invalidConstructs_data();
void invalidConstructs();
+ void qvariantCast();
+
public slots:
void cleanup() { safetyCheck(); }
@@ -1853,6 +1855,75 @@ void tst_QSharedPointer::invalidConstructs()
}
}
+void tst_QSharedPointer::qvariantCast()
+{
+ QSharedPointer<QFile> sp = QSharedPointer<QFile>::create();
+ sp->setObjectName("A test name");
+ QVariant v = QVariant::fromValue(sp);
+
+ {
+ QSharedPointer<QObject> other = qSharedPointerFromVariant<QObject>(v);
+ QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QSharedPointer<QIODevice> other = qSharedPointerFromVariant<QIODevice>(v);
+ QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QSharedPointer<QFile> other = qSharedPointerFromVariant<QFile>(v);
+ QCOMPARE(other->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QSharedPointer<QThread> other = qSharedPointerFromVariant<QThread>(v);
+ QVERIFY(!other);
+ }
+ // Intentionally does not compile.
+// QSharedPointer<int> sop = qSharedPointerFromVariant<int>(v);
+
+ v = QVariant::fromValue(sp.toWeakRef());
+
+ {
+ QWeakPointer<QObject> other = qWeakPointerFromVariant<QObject>(v);
+ QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QWeakPointer<QIODevice> other = qWeakPointerFromVariant<QIODevice>(v);
+ QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QWeakPointer<QFile> other = qWeakPointerFromVariant<QFile>(v);
+ QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QWeakPointer<QThread> other = qWeakPointerFromVariant<QThread>(v);
+ QVERIFY(!other);
+ }
+
+ // Intentionally does not compile.
+// QWeakPointer<int> sop = qWeakPointerFromVariant<int>(v);
+
+ QWeakPointer<QFile> tracking = new QFile;
+ tracking.data()->setObjectName("A test name");
+ v = QVariant::fromValue(tracking);
+
+ {
+ QWeakPointer<QObject> other = qWeakPointerFromVariant<QObject>(v);
+ QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QWeakPointer<QIODevice> other = qWeakPointerFromVariant<QIODevice>(v);
+ QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QWeakPointer<QFile> other = qWeakPointerFromVariant<QFile>(v);
+ QCOMPARE(other.data()->objectName(), QString::fromLatin1("A test name"));
+ }
+ {
+ QWeakPointer<QThread> other = qWeakPointerFromVariant<QThread>(v);
+ QVERIFY(!other);
+ }
+}
+
namespace ReentrancyWhileDestructing {
struct IB
{