Introduce Q_DECLARE_OPAQUE_POINTER

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>
This commit is contained in:
João Abecasis 2012-01-31 17:35:00 +01:00 committed by Qt by Nokia
parent 14577726ee
commit 0c97840708
7 changed files with 42 additions and 46 deletions

View File

@ -116,6 +116,16 @@ template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = fals
#endif #endif
} // namespace } // 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) \macro Q_DECLARE_METATYPE(Type)
@ -126,6 +136,11 @@ template<> struct TypeDefinition<QRegExp> { static const bool IsAvailable = fals
a public destructor. a public destructor.
It is needed to use the type \a Type as a custom type in QVariant. 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 Ideally, this macro should be placed below the declaration of
the class or struct. If that is not possible, it can be put in 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 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 public default constructor, a public copy constructor and a public
destructor can be registered. 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 After a type has been registered, you can create and destroy
objects of that type dynamically at run-time. objects of that type dynamically at run-time.

View File

@ -471,6 +471,16 @@ inline int qRegisterMetaTypeStreamOperators()
} }
#endif #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) \ #define Q_DECLARE_METATYPE(TYPE) \
QT_BEGIN_NAMESPACE \ QT_BEGIN_NAMESPACE \
template <> \ template <> \

View File

@ -107,18 +107,10 @@
template <typename T> template <typename T>
inline void PQfreemem(T *t, int = 0) { free(t); } inline void PQfreemem(T *t, int = 0) { free(t); }
QT_BEGIN_NAMESPACE namespace QtPrivate { Q_DECLARE_OPAQUE_POINTER(PGconn*)
template <> struct IsPointerToTypeDerivedFromQObject<PGconn*> {
enum { Value = false };
};
} QT_END_NAMESPACE
Q_DECLARE_METATYPE(PGconn*) Q_DECLARE_METATYPE(PGconn*)
QT_BEGIN_NAMESPACE namespace QtPrivate { Q_DECLARE_OPAQUE_POINTER(PGresult*)
template <> struct IsPointerToTypeDerivedFromQObject<PGresult*> {
enum { Value = false };
};
} QT_END_NAMESPACE
Q_DECLARE_METATYPE(PGresult*) Q_DECLARE_METATYPE(PGresult*)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -59,18 +59,10 @@
#include <sqlite3.h> #include <sqlite3.h>
QT_BEGIN_NAMESPACE namespace QtPrivate { Q_DECLARE_OPAQUE_POINTER(sqlite3*)
template <> struct IsPointerToTypeDerivedFromQObject<sqlite3*> {
enum { Value = false };
};
} QT_END_NAMESPACE
Q_DECLARE_METATYPE(sqlite3*) Q_DECLARE_METATYPE(sqlite3*)
QT_BEGIN_NAMESPACE namespace QtPrivate { Q_DECLARE_OPAQUE_POINTER(sqlite3_stmt*)
template <> struct IsPointerToTypeDerivedFromQObject<sqlite3_stmt*> {
enum { Value = false };
};
} QT_END_NAMESPACE
Q_DECLARE_METATYPE(sqlite3_stmt*) Q_DECLARE_METATYPE(sqlite3_stmt*)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -60,15 +60,10 @@
typedef struct sqlite_vm sqlite_vm; typedef struct sqlite_vm sqlite_vm;
QT_BEGIN_NAMESPACE namespace QtPrivate { Q_DECLARE_OPAQUE_POINTER(sqlite_vm*)
template <> struct IsPointerToTypeDerivedFromQObject<sqlite_vm*> {
enum { Value = false };
};
template <> struct IsPointerToTypeDerivedFromQObject<sqlite*> {
enum { Value = false };
};
} QT_END_NAMESPACE
Q_DECLARE_METATYPE(sqlite_vm*) Q_DECLARE_METATYPE(sqlite_vm*)
Q_DECLARE_OPAQUE_POINTER(sqlite*)
Q_DECLARE_METATYPE(sqlite*) Q_DECLARE_METATYPE(sqlite*)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -63,6 +63,9 @@
#include <stdlib.h> #include <stdlib.h>
Q_DECLARE_OPAQUE_POINTER(LOGINREC*)
Q_DECLARE_OPAQUE_POINTER(DBPROCESS*)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifdef DBNTWIN32 #ifdef DBNTWIN32
@ -127,18 +130,6 @@ QT_BEGIN_NAMESPACE
#define CS_PUBLIC #define CS_PUBLIC
#endif #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) QSqlError qMakeError(const QString& err, QSqlError::ErrorType type, int errNo = -1)
{ {
return QSqlError(QLatin1String("QTDS: ") + err, QString(), type, errNo); return QSqlError(QLatin1String("QTDS: ") + err, QString(), type, errNo);

View File

@ -3451,12 +3451,8 @@ void tst_QVariant::colorInteger()
} }
class Forward; class Forward;
QT_BEGIN_NAMESPACE namespace QtPrivate { Q_DECLARE_OPAQUE_POINTER(Forward*)
template <> struct IsPointerToTypeDerivedFromQObject<Forward*> { Q_DECLARE_METATYPE(Forward*)
enum { Value = false };
};
} QT_END_NAMESPACE
Q_DECLARE_METATYPE(Forward*);
void tst_QVariant::forwardDeclare() void tst_QVariant::forwardDeclare()
{ {