Fix the automatic declaration of smart pointer types.

Before this patch,

 qRegisterMetaType<QSharedPointer<double> >("QSharedPointer<double>")

without a metatype declaration fails to compile, whereas it works
with Qt 5.1 (ie, before commit e9a69c3ba9)

Change-Id: I9408f711c9df810ff29b879b7696dab81c1160f1
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
This commit is contained in:
Stephen Kelly 2013-09-05 18:03:44 +02:00 committed by The Qt Project
parent 87ff0af425
commit 2ff15ff065
2 changed files with 60 additions and 6 deletions

View File

@ -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,

View File

@ -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