Get rid of QT_STRICT_ITERATORS

The concept was a nice idea to avoid accidental detach() calls
in implicitly shared containers, but it conflicts with a C++11
compatible API for them, with signatures for modifying methods
taking a const_iterator as argument and returning an iterator
(e.g. iterator erase(const_iterator)).

Change-Id: Ia33124bedbd260774a0a66f49aedd84e19c9971b
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Lars Knoll 2019-11-03 21:47:23 +01:00 committed by Simon Hausmann
parent ab6affac10
commit 06456873fc
24 changed files with 15 additions and 165 deletions

View File

@ -363,13 +363,8 @@ public:
inline iterator &operator-=(int j) { return *this = *this - j; } inline iterator &operator-=(int j) { return *this = *this - j; }
friend inline iterator operator+(int j, iterator k) { return k + j; } friend inline iterator operator+(int j, iterator k) { return k + j; }
#ifndef QT_STRICT_ITERATORS inline bool operator==(const const_iterator &o) const { return i == o.i; }
public: 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 &o) const
{ return i != o.i; }
#endif
}; };
friend class iterator; friend class iterator;
@ -390,11 +385,7 @@ public:
Q_DECL_CONSTEXPR inline const_iterator() : i(nullptr) { } Q_DECL_CONSTEXPR inline const_iterator() : i(nullptr) { }
explicit inline const_iterator(void *node) explicit inline const_iterator(void *node)
: i(reinterpret_cast<QHashData::Node *>(node)) { } : i(reinterpret_cast<QHashData::Node *>(node)) { }
#ifdef QT_STRICT_ITERATORS
explicit inline const_iterator(const iterator &o)
#else
inline const_iterator(const iterator &o) inline const_iterator(const iterator &o)
#endif
{ i = o.i; } { i = o.i; }
inline const Key &key() const { return concrete(i)->key; } inline const Key &key() const { return concrete(i)->key; }
@ -428,13 +419,6 @@ public:
inline const_iterator &operator+=(int j) { return *this = *this + j; } inline const_iterator &operator+=(int j) { return *this = *this + j; }
inline const_iterator &operator-=(int j) { return *this = *this - j; } inline const_iterator &operator-=(int j) { return *this = *this - j; }
friend inline const_iterator operator+(int j, const_iterator k) { return k + j; } friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
// ### Qt 5: not sure this is necessary anymore
#ifdef QT_STRICT_ITERATORS
private:
inline bool operator==(const iterator &o) const { return operator==(const_iterator(o)); }
inline bool operator!=(const iterator &o) const { return operator!=(const_iterator(o)); }
#endif
}; };
friend class const_iterator; friend class const_iterator;

View File

@ -433,13 +433,8 @@ public:
inline iterator &operator-=(int j) { return *this = *this - j; } inline iterator &operator-=(int j) { return *this = *this - j; }
friend inline iterator operator+(int j, iterator k) { return k + j; } friend inline iterator operator+(int j, iterator k) { return k + j; }
#ifndef QT_STRICT_ITERATORS inline bool operator==(const const_iterator &o) const { return i == o.i; }
public: 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 &o) const
{ return i != o.i; }
#endif
friend class QMap<Key, T>; friend class QMap<Key, T>;
}; };
friend class iterator; friend class iterator;
@ -458,12 +453,7 @@ public:
Q_DECL_CONSTEXPR inline const_iterator() : i(nullptr) { } Q_DECL_CONSTEXPR inline const_iterator() : i(nullptr) { }
inline const_iterator(const Node *node) : i(node) { } inline const_iterator(const Node *node) : i(node) { }
#ifdef QT_STRICT_ITERATORS inline const_iterator(const iterator &o) { i = o.i; }
explicit inline const_iterator(const iterator &o)
#else
inline const_iterator(const iterator &o)
#endif
{ i = o.i; }
inline const Key &key() const { return i->key; } inline const Key &key() const { return i->key; }
inline const T &value() const { return i->value; } inline const T &value() const { return i->value; }
@ -497,11 +487,6 @@ public:
inline const_iterator &operator-=(int j) { return *this = *this - j; } inline const_iterator &operator-=(int j) { return *this = *this - j; }
friend inline const_iterator operator+(int j, const_iterator k) { return k + j; } friend inline const_iterator operator+(int j, const_iterator k) { return k + j; }
#ifdef QT_STRICT_ITERATORS
private:
inline bool operator==(const iterator &o) const { return operator==(const_iterator(o)); }
inline bool operator!=(const iterator &o) const { return operator!=(const_iterator(o)); }
#endif
friend class QMap<Key, T>; friend class QMap<Key, T>;
}; };
friend class const_iterator; friend class const_iterator;

