From 96a3d36a33dc5c1c7e414c873316027fab6cecf9 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 19 Feb 2010 15:19:11 +0100 Subject: create temporaries more intelligently we already know that we are dealing with a movable type, so it is safe to keep a temporary copy of the raw data instead of going through the copy c'tor. this way we save a pretty useless ref()/deref() pair for each and every insertion of an implicitly shared type into a QList. the QtPodForSize class is somewhat ugly. we should use QIntegerForSize, but that's not possible without having separate template specializations, which is not possible without some bigger changes to the qt type info system. it will be beautified in due time. :) Reviewed-by: joao --- src/corelib/tools/qlist.h | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 1e0cb76..b79011e 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -96,6 +96,25 @@ struct Q_CORE_EXPORT QListData { inline void **end() const { return d->array + d->end; } }; +////////////////////////////////////////////////////////////////////////////////// +// +// QtPodForSize and QtPodForType are internal and may change or go away any time. +// We mean it. +// +////////////////////////////////////////////////////////////////////////////////// +template struct QtPodForSize { + // This base type is rather obviously broken and cannot be made + // working due to alignment constraints. + // This doesn't matter as far as QList is concerned, as we are + // using this type only for QTypeInfo::isLarge == false. + typedef struct { } Type; +}; +template <> struct QtPodForSize<1> { typedef quint8 Type; }; +template <> struct QtPodForSize<2> { typedef quint16 Type; }; +template <> struct QtPodForSize<4> { typedef quint32 Type; }; +template <> struct QtPodForSize<8> { typedef quint64 Type; }; +template struct QtPodForType : QtPodForSize { }; + template class QList { @@ -491,10 +510,11 @@ Q_OUTOFLINE_TEMPLATE void QList::append(const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); Node *n = reinterpret_cast(p.append()); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast(&cpy)); } QT_CATCH(...) { --d->end; QT_RETHROW; @@ -515,10 +535,11 @@ inline void QList::prepend(const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); Node *n = reinterpret_cast(p.prepend()); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast(&cpy)); } QT_CATCH(...) { ++d->begin; QT_RETHROW; @@ -539,10 +560,11 @@ inline void QList::insert(int i, const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType::Type PodNode; + PodNode cpy = *reinterpret_cast(&t); Node *n = reinterpret_cast(p.insert(i)); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast(&cpy)); } QT_CATCH(...) { p.remove(i); QT_RETHROW; -- cgit v0.12