diff options
author | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2010-02-19 14:19:11 (GMT) |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@nokia.com> | 2010-02-22 17:12:16 (GMT) |
commit | 96a3d36a33dc5c1c7e414c873316027fab6cecf9 (patch) | |
tree | ac266a143ab35d3e39bb97cf6d9c8d357d9049d0 /src | |
parent | 0eafbdd480440e413f2fd9cdf4f19354be2a0bdb (diff) | |
download | Qt-96a3d36a33dc5c1c7e414c873316027fab6cecf9.zip Qt-96a3d36a33dc5c1c7e414c873316027fab6cecf9.tar.gz Qt-96a3d36a33dc5c1c7e414c873316027fab6cecf9.tar.bz2 |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qlist.h | 34 |
1 files 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 <int N> 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<T>::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 <class T> struct QtPodForType : QtPodForSize<sizeof(T)> { }; + template <typename T> class QList { @@ -491,10 +510,11 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType<T>::Type PodNode; + PodNode cpy = *reinterpret_cast<const PodNode *>(&t); Node *n = reinterpret_cast<Node *>(p.append()); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast<const T *>(&cpy)); } QT_CATCH(...) { --d->end; QT_RETHROW; @@ -515,10 +535,11 @@ inline void QList<T>::prepend(const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType<T>::Type PodNode; + PodNode cpy = *reinterpret_cast<const PodNode *>(&t); Node *n = reinterpret_cast<Node *>(p.prepend()); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast<const T *>(&cpy)); } QT_CATCH(...) { ++d->begin; QT_RETHROW; @@ -539,10 +560,11 @@ inline void QList<T>::insert(int i, const T &t) QT_RETHROW; } } else { - const T cpy(t); + typedef typename QtPodForType<T>::Type PodNode; + PodNode cpy = *reinterpret_cast<const PodNode *>(&t); Node *n = reinterpret_cast<Node *>(p.insert(i)); QT_TRY { - node_construct(n, cpy); + node_construct(n, *reinterpret_cast<const T *>(&cpy)); } QT_CATCH(...) { p.remove(i); QT_RETHROW; |