summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlist.h
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2010-02-19 15:19:11 +0100
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>2010-02-22 18:12:16 +0100
commit96a3d36a33dc5c1c7e414c873316027fab6cecf9 (patch)
treeac266a143ab35d3e39bb97cf6d9c8d357d9049d0 /src/corelib/tools/qlist.h
parent0eafbdd480440e413f2fd9cdf4f19354be2a0bdb (diff)
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/corelib/tools/qlist.h')
-rw-r--r--src/corelib/tools/qlist.h34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 1e0cb76f3b..b79011e95f 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;