Introduce Q_DECLARE_OPAQUE_POINTER
authorJoão Abecasis <joao.abecasis@nokia.com>
Tue, 31 Jan 2012 16:35:00 +0000 (17:35 +0100)
committerQt by Nokia <qt-info@nokia.com>
Wed, 8 Feb 2012 23:32:41 +0000 (00:32 +0100)
To hide the IsPointerToTypeDerivedFromQObject monstruosity :-)

Documentation for Q_DECLARE_METATYPE and qRegisterMetaType was updated
to mention requirements on registered types and how they can be
circumvented for pointer types with the new macro.

Change-Id: If83b037a8e2f28761eb903525e87008107298801
Reviewed-by: Harald Fernengel <harald.fernengel@nokia.com>
Reviewed-by: Stephen Kelly <stephen.kelly@kdab.com>
src/corelib/kernel/qmetatype.cpp
src/corelib/kernel/qmetatype.h
src/sql/drivers/psql/qsql_psql.cpp
src/sql/drivers/sqlite/qsql_sqlite.cpp
src/sql/drivers/sqlite2/qsql_sqlite2.cpp
src/sql/drivers/tds/qsql_tds.cpp
tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp

index 6a7c5c2..d965c48 100644 (file)
@@ -116,6 +116,16 @@ template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = fals
 #endif
 } // namespace
 
+/*!
+    \macro Q_DECLARE_OPAQUE_POINTER(Pointer)
+    \relates QMetaType
+
+    This macro enables pointers to forward-declared types to be registered with
+    QMetaType using either Q_DECLARE_METATYPE() or qRegisterMetaType().
+
+    \sa Q_DECLARE_METATYPE(), qRegisterMetaType()
+
+*/
 
 /*!
     \macro Q_DECLARE_METATYPE(Type)
@@ -126,6 +136,11 @@ template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = fals
     a public destructor.
     It is needed to use the type \a Type as a custom type in QVariant.
 
+    This macro requires that \a Type is a fully defined type at the point where
+    it is used. For pointer types, it also requires that the pointed to type is
+    fully defined. Use in conjunction with Q_DECLARE_OPAQUE_POINTER() to
+    register pointers to forward declared types.
+
     Ideally, this macro should be placed below the declaration of
     the class or struct. If that is not possible, it can be put in
     a private header file which has to be included every time that
@@ -1630,6 +1645,11 @@ QMetaType::TypeFlags QMetaType::typeFlags(int type)
     public default constructor, a public copy constructor and a public
     destructor can be registered.
 
+    This function requires that \c{T} is a fully defined type at the point
+    where the function is called. For pointer types, it also requires that the
+    pointed to type is fully defined. Use Q_DECLARE_OPAQUE_POINTER() to be able
+    to register pointers to forward declared types.
+
     After a type has been registered, you can create and destroy
     objects of that type dynamically at run-time.
 
index fd27bb8..9e70229 100644 (file)
@@ -471,6 +471,16 @@ inline int qRegisterMetaTypeStreamOperators()
 }
 #endif
 
+#define Q_DECLARE_OPAQUE_POINTER(POINTER)                               \
+    QT_BEGIN_NAMESPACE namespace QtPrivate {                            \
+        template <>                                                     \
+        struct IsPointerToTypeDerivedFromQObject<POINTER >              \
+        {                                                               \
+            enum { Value = false };                                     \
+        };                                                              \
+    } QT_END_NAMESPACE                                                  \
+    /**/
+
 #define Q_DECLARE_METATYPE(TYPE)                                        \
     QT_BEGIN_NAMESPACE                                                  \
     template <>                                                         \
index e353358..ec31d54 100644 (file)
 template <typename T>
 inline void PQfreemem(T *t, int = 0) { free(t); }
 
