diff options
Diffstat (limited to 'src/corelib/tools/qlist.h')
-rw-r--r-- | src/corelib/tools/qlist.h | 203 |
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); } |