summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qlist.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/tools/qlist.h')
-rw-r--r--src/corelib/tools/qlist.h203
1 files changed, 134 insertions, 69 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 49ccbc9c9f..77d8df4a88 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -45,6 +45,7 @@
#include <QtCore/qrefcount.h>
#include <QtCore/qarraydata.h>
#include <QtCore/qhashfunctions.h>
+#include <QtCore/qvector.h>
#include <iterator>
#include <list>
@@ -110,13 +111,18 @@ struct Q_CORE_EXPORT QListData {
void remove(int i);
void remove(int i, int n);
void move(int from, int to);
- inline int size() const Q_DECL_NOTHROW { return d->end - d->begin; }
- inline bool isEmpty() const Q_DECL_NOTHROW { return d->end == d->begin; }
- inline void **at(int i) const Q_DECL_NOTHROW { return d->array + d->begin + i; }
- inline void **begin() const Q_DECL_NOTHROW { return d->array + d->begin; }
- inline void **end() const Q_DECL_NOTHROW { return d->array + d->end; }
+ inline int size() const noexcept { return d->end - d->begin; }
+ inline bool isEmpty() const noexcept { return d->end == d->begin; }
+ inline void **at(int i) const noexcept { return d->array + d->begin + i; }
+ inline void **begin() const noexcept { return d->array + d->begin; }
+ inline void **end() const noexcept { return d->array + d->end; }
};
+namespace QtPrivate {
+ template <typename V, typename U> int indexOf(const QList<V> &list, const U &u, int from);
+ template <typename V, typename U> int lastIndexOf(const QList<V> &list, const U &u, int from);
+}
+
template <typename T>
class QList
#ifndef Q_QDOC
@@ -135,6 +141,8 @@ public:
QListData::InlineWithPaddingLayout
>::type>::type {};
private:
+ template <typename V, typename U> friend int QtPrivate::indexOf(const QList<V> &list, const U &u, int from);
+ template <typename V, typename U> friend int QtPrivate::lastIndexOf(const QList<V> &list, const U &u, int from);
struct Node { void *v;
#if defined(Q_CC_BOR)
Q_INLINE_TEMPLATE T &t();
@@ -148,17 +156,17 @@ private:
union { QListData p; QListData::Data *d; };
public:
- inline QList() Q_DECL_NOTHROW : d(const_cast<QListData::Data *>(&QListData::shared_null)) { }
+ inline QList() noexcept : d(const_cast<QListData::Data *>(&QListData::shared_null)) { }
QList(const QList<T> &l);
~QList();
QList<T> &operator=(const QList<T> &l);
#ifdef Q_COMPILER_RVALUE_REFS
- inline QList(QList<T> &&other) Q_DECL_NOTHROW
+ inline QList(QList<T> &&other) noexcept
: d(other.d) { other.d = const_cast<QListData::Data *>(&QListData::shared_null); }
- inline QList &operator=(QList<T> &&other) Q_DECL_NOTHROW
+ inline QList &operator=(QList<T> &&other) noexcept
{ QList moved(std::move(other)); swap(moved); return *this; }
#endif
- inline void swap(QList<T> &other) Q_DECL_NOTHROW { qSwap(d, other.d); }
+ inline void swap(QList<T> &other) noexcept { qSwap(d, other.d); }
#ifdef Q_COMPILER_INITIALIZER_LISTS
inline QList(std::initializer_list<T> args)
: d(const_cast<QListData::Data *>(&QListData::shared_null))
@@ -167,7 +175,7 @@ public:
bool operator==(const QList<T> &l) const;
inline bool operator!=(const QList<T> &l) const { return !(*this == l); }
- inline int size() const Q_DECL_NOTHROW { return p.size(); }
+ inline int size() const noexcept { return p.size(); }
inline void detach() { if (d->ref.isShared()) detach_helper(); }
@@ -190,9 +198,9 @@ public:
d->ref.setSharable(sharable);
}
#endif
- inline bool isSharedWith(const QList<T> &other) const Q_DECL_NOTHROW { return d == other.d; }
+ inline bool isSharedWith(const QList<T> &other) const noexcept { return d == other.d; }
- inline bool isEmpty() const Q_DECL_NOTHROW { return p.isEmpty(); }
+ inline bool isEmpty() const noexcept { return p.isEmpty(); }
void clear();
@@ -213,7 +221,11 @@ public:
T takeFirst();
T takeLast();
void move(int from, int to);
- void swap(int i, int j);
+ void swapItemsAt(int i, int j);
+#if QT_DEPRECATED_SINCE(5, 13) && QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ QT_DEPRECATED_X("Use QList<T>::swapItemsAt()")
+ void swap(int i, int j) { swapItemsAt(i, j); }
+#endif
int indexOf(const T &t, int from = 0) const;
int lastIndexOf(const T &t, int from = -1) const;
bool contains(const T &t) const;
@@ -231,34 +243,34 @@ public:
typedef T *pointer;
typedef T &reference;
- inline iterator() Q_DECL_NOTHROW : i(nullptr) {}
- inline iterator(Node *n) Q_DECL_NOTHROW : i(n) {}
+ inline iterator() noexcept : i(nullptr) {}
+ inline iterator(Node *n) noexcept : i(n) {}
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
// can't remove it in Qt 5, since doing so would make the type trivial,
// which changes the way it's passed to functions by value.
- inline iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i){}
+ inline iterator(const iterator &o) noexcept : i(o.i){}
#endif
inline T &operator*() const { return i->t(); }
inline T *operator->() const { return &i->t(); }
inline T &operator[](difference_type j) const { return i[j].t(); }
- inline bool operator==(const iterator &o) const Q_DECL_NOTHROW { return i == o.i; }
- inline bool operator!=(const iterator &o) const Q_DECL_NOTHROW { return i != o.i; }
- inline bool operator<(const iterator& other) const Q_DECL_NOTHROW { return i < other.i; }
- inline bool operator<=(const iterator& other) const Q_DECL_NOTHROW { return i <= other.i; }
- inline bool operator>(const iterator& other) const Q_DECL_NOTHROW { return i > other.i; }
- inline bool operator>=(const iterator& other) const Q_DECL_NOTHROW { return i >= other.i; }
+ inline bool operator==(const iterator &o) const noexcept { return i == o.i; }
+ inline bool operator!=(const iterator &o) const noexcept { return i != o.i; }
+ inline bool operator<(const iterator& other) const noexcept { return i < other.i; }
+ inline bool operator<=(const iterator& other) const noexcept { return i <= other.i; }
+ inline bool operator>(const iterator& other) const noexcept { return i > other.i; }
+ inline bool operator>=(const iterator& other) const noexcept { return i >= other.i; }
#ifndef QT_STRICT_ITERATORS
- inline bool operator==(const const_iterator &o) const Q_DECL_NOTHROW
+ inline bool operator==(const const_iterator &o) const noexcept
{ return i == o.i; }
- inline bool operator!=(const const_iterator &o) const Q_DECL_NOTHROW
+ inline bool operator!=(const const_iterator &o) const noexcept
{ return i != o.i; }
- inline bool operator<(const const_iterator& other) const Q_DECL_NOTHROW
+ inline bool operator<(const const_iterator& other) const noexcept
{ return i < other.i; }
- inline bool operator<=(const const_iterator& other) const Q_DECL_NOTHROW
+ inline bool operator<=(const const_iterator& other) const noexcept
{ return i <= other.i; }
- inline bool operator>(const const_iterator& other) const Q_DECL_NOTHROW
+ inline bool operator>(const const_iterator& other) const noexcept
{ return i > other.i; }
- inline bool operator>=(const const_iterator& other) const Q_DECL_NOTHROW
+ inline bool operator>=(const const_iterator& other) const noexcept
{ return i >= other.i; }
#endif
inline iterator &operator++() { ++i; return *this; }
@@ -284,27 +296,27 @@ public:
typedef const T *pointer;
typedef const T &reference;
- inline const_iterator() Q_DECL_NOTHROW : i(nullptr) {}
- inline const_iterator(Node *n) Q_DECL_NOTHROW : i(n) {}
+ inline const_iterator() noexcept : i(nullptr) {}
+ inline const_iterator(Node *n) noexcept : i(n) {}
#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
// can't remove it in Qt 5, since doing so would make the type trivial,
// which changes the way it's passed to functions by value.
- inline const_iterator(const const_iterator &o) Q_DECL_NOTHROW : i(o.i) {}
+ inline const_iterator(const const_iterator &o) noexcept : i(o.i) {}
#endif
#ifdef QT_STRICT_ITERATORS
- inline explicit const_iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i) {}
+ inline explicit const_iterator(const iterator &o) noexcept : i(o.i) {}
#else
- inline const_iterator(const iterator &o) Q_DECL_NOTHROW : i(o.i) {}
+ inline const_iterator(const iterator &o) noexcept : i(o.i) {}
#endif
inline const T &operator*() const { return i->t(); }
inline const T *operator->() const { return &i->t(); }
inline const T &operator[](difference_type j) const { return i[j].t(); }
- inline bool operator==(const const_iterator &o) const Q_DECL_NOTHROW { return i == o.i; }
- inline bool operator!=(const const_iterator &o) const Q_DECL_NOTHROW { return i != o.i; }
- inline bool operator<(const const_iterator& other) const Q_DECL_NOTHROW { return i < other.i; }
- inline bool operator<=(const const_iterator& other) const Q_DECL_NOTHROW { return i <= other.i; }
- inline bool operator>(const const_iterator& other) const Q_DECL_NOTHROW { return i > other.i; }
- inline bool operator>=(const const_iterator& other) const Q_DECL_NOTHROW { return i >= other.i; }
+ inline bool operator==(const const_iterator &o) const noexcept { return i == o.i; }
+ inline bool operator!=(const const_iterator &o) const noexcept { return i != o.i; }
+ inline bool operator<(const const_iterator& other) const noexcept { return i < other.i; }
+ inline bool operator<=(const const_iterator& other) const noexcept { return i <= other.i; }
+ inline bool operator>(const const_iterator& other) const noexcept { return i > other.i; }
+ inline bool operator>=(const const_iterator& other) const noexcept { return i >= other.i; }
inline const_iterator &operator++() { ++i; return *this; }
inline const_iterator operator++(int) { Node *n = i; ++i; return n; }
inline const_iterator &operator--() { i--; return *this; }
@@ -322,19 +334,19 @@ public:
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
inline iterator begin() { detach(); return reinterpret_cast<Node *>(p.begin()); }
- inline const_iterator begin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); }
- inline const_iterator cbegin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); }
- inline const_iterator constBegin() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.begin()); }
+ inline const_iterator begin() const noexcept { return reinterpret_cast<Node *>(p.begin()); }
+ inline const_iterator cbegin() const noexcept { return reinterpret_cast<Node *>(p.begin()); }
+ inline const_iterator constBegin() const noexcept { return reinterpret_cast<Node *>(p.begin()); }
inline iterator end() { detach(); return reinterpret_cast<Node *>(p.end()); }
- inline const_iterator end() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); }
- inline const_iterator cend() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); }
- inline const_iterator constEnd() const Q_DECL_NOTHROW { return reinterpret_cast<Node *>(p.end()); }
+ inline const_iterator end() const noexcept { return reinterpret_cast<Node *>(p.end()); }
+ inline const_iterator cend() const noexcept { return reinterpret_cast<Node *>(p.end()); }
+ inline const_iterator constEnd() const noexcept { return reinterpret_cast<Node *>(p.end()); }
reverse_iterator rbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
- const_reverse_iterator rbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
- const_reverse_iterator rend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
- const_reverse_iterator crbegin() const Q_DECL_NOTHROW { return const_reverse_iterator(end()); }
- const_reverse_iterator crend() const Q_DECL_NOTHROW { return const_reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(end()); }
+ const_reverse_iterator crend() const noexcept { return const_reverse_iterator(begin()); }
iterator insert(iterator before, const T &t);
iterator erase(iterator pos);
iterator erase(iterator first, iterator last);
@@ -411,7 +423,7 @@ private:
void node_copy(Node *from, Node *to, Node *src);
void node_destruct(Node *from, Node *to);
- bool isValidIterator(const iterator &i) const Q_DECL_NOTHROW
+ bool isValidIterator(const iterator &i) const noexcept
{
const std::less<const Node *> less = {};
return !less(i.i, cbegin().i) && !less(cend().i, i.i);
@@ -514,7 +526,7 @@ inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t)
Q_ASSERT_X(isValidIterator(before), "QList::insert", "The specified iterator argument 'before' is invalid");
int iBefore = int(before.i - reinterpret_cast<Node *>(p.begin()));
- Node *n = 0;
+ Node *n = nullptr;
if (d->ref.isShared())
n = detach_helper_grow(iBefore, 1);
else
@@ -689,7 +701,7 @@ inline void QList<T>::replace(int i, const T &t)
}
template <typename T>
-inline void QList<T>::swap(int i, int j)
+inline void QList<T>::swapItemsAt(int i, int j)
{
Q_ASSERT_X(i >= 0 && i < p.size() && j >= 0 && j < p.size(),
"QList<T>::swap", "index out of range");
@@ -970,35 +982,57 @@ inline void QList<T>::append(const QList<T> &t)
template <typename T>
Q_OUTOFLINE_TEMPLATE int QList<T>::indexOf(const T &t, int from) const
{
+ return QtPrivate::indexOf<T, T>(*this, t, from);
+}
+
+namespace QtPrivate
+{
+template <typename T, typename U>
+int indexOf(const QList<T> &list, const U &u, int from)
+{
+ typedef typename QList<T>::Node Node;
+
if (from < 0)
- from = qMax(from + p.size(), 0);
- if (from < p.size()) {
- Node *n = reinterpret_cast<Node *>(p.at(from -1));
- Node *e = reinterpret_cast<Node *>(p.end());
+ from = qMax(from + list.p.size(), 0);
+ if (from < list.p.size()) {
+ Node *n = reinterpret_cast<Node *>(list.p.at(from -1));
+ Node *e = reinterpret_cast<Node *>(list.p.end());
while (++n != e)
- if (n->t() == t)
- return int(n - reinterpret_cast<Node *>(p.begin()));
+ if (n->t() == u)
+ return int(n - reinterpret_cast<Node *>(list.p.begin()));
}
return -1;
}
+}
template <typename T>
Q_OUTOFLINE_TEMPLATE int QList<T>::lastIndexOf(const T &t, int from) const
{
+ return QtPrivate::lastIndexOf<T, T>(*this, t, from);
+}
+
+namespace QtPrivate
+{
+template <typename T, typename U>
+int lastIndexOf(const QList<T> &list, const U &u, int from)
+{
+ typedef typename QList<T>::Node Node;
+
if (from < 0)
- from += p.size();
- else if (from >= p.size())
- from = p.size()-1;
+ from += list.p.size();
+ else if (from >= list.p.size())
+ from = list.p.size()-1;
if (from >= 0) {
- Node *b = reinterpret_cast<Node *>(p.begin());
- Node *n = reinterpret_cast<Node *>(p.at(from + 1));
+ Node *b = reinterpret_cast<Node *>(list.p.begin());
+ Node *n = reinterpret_cast<Node *>(list.p.at(from + 1));
while (n-- != b) {
- if (n->t() == t)
+ if (n->t() == u)
return n - b;
}
}
return -1;
}
+}
template <typename T>
Q_OUTOFLINE_TEMPLATE bool QList<T>::contains(const T &t) const
@@ -1051,19 +1085,50 @@ inline int QList<T>::count_impl(const T &t, QListData::ArrayCompatibleLayout) co
t));
}
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QVector<T> QList<T>::toVector() const
+{
+ QVector<T> result(size());
+ for (int i = 0; i < size(); ++i)
+ result[i] = at(i);
+ return result;
+}
+
+template <typename T>
+QList<T> QList<T>::fromVector(const QVector<T> &vector)
+{
+ return vector.toList();
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const
+{
+ QList<T> result;
+ result.reserve(size());
+ for (int i = 0; i < size(); ++i)
+ result.append(at(i));
+ return result;
+}
+
+template <typename T>
+QVector<T> QVector<T>::fromList(const QList<T> &list)
+{
+ return list.toVector();
+}
+
Q_DECLARE_SEQUENTIAL_ITERATOR(List)
Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(List)
template <typename T>
uint qHash(const QList<T> &key, uint seed = 0)
- Q_DECL_NOEXCEPT_EXPR(noexcept(qHashRange(key.cbegin(), key.cend(), seed)))
+ noexcept(noexcept(qHashRange(key.cbegin(), key.cend(), seed)))
{
return qHashRange(key.cbegin(), key.cend(), seed);
}
template <typename T>
bool operator<(const QList<T> &lhs, const QList<T> &rhs)
- Q_DECL_NOEXCEPT_EXPR(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(),
+ noexcept(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(),
rhs.begin(), rhs.end())))
{
return std::lexicographical_compare(lhs.begin(), lhs.end(),
@@ -1072,21 +1137,21 @@ bool operator<(const QList<T> &lhs, const QList<T> &rhs)
template <typename T>
inline bool operator>(const QList<T> &lhs, const QList<T> &rhs)
- Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+ noexcept(noexcept(lhs < rhs))
{
return rhs < lhs;
}
template <typename T>
inline bool operator<=(const QList<T> &lhs, const QList<T> &rhs)
- Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+ noexcept(noexcept(lhs < rhs))
{
return !(lhs > rhs);
}
template <typename T>
inline bool operator>=(const QList<T> &lhs, const QList<T> &rhs)
- Q_DECL_NOEXCEPT_EXPR(noexcept(lhs < rhs))
+ noexcept(noexcept(lhs < rhs))
{
return !(lhs < rhs);
}