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>
This commit is contained in:
Jędrzej Nowacki 2012-01-24 13:58:04 +01:00 committed by Qt by Nokia
parent 72c0731122
commit d97fd99270

View File

@ -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 {