Add constexpr template specializations for built in metatypes.

This will make it possible (in Qt 6) to remove the enums listing
metatype ids. As it is constexpr, it can be used in switch statements
just like enums, as enum values, and as template specialization values.

Change-Id: I51293674c403714e34cb8a8b8953522fc97a740a
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
bb10
Stephen Kelly 2012-07-01 22:55:54 +02:00 committed by Qt by Nokia
parent 2ec9d34df6
commit 13e1e30ec3
2 changed files with 46 additions and 5 deletions

View File

@ -536,17 +536,17 @@ template <typename T>
struct QMetaTypeId2
{
enum { Defined = QMetaTypeId<T>::Defined };
static inline int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
};
namespace QtPrivate {
template <typename T, bool Defined = QMetaTypeId2<T>::Defined>
struct QMetaTypeIdHelper {
static inline int qt_metatype_id()
static inline Q_DECL_CONSTEXPR int qt_metatype_id()
{ return QMetaTypeId2<T>::qt_metatype_id(); }
};
template <typename T> struct QMetaTypeIdHelper<T, false> {
static inline int qt_metatype_id()
static inline Q_DECL_CONSTEXPR int qt_metatype_id()
{ return -1; }
};
@ -624,7 +624,7 @@ void qRegisterMetaTypeStreamOperators(const char *typeName
#endif // QT_NO_DATASTREAM
template <typename T>
inline int qMetaTypeId(
inline Q_DECL_CONSTEXPR int qMetaTypeId(
#ifndef qdoc
T * /* dummy */ = 0
#endif
@ -713,7 +713,7 @@ inline int qRegisterMetaTypeStreamOperators()
template<> struct QMetaTypeId2<TYPE> \
{ \
enum { Defined = 1, MetaType = QMetaType::NAME }; \
static inline int qt_metatype_id() { return QMetaType::NAME; } \
static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaType::NAME; } \
}; \
QT_END_NAMESPACE

View File

@ -107,6 +107,7 @@ private slots:
void saveAndLoadBuiltin();
void saveAndLoadCustom();
void metaObject();
void constexprMetaTypeIds();
};
struct Foo { int i; };
@ -1632,6 +1633,46 @@ void tst_QMetaType::metaObject()
QCOMPARE(QMetaType(QMetaType::Int).metaObject(), static_cast<const QMetaObject *>(0));
}
#define METATYPE_ID_FUNCTION(Type, MetaTypeId, Name) \
case ::qMetaTypeId< Name >(): metaType = MetaTypeIdStruct<MetaTypeId>::Value;
template<int>
struct MetaTypeIdStruct
{
};
#define METATYPE_ID_STRUCT(Type, MetaTypeId, Name) \
template<> \
struct MetaTypeIdStruct< ::qMetaTypeId< Name >()> \
{ \
enum { Value = ::qMetaTypeId< Name >() }; \
};
#if defined(Q_COMPILER_CONSTEXPR)
QT_FOR_EACH_STATIC_TYPE(METATYPE_ID_STRUCT)
template<int i = ::qMetaTypeId<int>()>
struct MetaTypeIdStructDefaultTemplateValue
{
enum { Value };
};
#endif
void tst_QMetaType::constexprMetaTypeIds()
{
int id = 0;
int metaType;
switch(id) {
#if defined(Q_COMPILER_CONSTEXPR)
QT_FOR_EACH_STATIC_TYPE(METATYPE_ID_FUNCTION)
metaType = MetaTypeIdStructDefaultTemplateValue<>::Value;
#endif
default:;
}
Q_UNUSED(metaType);
}
// Compile-time test, it should be possible to register function pointer types
class Undefined;