Make QVector compile with QT_STRICT_ITERATORS again
authorThiago Macieira <thiago.macieira@intel.com>
Thu, 24 May 2012 14:24:19 +0000 (16:24 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 1 Jun 2012 10:27:32 +0000 (12:27 +0200)
Move the iterator classes into QArrayTypedData and add constBegin()
and constEnd() to that class.

I also had to add an operator T*() to the strict iterators, since
there are many places that expect the iterator to behave like a
pointer (including in QVector itself).

Change-Id: Icc5ed56ad47b013664a48eef9d31b5273aecb4e3
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@nokia.com>
src/corelib/tools/qarraydata.h
src/corelib/tools/qvector.h
tests/auto/other/collections/collections.pro

index ae78fec..86ad762 100644 (file)
@@ -132,16 +132,89 @@ template <class T>
 struct QTypedArrayData
     : QArrayData
 {
-    typedef T *iterator;
-    typedef const T *const_iterator;
+#ifdef QT_STRICT_ITERATORS
+    class iterator {
+    public:
+        T *i;
+        typedef std::random_access_iterator_tag  iterator_category;
+        typedef qptrdiff difference_type;
+        typedef T value_type;
+        typedef T *pointer;
+        typedef T &reference;
+
+        inline iterator() : i(0) {}
+        inline iterator(T *n) : i(n) {}
+        inline iterator(const iterator &o): i(o.i){}
+        inline T &operator*() const { return *i; }
+        inline T *operator->() const { return i; }
+        inline T &operator[](int j) const { return *(i + j); }
+        inline bool operator==(const iterator &o) const { return i == o.i; }
+        inline bool operator!=(const iterator &o) const { return i != o.i; }
+        inline bool operator<(const iterator& other) const { return i < other.i; }
+        inline bool operator<=(const iterator& other) const { return i <= other.i; }
+        inline bool operator>(const iterator& other) const { return i > other.i; }
+        inline bool operator>=(const iterator& other) const { return i >= other.i; }
+        inline iterator &operator++() { ++i; return *this; }
+        inline iterator operator++(int) { T *n = i; ++i; return n; }
+        inline iterator &operator--() { i--; return *this; }
+        inline iterator operator--(int) { T *n = i; i--; return n; }
+        inline iterator &operator+=(int j) { i+=j; return *this; }
+        inline iterator &operator-=(int j) { i-=j; return *this; }
+        inline iterator operator+(int j) const { return iterator(i+j); }
+        inline iterator operator-(int j) const { return iterator(i-j); }
+        inline int operator-(iterator j) const { return i - j.i; }
+        inline operator T*() const { return i; }
+    };
+    friend class iterator;
+
+    class const_iterator {
+    public:
+        const T *i;
+        typedef std::random_access_iterator_tag  iterator_category;
+        typedef qptrdiff difference_type;
+        typedef T value_type;
+        typedef const T *pointer;
+        typedef const T &reference;
+
+        inline const_iterator() : i(0) {}
+        inline const_iterator(const T *n) : i(n) {}
+        inline const_iterator(const const_iterator &o): i(o.i) {}
+        inline explicit const_iterator(const iterator &o): i(o.i) {}
+        inline const T &operator*() const { return *i; }
+        inline const T *operator->() const { return i; }
+        inline const T &operator[](int j) const { return *(i + j); }
+        inline bool operator==(const const_iterator &o) const { return i == o.i; }
+        inline bool operator!=(const const_iterator &o) const { return i != o.i; }
+        inline bool operator<(const const_iterator& other) const { return i < other.i; }
+        inline bool operator<=(const const_iterator& other) const { return i <= other.i; }
+        inline bool operator>(const const_iterator& other) const { return i > other.i; }
+        inline bool operator>=(const const_iterator& other) const { return i >= other.i; }
+        inline const_iterator &operator++() { ++i; return *this; }
+        inline const_iterator operator++(int) { T *n = i; ++i; return n; }
+        inline const_iterator &operator--() { i--; return *this; }
+        inline const_iterator operator--(int) { T *n = i; i--; return n; }
+        inline const_iterator &operator+=(int j) { i+=j; return *this; }
+        inline const_iterator &operator-=(int j) { i-=j; return *this; }
+        inline const_iterator operator+(int j) const { return const_iterator(i+j); }
+        inline const_iterator operator-(int j) const { return const_iterator(i-j); }
+        inline int operator-(const_iterator j) const { return i - j.i; }
+        inline operator const T*() const { return i; }
+    };
+    friend class const_iterator;
+#else
+    typedef T* iterator;
+    typedef const T* const_iterator;
+#endif
 
     T *data() { return static_cast<T *>(QArrayData::data()); }
     const T *data() const { return static_cast<const T *>(QArrayData::data()); }
 
-    T *begin() { return data(); }
-    T *end() { return data() + size; }
-    const T *begin() const { return data(); }
-    const T *end() const { return data() + size; }
+    iterator begin() { return data(); }
+    iterator end() { return data() + size; }
+    const_iterator begin() const { return data(); }
+    const_iterator end() const { return data() + size; }
+    const_iterator constBegin() const { return data(); }
+    const_iterator constEnd() const { return data() + size; }
 
     class AlignmentDummy { QArrayData header; T data; };
 
index 581d871..06c269b 100644 (file)
@@ -148,86 +148,17 @@ public:
     bool contains(const T &t) const;
     int count(const T &t) const;
 
-#ifdef QT_STRICT_ITERATORS
-    class iterator {
-    public:
-        T *i;
-        typedef std::random_access_iterator_tag  iterator_category;
-        typedef qptrdiff difference_type;
-        typedef T value_type;
-        typedef T *pointer;
-        typedef T &reference;
-
-        inline iterator() : i(0) {}
-        inline iterator(T *n) : i(n) {}
-        inline iterator(const iterator &o): i(o.i){}
-        inline T &operator*() const { return *i; }
-        inline T *operator->() const { return i; }
-        inline T &operator[](int j) const { return *(i + j); }
-        inline bool operator==(const iterator &o) const { return i == o.i; }
-        inline bool operator!=(const iterator &o) const { return i != o.i; }
-        inline bool operator<(const iterator& other) const { return i < other.i; }
-        inline bool operator<=(const iterator& other) const { return i <= other.i; }
-        inline bool operator>(const iterator& other) const { return i > other.i; }
-        inline bool operator>=(const iterator& other) const { return i >= other.i; }
-        inline iterator &operator++() { ++i; return *this; }
-        inline iterator operator++(int) { T *n = i; ++i; return n; }
-        inline iterator &operator--() { i--; return *this; }
-        inline iterator operator--(int) { T *n = i; i--; return n; }
-        inline iterator &operator+=(int j) { i+=j; return *this; }
-        inline iterator &operator-=(int j) { i-=j; return *this; }
-        inline iterator operator+(int j) const { return iterator(i+j); }
-        inline iterator operator-(int j) const { return iterator(i-j); }
-        inline int operator-(iterator j) const { return i - j.i; }
-    };
-    friend class iterator;
-
-    class const_iterator {
-    public:
-        T *i;
-        typedef std::random_access_iterator_tag  iterator_category;
-        typedef qptrdiff difference_type;
-        typedef T value_type;
-        typedef const T *pointer;
-        typedef const T &reference;
-
-        inline const_iterator() : i(0) {}
-        inline const_iterator(T *n) : i(n) {}
-        inline const_iterator(const const_iterator &o): i(o.i) {}
-        inline explicit const_iterator(const iterator &o): i(o.i) {}
-        inline const T &operator*() const { return *i; }
-        inline const T *operator->() const { return i; }
-        inline const T &operator[](int j) const { return *(i + j); }
-        inline bool operator==(const const_iterator &o) const { return i == o.i; }
-        inline bool operator!=(const const_iterator &o) const { return i != o.i; }
-        inline bool operator<(const const_iterator& other) const { return i < other.i; }
-        inline bool operator<=(const const_iterator& other) const { return i <= other.i; }
-        inline bool operator>(const const_iterator& other) const { return i > other.i; }
-        inline bool operator>=(const const_iterator& other) const { return i >= other.i; }
-        inline const_iterator &operator++() { ++i; return *this; }
-        inline const_iterator operator++(int) { T *n = i; ++i; return n; }
-        inline const_iterator &operator--() { i--; return *this; }
-        inline const_iterator operator--(int) { T *n = i; i--; return n; }
-        inline const_iterator &operator+=(int j) { i+=j; return *this; }
-        inline const_iterator &operator-=(int j) { i-=j; return *this; }
-        inline const_iterator operator+(int j) const { return const_iterator(i+j); }
-        inline const_iterator operator-(int j) const { return const_iterator(i-j); }
-        inline int operator-(const_iterator j) const { return i - j.i; }
-    };
-    friend class const_iterator;
-#else
     // STL-style
-    typedef T* iterator;
-    typedef const T* const_iterator;
-#endif
+    typedef typename Data::iterator iterator;
+    typedef typename Data::const_iterator const_iterator;
     inline iterator begin() { detach(); return d->begin(); }
-    inline const_iterator begin() const { return d->begin(); }
-    inline const_iterator cbegin() const { return d->begin(); }
-    inline const_iterator constBegin() const { return d->begin(); }
+    inline const_iterator begin() const { return d->constBegin(); }
+    inline const_iterator cbegin() const { return d->constBegin(); }
+    inline const_iterator constBegin() const { return d->constBegin(); }
     inline iterator end() { detach(); return d->end(); }
-    inline const_iterator end() const { return d->end(); }
-    inline const_iterator cend() const { return d->end(); }
-    inline const_iterator constEnd() const { return d->end(); }
+    inline const_iterator end() const { return d->constEnd(); }
+    inline const_iterator cend() const { return d->constEnd(); }
+    inline const_iterator constEnd() const { return d->constEnd(); }
     iterator insert(iterator before, int n, const T &x);
     inline iterator insert(iterator before, const T &x) { return insert(before, 1, x); }
     iterator erase(iterator begin, iterator end);
@@ -617,7 +548,7 @@ void QVector<T>::append(const T &t)
 template <typename T>
 typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, const T &t)
 {
-    int offset = int(before - d->begin());
+    int offset = std::distance(d->begin(), before);
     if (n != 0) {
         const T copy(t);
         if (!isDetached() || d->size + n > int(d->alloc))
@@ -650,8 +581,10 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
 template <typename T>
 typename QVector<T>::iterator QVector<T>::erase(iterator abegin, iterator aend)
 {
-    abegin = qMax(abegin, d->begin());
-    aend = qMin(aend, d->end());
+    if (abegin < d->begin())
+        abegin = d->begin();
+    if (aend > d->end())
+        aend = d->end();
 
     Q_ASSERT(abegin <= aend);
 
index 364ae21..292c4e7 100644 (file)
@@ -3,3 +3,6 @@ TARGET = tst_collections
 SOURCES  += tst_collections.cpp
 QT = core testlib
 CONFIG += parallel_test
+
+# This test does not work with strict iterators
+DEFINES -= QT_STRICT_ITERATORS