View File

@ -208,7 +208,6 @@ public:
typedef typename Data::const_iterator const_iterator; typedef typename Data::const_iterator const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
#if !defined(QT_STRICT_ITERATORS) || defined(Q_CLANG_QDOC)
inline iterator begin() { detach(); return d->begin(); } inline iterator begin() { detach(); return d->begin(); }
inline const_iterator begin() const noexcept { return d->constBegin(); } inline const_iterator begin() const noexcept { return d->constBegin(); }
inline const_iterator cbegin() const noexcept { return d->constBegin(); } inline const_iterator cbegin() const noexcept { return d->constBegin(); }
@ -217,16 +216,6 @@ public:
inline const_iterator end() const noexcept { return d->constEnd(); } inline const_iterator end() const noexcept { return d->constEnd(); }
inline const_iterator cend() const noexcept { return d->constEnd(); } inline const_iterator cend() const noexcept { return d->constEnd(); }
inline const_iterator constEnd() const noexcept { return d->constEnd(); } inline const_iterator constEnd() const noexcept { return d->constEnd(); }
#else
inline iterator begin(iterator = iterator()) { detach(); return d->begin(); }
inline const_iterator begin(const_iterator = const_iterator()) const noexcept { return d->constBegin(); }
inline const_iterator cbegin(const_iterator = const_iterator()) const noexcept { return d->constBegin(); }
inline const_iterator constBegin(const_iterator = const_iterator()) const noexcept { return d->constBegin(); }
inline iterator end(iterator = iterator()) { detach(); return d->end(); }
inline const_iterator end(const_iterator = const_iterator()) const noexcept { return d->constEnd(); }
inline const_iterator cend(const_iterator = const_iterator()) const noexcept { return d->constEnd(); }
inline const_iterator constEnd(const_iterator = const_iterator()) const noexcept { return d->constEnd(); }
#endif
reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); } reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); } const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }

View File

@ -47,12 +47,5 @@
# error "This file must be compiled with no precompiled headers" # error "This file must be compiled with no precompiled headers"
#endif #endif
// invert the setting of QT_STRICT_ITERATORS, whichever it was
#ifdef QT_STRICT_ITERATORS
# undef QT_STRICT_ITERATORS
#else
# define QT_STRICT_ITERATORS
#endif
// the Q_TEMPLATE_EXTERN at the bottom of qvector.h will do the trick // the Q_TEMPLATE_EXTERN at the bottom of qvector.h will do the trick
#include <QtCore/qvector.h> #include <QtCore/qvector.h>

View File

@ -2,5 +2,4 @@ CONFIG += testcase
TARGET = tst_qtconcurrentfilter TARGET = tst_qtconcurrentfilter
QT = core testlib concurrent QT = core testlib concurrent
SOURCES = tst_qtconcurrentfilter.cpp SOURCES = tst_qtconcurrentfilter.cpp
DEFINES += QT_STRICT_ITERATORS
DEFINES -= QT_NO_LINKED_LIST DEFINES -= QT_NO_LINKED_LIST

View File

@ -2,7 +2,6 @@ CONFIG += testcase
TARGET = tst_qtconcurrentmap TARGET = tst_qtconcurrentmap
QT = core testlib concurrent QT = core testlib concurrent
SOURCES = tst_qtconcurrentmap.cpp SOURCES = tst_qtconcurrentmap.cpp
DEFINES += QT_STRICT_ITERATORS
DEFINES -= QT_NO_LINKED_LIST DEFINES -= QT_NO_LINKED_LIST
# Force C++17 if available # Force C++17 if available

View File

