diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2021-10-11 12:02:27 +0200 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2021-10-16 13:48:27 +0200 |
commit | b6cbd9c43afc7e005c1f78e1d0f700524930ed71 (patch) | |
tree | 6991cf9c004861c46cc29b9518e3f07eea07b342 /src/corelib/tools | |
parent | 0220484329029fc7598dfe11ba35ea10c3126477 (diff) |
QList: deprecate iterator<->pointer implicit conversions (2/3)
The constructor from a raw pointer should be
1) constexpr,
2) explicit, and
3) *private*.
We can do 1) without too much trouble.
2) is a (easy to fix) SIC in case of implicit conversions accidentally
relied upon from somewhere.
3) cannot be "easily" fixed by user code (they have to refactor), and
also, it's a BIC on Windows which encodes class members' access in
symbols. Someone may have been exporting some QList subclass, in turn
exporting the iterator classes, and therefore that someone now has the
constructors' symbols with a given access.
So, don't do 2+3 _just yet_ for user code, but set a deadline: Qt 6.5 is
the last that will support this. On Qt 6.6, we switch. All of this on
non-Windows, againt to avoid an ABI break. One can opt-in at any time
via a suitable define.
Given we have this define, use it to guard the other way around as well:
conversions from an iterator to a raw pointer should never be explicit
(there's std::to_address for this).
[ChangeLog][QtCore][QList] Converting a QList's iterator from and to a
raw pointer is deprecated, and will get removed in Qt 6.6. User code can
prepare for the change by defining QT_STRICT_QLIST_ITERATORS.
Change-Id: I0f34bfa3ac055c02af5a3ca159180304660dfc11
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qlist.h | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index e7dbb294b0..fe8d36a9c7 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -92,6 +92,10 @@ public: template <> struct QListSpecialMethods<QByteArray>; template <> struct QListSpecialMethods<QString>; +#if !defined(QT_STRICT_QLIST_ITERATORS) && (QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)) && !defined(Q_OS_WIN) +#define QT_STRICT_QLIST_ITERATORS +#endif + #ifdef Q_QDOC // define QVector for QDoc template<typename T> class QVector : public QList<T> {}; #endif @@ -134,6 +138,10 @@ public: friend class QList<T>; friend class const_iterator; T *i = nullptr; +#ifdef QT_STRICT_QLIST_ITERATORS + inline constexpr explicit iterator(T *n) : i(n) {} +#endif + public: using difference_type = qsizetype; using value_type = T; @@ -149,7 +157,9 @@ public: using reference = T &; inline constexpr iterator() = default; - inline iterator(T *n) : i(n) {} +#ifndef QT_STRICT_QLIST_ITERATORS + inline constexpr explicit iterator(T *n) : i(n) {} +#endif inline T &operator*() const { return *i; } inline T *operator->() const { return i; } inline T &operator[](qsizetype j) const { return *(i + j); } @@ -172,7 +182,7 @@ public: inline iterator &operator--() { --i; return *this; } inline iterator operator--(int) { auto copy = *this; --*this; return copy; } inline qsizetype operator-(iterator j) const { return i - j.i; } -#if QT_DEPRECATED_SINCE(6, 3) +#if QT_DEPRECATED_SINCE(6, 3) && !defined(QT_STRICT_QLIST_ITERATORS) QT_DEPRECATED_VERSION_X_6_3("Use operator* or operator-> rather than relying on " "the implicit conversion between a QList/QVector::iterator " "and a raw pointer") @@ -195,6 +205,10 @@ public: friend class QList<T>; friend class iterator; const T *i = nullptr; +#ifdef QT_STRICT_QLIST_ITERATORS + inline constexpr explicit const_iterator(const T *n) : i(n) {} +#endif + public: using difference_type = qsizetype; using value_type = T; @@ -209,7 +223,9 @@ public: using reference = const T &; inline constexpr const_iterator() = default; - inline const_iterator(const T *n) : i(n) {} +#ifndef QT_STRICT_QLIST_ITERATORS + inline constexpr explicit const_iterator(const T *n) : i(n) {} +#endif inline constexpr const_iterator(iterator o): i(o.i) {} inline const T &operator*() const { return *i; } inline const T *operator->() const { return i; } @@ -233,7 +249,7 @@ public: inline const_iterator &operator--() { --i; return *this; } inline const_iterator operator--(int) { auto copy = *this; --*this; return copy; } inline qsizetype operator-(const_iterator j) const { return i - j.i; } -#if QT_DEPRECATED_SINCE(6, 3) +#if QT_DEPRECATED_SINCE(6, 3) && !defined(QT_STRICT_QLIST_ITERATORS) QT_DEPRECATED_VERSION_X_6_3("Use operator* or operator-> rather than relying on " "the implicit conversion between a QList/QVector::const_iterator " "and a raw pointer") |