summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qmetatype.h40
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp26
2 files changed, 60 insertions, 6 deletions
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 5ce3f26b53..80c1f21c0d 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -1789,16 +1789,32 @@ struct QMetaTypeId< DOUBLE_ARG_TEMPLATE<T, U> > \
} \
};
+namespace QtPrivate {
+
+template<typename T, bool /* isSharedPointerToQObjectDerived */ = false>
+struct SharedPointerMetaTypeIdHelper
+{
+ enum {
+ Defined = 0
+ };
+ static int qt_metatype_id()
+ {
+ return -1;
+ }
+};
+
+}
+
#define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \
-template <typename T> \
-struct QMetaTypeId< SMART_POINTER<T> > \
+QT_BEGIN_NAMESPACE \
+namespace QtPrivate { \
+template<typename T> \
+struct SharedPointerMetaTypeIdHelper<SMART_POINTER<T>, true> \
{ \
enum { \
- Defined = QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value \
+ Defined = 1 \
}; \
- static \
- typename QtPrivate::QEnableIf<QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value, int>::Type \
- qt_metatype_id() \
+ static int qt_metatype_id() \
{ \
static QBasicAtomicInt metatype_id = Q_BASIC_ATOMIC_INITIALIZER(0); \
if (const int id = metatype_id.loadAcquire()) \
@@ -1814,7 +1830,15 @@ struct QMetaTypeId< SMART_POINTER<T> > \
metatype_id.storeRelease(newId); \
return newId; \
} \
+}; \
+} \
+template <typename T> \
+struct QMetaTypeId< SMART_POINTER<T> > \
+ : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER<T>, \
+ QtPrivate::IsPointerToTypeDerivedFromQObject<T*>::Value> \
+{ \
};\
+QT_END_NAMESPACE \
#define QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(F) \
F(QSharedPointer) \
@@ -1846,8 +1870,12 @@ Q_DECLARE_METATYPE_TEMPLATE_2ARG(std::map)
#define Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER(TEMPLATENAME) \
Q_DECLARE_SMART_POINTER_METATYPE(TEMPLATENAME)
+QT_END_NAMESPACE
+
QT_FOR_EACH_AUTOMATIC_TEMPLATE_SMART_POINTER(Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER)
+QT_BEGIN_NAMESPACE
+
#undef Q_DECLARE_METATYPE_TEMPLATE_SMART_POINTER_ITER
inline QMetaType::QMetaType(const ExtensionFlag extensionFlags, const QMetaTypeInterface *info,
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index 6baf6c4310..0b50bc7576 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -2259,6 +2259,28 @@ struct Converter
}
};
+namespace MyNS {
+
+template<typename T>
+class SmartPointer
+{
+ T* pointer;
+public:
+ typedef T element_type;
+ explicit SmartPointer(T *t = 0)
+ : pointer(t)
+ {
+ }
+
+ T* operator->() const { return pointer; }
+};
+
+}
+
+Q_DECLARE_SMART_POINTER_METATYPE(MyNS::SmartPointer)
+
+Q_DECLARE_METATYPE(MyNS::SmartPointer<int>)
+
void tst_QVariant::qvariant_cast_QObject_wrapper()
{
QMetaType::registerConverter<QObjectWrapper, QObject*>(&QObjectWrapper::getObject);
@@ -2270,6 +2292,10 @@ void tst_QVariant::qvariant_cast_QObject_wrapper()
v.convert(qMetaTypeId<QObject*>());
QCOMPARE(v.value<QObject*>(), object);
+ // Compile tests:
+ qRegisterMetaType<MyNS::SmartPointer<int> >();
+ // Not declared as a metatype:
+ qRegisterMetaType<MyNS::SmartPointer<double> >("MyNS::SmartPointer<double>");
}
void tst_QVariant::convertToQUint8() const