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 > \ } \ }; +namespace QtPrivate { + +template +struct SharedPointerMetaTypeIdHelper +{ + enum { + Defined = 0 + }; + static int qt_metatype_id() + { + return -1; + } +}; + +} + #define Q_DECLARE_SMART_POINTER_METATYPE(SMART_POINTER) \ -template \ -struct QMetaTypeId< SMART_POINTER > \ +QT_BEGIN_NAMESPACE \ +namespace QtPrivate { \ +template \ +struct SharedPointerMetaTypeIdHelper, true> \ { \ enum { \ - Defined = QtPrivate::IsPointerToTypeDerivedFromQObject::Value \ + Defined = 1 \ }; \ - static \ - typename QtPrivate::QEnableIf::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 > \ metatype_id.storeRelease(newId); \ return newId; \ } \ +}; \ +} \ +template \ +struct QMetaTypeId< SMART_POINTER > \ + : QtPrivate::SharedPointerMetaTypeIdHelper< SMART_POINTER, \ + QtPrivate::IsPointerToTypeDerivedFromQObject::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 +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) + void tst_QVariant::qvariant_cast_QObject_wrapper() { QMetaType::registerConverter(&QObjectWrapper::getObject); @@ -2270,6 +2292,10 @@ void tst_QVariant::qvariant_cast_QObject_wrapper() v.convert(qMetaTypeId()); QCOMPARE(v.value(), object); + // Compile tests: + qRegisterMetaType >(); + // Not declared as a metatype: + qRegisterMetaType >("MyNS::SmartPointer"); } void tst_QVariant::convertToQUint8() const