Add missing <=> 0 operator to Qt ordering types
It's required by the standard, see e.g. [1] and the eel.is links in the code. [ChangeLog][QtCore][QPartialOrdering] Added three-way comparison operator (<=>) against literal zero, available when compiling in C++20 mode. [1] https://en.cppreference.com/w/cpp/utility/compare/partial_ordering#Comparisons Change-Id: I8a3b76661400930c6e247cf5b138ff52bf784395 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This commit is contained in:
parent
ccd0dc7f6d
commit
c39fff0da5
@ -47,6 +47,19 @@ enum class Uncomparable : CompareUnderlyingType
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
namespace QtOrderingPrivate {
|
||||
|
||||
template <typename O>
|
||||
constexpr O reversed(O o) noexcept
|
||||
{
|
||||
// https://eel.is/c++draft/cmp.partialord#5
|
||||
return is_lt(o) ? O::greater :
|
||||
is_gt(o) ? O::less :
|
||||
/*else*/ o ;
|
||||
}
|
||||
|
||||
} // namespace QtOrderingPrivate
|
||||
|
||||
namespace Qt {
|
||||
|
||||
class partial_ordering
|
||||
@ -107,6 +120,17 @@ public:
|
||||
{ return rhs.isOrdered() && 0 >= rhs.m_order; }
|
||||
|
||||
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
friend constexpr std::partial_ordering
|
||||
operator<=>(partial_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
|
||||
{ return lhs; } // https://eel.is/c++draft/cmp.partialord#4
|
||||
|
||||
friend constexpr std::partial_ordering
|
||||
operator<=>(QtPrivate::CompareAgainstLiteralZero, partial_ordering rhs) noexcept
|
||||
{ return QtOrderingPrivate::reversed(rhs); }
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
|
||||
|
||||
friend constexpr bool operator==(partial_ordering lhs, partial_ordering rhs) noexcept
|
||||
{ return lhs.m_order == rhs.m_order; }
|
||||
|
||||
@ -253,6 +277,17 @@ public:
|
||||
{ return 0 >= rhs.m_order; }
|
||||
|
||||
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
friend constexpr std::weak_ordering
|
||||
operator<=>(weak_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
|
||||
{ return lhs; } // https://eel.is/c++draft/cmp.weakord#5
|
||||
|
||||
friend constexpr std::weak_ordering
|
||||
operator<=>(QtPrivate::CompareAgainstLiteralZero, weak_ordering rhs) noexcept
|
||||
{ return QtOrderingPrivate::reversed(rhs); }
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
|
||||
|
||||
friend constexpr bool operator==(weak_ordering lhs, weak_ordering rhs) noexcept
|
||||
{ return lhs.m_order == rhs.m_order; }
|
||||
|
||||
@ -425,6 +460,17 @@ public:
|
||||
{ return 0 >= rhs.m_order; }
|
||||
|
||||
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
friend constexpr std::strong_ordering
|
||||
operator<=>(strong_ordering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
|
||||
{ return lhs; } // https://eel.is/c++draft/cmp.strongord#6
|
||||
|
||||
friend constexpr std::strong_ordering
|
||||
operator<=>(QtPrivate::CompareAgainstLiteralZero, strong_ordering rhs) noexcept
|
||||
{ return QtOrderingPrivate::reversed(rhs); }
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
|
||||
|
||||
friend constexpr bool operator==(strong_ordering lhs, strong_ordering rhs) noexcept
|
||||
{ return lhs.m_order == rhs.m_order; }
|
||||
|
||||
@ -699,6 +745,17 @@ public:
|
||||
{ return rhs.isOrdered() && 0 >= rhs.m_order; }
|
||||
|
||||
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
friend constexpr std::partial_ordering
|
||||
operator<=>(QPartialOrdering lhs, QtPrivate::CompareAgainstLiteralZero) noexcept
|
||||
{ return lhs; } // https://eel.is/c++draft/cmp.partialord#4
|
||||
|
||||
friend constexpr std::partial_ordering
|
||||
operator<=>(QtPrivate::CompareAgainstLiteralZero, QPartialOrdering rhs) noexcept
|
||||
{ return QtOrderingPrivate::reversed(rhs); }
|
||||
#endif // __cpp_lib_three_way_comparison
|
||||
|
||||
|
||||
friend constexpr bool operator==(QPartialOrdering lhs, QPartialOrdering rhs) noexcept
|
||||
{ return lhs.m_order == rhs.m_order; }
|
||||
|
||||
|
@ -27,6 +27,8 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPartialOrdering;
|
||||
|
||||
namespace QtOrderingPrivate {
|
||||
#ifdef __cpp_lib_three_way_comparison
|
||||
|
||||
@ -44,6 +46,9 @@ QT_STD_MAP(weak)
|
||||
QT_STD_MAP(strong)
|
||||
#undef QT_STD_MAP
|
||||
|
||||
template <> struct StdOrdering<QPartialOrdering> : q20::type_identity<std::partial_ordering> {};
|
||||
template <> struct QtOrdering<QPartialOrdering> : q20::type_identity< Qt::partial_ordering> {};
|
||||
|
||||
template <typename In> constexpr auto to_std(In in) noexcept
|
||||
-> typename QtOrderingPrivate::StdOrdering<In>::type
|
||||
{ return in; }
|
||||
|
@ -18,6 +18,7 @@ private slots:
|
||||
void partialOrdering();
|
||||
void weakOrdering();
|
||||
void strongOrdering();
|
||||
void threeWayCompareWithLiteralZero();
|
||||
void conversions();
|
||||
void is_eq_overloads();
|
||||
void compareThreeWay();
|
||||
@ -500,6 +501,73 @@ void tst_QCompare::strongOrdering()
|
||||
static_assert(!(0 >= Qt::strong_ordering::greater));
|
||||
}
|
||||
|
||||
void tst_QCompare::threeWayCompareWithLiteralZero()
|
||||
{
|
||||
#ifndef __cpp_lib_three_way_comparison
|
||||
QSKIP("This test requires C++20 <=> support enabled in the compiler and the stdlib.");
|
||||
#else
|
||||
// the result of <=> is _always_ a std::_ordering type:
|
||||
#define CHECK(O) do { \
|
||||
using StdO = typename QtOrderingPrivate::StdOrdering<O>::type; \
|
||||
static_assert(std::is_same_v<decltype(0 <=> std::declval<O&>()), StdO>); \
|
||||
static_assert(std::is_same_v<decltype(std::declval<O&>() <=> 0), StdO>); \
|
||||
} while (false)
|
||||
|
||||
CHECK(Qt::partial_ordering);
|
||||
CHECK(Qt::weak_ordering);
|
||||
CHECK(Qt::strong_ordering);
|
||||
CHECK(QPartialOrdering);
|
||||
// API symmetry check:
|
||||
CHECK(std::partial_ordering);
|
||||
CHECK(std::weak_ordering);
|
||||
CHECK(std::strong_ordering);
|
||||
|
||||
#undef CHECK
|
||||
|
||||
#define CHECK(O, what, reversed) do { \
|
||||
using StdO = typename QtOrderingPrivate::StdOrdering<O>::type; \
|
||||
static_assert((O :: what <=> 0) == StdO:: what); \
|
||||
static_assert((0 <=> O :: what) == StdO:: reversed); \
|
||||
} while (false)
|
||||
|
||||
CHECK(Qt::partial_ordering, unordered, unordered);
|
||||
CHECK(Qt::partial_ordering, equivalent, equivalent);
|
||||
CHECK(Qt::partial_ordering, less, greater);
|
||||
CHECK(Qt::partial_ordering, greater, less);
|
||||
|
||||
CHECK(Qt::weak_ordering, equivalent, equivalent);
|
||||
CHECK(Qt::weak_ordering, less, greater);
|
||||
CHECK(Qt::weak_ordering, greater, less);
|
||||
|
||||
CHECK(Qt::strong_ordering, equal, equal);
|
||||
CHECK(Qt::strong_ordering, less, greater);
|
||||
CHECK(Qt::strong_ordering, greater, less);
|
||||
|
||||
CHECK(QPartialOrdering, unordered, unordered);
|
||||
CHECK(QPartialOrdering, equivalent, equivalent);
|
||||
CHECK(QPartialOrdering, less, greater);
|
||||
CHECK(QPartialOrdering, greater, less);
|
||||
|
||||
// API symmetry check:
|
||||
|
||||
CHECK(std::partial_ordering, unordered, unordered);
|
||||
CHECK(std::partial_ordering, equivalent, equivalent);
|
||||
CHECK(std::partial_ordering, less, greater);
|
||||
CHECK(std::partial_ordering, greater, less);
|
||||
|
||||
CHECK(std::weak_ordering, equivalent, equivalent);
|
||||
CHECK(std::weak_ordering, less, greater);
|
||||
CHECK(std::weak_ordering, greater, less);
|
||||
|
||||
CHECK(std::strong_ordering, equal, equal);
|
||||
CHECK(std::strong_ordering, less, greater);
|
||||
CHECK(std::strong_ordering, greater, less);
|
||||
|
||||
#undef CHECK
|
||||
#endif // __cpp_lib_three_way_comparisons
|
||||
|
||||
}
|
||||
|
||||
void tst_QCompare::conversions()
|
||||
{
|
||||
// Qt::weak_ordering -> Qt::partial_ordering
|
||||
|
Loading…
x
Reference in New Issue
Block a user