diff options
author | Jędrzej Nowacki <jedrzej.nowacki@nokia.com> | 2012-01-24 13:58:04 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-05 12:33:30 +0100 |
commit | d97fd99270763468df08c4fb74c6df52db9b2ff6 (patch) | |
tree | ee172d5c592f9243a89242fab52ee65d52e5a91c | |
parent | 72c07311228ce6eefb460d7e5da3de24220ba81e (diff) |
Reimplement QMetaType::destroy.
New implementation is using QMetaTypeSwitcher, which should reduce
maintenance costs.
Change-Id: Ibb7bb4b9de0e19c081c087d9eebf0c709118d3b4
Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
-rw-r--r-- | src/corelib/kernel/qmetatype.cpp | 223 |
1 files changed, 56 insertions, 167 deletions
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index fa3398b6bf..cdabf2c6d2 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1261,6 +1261,60 @@ void *QMetaType::create(int type, const void *copy) return creator(copy); } +namespace { +class TypeDestroyer { + template<typename T, bool IsAcceptedType = DefinedTypesFilter::Acceptor<T>::IsAccepted> + struct DestroyerImpl { + static void Destroy(const int /* type */, T *where) { delete where; } + }; + template<typename T> + struct DestroyerImpl<T, /* IsAcceptedType = */ false> { + static void Destroy(const int type, void *where) + { + if (QTypeModuleInfo<T>::IsGui) { + if (qMetaTypeGuiHelper) + qMetaTypeGuiHelper[type - QMetaType::FirstGuiType].deleter(where); + return; + } + if (QTypeModuleInfo<T>::IsWidget) { + if (qMetaTypeWidgetsHelper) + qMetaTypeWidgetsHelper[type - QMetaType::FirstWidgetsType].deleter(where); + return; + } + // This point can be reached only for known types that definition is not available, for example + // in bootstrap mode. We have no other choice then ignore it. + } + }; +public: + TypeDestroyer(const int type) + : m_type(type) + {} + + template<typename T> + void delegate(const T *where) { DestroyerImpl<T>::Destroy(m_type, const_cast<T*>(where)); } + void delegate(const void *) {} + void delegate(const QMetaTypeSwitcher::UnknownType *where) { customTypeDestroyer(m_type, (void*)where); } + +private: + static void customTypeDestroyer(const int type, void *where) + { + QMetaType::Destructor deleter; + const QVector<QCustomTypeInfo> * const ct = customTypes(); + { + QReadLocker locker(customTypesLock()); + if (Q_UNLIKELY(type < QMetaType::User || !ct || ct->count() <= type - QMetaType::User)) + return; + deleter = ct->at(type - QMetaType::User).deleter; + } + if (Q_LIKELY(deleter)) + deleter(where); + } + + const int m_type; +}; +} // namespace + + /*! Destroys the \a data, assuming it is of the \a type given. @@ -1268,173 +1322,8 @@ void *QMetaType::create(int type, const void *copy) */ void QMetaType::destroy(int type, void *data) { - if (!data) - return; - switch(type) { - case QMetaType::VoidStar: - case QMetaType::QObjectStar: - case QMetaType::QWidgetStar: - delete static_cast<void**>(data); - break; - case QMetaType::Long: - delete static_cast<long*>(data); - break; - case QMetaType::Int: - delete static_cast<int*>(data); - break; - case QMetaType::Short: - delete static_cast<short*>(data); - break; - case QMetaType::Char: - delete static_cast<char*>(data); - break; - case QMetaType::ULong: - delete static_cast<ulong*>(data); - break; - case QMetaType::LongLong: - delete static_cast<qlonglong*>(data); - break; - case QMetaType::ULongLong: - delete static_cast<qulonglong*>(data); - break; - case QMetaType::UInt: - delete static_cast<uint*>(data); - break; - case QMetaType::UShort: - delete static_cast<ushort*>(data); - break; - case QMetaType::UChar: - delete static_cast<uchar*>(data); - break; - case QMetaType::Bool: - delete static_cast<bool*>(data); - break; - case QMetaType::Float: - delete static_cast<float*>(data); - break; - case QMetaType::Double: - delete static_cast<double*>(data); - break; - case QMetaType::QChar: - delete static_cast< NS(QChar)* >(data); - break; -#ifndef QT_BOOTSTRAPPED - case QMetaType::QVariantMap: - delete static_cast< NS(QVariantMap)* >(data); - break; - case QMetaType::QVariantHash: - delete static_cast< NS(QVariantHash)* >(data); - break; - case QMetaType::QVariantList: - delete static_cast< NS(QVariantList)* >(data); - break; - case QMetaType::QVariant: - delete static_cast< NS(QVariant)* >(data); - break; -#endif - case QMetaType::QByteArray: - delete static_cast< NS(QByteArray)* >(data); - break; - case QMetaType::QString: - delete static_cast< NS(QString)* >(data); - break; - case QMetaType::QStringList: - delete static_cast< NS(QStringList)* >(data); - break; -#ifndef QT_BOOTSTRAPPED - case QMetaType::QBitArray: - delete static_cast< NS(QBitArray)* >(data); - break; -#endif - case QMetaType::QDate: - delete static_cast< NS(QDate)* >(data); - break; - case QMetaType::QTime: - delete static_cast< NS(QTime)* >(data); - break; - case QMetaType::QDateTime: - delete static_cast< NS(QDateTime)* >(data); - break; -#ifndef QT_BOOTSTRAPPED - case QMetaType::QUrl: - delete static_cast< NS(QUrl)* >(data); -#endif - break; - case QMetaType::QLocale: - delete static_cast< NS(QLocale)* >(data); - break; -#ifndef QT_NO_GEOM_VARIANT - case QMetaType::QRect: - delete static_cast< NS(QRect)* >(data); - break; - case QMetaType::QRectF: - delete static_cast< NS(QRectF)* >(data); - break; - case QMetaType::QSize: - delete static_cast< NS(QSize)* >(data); - break; - case QMetaType::QSizeF: - delete static_cast< NS(QSizeF)* >(data); - break; - case QMetaType::QLine: - delete static_cast< NS(QLine)* >(data); - break; - case QMetaType::QLineF: - delete static_cast< NS(QLineF)* >(data); - break; - case QMetaType::QPoint: - delete static_cast< NS(QPoint)* >(data); - break; - case QMetaType::QPointF: - delete static_cast< NS(QPointF)* >(data); - break; -#endif -#ifndef QT_NO_REGEXP - case QMetaType::QRegExp: - delete static_cast< NS(QRegExp)* >(data); - break; -#endif -#ifndef QT_BOOTSTRAPPED - case QMetaType::QEasingCurve: - delete static_cast< NS(QEasingCurve)* >(data); - break; -#endif - case QMetaType::QUuid: - delete static_cast< NS(QUuid)* >(data); - break; -#ifndef QT_BOOTSTRAPPED - case QMetaType::QModelIndex: - delete static_cast< NS(QModelIndex)* >(data); - break; -#endif - case QMetaType::Void: - break; - default: { - const QVector<QCustomTypeInfo> * const ct = customTypes(); - Deleter deleter = 0; - if (type >= FirstGuiType && type <= LastGuiType) { - Q_ASSERT(qMetaTypeGuiHelper); - - if (!qMetaTypeGuiHelper) - return; - deleter = qMetaTypeGuiHelper[type - FirstGuiType].deleter; - } else if (type >= FirstWidgetsType && type <= LastWidgetsType) { - Q_ASSERT(qMetaTypeWidgetsHelper); - - if (!qMetaTypeWidgetsHelper) - return; - deleter = qMetaTypeWidgetsHelper[type - FirstWidgetsType].deleter; - } else { - QReadLocker locker(customTypesLock()); - if (type < User || !ct || ct->count() <= type - User) - break; - if (ct->at(type - User).typeName.isEmpty()) - break; - deleter = ct->at(type - User).deleter; - } - deleter(data); - break; } - } + TypeDestroyer deleter(type); + QMetaTypeSwitcher::switcher<void>(deleter, type, data); } namespace { |