summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2014-08-19 23:30:38 +0200
committerMarc Mutz <marc.mutz@kdab.com>2015-02-17 15:05:15 +0000
commit18885297de880493831f63d20a8d45c6689a01b8 (patch)
treec4a204b499d37cc051b0f11916f50d38123b6797
parent40d6e8adf5e3cc45b3bd4a94ad3b57f9444e447f (diff)
QList: share the implementations of contains()/count() with QVector where possible
If QList data-layout-compatible with QVector and a C array, implement count() via std::count() and contains() via std::find() and use const_pointer instead of const_iterator as the iterators. This essentially makes the QVector and QList implementations identical to each other, at least for important cases such as QString. To switch between the different implementations, use tag dispatching instead of the previously used technique "use 'if' as if it were 'static if'", which imposes accidental requirements on the element types (something that esp. QVector is plagued with). Change-Id: I6caf74442a22059676b5bf115a6089768f3a0952 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/tools/qlist.h34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 255816d0ba..5d6cf9fe15 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -377,6 +377,12 @@ private:
{
return (constBegin().i <= i.i) && (i.i <= constEnd().i);
}
+
+private:
+ inline bool contains_impl(const T &, QListData::NotArrayCompatibleLayout) const;
+ inline bool contains_impl(const T &, QListData::ArrayCompatibleLayout) const;
+ inline int count_impl(const T &, QListData::NotArrayCompatibleLayout) const;
+ inline int count_impl(const T &, QListData::ArrayCompatibleLayout) const;
};
#if defined(Q_CC_BOR)
@@ -941,6 +947,12 @@ Q_OUTOFLINE_TEMPLATE int QList<T>::lastIndexOf(const T &t, int from) const
template <typename T>
Q_OUTOFLINE_TEMPLATE bool QList<T>::contains(const T &t) const
{
+ return contains_impl(t, MemoryLayout());
+}
+
+template <typename T>
+inline bool QList<T>::contains_impl(const T &t, QListData::NotArrayCompatibleLayout) const
+{
Node *e = reinterpret_cast<Node *>(p.end());
Node *i = reinterpret_cast<Node *>(p.begin());
for (; i != e; ++i)
@@ -950,8 +962,22 @@ Q_OUTOFLINE_TEMPLATE bool QList<T>::contains(const T &t) const
}
template <typename T>
+inline bool QList<T>::contains_impl(const T &t, QListData::ArrayCompatibleLayout) const
+{
+ const T *b = reinterpret_cast<const T*>(p.begin());
+ const T *e = reinterpret_cast<const T*>(p.end());
+ return std::find(b, e, t) != e;
+}
+
+template <typename T>
Q_OUTOFLINE_TEMPLATE int QList<T>::count(const T &t) const
{
+ return this->count_impl(t, MemoryLayout());
+}
+
+template <typename T>
+inline int QList<T>::count_impl(const T &t, QListData::NotArrayCompatibleLayout) const
+{
int c = 0;
Node *e = reinterpret_cast<Node *>(p.end());
Node *i = reinterpret_cast<Node *>(p.begin());
@@ -961,6 +987,14 @@ Q_OUTOFLINE_TEMPLATE int QList<T>::count(const T &t) const
return c;
}
+template <typename T>
+inline int QList<T>::count_impl(const T &t, QListData::ArrayCompatibleLayout) const
+{
+ return int(std::count(reinterpret_cast<const T*>(p.begin()),
+ reinterpret_cast<const T*>(p.end()),
+ t));
+}
+
Q_DECLARE_SEQUENTIAL_ITERATOR(List)
Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List)