@ -2,4 +2,3 @@ CONFIG += testcase
TARGET = tst_qtconcurrentmedian TARGET = tst_qtconcurrentmedian
QT = core testlib concurrent QT = core testlib concurrent
SOURCES = tst_qtconcurrentmedian.cpp SOURCES = tst_qtconcurrentmedian.cpp
DEFINES += QT_STRICT_ITERATORS

View File

@ -2,5 +2,4 @@ CONFIG += testcase
TARGET = tst_qfuture TARGET = tst_qfuture
QT = core core-private testlib QT = core core-private testlib
SOURCES = tst_qfuture.cpp SOURCES = tst_qfuture.cpp
DEFINES += QT_STRICT_ITERATORS
DEFINES -= QT_NO_JAVA_STYLE_ITERATORS DEFINES -= QT_NO_JAVA_STYLE_ITERATORS

View File

@ -2,4 +2,3 @@ CONFIG += testcase
TARGET = tst_qresultstore TARGET = tst_qresultstore
QT = core-private testlib QT = core-private testlib
SOURCES = tst_qresultstore.cpp SOURCES = tst_qresultstore.cpp
DEFINES += QT_STRICT_ITERATORS

View File

@ -5,5 +5,4 @@ QT = core testlib
# This test does not work with strict iterators # This test does not work with strict iterators
DEFINES -= QT_NO_LINKED_LIST DEFINES -= QT_NO_LINKED_LIST
DEFINES -= QT_STRICT_ITERATORS
DEFINES -= QT_NO_JAVA_STYLE_ITERATORS DEFINES -= QT_NO_JAVA_STYLE_ITERATORS

View File

@ -3,6 +3,4 @@ TARGET = tst_containerapisymmetry
SOURCES += tst_containerapisymmetry.cpp SOURCES += tst_containerapisymmetry.cpp
QT = core testlib QT = core testlib
# This test does not work with strict iterators
DEFINES -= QT_STRICT_ITERATORS
DEFINES -= QT_NO_LINKED_LIST DEFINES -= QT_NO_LINKED_LIST

View File

@ -1,3 +0,0 @@
include(../qarraydata/qarraydata.pro)
TARGET = tst_qarraydata_strictiterators
DEFINES += QT_STRICT_ITERATORS=1 tst_QArrayData=tst_QArrayData_StrictIterators

View File

@ -1,3 +0,0 @@
include(../qhash/qhash.pro)
TARGET = tst_qhash_strictiterators
DEFINES += QT_STRICT_ITERATORS tst_QHash=tst_QHash_StrictIterators

View File

@ -1351,17 +1351,16 @@ void tst_QMap::testInsertMultiWithHint()
{ {
QMap<int, int> map; QMap<int, int> map;
typedef QMap<int, int>::const_iterator cite; // Hack since we define QT_STRICT_ITERATORS map.insertMulti(map.end(), 64, 65);
map.insertMulti(cite(map.end()), 64, 65);
map[128] = 129; map[128] = 129;
map[256] = 257; map[256] = 257;
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
map.insertMulti(cite(map.end()), 512, 513); map.insertMulti(map.end(), 512, 513);
map.insertMulti(cite(map.end()), 512, 513 * 2); map.insertMulti(map.end(), 512, 513 * 2);
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 5); QCOMPARE(map.size(), 5);
map.insertMulti(cite(map.end()), 256, 258); // wrong hint map.insertMulti(map.end(), 256, 258); // wrong hint
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 6); QCOMPARE(map.size(), 6);
@ -1373,23 +1372,23 @@ void tst_QMap::testInsertMultiWithHint()
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 8); QCOMPARE(map.size(), 8);
j = map.insertMulti(cite(j), 68, 259); j = map.insertMulti(j, 68, 259);
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 9); QCOMPARE(map.size(), 9);
j = map.insertMulti(cite(j), 67, 67); j = map.insertMulti(j, 67, 67);
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 10); QCOMPARE(map.size(), 10);
i = map.insertMulti(cite(i), 256, 259); i = map.insertMulti(i, 256, 259);
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 11); QCOMPARE(map.size(), 11);
i = map.insertMulti(cite(i), 256, 260); i = map.insertMulti(i, 256, 260);
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 12); QCOMPARE(map.size(), 12);
map.insertMulti(cite(i), 64, 67); map.insertMulti(i, 64, 67);
sanityCheckTree(map, __LINE__); sanityCheckTree(map, __LINE__);
QCOMPARE(map.size(), 13); QCOMPARE(map.size(), 13);

