Reimplement some QMetaType methods.

Methods of QMetaType; sizeOf, construct and destruct were reimplement
using QMetaTypeSwitcher. The change should have impact only on
maintenance (by removing 3 type switches).

Change-Id: Iac3eb52de75d46f12ac32f229a26aec5b5bc7af2
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Jędrzej Nowacki 2011-11-01 12:58:42 +01:00 committed by Qt by Nokia
parent 7c670aa88b
commit e70457fc4f

View File

@ -40,6 +40,7 @@
****************************************************************************/
#include "qmetatype.h"
#include "qmetatype_p.h"
#include "qobjectdefs.h"
#include "qdatetime.h"
#include "qbytearray.h"
@ -50,6 +51,7 @@
#include "qlocale.h"
#include "qeasingcurve.h"
#include "qvariant.h"
#include "qmetatypeswitcher_p.h"
#ifdef QT_BOOTSTRAPPED
# ifndef QT_NO_GEOM_VARIANT
@ -72,6 +74,46 @@ QT_BEGIN_NAMESPACE
#define NS(x) QT_PREPEND_NAMESPACE(x)
namespace {
template<typename T>
struct TypeDefiniton {
static const bool IsAvailable = true;
};
struct DefinedTypesFilter {
template<typename T>
struct Acceptor {
static const bool IsAccepted = TypeDefiniton<T>::IsAvailable && QTypeModuleInfo<T>::IsCore;
};
};
// Ignore these types, as incomplete
#ifdef QT_NO_GEOM_VARIANT
template<> struct TypeDefiniton<QRect> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QRectF> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QSize> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QSizeF> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QLine> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QLineF> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QPoint> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QPointF> { static const bool IsAvailable = false; };
#endif
#ifdef QT_BOOTSTRAPPED
template<> struct TypeDefiniton<QVariantMap> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QVariantHash> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QVariantList> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QVariant> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QBitArray> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QUrl> { static const bool IsAvailable = false; };
template<> struct TypeDefiniton<QEasingCurve> { static const bool IsAvailable = false; };
#endif
#ifdef QT_NO_REGEXP
template<> struct TypeDefiniton<QRegExp> { static const bool IsAvailable = false; };
#endif
} // namespace
/*!
\macro Q_DECLARE_METATYPE(Type)
\relates QMetaType
@ -1372,6 +1414,62 @@ void QMetaType::destroy(int type, void *data)
}
}
namespace {
template<class Filter>
class TypeConstructor {
template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
struct ConstructorImpl {
static void *Construct(const int /*type*/, void *where, const T *copy) { return qMetaTypeConstructHelper(where, copy); }
};
template<typename T>
struct ConstructorImpl<T, /* IsAcceptedType = */ false> {
static void *Construct(const int type, void *where, const T *copy)
{
QMetaType::Constructor ctor = 0;
if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType) {
Q_ASSERT(qMetaTypeGuiHelper);
if (!qMetaTypeGuiHelper)
return 0;
ctor = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].constructor;
} else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType) {
Q_ASSERT(qMetaTypeWidgetsHelper);
if (!qMetaTypeWidgetsHelper)
return 0;
ctor = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].constructor;
} else
return customTypeConstructor(type, where, copy);
return ctor(where, copy);
}
};
public:
TypeConstructor(const int type, void *where)
: m_type(type)
, m_where(where)
{}
template<typename T>
void *delegate(const T *copy) { return ConstructorImpl<T>::Construct(m_type, m_where, copy); }
void *delegate(const void *) { return m_where; }
void *delegate(const QMetaTypeSwitcher::UnknownType *copy) { return customTypeConstructor(m_type, m_where, copy); }
private:
static void *customTypeConstructor(const int type, void *where, const void *copy)
{
QMetaType::Constructor ctor = 0;
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
if (type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)
return 0;
ctor = ct->at(type - QMetaType::User).constructor;
return ctor ? ctor(where, copy) : 0;
}
const int m_type;
void *m_where;
};
} // namespace
/*!
\since 5.0
@ -1402,126 +1500,65 @@ void *QMetaType::construct(int type, void *where, const void *copy)
{
if (!where)
return 0;
switch (type) {
case QMetaType::VoidStar:
case QMetaType::QObjectStar:
case QMetaType::QWidgetStar:
return qMetaTypeConstructHelper<void*>(where, static_cast<void* const *>(copy));
case QMetaType::Long:
return qMetaTypeConstructHelper<long>(where, static_cast<const long *>(copy));
case QMetaType::Int:
return qMetaTypeConstructHelper<int>(where, static_cast<const int *>(copy));
case QMetaType::Short:
return qMetaTypeConstructHelper<short>(where, static_cast<const short *>(copy));
case QMetaType::Char:
return qMetaTypeConstructHelper<char>(where, static_cast<const char *>(copy));
case QMetaType::ULong:
return qMetaTypeConstructHelper<ulong>(where, static_cast<const ulong *>(copy));
case QMetaType::UInt:
return qMetaTypeConstructHelper<uint>(where, static_cast<const uint *>(copy));
case QMetaType::LongLong:
return qMetaTypeConstructHelper<qlonglong>(where, static_cast<const qlonglong *>(copy));
case QMetaType::ULongLong:
return qMetaTypeConstructHelper<qulonglong>(where, static_cast<const qulonglong *>(copy));
case QMetaType::UShort:
return qMetaTypeConstructHelper<ushort>(where, static_cast<const ushort *>(copy));
case QMetaType::UChar:
return qMetaTypeConstructHelper<uchar>(where, static_cast<const uchar *>(copy));
case QMetaType::Bool:
return qMetaTypeConstructHelper<bool>(where, static_cast<const bool *>(copy));
case QMetaType::Float:
return qMetaTypeConstructHelper<float>(where, static_cast<const float *>(copy));
case QMetaType::Double:
return qMetaTypeConstructHelper<double>(where, static_cast<const double *>(copy));
case QMetaType::QChar:
return qMetaTypeConstructHelper<NS(QChar)>(where, static_cast<const NS(QChar) *>(copy));
#ifndef QT_BOOTSTRAPPED
case QMetaType::QVariantMap:
return qMetaTypeConstructHelper<NS(QVariantMap)>(where, static_cast<const NS(QVariantMap) *>(copy));
case QMetaType::QVariantHash:
return qMetaTypeConstructHelper<NS(QVariantHash)>(where, static_cast<const NS(QVariantHash) *>(copy));
case QMetaType::QVariantList:
return qMetaTypeConstructHelper<NS(QVariantList)>(where, static_cast<const NS(QVariantList) *>(copy));
case QMetaType::QVariant:
return qMetaTypeConstructHelper<NS(QVariant)>(where, static_cast<const NS(QVariant) *>(copy));
#endif
case QMetaType::QByteArray:
return qMetaTypeConstructHelper<NS(QByteArray)>(where, static_cast<const NS(QByteArray) *>(copy));
case QMetaType::QString:
return qMetaTypeConstructHelper<NS(QString)>(where, static_cast<const NS(QString) *>(copy));
case QMetaType::QStringList:
return qMetaTypeConstructHelper<NS(QStringList)>(where, static_cast<const NS(QStringList) *>(copy));
#ifndef QT_BOOTSTRAPPED
case QMetaType::QBitArray:
return qMetaTypeConstructHelper<NS(QBitArray)>(where, static_cast<const NS(QBitArray) *>(copy));
#endif
case QMetaType::QDate:
return qMetaTypeConstructHelper<NS(QDate)>(where, static_cast<const NS(QDate) *>(copy));
case QMetaType::QTime:
return qMetaTypeConstructHelper<NS(QTime)>(where, static_cast<const NS(QTime) *>(copy));
case QMetaType::QDateTime:
return qMetaTypeConstructHelper<NS(QDateTime)>(where, static_cast<const NS(QDateTime) *>(copy));
#ifndef QT_BOOTSTRAPPED
case QMetaType::QUrl:
return qMetaTypeConstructHelper<NS(QUrl)>(where, static_cast<const NS(QUrl) *>(copy));
#endif
case QMetaType::QLocale:
return qMetaTypeConstructHelper<NS(QLocale)>(where, static_cast<const NS(QLocale) *>(copy));
#ifndef QT_NO_GEOM_VARIANT
case QMetaType::QRect:
return qMetaTypeConstructHelper<NS(QRect)>(where, static_cast<const NS(QRect) *>(copy));
case QMetaType::QRectF:
return qMetaTypeConstructHelper<NS(QRectF)>(where, static_cast<const NS(QRectF) *>(copy));
case QMetaType::QSize:
return qMetaTypeConstructHelper<NS(QSize)>(where, static_cast<const NS(QSize) *>(copy));
case QMetaType::QSizeF:
return qMetaTypeConstructHelper<NS(QSizeF)>(where, static_cast<const NS(QSizeF) *>(copy));
case QMetaType::QLine:
return qMetaTypeConstructHelper<NS(QLine)>(where, static_cast<const NS(QLine) *>(copy));
case QMetaType::QLineF:
return qMetaTypeConstructHelper<NS(QLineF)>(where, static_cast<const NS(QLineF) *>(copy));
case QMetaType::QPoint:
return qMetaTypeConstructHelper<NS(QPoint)>(where, static_cast<const NS(QPoint) *>(copy));
case QMetaType::QPointF:
return qMetaTypeConstructHelper<NS(QPointF)>(where, static_cast<const NS(QPointF) *>(copy));
#endif
#ifndef QT_NO_REGEXP
case QMetaType::QRegExp:
return qMetaTypeConstructHelper<NS(QRegExp)>(where, static_cast<const NS(QRegExp) *>(copy));
#endif
#ifndef QT_BOOTSTRAPPED
case QMetaType::QEasingCurve:
return qMetaTypeConstructHelper<NS(QEasingCurve)>(where, static_cast<const NS(QEasingCurve) *>(copy));
#endif
case QMetaType::Void:
return where;
default:
;
}
TypeConstructor<DefinedTypesFilter> constructor(type, where);
return QMetaTypeSwitcher::switcher<void*>(constructor, type, copy);
}
Constructor ctor = 0;
if (type >= FirstGuiType && type <= LastGuiType) {
Q_ASSERT(qMetaTypeGuiHelper);
if (!qMetaTypeGuiHelper)
return 0;
ctor = qMetaTypeGuiHelper[type - FirstGuiType].constructor;
} else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
Q_ASSERT(qMetaTypeWidgetsHelper);
if (!qMetaTypeWidgetsHelper)
return 0;
ctor = qMetaTypeWidgetsHelper[type - FirstWidgetsType].constructor;
} else {
namespace {
template<class Filter>
class TypeDestructor {
template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
struct DestructorImpl {
static void Destruct(const int /* type */, T *where) { qMetaTypeDestructHelper(where); }
};
template<typename T>
struct DestructorImpl<T, /* IsAcceptedType = */ false> {
static void Destruct(const int type, void *where)
{
QMetaType::Destructor dtor = 0;
if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType) {
Q_ASSERT(qMetaTypeGuiHelper);
if (!qMetaTypeGuiHelper)
return;
dtor = qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].destructor;
} else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType) {
Q_ASSERT(qMetaTypeWidgetsHelper);
if (!qMetaTypeWidgetsHelper)
return;
dtor = qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].destructor;
} else
customTypeDestructor(type, where);
dtor(where);
}
};
public:
TypeDestructor(const int type)
: m_type(type)
{}
template<typename T>
void delegate(const T *where) { DestructorImpl<T>::Destruct(m_type, const_cast<T*>(where)); }
void delegate(const void *) {}
void delegate(const QMetaTypeSwitcher::UnknownType *where) { customTypeDestructor(m_type, (void*)where); }
private:
static void customTypeDestructor(const int type, void *where)
{
QMetaType::Destructor dtor = 0;
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
if (type < User || !ct || ct->count() <= type - User)
return 0;
ctor = ct->at(type - User).constructor;
if (!ctor)
return 0;
if (type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)
return;
dtor = ct->at(type - QMetaType::User).destructor;
if (!dtor)
return;
dtor(where);
}
return ctor(where, copy);
}
const int m_type;
};
} // namespace
/*!
\since 5.0
@ -1537,149 +1574,60 @@ void QMetaType::destruct(int type, void *where)
{
if (!where)
return;
switch (type) {
case QMetaType::VoidStar:
case QMetaType::QObjectStar:
case QMetaType::QWidgetStar:
break;
case QMetaType::Long:
break;
case QMetaType::Int:
break;
case QMetaType::Short:
break;
case QMetaType::Char:
break;
case QMetaType::ULong:
break;
case QMetaType::LongLong:
break;
case QMetaType::ULongLong:
break;
case QMetaType::UInt:
break;
case QMetaType::UShort:
break;
case QMetaType::UChar:
break;
case QMetaType::Bool:
break;
case QMetaType::Float:
break;
case QMetaType::Double:
break;
case QMetaType::QChar:
static_cast< NS(QChar)* >(where)->NS(QChar)::~QChar();
break;
#ifndef QT_BOOTSTRAPPED
case QMetaType::QVariantMap:
static_cast< NS(QVariantMap)* >(where)->NS(QVariantMap)::~QMap<class QString, class QVariant>();
break;
case QMetaType::QVariantHash:
static_cast< NS(QVariantHash)* >(where)->NS(QVariantHash)::~QHash<class QString, class QVariant>();
break;
case QMetaType::QVariantList: {
static_cast< NS(QVariantList)* >(where)->NS(QVariantList)::~QList<class QVariant>();
break; }
case QMetaType::QVariant:
static_cast< NS(QVariant)* >(where)->NS(QVariant)::~QVariant();
break;
#endif
case QMetaType::QByteArray:
static_cast< NS(QByteArray)* >(where)->NS(QByteArray)::~QByteArray();
break;
case QMetaType::QString:
static_cast< NS(QString)* >(where)->NS(QString)::~QString();
break;
case QMetaType::QStringList:
static_cast< NS(QStringList)* >(where)->NS(QStringList)::~QStringList();
break;
#ifndef QT_BOOTSTRAPPED
case QMetaType::QBitArray:
static_cast< NS(QBitArray)* >(where)->NS(QBitArray)::~QBitArray();
break;
#endif
case QMetaType::QDate:
static_cast< NS(QDate)* >(where)->NS(QDate)::~QDate();
break;
case QMetaType::QTime:
static_cast< NS(QTime)* >(where)->NS(QTime)::~QTime();
break;
case QMetaType::QDateTime:
static_cast< NS(QDateTime)* >(where)->NS(QDateTime)::~QDateTime();
break;
#ifndef QT_BOOTSTRAPPED
case QMetaType::QUrl:
static_cast< NS(QUrl)* >(where)->NS(QUrl)::~QUrl();
#endif
break;
case QMetaType::QLocale:
static_cast< NS(QLocale)* >(where)->NS(QLocale)::~QLocale();
break;
#ifndef QT_NO_GEOM_VARIANT
case QMetaType::QRect:
static_cast< NS(QRect)* >(where)->NS(QRect)::~QRect();
break;
case QMetaType::QRectF:
static_cast< NS(QRectF)* >(where)->NS(QRectF)::~QRectF();
break;
case QMetaType::QSize:
static_cast< NS(QSize)* >(where)->NS(QSize)::~QSize();
break;
case QMetaType::QSizeF:
static_cast< NS(QSizeF)* >(where)->NS(QSizeF)::~QSizeF();
break;
case QMetaType::QLine:
static_cast< NS(QLine)* >(where)->NS(QLine)::~QLine();
break;
case QMetaType::QLineF:
static_cast< NS(QLineF)* >(where)->NS(QLineF)::~QLineF();
break;
case QMetaType::QPoint:
static_cast< NS(QPoint)* >(where)->NS(QPoint)::~QPoint();
break;
case QMetaType::QPointF:
static_cast< NS(QPointF)* >(where)->NS(QPointF)::~QPointF();
break;
#endif
#ifndef QT_NO_REGEXP
case QMetaType::QRegExp:
static_cast< NS(QRegExp)* >(where)->NS(QRegExp)::~QRegExp();
break;
#endif
#ifndef QT_BOOTSTRAPPED
case QMetaType::QEasingCurve:
static_cast< NS(QEasingCurve)* >(where)->NS(QEasingCurve)::~QEasingCurve();
break;
#endif
case QMetaType::Void:
break;
default: {
const QVector<QCustomTypeInfo> * const ct = customTypes();
Destructor dtor = 0;
if (type >= FirstGuiType && type <= LastGuiType) {
Q_ASSERT(qMetaTypeGuiHelper);
if (!qMetaTypeGuiHelper)
return;
dtor = qMetaTypeGuiHelper[type - FirstGuiType].destructor;
} else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
Q_ASSERT(qMetaTypeWidgetsHelper);
if (!qMetaTypeWidgetsHelper)
return;
dtor = qMetaTypeWidgetsHelper[type - FirstWidgetsType].destructor;
} else {
QReadLocker locker(customTypesLock());
if (type < User || !ct || ct->count() <= type - User)
break;
dtor = ct->at(type - User).destructor;
if (!dtor)
break;
}
dtor(where);
break; }
}
TypeDestructor<DefinedTypesFilter> destructor(type);
QMetaTypeSwitcher::switcher<void>(destructor, type, where);
}
namespace {
template<class Filter>
class SizeOf {
template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
struct SizeOfImpl {
static int Size(const int) { return sizeof(T); }
};
template<typename T>
struct SizeOfImpl<T, /* IsAcceptedType = */ false> {
static int Size(const int type)
{
if (type >= QMetaType::FirstGuiType && type <= QMetaType::LastGuiType) {
Q_ASSERT(qMetaTypeGuiHelper);
if (!qMetaTypeGuiHelper)
return 0;
return qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].size;
} else if (type >= QMetaType::FirstWidgetsType && type <= QMetaType::LastWidgetsType) {
Q_ASSERT(qMetaTypeWidgetsHelper);
if (!qMetaTypeWidgetsHelper)
return 0;
return qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].size;
}
return customTypeSizeOf(type);
}
};
public:
SizeOf(int type)
: m_type(type)
{}
template<typename T>
int delegate(const T*) { return SizeOfImpl<T>::Size(m_type); }
int delegate(const void*) { return 0; }
int delegate(const QMetaTypeSwitcher::UnknownType*) { return customTypeSizeOf(m_type); }
private:
static int customTypeSizeOf(const int type)
{
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
if (type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)
return 0;
return ct->at(type - QMetaType::User).size;
}
const int m_type;
};
} // namespace
/*!
\since 5.0
@ -1693,120 +1641,8 @@ void QMetaType::destruct(int type, void *where)
*/
int QMetaType::sizeOf(int type)
{
switch (type) {
case QMetaType::VoidStar:
case QMetaType::QObjectStar:
case QMetaType::QWidgetStar:
return sizeof(void *);
case QMetaType::Long:
return sizeof(long);
case QMetaType::Int:
return sizeof(int);
case QMetaType::Short:
return sizeof(short);
case QMetaType::Char:
return sizeof(char);
case QMetaType::ULong:
return sizeof(ulong);
case QMetaType::UInt:
return sizeof(uint);
case QMetaType::LongLong:
return sizeof(qlonglong);
case QMetaType::ULongLong:
return sizeof(qulonglong);
case QMetaType::UShort:
return sizeof(ushort);
case QMetaType::UChar:
return sizeof(uchar);
case QMetaType::Bool:
return sizeof(bool);
case QMetaType::Float:
return sizeof(float);
case QMetaType::Double:
return sizeof(double);
case QMetaType::QChar:
return sizeof(NS(QChar));
#ifndef QT_BOOTSTRAPPED
case QMetaType::QVariantMap:
return sizeof(NS(QVariantMap));
case QMetaType::QVariantHash:
return sizeof(NS(QVariantHash));
case QMetaType::QVariantList:
return sizeof(NS(QVariantList));
case QMetaType::QVariant:
return sizeof(NS(QVariant));
#endif
case QMetaType::QByteArray:
return sizeof(NS(QByteArray));
case QMetaType::QString:
return sizeof(NS(QString));
case QMetaType::QStringList:
return sizeof(NS(QStringList));
#ifndef QT_BOOTSTRAPPED
case QMetaType::QBitArray:
return sizeof(NS(QBitArray));
#endif
case QMetaType::QDate:
return sizeof(NS(QDate));
case QMetaType::QTime:
return sizeof(NS(QTime));
case QMetaType::QDateTime:
return sizeof(NS(QDateTime));
#ifndef QT_BOOTSTRAPPED
case QMetaType::QUrl:
return sizeof(NS(QUrl));
#endif
case QMetaType::QLocale:
return sizeof(NS(QLocale));
#ifndef QT_NO_GEOM_VARIANT
case QMetaType::QRect:
return sizeof(NS(QRect));
case QMetaType::QRectF:
return sizeof(NS(QRectF));
case QMetaType::QSize:
return sizeof(NS(QSize));
case QMetaType::QSizeF:
return sizeof(NS(QSizeF));
case QMetaType::QLine:
return sizeof(NS(QLine));
case QMetaType::QLineF:
return sizeof(NS(QLineF));
case QMetaType::QPoint:
return sizeof(NS(QPoint));
case QMetaType::QPointF:
return sizeof(NS(QPointF));
#endif
#ifndef QT_NO_REGEXP
case QMetaType::QRegExp:
return sizeof(NS(QRegExp));
#endif
#ifndef QT_BOOTSTRAPPED
case QMetaType::QEasingCurve:
return sizeof(NS(QEasingCurve));
#endif
case QMetaType::Void:
return 0;
default:
;
}
if (type >= FirstGuiType && type <= LastGuiType) {
Q_ASSERT(qMetaTypeGuiHelper);
if (!qMetaTypeGuiHelper)
return 0;
return qMetaTypeGuiHelper[type - FirstGuiType].size;
} else if (type >= FirstWidgetsType && type <= LastWidgetsType) {
Q_ASSERT(qMetaTypeWidgetsHelper);
if (!qMetaTypeWidgetsHelper)
return 0;
return qMetaTypeWidgetsHelper[type - FirstWidgetsType].size;
}
const QVector<QCustomTypeInfo> * const ct = customTypes();
QReadLocker locker(customTypesLock());
if (type < User || !ct || ct->count() <= type - User)
return 0;
return ct->at(type - User).size;
SizeOf<DefinedTypesFilter> sizeOf(type);
return QMetaTypeSwitcher::switcher<int>(sizeOf, type, 0);
}
/*!