-QT_BEGIN_NAMESPACE namespace QtPrivate {
-template <> struct IsPointerToTypeDerivedFromQObject<PGconn*> {
-    enum { Value = false };
-};
-} QT_END_NAMESPACE
+Q_DECLARE_OPAQUE_POINTER(PGconn*)
 Q_DECLARE_METATYPE(PGconn*)
 
-QT_BEGIN_NAMESPACE namespace QtPrivate {
-template <> struct IsPointerToTypeDerivedFromQObject<PGresult*> {
-    enum { Value = false };
-};
-} QT_END_NAMESPACE
+Q_DECLARE_OPAQUE_POINTER(PGresult*)
 Q_DECLARE_METATYPE(PGresult*)
 
 QT_BEGIN_NAMESPACE
index 962fc97..d2dc5af 100644 (file)
 
 #include <sqlite3.h>
 
-QT_BEGIN_NAMESPACE namespace QtPrivate {
-template <> struct IsPointerToTypeDerivedFromQObject<sqlite3*> {
-    enum { Value = false };
-};
-} QT_END_NAMESPACE
+Q_DECLARE_OPAQUE_POINTER(sqlite3*)
 Q_DECLARE_METATYPE(sqlite3*)
 
-QT_BEGIN_NAMESPACE namespace QtPrivate {
-template <> struct IsPointerToTypeDerivedFromQObject<sqlite3_stmt*> {
-    enum { Value = false };
-};
-} QT_END_NAMESPACE
+Q_DECLARE_OPAQUE_POINTER(sqlite3_stmt*)
 Q_DECLARE_METATYPE(sqlite3_stmt*)
 
 QT_BEGIN_NAMESPACE
index 4612792..b42f82e 100644 (file)
 
 typedef struct sqlite_vm sqlite_vm;
 
-QT_BEGIN_NAMESPACE namespace QtPrivate {
-template <> struct IsPointerToTypeDerivedFromQObject<sqlite_vm*> {
-    enum { Value = false };
-};
-template <> struct IsPointerToTypeDerivedFromQObject<sqlite*> {
-    enum { Value = false };
-};
-} QT_END_NAMESPACE
+Q_DECLARE_OPAQUE_POINTER(sqlite_vm*)
 Q_DECLARE_METATYPE(sqlite_vm*)
+
+Q_DECLARE_OPAQUE_POINTER(sqlite*)
 Q_DECLARE_METATYPE(sqlite*)
 
 QT_BEGIN_NAMESPACE
index 2a97a3c..b941449 100644 (file)
@@ -63,6 +63,9 @@
 
 #include <stdlib.h>
 
+Q_DECLARE_OPAQUE_POINTER(LOGINREC*)
+Q_DECLARE_OPAQUE_POINTER(DBPROCESS*)
+
 QT_BEGIN_NAMESPACE
 
 #ifdef DBNTWIN32
@@ -127,18 +130,6 @@ QT_BEGIN_NAMESPACE
 #define CS_PUBLIC
 #endif
 
-namespace QtPrivate {
-template <> struct IsPointerToTypeDerivedFromQObject<LOGINREC*> {
-    enum { Value = false };
-};
-}
-
-namespace QtPrivate {
-template <> struct IsPointerToTypeDerivedFromQObject<DBPROCESS*> {
-    enum { Value = false };
-};
-}
-
 QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, int errNo = -1)
 {
     return QSqlError(QLatin1String("QTDS: ") + err, QString(), type, errNo);
index 6991134..001749e 100644 (file)
@@ -3451,12 +3451,8 @@ void tst_QVariant::colorInteger()
 }
 
 class Forward;
-QT_BEGIN_NAMESPACE namespace QtPrivate {
-template <> struct IsPointerToTypeDerivedFromQObject<Forward*> {
-    enum { Value = false };
-};
-} QT_END_NAMESPACE
-Q_DECLARE_METATYPE(Forward*);
+Q_DECLARE_OPAQUE_POINTER(Forward*)
+Q_DECLARE_METATYPE(Forward*)
 
 void tst_QVariant::forwardDeclare()
 {