QVarLengthArray: rework comparison operators
Similarly to QList, provide compareThreeWay() helper for types that implement compareThreeWay() helpers on their own. Do not change the existing implementation of relational operators for C++17 mode to avoid any potential regressions. In C++20 mode, provide the new operator<=>() only for types that meet the requirements of the std::three_way_comparable concept or provide operator<(). [ChangeLog][QtCore][QVarLengthArray] QVarLengthArray now implements operator<=>() in C++20 mode. Task-number: QTBUG-120305 Change-Id: Ie76ac8b503b08f514fd353deb3de4f72e3237d19 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
08c6cc62c7
commit
9cbfa8cb4c
@ -9,6 +9,7 @@
|
||||
#pragma qt_sync_stop_processing
|
||||
#endif
|
||||
|
||||
#include <QtCore/qcompare.h>
|
||||
#include <QtCore/qcontainerfwd.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qalgorithms.h>
|
||||
@ -625,7 +626,39 @@ public:
|
||||
friend inline bool operator<=(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T, Prealloc2> &r);
|
||||
template <typename T, qsizetype Prealloc1, qsizetype Prealloc2>
|
||||
friend inline bool operator>=(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T, Prealloc2> &r);
|
||||
template <typename T, qsizetype Prealloc1, qsizetype Prealloc2>
|
||||
friend inline auto operator<=>(const QVarLengthArray<T, Prealloc1> &l, const QVarLengthArray<T, Prealloc2> &r);
|
||||
#else
|
||||
private:
|
||||
template <typename U = T, qsizetype Prealloc2 = Prealloc,
|
||||
Qt::if_has_qt_compare_three_way<U, U> = true>
|
||||
friend auto
|
||||
compareThreeWay(const QVarLengthArray &lhs, const QVarLengthArray<T, Prealloc2> &rhs)
|
||||
{
|
||||
return QtOrderingPrivate::lexicographicalCompareThreeWay(lhs.begin(), lhs.end(),
|
||||
rhs.begin(), rhs.end());
|
||||
}
|
||||
|
||||
#if defined(__cpp_lib_three_way_comparison) && defined(__cpp_lib_concepts)
|
||||
template <typename U = T>
|
||||
using if_has_op_less_or_op_compare_three_way =
|
||||
std::enable_if_t<
|
||||
std::disjunction_v<QTypeTraits::has_operator_less_than<U>,
|
||||
QTypeTraits::has_operator_compare_three_way<U>>,
|
||||
bool>;
|
||||
|
||||
template <typename U = T, qsizetype Prealloc2 = Prealloc,
|
||||
if_has_op_less_or_op_compare_three_way<U> = true>
|
||||
friend auto
|
||||
operator<=>(const QVarLengthArray &lhs, const QVarLengthArray<T, Prealloc2> &rhs)
|
||||
{
|
||||
return std::lexicographical_compare_three_way(lhs.begin(), lhs.end(),
|
||||
rhs.begin(), rhs.end(),
|
||||
QtOrderingPrivate::synthThreeWay);
|
||||
}
|
||||
#endif // __cpp_lib_three_way_comparison && __cpp_lib_concepts
|
||||
|
||||
public:
|
||||
template <typename U = T, qsizetype Prealloc2 = Prealloc> friend
|
||||
QTypeTraits::compare_eq_result<U> operator==(const QVarLengthArray<T, Prealloc> &l, const QVarLengthArray<T, Prealloc2> &r)
|
||||
{
|
||||
@ -638,6 +671,7 @@ public:
|
||||
return !(l == r);
|
||||
}
|
||||
|
||||
#ifndef __cpp_lib_three_way_comparison
|
||||
template <typename U = T, qsizetype Prealloc2 = Prealloc> friend
|
||||
QTypeTraits::compare_lt_result<U> operator<(const QVarLengthArray<T, Prealloc> &lhs, const QVarLengthArray<T, Prealloc2> &rhs)
|
||||
noexcept(noexcept(std::lexicographical_compare(lhs.begin(), lhs.end(),
|
||||
@ -666,7 +700,8 @@ public:
|
||||
{
|
||||
return !(lhs < rhs);
|
||||
}
|
||||
#endif
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
#endif // Q_QDOC
|
||||
|
||||
private:
|
||||
template <typename U, qsizetype Prealloc2>
|
||||
|
@ -876,6 +876,21 @@
|
||||
of \c operator<().
|
||||
*/
|
||||
|
||||
/*! \fn template<typename T, qsizetype Prealloc1, qsizetype Prealloc2> auto operator<=>(const QVarLengthArray<T,Prealloc1> &lhs, const QVarLengthArray<T,Prealloc2> &rhs)
|
||||
\since 6.9
|
||||
\relates QVarLengthArray
|
||||
|
||||
Compares the contents of \a lhs and \a rhs
|
||||
\l {https://en.cppreference.com/w/cpp/algorithm/lexicographical_compare_three_way}
|
||||
{lexicographically}. Returns the result of the strongest applicable category
|
||||
type, that is \c {decltype(lhs[0] <=> rhs[0])} if \c {operator<=>()} is
|
||||
available for type \c {T}; otherwise \c {std::weak_ordering}.
|
||||
|
||||
\note This operator is only available in C++20 mode, and when the underlying
|
||||
type \c T models the \c {std::three_way_comparable} concept
|
||||
or provides \c {operator<()}.
|
||||
*/
|
||||
|
||||
/*! \fn template<class T, qsizetype Prealloc> QVarLengthArray<T, Prealloc> &QVarLengthArray<T, Prealloc>::operator<<(const T &value)
|
||||
|
||||
\since 4.8
|
||||
|
@ -487,6 +487,17 @@ private Q_SLOTS:
|
||||
{ comparisonTest_impl<QList<const int *>, Qt::strong_ordering>(); }
|
||||
void comparisonTest_QList_LessOnly()
|
||||
{ comparisonTest_impl<QList<LessOnly>, Qt::weak_ordering>(); }
|
||||
|
||||
void comparisonTest_QVarLengthArray_int()
|
||||
{ comparisonTest_impl<QVarLengthArray<int>, Qt::strong_ordering>(); }
|
||||
void comparisonTest_QVarLengthArray_float()
|
||||
{ comparisonTest_impl<QVarLengthArray<float>, Qt::partial_ordering>(); }
|
||||
void comparisonTest_QVarLengthArray_QDateTime()
|
||||
{ comparisonTest_impl<QVarLengthArray<QDateTime>, Qt::weak_ordering>(); }
|
||||
void comparisonTest_QVarLengthArray_intptr()
|
||||
{ comparisonTest_impl<QVarLengthArray<const int *>, Qt::strong_ordering>(); }
|
||||
void comparisonTest_QVarLengthArray_LessOnly()
|
||||
{ comparisonTest_impl<QVarLengthArray<LessOnly>, Qt::weak_ordering>(); }
|
||||
};
|
||||
|
||||
void tst_ContainerApiSymmetry::init()
|
||||
|
Loading…
x
Reference in New Issue
Block a user