summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@nokia.com>2010-02-19 14:19:11 (GMT)
committerOswald Buddenhagen <oswald.buddenhagen@nokia.com>2010-02-22 17:12:16 (GMT)
commit96a3d36a33dc5c1c7e414c873316027fab6cecf9 (patch)
treeac266a143ab35d3e39bb97cf6d9c8d357d9049d0 /src
parent0eafbdd480440e413f2fd9cdf4f19354be2a0bdb (diff)
downloadQt-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.h34
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;