From e20a3694c7b96cef73a4d4e140a5def7cf17ab8a Mon Sep 17 00:00:00 2001 From: Tatiana Borisova Date: Fri, 22 Mar 2024 12:55:09 +0100 Subject: [PATCH] QCborArray iterators: use new comparison helper macros New comparison macros are used for following classes: - QCborArray::Iterator - QCborArray::ConstIterator Replace public operators operator==(), operator!=(), operator!<(), etc of classes to friend methods comparesEqual(), compareThreeWay(); Use *_helper methods to have an access to protected members of QCborValueRef class from friend functions. Task-number: QTBUG-120300 Change-Id: Ie8ffef3e2278dfbf2bf0b32c30a7bf98d99fd1c3 Reviewed-by: Qt CI Bot Reviewed-by: Thiago Macieira --- src/corelib/serialization/qcborarray.cpp | 94 ++++++++++--------- src/corelib/serialization/qcborarray.h | 86 +++++++++++++++-- .../qcborvalue/tst_qcborvalue.cpp | 29 ++++++ 3 files changed, 157 insertions(+), 52 deletions(-) diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp index 78f2ca3f33..626fb49a70 100644 --- a/src/corelib/serialization/qcborarray.cpp +++ b/src/corelib/serialization/qcborarray.cpp @@ -722,6 +722,10 @@ void QCborArray::detach(qsizetype reserved) \brief The QCborArray::Iterator class provides an STL-style non-const iterator for QCborArray. + \compares strong + \compareswith strong QCborArray::ConstIterator + \endcompareswith + QCborArray::Iterator allows you to iterate over a QCborArray and to modify the array item associated with the iterator. If you want to iterate over a const QCborArray, use QCborArray::ConstIterator instead. It is generally a @@ -836,56 +840,56 @@ void QCborArray::detach(qsizetype reserved) */ /*! - \fn bool QCborArray::Iterator::operator==(const Iterator &other) const - \fn bool QCborArray::Iterator::operator==(const ConstIterator &other) const + \fn bool QCborArray::Iterator::operator==(const Iterator &lhs, const Iterator &rhs) + \fn bool QCborArray::Iterator::operator==(const Iterator &lhs, const ConstIterator &rhs) - Returns \c true if \a other points to the same entry in the array as this + Returns \c true if \a lhs points to the same entry in the array as \a rhs iterator; otherwise returns \c false. \sa operator!=() */ /*! - \fn bool QCborArray::Iterator::operator!=(const Iterator &other) const - \fn bool QCborArray::Iterator::operator!=(const ConstIterator &other) const + \fn bool QCborArray::Iterator::operator!=(const Iterator &lhs, const Iterator &rhs) + \fn bool QCborArray::Iterator::operator!=(const Iterator &lhs, const ConstIterator &rhs) - Returns \c true if \a other points to a different entry in the array than - this iterator; otherwise returns \c false. + Returns \c true if \a lhs points to a different entry in the array than + \a rhs iterator; otherwise returns \c false. \sa operator==() */ /*! - \fn bool QCborArray::Iterator::operator<(const Iterator& other) const - \fn bool QCborArray::Iterator::operator<(const ConstIterator& other) const + \fn bool QCborArray::Iterator::operator<(const Iterator &lhs, const Iterator &rhs) + \fn bool QCborArray::Iterator::operator<(const Iterator &lhs, const ConstIterator &rhs) - Returns \c true if the entry in the array pointed to by this iterator - occurs before the entry pointed to by the \a other iterator. + Returns \c true if the entry in the array pointed to by \a lhs iterator + occurs before the entry pointed to by the \a rhs iterator. */ /*! - \fn bool QCborArray::Iterator::operator<=(const Iterator& other) const - \fn bool QCborArray::Iterator::operator<=(const ConstIterator& other) const + \fn bool QCborArray::Iterator::operator<=(const Iterator &lhs, const Iterator &rhs) + \fn bool QCborArray::Iterator::operator<=(const Iterator &lhs, const ConstIterator &rhs) - Returns \c true if the entry in the array pointed to by this iterator - occurs before or is the same entry as is pointed to by the \a other + Returns \c true if the entry in the array pointed to by \a lhs iterator + occurs before or is the same entry as is pointed to by the \a rhs iterator. */ /*! - \fn bool QCborArray::Iterator::operator>(const Iterator& other) const - \fn bool QCborArray::Iterator::operator>(const ConstIterator& other) const + \fn bool QCborArray::Iterator::operator>(const Iterator &lhs, const Iterator &rhs) + \fn bool QCborArray::Iterator::operator>(const Iterator &lhs, const ConstIterator &rhs) - Returns \c true if the entry in the array pointed to by this iterator - occurs after the entry pointed to by the \a other iterator. + Returns \c true if the entry in the array pointed to by \a lhs iterator + occurs after the entry pointed to by the \a rhs iterator. */ /*! - \fn bool QCborArray::Iterator::operator>=(const Iterator& other) const - \fn bool QCborArray::Iterator::operator>=(const ConstIterator& other) const + \fn bool QCborArray::Iterator::operator>=(const Iterator &lhs, const Iterator &rhs) + \fn bool QCborArray::Iterator::operator>=(const Iterator &lhs, const ConstIterator &rhs) - Returns \c true if the entry in the array pointed to by this iterator - occurs after or is the same entry as is pointed to by the \a other + Returns \c true if the entry in the array pointed to by \a lhs iterator + occurs after or is the same entry as is pointed to by the \a rhs iterator. */ @@ -977,6 +981,10 @@ void QCborArray::detach(qsizetype reserved) \brief The QCborArray::ConstIterator class provides an STL-style const iterator for QCborArray. + \compares strong + \compareswith strong QCborArray::Iterator + \endcompareswith + QCborArray::ConstIterator allows you to iterate over a QCborArray. If you want to modify the QCborArray as you iterate over it, use QCborArray::Iterator instead. It is generally good practice to use @@ -1076,56 +1084,50 @@ void QCborArray::detach(qsizetype reserved) */ /*! - \fn bool QCborArray::ConstIterator::operator==(const Iterator &other) const - \fn bool QCborArray::ConstIterator::operator==(const ConstIterator &other) const + \fn bool QCborArray::ConstIterator::operator==(const ConstIterator &lhs, const ConstIterator &rhs) - Returns \c true if \a other points to the same entry in the array as this + Returns \c true if \a lhs points to the same entry in the array as \a rhs iterator; otherwise returns \c false. \sa operator!=() */ /*! - \fn bool QCborArray::ConstIterator::operator!=(const Iterator &o) const - \fn bool QCborArray::ConstIterator::operator!=(const ConstIterator &o) const + \fn bool QCborArray::ConstIterator::operator!=(const ConstIterator &lhs, const ConstIterator &rhs) - Returns \c true if \a o points to a different entry in the array than - this iterator; otherwise returns \c false. + Returns \c true if \a lhs points to a different entry in the array than + \a rhs iterator; otherwise returns \c false. \sa operator==() */ /*! - \fn bool QCborArray::ConstIterator::operator<(const Iterator &other) const - \fn bool QCborArray::ConstIterator::operator<(const ConstIterator &other) const + \fn bool QCborArray::ConstIterator::operator<(const ConstIterator &lhs, const ConstIterator &rhs) - Returns \c true if the entry in the array pointed to by this iterator - occurs before the entry pointed to by the \a other iterator. + Returns \c true if the entry in the array pointed to by \a lhs iterator + occurs before the entry pointed to by the \a rhs iterator. */ /*! - \fn bool QCborArray::ConstIterator::operator<=(const Iterator &other) const - \fn bool QCborArray::ConstIterator::operator<=(const ConstIterator &other) const + \fn bool QCborArray::ConstIterator::operator<=(const ConstIterator &lhs, const ConstIterator &rhs) - Returns \c true if the entry in the array pointed to by this iterator - occurs before or is the same entry as is pointed to by the \a other + Returns \c true if the entry in the array pointed to by \a lhs iterator + occurs before or is the same entry as is pointed to by the \a rhs iterator. */ /*! - \fn bool QCborArray::ConstIterator::operator>(const Iterator &other) const - \fn bool QCborArray::ConstIterator::operator>(const ConstIterator &other) const + \fn bool QCborArray::ConstIterator::operator>(const ConstIterator &lhs, const ConstIterator &rhs) - Returns \c true if the entry in the array pointed to by this iterator - occurs after the entry pointed to by the \a other iterator. + Returns \c true if the entry in the array pointed to by \a lhs iterator + occurs after the entry pointed to by the \a rhs iterator. */ /*! - \fn bool QCborArray::ConstIterator::operator>=(const Iterator &other) const - \fn bool QCborArray::ConstIterator::operator>=(const ConstIterator &other) const + \fn bool QCborArray::ConstIterator::operator>=(const ConstIterator &lhs, const ConstIterator &rhs) - Returns \c true if the entry in the array pointed to by this iterator - occurs after or is the same entry as is pointed to by the \a other + Returns \c true if the entry in the array pointed to by \a lhs iterator + occurs after or is the same entry as is pointed to by the \a rhs iterator. */ diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h index f70dd44425..481f316f33 100644 --- a/src/corelib/serialization/qcborarray.h +++ b/src/corelib/serialization/qcborarray.h @@ -46,19 +46,20 @@ public: QCborValueRef *operator->() { return &item; } const QCborValueConstRef *operator->() const { return &item; } QCborValueRef operator[](qsizetype j) const { return { item.d, item.i + j }; } - +#if QT_CORE_REMOVED_SINCE(6, 8) bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; } - bool operator!=(const Iterator &o) const { return !(*this == o); } + bool operator!=(const Iterator &o) const { return !operator==(o); } bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; } bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; } bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; } bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; } bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; } - bool operator!=(const ConstIterator &o) const { return !(*this == o); } + bool operator!=(const ConstIterator &o) const { return !operator==(o); } bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; } bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; } bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; } bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; } +#endif Iterator &operator++() { ++item.i; return *this; } Iterator operator++(int) { Iterator n = *this; ++item.i; return n; } Iterator &operator--() { item.i--; return *this; } @@ -68,6 +69,53 @@ public: Iterator operator+(qsizetype j) const { return Iterator({ item.d, item.i + j }); } Iterator operator-(qsizetype j) const { return Iterator({ item.d, item.i - j }); } qsizetype operator-(Iterator j) const { return item.i - j.item.i; } + private: + // Helper functions + static bool comparesEqual_helper(const Iterator &lhs, const Iterator &rhs) noexcept + { + return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i; + } + + static bool comparesEqual_helper(const Iterator &lhs, const ConstIterator &rhs) noexcept + { + return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i; + } + + static Qt::strong_ordering compareThreeWay_helper(const Iterator &lhs, + const Iterator &rhs) noexcept + { + Q_ASSERT(lhs.item.d == rhs.item.d); + return Qt::compareThreeWay(lhs.item.i, rhs.item.i); + } + + static Qt::strong_ordering compareThreeWay_helper(const Iterator &lhs, + const ConstIterator &rhs) noexcept + { + Q_ASSERT(lhs.item.d == rhs.item.d); + return Qt::compareThreeWay(lhs.item.i, rhs.item.i); + } + + // Compare friends + friend bool comparesEqual(const Iterator &lhs, const Iterator &rhs) noexcept + { + return comparesEqual_helper(lhs, rhs); + } + friend Qt::strong_ordering compareThreeWay(const Iterator &lhs, + const Iterator &rhs) noexcept + { + return compareThreeWay_helper(lhs, rhs); + } + Q_DECLARE_STRONGLY_ORDERED(Iterator) + friend bool comparesEqual(const Iterator &lhs, const ConstIterator &rhs) noexcept + { + return comparesEqual_helper(lhs, rhs); + } + friend Qt::strong_ordering compareThreeWay(const Iterator &lhs, + const ConstIterator &rhs) noexcept + { + return compareThreeWay_helper(lhs, rhs); + } + Q_DECLARE_STRONGLY_ORDERED(Iterator, ConstIterator) }; class ConstIterator { @@ -95,19 +143,20 @@ public: QCborValueConstRef operator*() const { return item; } const QCborValueConstRef *operator->() const { return &item; } QCborValueConstRef operator[](qsizetype j) const { return QCborValueRef{ item.d, item.i + j }; } - +#if QT_CORE_REMOVED_SINCE(6, 8) bool operator==(const Iterator &o) const { return item.d == o.item.d && item.i == o.item.i; } - bool operator!=(const Iterator &o) const { return !(*this == o); } + bool operator!=(const Iterator &o) const { return !operator==(o); } bool operator<(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; } bool operator<=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; } bool operator>(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; } bool operator>=(const Iterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; } bool operator==(const ConstIterator &o) const { return item.d == o.item.d && item.i == o.item.i; } - bool operator!=(const ConstIterator &o) const { return !(*this == o); } + bool operator!=(const ConstIterator &o) const { return !operator==(o); } bool operator<(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i < other.item.i; } bool operator<=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i <= other.item.i; } bool operator>(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i > other.item.i; } bool operator>=(const ConstIterator& other) const { Q_ASSERT(item.d == other.item.d); return item.i >= other.item.i; } +#endif ConstIterator &operator++() { ++item.i; return *this; } ConstIterator operator++(int) { ConstIterator n = *this; ++item.i; return n; } ConstIterator &operator--() { item.i--; return *this; } @@ -117,6 +166,31 @@ public: ConstIterator operator+(qsizetype j) const { return ConstIterator({ item.d, item.i + j }); } ConstIterator operator-(qsizetype j) const { return ConstIterator({ item.d, item.i - j }); } qsizetype operator-(ConstIterator j) const { return item.i - j.item.i; } + private: + // Helper functions + static bool comparesEqual_helper(const ConstIterator &lhs, + const ConstIterator &rhs) noexcept + { + return lhs.item.d == rhs.item.d && lhs.item.i == rhs.item.i; + } + static Qt::strong_ordering compareThreeWay_helper(const ConstIterator &lhs, + const ConstIterator &rhs) noexcept + { + Q_ASSERT(lhs.item.d == rhs.item.d); + return Qt::compareThreeWay(lhs.item.i, rhs.item.i); + } + + // Compare friends + friend bool comparesEqual(const ConstIterator &lhs, const ConstIterator &rhs) noexcept + { + return comparesEqual_helper(lhs, rhs); + } + friend Qt::strong_ordering compareThreeWay(const ConstIterator &lhs, + const ConstIterator &rhs) noexcept + { + return compareThreeWay_helper(lhs, rhs); + } + Q_DECLARE_STRONGLY_ORDERED(ConstIterator) }; typedef qsizetype size_type; diff --git a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp index a1b01195bf..2d72c8ac07 100644 --- a/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp +++ b/tests/auto/corelib/serialization/qcborvalue/tst_qcborvalue.cpp @@ -458,6 +458,8 @@ void tst_QCborValue::compareCompiles() QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); // QCborValue, Ref and ConstRef @@ -472,6 +474,8 @@ void tst_QCborValue::compareCompiles() QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); } void tst_QCborValue::extendedTypes() @@ -786,12 +790,17 @@ void tst_QCborValue::arrayInitializerList() // iterators auto it = a.constBegin(); auto end = a.constEnd(); + QT_TEST_ALL_COMPARISON_OPS(it, end, Qt::strong_ordering::less); QCOMPARE(end - it, 7); QCOMPARE(it + 7, end); + QT_TEST_EQUALITY_OPS(it + 7, end, true); QVERIFY(it->isInteger()); QCOMPARE(*it, QCborValue(0)); QCOMPARE(it[1], QCborValue(-1)); QCOMPARE(*(it + 2), QCborValue(false)); + QT_TEST_EQUALITY_OPS(*it, QCborValue(0), true); + QT_TEST_EQUALITY_OPS(it[1], QCborValue(-1), true); + QT_TEST_EQUALITY_OPS(*(it + 2), QCborValue(false), true); it += 3; QCOMPARE(*it, QCborValue(true)); ++it; @@ -802,6 +811,24 @@ void tst_QCborValue::arrayInitializerList() QCOMPARE(*end, QCborValue(1.0)); end--; QCOMPARE(it, end); + QT_TEST_EQUALITY_OPS(it, end, true); + QT_TEST_EQUALITY_OPS(it, QCborArray::ConstIterator(), false); + QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), end, false); + QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), QCborArray::ConstIterator(), true); + QT_TEST_EQUALITY_OPS(QCborArray::ConstIterator(), QCborArray::Iterator(), true); + + { + auto it = a.begin(); + auto it1 = a.constBegin(); + auto end = a.end(); + QT_TEST_ALL_COMPARISON_OPS(it, end, Qt::strong_ordering::less); + QT_TEST_ALL_COMPARISON_OPS(it1, end, Qt::strong_ordering::less); + QT_TEST_EQUALITY_OPS(it + 7, end, true); + QT_TEST_EQUALITY_OPS(it1 + 7, end, true); + QT_TEST_EQUALITY_OPS(it, QCborArray::Iterator(), false); + QT_TEST_EQUALITY_OPS(QCborArray::Iterator(), end, false); + QT_TEST_EQUALITY_OPS(QCborArray::Iterator(), QCborArray::ConstIterator(), true); + } // range for int i = 0; @@ -1288,6 +1315,8 @@ void tst_QCborValue::arrayValueRef() QVERIFY(v == a.first()); QVERIFY(v == a.last()); QVERIFY(v == a[0]); + QT_TEST_EQUALITY_OPS(a.first(), v, true); + QT_TEST_EQUALITY_OPS(a.last(), v, true); auto iteratorCheck = [&v](auto it) { QT_TEST_EQUALITY_OPS(*it, v, true);