From e70457fc4f60a17358e280f9b222f36bcd4f591f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 1 Nov 2011 12:58:42 +0100 Subject: [PATCH] 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 --- src/corelib/kernel/qmetatype.cpp | 576 +++++++++++-------------------- 1 file changed, 206 insertions(+), 370 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 07bc32b7be..ebb4548934 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -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 +struct TypeDefiniton { + static const bool IsAvailable = true; +}; + +struct DefinedTypesFilter { + template + struct Acceptor { + static const bool IsAccepted = TypeDefiniton::IsAvailable && QTypeModuleInfo::IsCore; + }; +}; + +// Ignore these types, as incomplete +#ifdef QT_NO_GEOM_VARIANT +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +#endif +#ifdef QT_BOOTSTRAPPED +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +template<> struct TypeDefiniton { static const bool IsAvailable = false; }; +#endif +#ifdef QT_NO_REGEXP +template<> struct TypeDefiniton { 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 TypeConstructor { + template::IsAccepted> + struct ConstructorImpl { + static void *Construct(const int /*type*/, void *where, const T *copy) { return qMetaTypeConstructHelper(where, copy); } + }; + template + struct ConstructorImpl { + 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 + void *delegate(const T *copy) { return ConstructorImpl::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 * 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(where, static_cast(copy)); - case QMetaType::Long: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::Int: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::Short: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::Char: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::ULong: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::UInt: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::LongLong: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::ULongLong: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::UShort: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::UChar: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::Bool: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::Float: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::Double: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QChar: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#ifndef QT_BOOTSTRAPPED - case QMetaType::QVariantMap: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QVariantHash: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QVariantList: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QVariant: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#endif - case QMetaType::QByteArray: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QString: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QStringList: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#ifndef QT_BOOTSTRAPPED - case QMetaType::QBitArray: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#endif - case QMetaType::QDate: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QTime: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QDateTime: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#ifndef QT_BOOTSTRAPPED - case QMetaType::QUrl: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#endif - case QMetaType::QLocale: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#ifndef QT_NO_GEOM_VARIANT - case QMetaType::QRect: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QRectF: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QSize: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QSizeF: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QLine: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QLineF: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QPoint: - return qMetaTypeConstructHelper(where, static_cast(copy)); - case QMetaType::QPointF: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#endif -#ifndef QT_NO_REGEXP - case QMetaType::QRegExp: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#endif -#ifndef QT_BOOTSTRAPPED - case QMetaType::QEasingCurve: - return qMetaTypeConstructHelper(where, static_cast(copy)); -#endif - case QMetaType::Void: - return where; - default: - ; - } + TypeConstructor constructor(type, where); + return QMetaTypeSwitcher::switcher(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 TypeDestructor { + template::IsAccepted> + struct DestructorImpl { + static void Destruct(const int /* type */, T *where) { qMetaTypeDestructHelper(where); } + }; + template + struct DestructorImpl { + 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 + void delegate(const T *where) { DestructorImpl::Destruct(m_type, const_cast(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 * 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(); - break; - case QMetaType::QVariantHash: - static_cast< NS(QVariantHash)* >(where)->NS(QVariantHash)::~QHash(); - break; - case QMetaType::QVariantList: { - static_cast< NS(QVariantList)* >(where)->NS(QVariantList)::~QList(); - 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 * 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 destructor(type); + QMetaTypeSwitcher::switcher(destructor, type, where); } + +namespace { +template +class SizeOf { + template::IsAccepted> + struct SizeOfImpl { + static int Size(const int) { return sizeof(T); } + }; + template + struct SizeOfImpl { + 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 + int delegate(const T*) { return SizeOfImpl::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 * 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 * const ct = customTypes(); - QReadLocker locker(customTypesLock()); - if (type < User || !ct || ct->count() <= type - User) - return 0; - return ct->at(type - User).size; + SizeOf sizeOf(type); + return QMetaTypeSwitcher::switcher(sizeOf, type, 0); } /*!