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>
This commit is contained in:
parent
40d6e8adf5
commit
18885297de
@ -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<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());
|
||||
@ -949,8 +961,22 @@ Q_OUTOFLINE_TEMPLATE bool QList<T>::contains(const T &t) const
|
||||
return false;
|
||||
}
|
||||
|
||||
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());
|
||||
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user