From 18885297de880493831f63d20a8d45c6689a01b8 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 19 Aug 2014 23:30:38 +0200 Subject: 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 --- src/corelib/tools/qlist.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) 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) @@ -940,6 +946,12 @@ Q_OUTOFLINE_TEMPLATE int QList::lastIndexOf(const T &t, int from) const template Q_OUTOFLINE_TEMPLATE bool QList::contains(const T &t) const +{ + return contains_impl(t, MemoryLayout()); +} + +template +inline bool QList::contains_impl(const T &t, QListData::NotArrayCompatibleLayout) const { Node *e = reinterpret_cast(p.end()); Node *i = reinterpret_cast(p.begin()); @@ -949,8 +961,22 @@ Q_OUTOFLINE_TEMPLATE bool QList::contains(const T &t) const return false; } +template +inline bool QList::contains_impl(const T &t, QListData::ArrayCompatibleLayout) const +{ + const T *b = reinterpret_cast(p.begin()); + const T *e = reinterpret_cast(p.end()); + return std::find(b, e, t) != e; +} + template Q_OUTOFLINE_TEMPLATE int QList::count(const T &t) const +{ + return this->count_impl(t, MemoryLayout()); +} + +template +inline int QList::count_impl(const T &t, QListData::NotArrayCompatibleLayout) const { int c = 0; Node *e = reinterpret_cast(p.end()); @@ -961,6 +987,14 @@ Q_OUTOFLINE_TEMPLATE int QList::count(const T &t) const return c; } +template +inline int QList::count_impl(const T &t, QListData::ArrayCompatibleLayout) const +{ + return int(std::count(reinterpret_cast(p.begin()), + reinterpret_cast(p.end()), + t)); +} + Q_DECLARE_SEQUENTIAL_ITERATOR(List) Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List) -- cgit v1.2.3