View File

@ -1,3 +0,0 @@
include(../qmap/qmap.pro)
TARGET = tst_qmap_strictiterators
DEFINES += QT_STRICT_ITERATORS tst_QMap=tst_QMap_StrictIterators

View File

@ -26,8 +26,6 @@
** **
****************************************************************************/ ****************************************************************************/
//#define QT_STRICT_ITERATORS
#include <QtTest/QtTest> #include <QtTest/QtTest>
#include <qset.h> #include <qset.h>
#include <qdebug.h> #include <qdebug.h>

View File

@ -1,3 +0,0 @@
include(../qvector/qvector.pro)
TARGET = tst_qvector_strictiterators
DEFINES += QT_STRICT_ITERATORS=1 tst_QVector=tst_QVector_StrictIterators

View File

@ -4,7 +4,6 @@ SUBDIRS=\
containerapisymmetry \ containerapisymmetry \
qalgorithms \ qalgorithms \
qarraydata \ qarraydata \
qarraydata_strictiterators \
qbitarray \ qbitarray \
qcache \ qcache \
qcommandlineparser \ qcommandlineparser \
@ -14,13 +13,11 @@ SUBDIRS=\
qexplicitlyshareddatapointer \ qexplicitlyshareddatapointer \
qfreelist \ qfreelist \
qhash \ qhash \
qhash_strictiterators \
qhashfunctions \ qhashfunctions \
qline \ qline \
qlinkedlist \ qlinkedlist \
qmakearray \ qmakearray \
qmap \ qmap \
qmap_strictiterators \
qmargins \ qmargins \
qmessageauthenticationcode \ qmessageauthenticationcode \
qoffsetstringarray \ qoffsetstringarray \
@ -41,7 +38,6 @@ SUBDIRS=\
qtimeline \ qtimeline \
qvarlengtharray \ qvarlengtharray \
qvector \ qvector \
qvector_strictiterators \
qversionnumber qversionnumber
darwin: SUBDIRS += qmacautoreleasepool darwin: SUBDIRS += qmacautoreleasepool

View File

@ -130,78 +130,9 @@ public:
bool contains(const T &t) const; bool contains(const T &t) const;
int count(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 ptrdiff_t 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 ptrdiff_t 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 // STL-style
typedef T *iterator; typedef T *iterator;
typedef const T *const_iterator; typedef const T *const_iterator;
#endif
inline iterator begin() { return m_begin; } inline iterator begin() { return m_begin; }
inline const_iterator begin() const { return m_begin; } inline const_iterator begin() const { return m_begin; }
inline const_iterator constBegin() const { return m_begin; } inline const_iterator constBegin() const { return m_begin; }

View File

@ -27,7 +27,6 @@
****************************************************************************/ ****************************************************************************/
#include <QDebug> #include <QDebug>
//#define QT_STRICT_ITERATORS
#include <QHash> #include <QHash>
void testEraseNoError() void testEraseNoError()

View File

@ -26,7 +26,6 @@
** **
****************************************************************************/ ****************************************************************************/
#include <QDebug> #include <QDebug>
//#define QT_STRICT_ITERATORS
#include <QVector> #include <QVector>
void testErase() void testErase()
{ {
@ -55,4 +54,4 @@ int main()
// testErase(); // testErase();
testInsert(); testInsert();
return 0; return 0;
} }

View File

@ -27,7 +27,6 @@
****************************************************************************/ ****************************************************************************/
#include <QDebug> #include <QDebug>
//#define QT_STRICT_ITERATORS
#include <QSet> #include <QSet>
void testErase() void testErase()

View File

@ -27,7 +27,6 @@
****************************************************************************/ ****************************************************************************/
#include <QDebug> #include <QDebug>
//#define QT_STRICT_ITERATORS
#include <QVarLengthArray> #include <QVarLengthArray>
void testErase() void testErase()

View File

@ -27,7 +27,6 @@
****************************************************************************/ ****************************************************************************/
#include <QDebug> #include <QDebug>
//#define QT_STRICT_ITERATORS
#include <QVector> #include <QVector>
void testErase() void testErase()