diff options
Diffstat (limited to 'src/corelib/tools/qiterator.h')
-rw-r--r-- | src/corelib/tools/qiterator.h | 186 |
1 files changed, 130 insertions, 56 deletions
diff --git a/src/corelib/tools/qiterator.h b/src/corelib/tools/qiterator.h index 16c2d7f07c..8a2b493ef4 100644 --- a/src/corelib/tools/qiterator.h +++ b/src/corelib/tools/qiterator.h @@ -1,51 +1,23 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QITERATOR_H #define QITERATOR_H #include <QtCore/qglobal.h> +#include <QtCore/qcontainertools_impl.h> QT_BEGIN_NAMESPACE #if !defined(QT_NO_JAVA_STYLE_ITERATORS) +#ifdef Q_QDOC +#define Q_DISABLE_BACKWARD_ITERATOR +#else +#define Q_DISABLE_BACKWARD_ITERATOR \ + template<typename It = decltype(i), QtPrivate::IfIteratorCanMoveBackwards<It> = true> +#endif + #define Q_DECLARE_SEQUENTIAL_ITERATOR(C) \ \ template <class T> \ @@ -64,11 +36,15 @@ public: \ inline bool hasNext() const { return i != c.constEnd(); } \ inline const T &next() { return *i++; } \ inline const T &peekNext() const { return *i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool hasPrevious() const { return i != c.constBegin(); } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline const T &previous() { return *--i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \ inline bool findNext(const T &t) \ { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool findPrevious(const T &t) \ { while (i != c.constBegin()) if (*(--i) == t) return true; \ return false; } \ @@ -95,8 +71,11 @@ public: \ inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \ inline T &next() { n = i++; return *n; } \ inline T &peekNext() const { return *i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline T &previous() { n = --i; return *n; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline T &peekPrevious() const { iterator p = i; return *--p; } \ inline void remove() \ { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \ @@ -106,6 +85,7 @@ public: \ inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \ inline bool findNext(const T &t) \ { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool findPrevious(const T &t) \ { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \ n = c->end(); return false; } \ @@ -131,13 +111,17 @@ public: \ inline bool hasNext() const { return i != c.constEnd(); } \ inline Item next() { n = i++; return n; } \ inline Item peekNext() const { return i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool hasPrevious() const { return i != c.constBegin(); } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline Item previous() { n = --i; return n; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline Item peekPrevious() const { const_iterator p = i; return --p; } \ inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \ inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \ inline bool findNext(const T &t) \ { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool findPrevious(const T &t) \ { while (i != c.constBegin()) if (*(n = --i) == t) return true; \ n = c.constEnd(); return false; } \ @@ -165,8 +149,11 @@ public: \ inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \ inline Item next() { n = i++; return n; } \ inline Item peekNext() const { return i; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline Item previous() { n = --i; return n; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline Item peekPrevious() const { iterator p = i; return --p; } \ inline void remove() \ { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \ @@ -176,16 +163,78 @@ public: \ inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \ inline bool findNext(const T &t) \ { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \ + Q_DISABLE_BACKWARD_ITERATOR \ inline bool findPrevious(const T &t) \ { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) return true; \ n = c->end(); return false; } \ }; +#define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C) \ +\ +template <class Key, class T> \ +class Q##C##Iterator \ +{ \ + typedef typename Q##C<Key,T>::const_iterator const_iterator; \ + Q##C<Key,T> c; \ + const_iterator i, n; \ + inline bool item_exists() const { return n != c.constEnd(); } \ +public: \ + typedef const_iterator Item; \ + inline Q##C##Iterator(const Q##C<Key,T> &container) \ + : c(container), i(c.constBegin()), n(c.constEnd()) {} \ + inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \ + { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \ + inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \ + inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \ + inline bool hasNext() const { return i != c.constEnd(); } \ + inline Item next() { n = i++; return n; } \ + inline Item peekNext() const { return i; } \ + inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \ + inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \ + inline bool findNext(const T &t) \ + { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \ +}; + +#define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C) \ +\ +template <class Key, class T> \ +class QMutable##C##Iterator \ +{ \ + typedef typename Q##C<Key,T>::iterator iterator; \ + typedef typename Q##C<Key,T>::const_iterator const_iterator; \ + Q##C<Key,T> *c; \ + iterator i, n; \ + inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \ +public: \ + typedef iterator Item; \ + inline QMutable##C##Iterator(Q##C<Key,T> &container) \ + : c(&container) \ + { i = c->begin(); n = c->end(); } \ + inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \ + { c = &container; i = c->begin(); n = c->end(); return *this; } \ + inline void toFront() { i = c->begin(); n = c->end(); } \ + inline void toBack() { i = c->end(); n = c->end(); } \ + inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \ + inline Item next() { n = i++; return n; } \ + inline Item peekNext() const { return i; } \ + inline void remove() \ + { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \ + inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \ + inline T &value() { Q_ASSERT(item_exists()); return *n; } \ + inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \ + inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \ + inline bool findNext(const T &t) \ + { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \ +}; + + #else // QT_NO_JAVA_STYLE_ITERATORS #define Q_DECLARE_SEQUENTIAL_ITERATOR(C) #define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) #define Q_DECLARE_ASSOCIATIVE_ITERATOR(C) #define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C) +#define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C) +#define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C) #endif // QT_NO_JAVA_STYLE_ITERATORS template<typename Key, typename T, class Iterator> @@ -205,26 +254,10 @@ public: return std::pair<Key, T>(i.key(), i.value()); } - struct pointer - { - pointer(value_type &&r_) : r(std::move(r_)) { } - - pointer() = default; - pointer(const pointer &other) = default; - pointer(pointer &&other) = default; - pointer &operator=(const pointer &other) = default; - pointer &operator=(pointer &&other) = default; - - value_type &operator*() const { return r; } - - value_type r; - const value_type *operator->() const { - return &r; - } - }; + using pointer = QtPrivate::ArrowProxy<value_type>; pointer operator->() const { - return pointer(std::pair<Key, T>(i.key(), i.value())); + return pointer{std::pair<Key, T>(i.key(), i.value())}; } friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i == rhs.i; } @@ -240,6 +273,47 @@ private: Iterator i; }; +namespace QtPrivate { + +template <typename Map> +class QKeyValueRangeStorage +{ +protected: + Map m_map; +public: + explicit QKeyValueRangeStorage(const Map &map) : m_map(map) {} + explicit QKeyValueRangeStorage(Map &&map) : m_map(std::move(map)) {} +}; + +template <typename Map> +class QKeyValueRangeStorage<Map &> +{ +protected: + Map &m_map; +public: + explicit QKeyValueRangeStorage(Map &map) : m_map(map) {} +}; + +template <typename Map> +class QKeyValueRange : public QKeyValueRangeStorage<Map> +{ +public: + using QKeyValueRangeStorage<Map>::QKeyValueRangeStorage; + auto begin() { return this->m_map.keyValueBegin(); } + auto begin() const { return this->m_map.keyValueBegin(); } + auto end() { return this->m_map.keyValueEnd(); } + auto end() const { return this->m_map.keyValueEnd(); } +}; + +template <typename Map> +QKeyValueRange(Map &) -> QKeyValueRange<Map &>; + +template <typename Map, std::enable_if_t<!std::is_reference_v<Map>, bool> = false> +QKeyValueRange(Map &&) -> QKeyValueRange<std::remove_const_t<Map>>; + +} // namespace QtPrivate + + QT_END_NAMESPACE #endif // QITERATOR_H |