Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:07:26

0001 // Copyright (C) 2016 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 
0004 #ifndef QITERATOR_H
0005 #define QITERATOR_H
0006 
0007 #include <QtCore/qglobal.h>
0008 
0009 QT_BEGIN_NAMESPACE
0010 
0011 #if !defined(QT_NO_JAVA_STYLE_ITERATORS)
0012 
0013 #ifdef Q_QDOC
0014 #define Q_DISABLE_BACKWARD_ITERATOR
0015 #else
0016 #define Q_DISABLE_BACKWARD_ITERATOR \
0017         template<typename It = decltype(i), QtPrivate::IfIteratorCanMoveBackwards<It> = true>
0018 #endif
0019 
0020 #define Q_DECLARE_SEQUENTIAL_ITERATOR(C) \
0021 \
0022 template <class T> \
0023 class Q##C##Iterator \
0024 { \
0025     typedef typename Q##C<T>::const_iterator const_iterator; \
0026     Q##C<T> c; \
0027     const_iterator i; \
0028 public: \
0029     inline Q##C##Iterator(const Q##C<T> &container) \
0030         : c(container), i(c.constBegin()) {} \
0031     inline Q##C##Iterator &operator=(const Q##C<T> &container) \
0032     { c = container; i = c.constBegin(); return *this; } \
0033     inline void toFront() { i = c.constBegin(); } \
0034     inline void toBack() { i = c.constEnd(); } \
0035     inline bool hasNext() const { return i != c.constEnd(); } \
0036     inline const T &next() { return *i++; } \
0037     inline const T &peekNext() const { return *i; } \
0038     Q_DISABLE_BACKWARD_ITERATOR \
0039     inline bool hasPrevious() const { return i != c.constBegin(); } \
0040     Q_DISABLE_BACKWARD_ITERATOR \
0041     inline const T &previous() { return *--i; } \
0042     Q_DISABLE_BACKWARD_ITERATOR \
0043     inline const T &peekPrevious() const { const_iterator p = i; return *--p; } \
0044     inline bool findNext(const T &t) \
0045     { while (i != c.constEnd()) if (*i++ == t) return true; return false; } \
0046     Q_DISABLE_BACKWARD_ITERATOR \
0047     inline bool findPrevious(const T &t) \
0048     { while (i != c.constBegin()) if (*(--i) == t) return true; \
0049       return false;  } \
0050 };
0051 
0052 #define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C) \
0053 \
0054 template <class T> \
0055 class QMutable##C##Iterator \
0056 { \
0057     typedef typename Q##C<T>::iterator iterator; \
0058     typedef typename Q##C<T>::const_iterator const_iterator; \
0059     Q##C<T> *c; \
0060     iterator i, n; \
0061     inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
0062 public: \
0063     inline QMutable##C##Iterator(Q##C<T> &container) \
0064         : c(&container) \
0065     { i = c->begin(); n = c->end(); } \
0066     inline QMutable##C##Iterator &operator=(Q##C<T> &container) \
0067     { c = &container; i = c->begin(); n = c->end(); return *this; } \
0068     inline void toFront() { i = c->begin(); n = c->end(); } \
0069     inline void toBack() { i = c->end(); n = i; } \
0070     inline bool hasNext() const { return c->constEnd() != const_iterator(i); } \
0071     inline T &next() { n = i++; return *n; } \
0072     inline T &peekNext() const { return *i; } \
0073     Q_DISABLE_BACKWARD_ITERATOR \
0074     inline bool hasPrevious() const { return c->constBegin() != const_iterator(i); } \
0075     Q_DISABLE_BACKWARD_ITERATOR \
0076     inline T &previous() { n = --i; return *n; } \
0077     Q_DISABLE_BACKWARD_ITERATOR \
0078     inline T &peekPrevious() const { iterator p = i; return *--p; } \
0079     inline void remove() \
0080     { if (c->constEnd() != const_iterator(n)) { i = c->erase(n); n = c->end(); } } \
0081     inline void setValue(const T &t) const { if (c->constEnd() != const_iterator(n)) *n = t; } \
0082     inline T &value() { Q_ASSERT(item_exists()); return *n; } \
0083     inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0084     inline void insert(const T &t) { n = i = c->insert(i, t); ++i; } \
0085     inline bool findNext(const T &t) \
0086     { while (c->constEnd() != const_iterator(n = i)) if (*i++ == t) return true; return false; } \
0087     Q_DISABLE_BACKWARD_ITERATOR \
0088     inline bool findPrevious(const T &t) \
0089     { while (c->constBegin() != const_iterator(i)) if (*(n = --i) == t) return true; \
0090       n = c->end(); return false;  } \
0091 };
0092 
0093 #define Q_DECLARE_ASSOCIATIVE_ITERATOR(C) \
0094 \
0095 template <class Key, class T> \
0096 class Q##C##Iterator \
0097 { \
0098     typedef typename Q##C<Key,T>::const_iterator const_iterator; \
0099     Q##C<Key,T> c; \
0100     const_iterator i, n; \
0101     inline bool item_exists() const { return n != c.constEnd(); } \
0102 public: \
0103     typedef const_iterator Item; \
0104     inline Q##C##Iterator(const Q##C<Key,T> &container) \
0105         : c(container), i(c.constBegin()), n(c.constEnd()) {} \
0106     inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
0107     { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \
0108     inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \
0109     inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \
0110     inline bool hasNext() const { return i != c.constEnd(); } \
0111     inline Item next() { n = i++; return n; } \
0112     inline Item peekNext() const { return i; } \
0113     Q_DISABLE_BACKWARD_ITERATOR \
0114     inline bool hasPrevious() const { return i != c.constBegin(); } \
0115     Q_DISABLE_BACKWARD_ITERATOR \
0116     inline Item previous() { n = --i; return n; } \
0117     Q_DISABLE_BACKWARD_ITERATOR \
0118     inline Item peekPrevious() const { const_iterator p = i; return --p; } \
0119     inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0120     inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
0121     inline bool findNext(const T &t) \
0122     { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \
0123     Q_DISABLE_BACKWARD_ITERATOR \
0124     inline bool findPrevious(const T &t) \
0125     { while (i != c.constBegin()) if (*(n = --i) == t) return true; \
0126       n = c.constEnd(); return false; } \
0127 };
0128 
0129 #define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C) \
0130 \
0131 template <class Key, class T> \
0132 class QMutable##C##Iterator \
0133 { \
0134     typedef typename Q##C<Key,T>::iterator iterator; \
0135     typedef typename Q##C<Key,T>::const_iterator const_iterator; \
0136     Q##C<Key,T> *c; \
0137     iterator i, n; \
0138     inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
0139 public: \
0140     typedef iterator Item; \
0141     inline QMutable##C##Iterator(Q##C<Key,T> &container) \
0142         : c(&container) \
0143     { i = c->begin(); n = c->end(); } \
0144     inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \
0145     { c = &container; i = c->begin(); n = c->end(); return *this; } \
0146     inline void toFront() { i = c->begin(); n = c->end(); } \
0147     inline void toBack() { i = c->end(); n = c->end(); } \
0148     inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \
0149     inline Item next() { n = i++; return n; } \
0150     inline Item peekNext() const { return i; } \
0151     Q_DISABLE_BACKWARD_ITERATOR \
0152     inline bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } \
0153     Q_DISABLE_BACKWARD_ITERATOR \
0154     inline Item previous() { n = --i; return n; } \
0155     Q_DISABLE_BACKWARD_ITERATOR \
0156     inline Item peekPrevious() const { iterator p = i; return --p; } \
0157     inline void remove() \
0158     { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \
0159     inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \
0160     inline T &value() { Q_ASSERT(item_exists()); return *n; } \
0161     inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0162     inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
0163     inline bool findNext(const T &t) \
0164     { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \
0165     Q_DISABLE_BACKWARD_ITERATOR \
0166     inline bool findPrevious(const T &t) \
0167     { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) return true; \
0168       n = c->end(); return false; } \
0169 };
0170 
0171 #define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C) \
0172 \
0173 template <class Key, class T> \
0174 class Q##C##Iterator \
0175 { \
0176     typedef typename Q##C<Key,T>::const_iterator const_iterator; \
0177     Q##C<Key,T> c; \
0178     const_iterator i, n; \
0179     inline bool item_exists() const { return n != c.constEnd(); } \
0180 public: \
0181     typedef const_iterator Item; \
0182     inline Q##C##Iterator(const Q##C<Key,T> &container) \
0183         : c(container), i(c.constBegin()), n(c.constEnd()) {} \
0184     inline Q##C##Iterator &operator=(const Q##C<Key,T> &container) \
0185     { c = container; i = c.constBegin(); n = c.constEnd(); return *this; } \
0186     inline void toFront() { i = c.constBegin(); n = c.constEnd(); } \
0187     inline void toBack() { i = c.constEnd(); n = c.constEnd(); } \
0188     inline bool hasNext() const { return i != c.constEnd(); } \
0189     inline Item next() { n = i++; return n; } \
0190     inline Item peekNext() const { return i; } \
0191     inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0192     inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
0193     inline bool findNext(const T &t) \
0194     { while ((n = i) != c.constEnd()) if (*i++ == t) return true; return false; } \
0195 };
0196 
0197 #define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C) \
0198 \
0199 template <class Key, class T> \
0200 class QMutable##C##Iterator \
0201 { \
0202     typedef typename Q##C<Key,T>::iterator iterator; \
0203     typedef typename Q##C<Key,T>::const_iterator const_iterator; \
0204     Q##C<Key,T> *c; \
0205     iterator i, n; \
0206     inline bool item_exists() const { return const_iterator(n) != c->constEnd(); } \
0207 public: \
0208     typedef iterator Item; \
0209     inline QMutable##C##Iterator(Q##C<Key,T> &container) \
0210         : c(&container) \
0211     { i = c->begin(); n = c->end(); } \
0212     inline QMutable##C##Iterator &operator=(Q##C<Key,T> &container) \
0213     { c = &container; i = c->begin(); n = c->end(); return *this; } \
0214     inline void toFront() { i = c->begin(); n = c->end(); } \
0215     inline void toBack() { i = c->end(); n = c->end(); } \
0216     inline bool hasNext() const { return const_iterator(i) != c->constEnd(); } \
0217     inline Item next() { n = i++; return n; } \
0218     inline Item peekNext() const { return i; } \
0219     inline void remove() \
0220     { if (const_iterator(n) != c->constEnd()) { i = c->erase(n); n = c->end(); } } \
0221     inline void setValue(const T &t) { if (const_iterator(n) != c->constEnd()) *n = t; } \
0222     inline T &value() { Q_ASSERT(item_exists()); return *n; } \
0223     inline const T &value() const { Q_ASSERT(item_exists()); return *n; } \
0224     inline const Key &key() const { Q_ASSERT(item_exists()); return n.key(); } \
0225     inline bool findNext(const T &t) \
0226     { while (const_iterator(n = i) != c->constEnd()) if (*i++ == t) return true; return false; } \
0227 };
0228 
0229 
0230 #else // QT_NO_JAVA_STYLE_ITERATORS
0231 #define Q_DECLARE_SEQUENTIAL_ITERATOR(C)
0232 #define Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR(C)
0233 #define Q_DECLARE_ASSOCIATIVE_ITERATOR(C)
0234 #define Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR(C)
0235 #define Q_DECLARE_ASSOCIATIVE_FORWARD_ITERATOR(C)
0236 #define Q_DECLARE_MUTABLE_ASSOCIATIVE_FORWARD_ITERATOR(C)
0237 #endif // QT_NO_JAVA_STYLE_ITERATORS
0238 
0239 template<typename Key, typename T, class Iterator>
0240 class QKeyValueIterator
0241 {
0242 public:
0243     typedef typename Iterator::iterator_category iterator_category;
0244     typedef typename Iterator::difference_type difference_type;
0245     typedef std::pair<Key, T> value_type;
0246     typedef const value_type &reference;
0247 
0248     QKeyValueIterator() = default;
0249     constexpr explicit QKeyValueIterator(Iterator o) noexcept(std::is_nothrow_move_constructible<Iterator>::value)
0250         : i(std::move(o)) {}
0251 
0252     std::pair<Key, T> operator*() const {
0253         return std::pair<Key, T>(i.key(), i.value());
0254     }
0255 
0256     struct pointer
0257     {
0258         pointer(value_type &&r_) : r(std::move(r_)) { }
0259 
0260         pointer() = default;
0261         pointer(const pointer &other) = default;
0262         pointer(pointer &&other) = default;
0263         pointer &operator=(const pointer &other) = default;
0264         pointer &operator=(pointer &&other) = default;
0265 
0266         value_type &operator*() const { return r; }
0267 
0268         value_type r;
0269         const value_type *operator->() const {
0270             return &r;
0271         }
0272     };
0273 
0274     pointer operator->() const {
0275         return pointer(std::pair<Key, T>(i.key(), i.value()));
0276     }
0277 
0278     friend bool operator==(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i == rhs.i; }
0279     friend bool operator!=(QKeyValueIterator lhs, QKeyValueIterator rhs) noexcept { return lhs.i != rhs.i; }
0280 
0281     inline QKeyValueIterator &operator++() { ++i; return *this; }
0282     inline QKeyValueIterator operator++(int) { return QKeyValueIterator(i++);}
0283     inline QKeyValueIterator &operator--() { --i; return *this; }
0284     inline QKeyValueIterator operator--(int) { return QKeyValueIterator(i--); }
0285     Iterator base() const { return i; }
0286 
0287 private:
0288     Iterator i;
0289 };
0290 
0291 namespace QtPrivate {
0292 
0293 template <typename Map>
0294 class QKeyValueRangeStorage
0295 {
0296 protected:
0297     Map m_map;
0298 public:
0299     explicit QKeyValueRangeStorage(const Map &map) : m_map(map) {}
0300     explicit QKeyValueRangeStorage(Map &&map) : m_map(std::move(map)) {}
0301 };
0302 
0303 template <typename Map>
0304 class QKeyValueRangeStorage<Map &>
0305 {
0306 protected:
0307     Map &m_map;
0308 public:
0309     explicit QKeyValueRangeStorage(Map &map) : m_map(map) {}
0310 };
0311 
0312 template <typename Map>
0313 class QKeyValueRange : public QKeyValueRangeStorage<Map>
0314 {
0315 public:
0316     using QKeyValueRangeStorage<Map>::QKeyValueRangeStorage;
0317     auto begin() { return this->m_map.keyValueBegin(); }
0318     auto begin() const { return this->m_map.keyValueBegin(); }
0319     auto end() { return this->m_map.keyValueEnd(); }
0320     auto end() const { return this->m_map.keyValueEnd(); }
0321 };
0322 
0323 template <typename Map>
0324 QKeyValueRange(Map &) -> QKeyValueRange<Map &>;
0325 
0326 template <typename Map, std::enable_if_t<!std::is_reference_v<Map>, bool> = false>
0327 QKeyValueRange(Map &&) -> QKeyValueRange<std::remove_const_t<Map>>;
0328 
0329 } // namespace QtPrivate
0330 
0331 
0332 QT_END_NAMESPACE
0333 
0334 #endif // QITERATOR_H