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:
parent
72c0731122
commit
d97fd99270
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user