summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJędrzej Nowacki <jedrzej.nowacki@nokia.com>2012-01-24 13:58:04 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-05 12:33:30 +0100
commitd97fd99270763468df08c4fb74c6df52db9b2ff6 (patch)
treeee172d5c592f9243a89242fab52ee65d52e5a91c
parent72c07311228ce6eefb460d7e5da3de24220ba81e (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.cpp223
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 {