QVersionNumber: make iterable
Since QVersionNumber doesn't have an existing way to modify individual segments, provide only const_iterator. [ChangeLog][QtCore][QVersionNumber] Added (const) iterators over segments (begin()/end(), incl. c- and r- variants). Change-Id: Ia9af70c2a9c59f630123894ad2c9f38031ef5b8f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>bb10
parent
900d4bd29f
commit
2188ca2c5d
|
|
@ -171,6 +171,55 @@ QList<int> QVersionNumber::segments() const
|
|||
\sa segments()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QVersionNumber::const_iterator
|
||||
\typedef QVersionNumber::const_reverse_iterator
|
||||
\since 6.8
|
||||
|
||||
Typedefs for an opaque class that implements a (reverse) random-access
|
||||
iterator over QVersionNumber segments.
|
||||
|
||||
\note QVersionNumber does not support modifying segments in-place, so
|
||||
there is no mutable iterator.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QVersionNumber::value_type
|
||||
\typedef QVersionNumber::difference_type
|
||||
\typedef QVersionNumber::size_type
|
||||
\typedef QVersionNumber::reference
|
||||
\typedef QVersionNumber::const_reference
|
||||
\typedef QVersionNumber::pointer
|
||||
\typedef QVersionNumber::const_pointer
|
||||
\since 6.8
|
||||
|
||||
Provided for STL-compatibility.
|
||||
|
||||
\note QVersionNumber does not support modifying segments in-place, so
|
||||
reference and const_reference, as well as pointer and const_pointer are
|
||||
pairwise the same types.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber::begin() const
|
||||
\fn QVersionNumber::end() const;
|
||||
\fn QVersionNumber::rbegin() const
|
||||
\fn QVersionNumber::rend() const;
|
||||
\fn QVersionNumber::cbegin() const
|
||||
\fn QVersionNumber::cend() const;
|
||||
\fn QVersionNumber::crbegin() const
|
||||
\fn QVersionNumber::crend() const;
|
||||
\fn QVersionNumber::constBegin() const;
|
||||
\fn QVersionNumber::constEnd() const;
|
||||
\since 6.8
|
||||
|
||||
Returns a const_iterator or const_reverse_iterator, respectively, pointing
|
||||
to the first or one past the last segment of this version number.
|
||||
|
||||
\note QVersionNumber does not support modifying segments in-place, so
|
||||
there is no mutable iterator.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QVersionNumber QVersionNumber::normalized() const
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#ifndef QVERSIONNUMBER_H
|
||||
#define QVERSIONNUMBER_H
|
||||
|
||||
#include <QtCore/qcontainertools_impl.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
|
@ -190,7 +191,66 @@ class QVersionNumber
|
|||
Q_CORE_EXPORT void setVector(int len, int maj, int min, int mic);
|
||||
} m_segments;
|
||||
|
||||
class It
|
||||
{
|
||||
const QVersionNumber *v;
|
||||
qsizetype i;
|
||||
|
||||
friend class QVersionNumber;
|
||||
explicit constexpr It(const QVersionNumber *vn, qsizetype idx) noexcept : v(vn), i(idx) {}
|
||||
|
||||
friend constexpr bool comparesEqual(const It &lhs, const It &rhs)
|
||||
{ Q_ASSERT(lhs.v == rhs.v); return lhs.i == rhs.i; }
|
||||
friend constexpr Qt::strong_ordering compareThreeWay(const It &lhs, const It &rhs)
|
||||
{ Q_ASSERT(lhs.v == rhs.v); return Qt::compareThreeWay(lhs.i, rhs.i); }
|
||||
Q_DECLARE_STRONGLY_ORDERED_LITERAL_TYPE(It)
|
||||
|
||||
public:
|
||||
// Rule Of Zero applies
|
||||
It() = default;
|
||||
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
using value_type = int;
|
||||
using element_type = const int;
|
||||
using difference_type = qptrdiff; // difference to container requirements
|
||||
using size_type = qsizetype; // difference to container requirements
|
||||
using reference = value_type; // difference to container requirements
|
||||
using pointer = QtPrivate::ArrowProxy<reference>;
|
||||
|
||||
reference operator*() const { return v->segmentAt(i); }
|
||||
pointer operator->() const { return {**this}; }
|
||||
|
||||
It &operator++() { ++i; return *this; }
|
||||
It operator++(int) { auto copy = *this; ++*this; return copy; }
|
||||
|
||||
It &operator--() { --i; return *this; }
|
||||
It operator--(int) { auto copy = *this; --*this; return copy; }
|
||||
|
||||
It &operator+=(difference_type n) { i += n; return *this; }
|
||||
friend It operator+(It it, difference_type n) { it += n; return it; }
|
||||
friend It operator+(difference_type n, It it) { return it + n; }
|
||||
|
||||
It &operator-=(difference_type n) { i -= n; return *this; }
|
||||
friend It operator-(It it, difference_type n) { it -= n; return it; }
|
||||
|
||||
friend difference_type operator-(It lhs, It rhs)
|
||||
{ Q_ASSERT(lhs.v == rhs.v); return lhs.i - rhs.i; }
|
||||
|
||||
reference operator[](difference_type n) const { return *(*this + n); }
|
||||
};
|
||||
|
||||
public:
|
||||
using const_iterator = It;
|
||||
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||
|
||||
using value_type = It::value_type;
|
||||
using difference_type = It::difference_type;
|
||||
using size_type = It::size_type;
|
||||
using reference = It::reference;
|
||||
using const_reference = reference;
|
||||
using pointer = It::pointer;
|
||||
using const_pointer = pointer;
|
||||
|
||||
inline QVersionNumber() noexcept
|
||||
: m_segments()
|
||||
{}
|
||||
|
|
@ -243,6 +303,19 @@ public:
|
|||
[[nodiscard]] inline qsizetype segmentCount() const noexcept
|
||||
{ return m_segments.size(); }
|
||||
|
||||
[[nodiscard]] const_iterator begin() const noexcept { return const_iterator{this, 0}; }
|
||||
[[nodiscard]] const_iterator end() const noexcept { return begin() + segmentCount(); }
|
||||
[[nodiscard]] const_iterator cbegin() const noexcept { return begin(); }
|
||||
[[nodiscard]] const_iterator cend() const noexcept { return end(); }
|
||||
|
||||
[[nodiscard]] const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator{end()}; }
|
||||
[[nodiscard]] const_reverse_iterator rend() const noexcept { return const_reverse_iterator{begin()}; }
|
||||
[[nodiscard]] const_reverse_iterator crbegin() const noexcept { return rbegin(); }
|
||||
[[nodiscard]] const_reverse_iterator crend() const noexcept { return rend(); }
|
||||
|
||||
[[nodiscard]] const_iterator constBegin() const noexcept { return begin(); }
|
||||
[[nodiscard]] const_iterator constEnd() const noexcept { return end(); }
|
||||
|
||||
[[nodiscard]] Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const noexcept;
|
||||
|
||||
[[nodiscard]] Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) noexcept;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ private slots:
|
|||
void toString();
|
||||
void isNull_data();
|
||||
void isNull();
|
||||
void iterators_data();
|
||||
void iterators();
|
||||
void iteratorsAreDefaultConstructible();
|
||||
void valueInitializedIteratorsCompareEqual();
|
||||
void serialize_data();
|
||||
void serialize();
|
||||
void moveSemantics();
|
||||
|
|
@ -575,6 +579,45 @@ void tst_QVersionNumber::isNull()
|
|||
QCOMPARE(version.isNull(), isNull);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::iterators_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::iterators()
|
||||
{
|
||||
QFETCH(const QList<int>, segments);
|
||||
QFETCH(QVersionNumber, expectedVersion);
|
||||
|
||||
QVERIFY(std::equal(expectedVersion.begin(), expectedVersion.end(),
|
||||
segments.begin(), segments.end()));
|
||||
QVERIFY(std::equal(std::as_const(expectedVersion).begin(), std::as_const(expectedVersion).end(),
|
||||
segments.begin(), segments.end()));
|
||||
QVERIFY(std::equal(expectedVersion.cbegin(), expectedVersion.cend(),
|
||||
segments.cbegin(), segments.cend()));
|
||||
QVERIFY(std::equal(expectedVersion.rbegin(), expectedVersion.rend(),
|
||||
segments.rbegin(), segments.rend()));
|
||||
QVERIFY(std::equal(std::as_const(expectedVersion).rbegin(), std::as_const(expectedVersion).rend(),
|
||||
segments.rbegin(), segments.rend()));
|
||||
QVERIFY(std::equal(expectedVersion.crbegin(), expectedVersion.crend(),
|
||||
segments.crbegin(), segments.crend()));
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::iteratorsAreDefaultConstructible()
|
||||
{
|
||||
static_assert(std::is_default_constructible_v<QVersionNumber::const_iterator>);
|
||||
[[maybe_unused]] QVersionNumber::const_iterator ci;
|
||||
[[maybe_unused]] QVersionNumber::const_reverse_iterator cri;
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::valueInitializedIteratorsCompareEqual()
|
||||
{
|
||||
QVersionNumber::const_iterator it = {}, jt = {};
|
||||
QCOMPARE_EQ(it, jt);
|
||||
QVersionNumber::const_reverse_iterator rit = {}, rjt = {};
|
||||
QCOMPARE_EQ(rit, rjt);
|
||||
}
|
||||
|
||||
void tst_QVersionNumber::serialize_data()
|
||||
{
|
||||
singleInstanceData();
|
||||
|
|
|
|||
Loading…
Reference in New Issue