Introduce QTypeInfoMerger.
authorJędrzej Nowacki <jedrzej.nowacki@nokia.com>
Mon, 4 Jun 2012 14:52:32 +0000 (16:52 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 27 Jul 2012 01:27:27 +0000 (03:27 +0200)
QTypeInfoMerger class was created to allow "inheriting" QTypeInfo
traits. The class implementation was based on the QTypeInfo<QPair<>>
specialization, therefore the specialization was refactored to
use the new class.

Change-Id: I4ff3e5eac1d55da086dad84274cce2b2c0a721be
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
src/corelib/doc/snippets/code/src_corelib_global_qglobal.cpp
src/corelib/global/qtypeinfo.h
src/corelib/tools/qpair.h

index dc6c3aa..8feac30 100644 (file)
@@ -538,6 +538,20 @@ CApaApplication *myApplicationFactory();
 void myMessageHandler(QtMsgType, const QMessageLogContext &, const char *);
 //! [49]
 
+//! [50]
+class B {...};
+class C {...};
+class D {...};
+struct A : public B {
+    C c;
+    D d;
+};
+//! [50]
+
+//! [51]
+template<> class QTypeInfo<A> : public QTypeInfoMerger<A, B, C, D> {};
+//! [51]
+
 //! [qlikely]
     // the condition inside the "if" will be successful most of the times
     for (int i = 1; i <= 365; i++) {
index 4255548..e8aa883 100644 (file)
@@ -97,6 +97,38 @@ public:
     };
 };
 
+/*!
+    \class QTypeInfoMerger
+    \internal
+
+    \brief QTypeInfoMerger merges the QTypeInfo flags of T1, T2... and presents them
+    as a QTypeInfo<T> would do.
+
+    Let's assume that we have a simple set of structs:
+
+    \snippet code/src_corelib_global_qglobal.cpp 50
+
+    To create a proper QTypeInfo specialization for A struct, we have to check
+    all sub-components; B, C and D, then take the lowest common denominator and call
+    Q_DECLATE_TYPEINFO with the resulting flags. An easier and less fragile approach is to
+    use QTypeInfoMerger, which does that automatically. So struct A would have
+    the following QTypeInfo definition:
+
+    \snippet code/src_corelib_global_qglobal.cpp 51
+*/
+template <class T, class T1, class T2 = T1, class T3 = T1, class T4 = T1>
+class QTypeInfoMerger
+{
+public:
+    enum {
+        isComplex = QTypeInfo<T1>::isComplex || QTypeInfo<T2>::isComplex || QTypeInfo<T3>::isComplex || QTypeInfo<T4>::isComplex,
+        isStatic = QTypeInfo<T1>::isStatic || QTypeInfo<T2>::isStatic || QTypeInfo<T3>::isStatic || QTypeInfo<T4>::isStatic,
+        isLarge = sizeof(T) > sizeof(void*),
+        isPointer = false,
+        isDummy = false,
+        sizeOf = sizeof(T)
+    };
+};
 
 #define Q_DECLARE_MOVABLE_CONTAINER(CONTAINER) \
 template <typename T> class CONTAINER; \
index f845533..b73bf67 100644 (file)
@@ -66,18 +66,7 @@ struct QPair
 // mark QPair<T1,T2> as complex/movable/primitive depending on the
 // typeinfos of the constituents:
 template<class T1, class T2>
-class QTypeInfo< QPair<T1, T2> >
-{
-public:
-    enum {
-        isComplex = QTypeInfo<T1>::isComplex || QTypeInfo<T2>::isComplex,
-        isStatic  = QTypeInfo<T1>::isStatic  || QTypeInfo<T2>::isStatic,
-        isLarge   = sizeof(QPair<T1, T2>) > sizeof(void*),
-        isPointer = false,
-        isDummy   = false,
-        sizeOf    = sizeof(QPair<T1, T2>)
-    };
-};
+class QTypeInfo<QPair<T1, T2> > : public QTypeInfoMerger<QPair<T1, T2>, T1, T2> {}; // Q_DECLARE_TYPEINFO
 
 template <class T1, class T2>
 Q_INLINE_TEMPLATE bool operator==(const QPair<T1, T2> &p1, const QPair<T1, T2> &p2)