QMetaTypeId2::IsBuiltIn: (new) template meta-function to check for built-in types
authorMarc Mutz <marc.mutz@kdab.com>
Fri, 20 Jul 2012 13:46:40 +0000 (15:46 +0200)
committerQt by Nokia <qt-info@nokia.com>
Thu, 26 Jul 2012 13:01:04 +0000 (15:01 +0200)
This allows to check whether QMetaTypeId2::MetaType exists, and can help
turn run-time into compile-time expressions, even without constexpr support,
or in situations where constexpr can't be used (because you can't overload
on it). This was designed for the QMetaType::registerConversion feature,
but it's much more widely applicable.

Change-Id: Iafa04add04bcb531b3f7fe3e751c7e91ee6a3bc0
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
src/corelib/kernel/qmetatype.h
tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
tests/auto/gui/kernel/qguimetatype/tst_qguimetatype.cpp
tests/auto/widgets/kernel/qwidgetmetatype/tst_qwidgetmetatype.cpp

index 6fc8333..7c3cae6 100644 (file)
@@ -539,7 +539,7 @@ struct QMetaTypeId : public QMetaTypeIdQObject<T>
 template <typename T>
 struct QMetaTypeId2
 {
-    enum { Defined = QMetaTypeId<T>::Defined };
+    enum { Defined = QMetaTypeId<T>::Defined, IsBuiltIn=false };
     static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
 };
 
@@ -717,7 +717,7 @@ inline int qRegisterMetaTypeStreamOperators()
     QT_BEGIN_NAMESPACE \
     template<> struct QMetaTypeId2<NAME> \
     { \
-        enum { Defined = 1, MetaType = METATYPEID }; \
+        enum { Defined = 1, IsBuiltIn = true, MetaType = METATYPEID };   \
         static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return METATYPEID; } \
     }; \
     QT_END_NAMESPACE
index 8247385..b251761 100644 (file)
@@ -383,6 +383,25 @@ void tst_QMetaType::typeName()
     FOR_EACH_PRIMITIVE_METATYPE(F) \
     FOR_EACH_COMPLEX_CORE_METATYPE(F) \
 
+namespace {
+    template <typename T>
+    struct static_assert_trigger {
+        Q_STATIC_ASSERT(( QMetaTypeId2<T>::IsBuiltIn ));
+        enum { value = true };
+    };
+}
+
+#define CHECK_BUILTIN(MetaTypeName, MetaTypeId, RealType) static_assert_trigger< RealType >::value &&
+Q_STATIC_ASSERT(( FOR_EACH_CORE_METATYPE(CHECK_BUILTIN) true ));
+#undef CHECK_BUILTIN
+Q_STATIC_ASSERT(( QMetaTypeId2<QList<QVariant> >::IsBuiltIn));
+Q_STATIC_ASSERT(( QMetaTypeId2<QMap<QString,QVariant> >::IsBuiltIn));
+Q_STATIC_ASSERT(( QMetaTypeId2<QObject*>::IsBuiltIn));
+Q_STATIC_ASSERT((!QMetaTypeId2<tst_QMetaType*>::IsBuiltIn)); // QObject subclass
+Q_STATIC_ASSERT((!QMetaTypeId2<QList<int> >::IsBuiltIn));
+Q_STATIC_ASSERT((!QMetaTypeId2<QMap<int,int> >::IsBuiltIn));
+Q_STATIC_ASSERT((!QMetaTypeId2<QMetaType::Type>::IsBuiltIn));
+
 template <int ID>
 struct MetaEnumToType {};
 
index 0514eaf..fae9995 100644 (file)
@@ -87,6 +87,20 @@ private slots:
     F(QVector4D, QVector4D) \
     F(QQuaternion, QQuaternion)
 
+namespace {
+    template <typename T>
+    struct static_assert_trigger {
+        Q_STATIC_ASSERT(( QMetaTypeId2<T>::IsBuiltIn ));
+        enum { value = true };
+    };
+}
+
+#define CHECK_BUILTIN(TYPE, ID) static_assert_trigger< TYPE >::value &&
+Q_STATIC_ASSERT(( FOR_EACH_GUI_METATYPE(CHECK_BUILTIN) true ));
+#undef CHECK_BUILTIN
+Q_STATIC_ASSERT((!QMetaTypeId2<QList<QPen> >::IsBuiltIn));
+Q_STATIC_ASSERT((!QMetaTypeId2<QMap<QString,QPen> >::IsBuiltIn));
+
 template <int ID>
 struct MetaEnumToType {};
 
index 9d2fd14..f92a4fd 100644 (file)
@@ -67,6 +67,12 @@ public:
   }
 };
 
+Q_STATIC_ASSERT(( QMetaTypeId2<QSizePolicy>::IsBuiltIn));
+Q_STATIC_ASSERT(( QMetaTypeId2<QWidget*>::IsBuiltIn));
+Q_STATIC_ASSERT((!QMetaTypeId2<QList<QSizePolicy> >::IsBuiltIn));
+Q_STATIC_ASSERT((!QMetaTypeId2<QMap<QString,QSizePolicy> >::IsBuiltIn));
+
+
 void tst_QWidgetMetaType::metaObject()
 {
     QCOMPARE(QMetaType::metaObjectForType(QMetaType::QWidgetStar), &QWidget::staticMetaObject);