summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@qt.io>2023-11-13 18:48:32 +0100
committerMarc Mutz <marc.mutz@qt.io>2023-11-21 11:46:27 +0100
commit67072a70aff6688180bd3e008aef1f2a44e7469a (patch)
treead7ea98466f22db2e19898ce6aaf4592d1640046
parentd61cee0ed87eccbc7ebf14ac03a9c1adca162195 (diff)
Q*Ordering: supply is_{lt,gt,n,}eq
std::is_eq etc work fine on our Q*Ordering types when C++20 is available. But in C++17 mode, they're absent. Plug the hole by providing them for our own types as hidden friends, so that users can use unqualified calls to transparently support both std::*ordering and Q*Ordering types, just like with comparison to literal zero. For some reason, we running here into https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903, even though this wasn't seen in other commits of the chain that use comparisons to literal zero. Suppress the warning. Then at least is_eq etc provide a safe fall-back for compilers and users affected by this bogus warning. Fixes: QTBUG-119100 Change-Id: Ie8519c92363401a0c9c8efba6eb0b6e030a8e235 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/corelib/global/qcompare.h33
-rw-r--r--src/corelib/global/qcompare.qdoc50
-rw-r--r--tests/auto/corelib/global/qcompare/tst_qcompare.cpp109
3 files changed, 192 insertions, 0 deletions
diff --git a/src/corelib/global/qcompare.h b/src/corelib/global/qcompare.h
index 4bc97fa24e..2c0392097c 100644
--- a/src/corelib/global/qcompare.h
+++ b/src/corelib/global/qcompare.h
@@ -152,6 +152,17 @@ private:
: m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
{}
+ QT_WARNING_PUSH
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
+ QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
+ friend constexpr bool is_eq (QPartialOrdering o) noexcept { return o == 0; }
+ friend constexpr bool is_neq (QPartialOrdering o) noexcept { return o != 0; }
+ friend constexpr bool is_lt (QPartialOrdering o) noexcept { return o < 0; }
+ friend constexpr bool is_lteq(QPartialOrdering o) noexcept { return o <= 0; }
+ friend constexpr bool is_gt (QPartialOrdering o) noexcept { return o > 0; }
+ friend constexpr bool is_gteq(QPartialOrdering o) noexcept { return o >= 0; }
+ QT_WARNING_POP
+
// instead of the exposition only is_ordered member in [cmp.partialord],
// use a private function
constexpr bool isOrdered() const noexcept
@@ -309,6 +320,17 @@ private:
: m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
{}
+ QT_WARNING_PUSH
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
+ QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
+ friend constexpr bool is_eq (QWeakOrdering o) noexcept { return o == 0; }
+ friend constexpr bool is_neq (QWeakOrdering o) noexcept { return o != 0; }
+ friend constexpr bool is_lt (QWeakOrdering o) noexcept { return o < 0; }
+ friend constexpr bool is_lteq(QWeakOrdering o) noexcept { return o <= 0; }
+ friend constexpr bool is_gt (QWeakOrdering o) noexcept { return o > 0; }
+ friend constexpr bool is_gteq(QWeakOrdering o) noexcept { return o >= 0; }
+ QT_WARNING_POP
+
QtPrivate::CompareUnderlyingType m_order;
};
@@ -478,6 +500,17 @@ public:
: m_order(static_cast<QtPrivate::CompareUnderlyingType>(order))
{}
+ QT_WARNING_PUSH
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100903
+ QT_WARNING_DISABLE_GCC("-Wzero-as-null-pointer-constant")
+ friend constexpr bool is_eq (QStrongOrdering o) noexcept { return o == 0; }
+ friend constexpr bool is_neq (QStrongOrdering o) noexcept { return o != 0; }
+ friend constexpr bool is_lt (QStrongOrdering o) noexcept { return o < 0; }
+ friend constexpr bool is_lteq(QStrongOrdering o) noexcept { return o <= 0; }
+ friend constexpr bool is_gt (QStrongOrdering o) noexcept { return o > 0; }
+ friend constexpr bool is_gteq(QStrongOrdering o) noexcept { return o >= 0; }
+ QT_WARNING_POP
+
QtPrivate::CompareUnderlyingType m_order;
};
diff --git a/src/corelib/global/qcompare.qdoc b/src/corelib/global/qcompare.qdoc
index ffeb1ec887..ab0f2fb49f 100644
--- a/src/corelib/global/qcompare.qdoc
+++ b/src/corelib/global/qcompare.qdoc
@@ -224,6 +224,30 @@
*/
/*!
+ \fn QStrongOrdering::is_eq (QStrongOrdering o)
+ \fn QStrongOrdering::is_neq (QStrongOrdering o)
+ \fn QStrongOrdering::is_lt (QStrongOrdering o)
+ \fn QStrongOrdering::is_lteq(QStrongOrdering o)
+ \fn QStrongOrdering::is_gt (QStrongOrdering o)
+ \fn QStrongOrdering::is_gteq(QStrongOrdering o)
+
+//! [is_eq_table]
+ Converts \a o into the result of one of the six relational operators:
+ \table
+ \header \li Function \li Operation
+ \row \li \c{is_eq} \li \a o \c{== 0}
+ \row \li \c{is_neq} \li \a o \c{!= 0}
+ \row \li \c{is_lt} \li \a o \c{< 0}
+ \row \li \c{is_lteq} \li \a o \c{<= 0}
+ \row \li \c{is_gt} \li \a o \c{> 0}
+ \row \li \c{is_gteq} \li \a o \c{>= 0}
+ \endtable
+//! [is_eq_table]
+
+ These functions are provided for compatibility with \c{std::strong_ordering}.
+*/
+
+/*!
\variable QStrongOrdering::Less
Represents the result of a comparison where the left operand is less
@@ -367,6 +391,19 @@
*/
/*!
+ \fn QWeakOrdering::is_eq (QWeakOrdering o)
+ \fn QWeakOrdering::is_neq (QWeakOrdering o)
+ \fn QWeakOrdering::is_lt (QWeakOrdering o)
+ \fn QWeakOrdering::is_lteq(QWeakOrdering o)
+ \fn QWeakOrdering::is_gt (QWeakOrdering o)
+ \fn QWeakOrdering::is_gteq(QWeakOrdering o)
+
+ \include qcompare.qdoc is_eq_table
+
+ These functions are provided for compatibility with \c{std::weak_ordering}.
+*/
+
+/*!
\variable QWeakOrdering::Less
Represents the result of a comparison where the left operand is less than
@@ -500,6 +537,19 @@
*/
/*!
+ \fn QPartialOrdering::is_eq (QPartialOrdering o)
+ \fn QPartialOrdering::is_neq (QPartialOrdering o)
+ \fn QPartialOrdering::is_lt (QPartialOrdering o)
+ \fn QPartialOrdering::is_lteq(QPartialOrdering o)
+ \fn QPartialOrdering::is_gt (QPartialOrdering o)
+ \fn QPartialOrdering::is_gteq(QPartialOrdering o)
+
+ \include qcompare.qdoc is_eq_table
+
+ These functions are provided for compatibility with \c{std::partial_ordering}.
+*/
+
+/*!
\variable QPartialOrdering::Less
Represents the result of a comparison where the left operand is less than
diff --git a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp
index a8dcc3a201..ac5aa7cb17 100644
--- a/tests/auto/corelib/global/qcompare/tst_qcompare.cpp
+++ b/tests/auto/corelib/global/qcompare/tst_qcompare.cpp
@@ -16,6 +16,7 @@ private slots:
void weakOrdering();
void strongOrdering();
void conversions();
+ void is_eq_overloads();
};
void tst_QCompare::partialOrdering()
@@ -40,6 +41,12 @@ void tst_QCompare::partialOrdering()
static_assert(QPartialOrdering::Greater != QPartialOrdering::Equivalent);
static_assert(QPartialOrdering::Greater == QPartialOrdering::Greater);
+ static_assert(!is_eq (QPartialOrdering::Unordered));
+ static_assert(!is_neq (QPartialOrdering::Unordered));
+ static_assert(!is_lt (QPartialOrdering::Unordered));
+ static_assert(!is_lteq(QPartialOrdering::Unordered));
+ static_assert(!is_gt (QPartialOrdering::Unordered));
+ static_assert(!is_gteq(QPartialOrdering::Unordered));
static_assert(!(QPartialOrdering::Unordered == 0));
static_assert(!(QPartialOrdering::Unordered != 0));
@@ -56,6 +63,13 @@ void tst_QCompare::partialOrdering()
static_assert(!(0 >= QPartialOrdering::Unordered));
+ static_assert(!is_eq (QPartialOrdering::Less));
+ static_assert( is_neq (QPartialOrdering::Less));
+ static_assert( is_lt (QPartialOrdering::Less));
+ static_assert( is_lteq(QPartialOrdering::Less));
+ static_assert(!is_gt (QPartialOrdering::Less));
+ static_assert(!is_gteq(QPartialOrdering::Less));
+
static_assert(!(QPartialOrdering::Less == 0));
static_assert( (QPartialOrdering::Less != 0));
static_assert( (QPartialOrdering::Less < 0));
@@ -71,6 +85,13 @@ void tst_QCompare::partialOrdering()
static_assert( (0 >= QPartialOrdering::Less));
+ static_assert( is_eq (QPartialOrdering::Equivalent));
+ static_assert(!is_neq (QPartialOrdering::Equivalent));
+ static_assert(!is_lt (QPartialOrdering::Equivalent));
+ static_assert( is_lteq(QPartialOrdering::Equivalent));
+ static_assert(!is_gt (QPartialOrdering::Equivalent));
+ static_assert( is_gteq(QPartialOrdering::Equivalent));
+
static_assert( (QPartialOrdering::Equivalent == 0));
static_assert(!(QPartialOrdering::Equivalent != 0));
static_assert(!(QPartialOrdering::Equivalent < 0));
@@ -86,6 +107,13 @@ void tst_QCompare::partialOrdering()
static_assert( (0 >= QPartialOrdering::Equivalent));
+ static_assert(!is_eq (QPartialOrdering::Greater));
+ static_assert( is_neq (QPartialOrdering::Greater));
+ static_assert(!is_lt (QPartialOrdering::Greater));
+ static_assert(!is_lteq(QPartialOrdering::Greater));
+ static_assert( is_gt (QPartialOrdering::Greater));
+ static_assert( is_gteq(QPartialOrdering::Greater));
+
static_assert(!(QPartialOrdering::Greater == 0));
static_assert( (QPartialOrdering::Greater != 0));
static_assert(!(QPartialOrdering::Greater < 0));
@@ -115,6 +143,13 @@ void tst_QCompare::weakOrdering()
static_assert(QWeakOrdering::Greater != QWeakOrdering::Equivalent);
static_assert(QWeakOrdering::Greater == QWeakOrdering::Greater);
+ static_assert(!is_eq (QWeakOrdering::Less));
+ static_assert( is_neq (QWeakOrdering::Less));
+ static_assert( is_lt (QWeakOrdering::Less));
+ static_assert( is_lteq(QWeakOrdering::Less));
+ static_assert(!is_gt (QWeakOrdering::Less));
+ static_assert(!is_gteq(QWeakOrdering::Less));
+
static_assert(!(QWeakOrdering::Less == 0));
static_assert( (QWeakOrdering::Less != 0));
static_assert( (QWeakOrdering::Less < 0));
@@ -129,6 +164,14 @@ void tst_QCompare::weakOrdering()
static_assert( (0 > QWeakOrdering::Less));
static_assert( (0 >= QWeakOrdering::Less));
+
+ static_assert( is_eq (QWeakOrdering::Equivalent));
+ static_assert(!is_neq (QWeakOrdering::Equivalent));
+ static_assert(!is_lt (QWeakOrdering::Equivalent));
+ static_assert( is_lteq(QWeakOrdering::Equivalent));
+ static_assert(!is_gt (QWeakOrdering::Equivalent));
+ static_assert( is_gteq(QWeakOrdering::Equivalent));
+
static_assert( (QWeakOrdering::Equivalent == 0));
static_assert(!(QWeakOrdering::Equivalent != 0));
static_assert(!(QWeakOrdering::Equivalent < 0));
@@ -143,6 +186,14 @@ void tst_QCompare::weakOrdering()
static_assert(!(0 > QWeakOrdering::Equivalent));
static_assert( (0 >= QWeakOrdering::Equivalent));
+
+ static_assert(!is_eq (QWeakOrdering::Greater));
+ static_assert( is_neq (QWeakOrdering::Greater));
+ static_assert(!is_lt (QWeakOrdering::Greater));
+ static_assert(!is_lteq(QWeakOrdering::Greater));
+ static_assert( is_gt (QWeakOrdering::Greater));
+ static_assert( is_gteq(QWeakOrdering::Greater));
+
static_assert(!(QWeakOrdering::Greater == 0));
static_assert( (QWeakOrdering::Greater != 0));
static_assert(!(QWeakOrdering::Greater < 0));
@@ -180,6 +231,13 @@ void tst_QCompare::strongOrdering()
static_assert(QStrongOrdering::Greater != QStrongOrdering::Equivalent);
static_assert(QStrongOrdering::Greater == QStrongOrdering::Greater);
+ static_assert(!is_eq (QStrongOrdering::Less));
+ static_assert( is_neq (QStrongOrdering::Less));
+ static_assert( is_lt (QStrongOrdering::Less));
+ static_assert( is_lteq(QStrongOrdering::Less));
+ static_assert(!is_gt (QStrongOrdering::Less));
+ static_assert(!is_gteq(QStrongOrdering::Less));
+
static_assert(!(QStrongOrdering::Less == 0));
static_assert( (QStrongOrdering::Less != 0));
static_assert( (QStrongOrdering::Less < 0));
@@ -194,6 +252,14 @@ void tst_QCompare::strongOrdering()
static_assert( (0 > QStrongOrdering::Less));
static_assert( (0 >= QStrongOrdering::Less));
+
+ static_assert( is_eq (QStrongOrdering::Equal));
+ static_assert(!is_neq (QStrongOrdering::Equal));
+ static_assert(!is_lt (QStrongOrdering::Equal));
+ static_assert( is_lteq(QStrongOrdering::Equal));
+ static_assert(!is_gt (QStrongOrdering::Equal));
+ static_assert( is_gteq(QStrongOrdering::Equal));
+
static_assert( (QStrongOrdering::Equal == 0));
static_assert(!(QStrongOrdering::Equal != 0));
static_assert(!(QStrongOrdering::Equal < 0));
@@ -208,6 +274,14 @@ void tst_QCompare::strongOrdering()
static_assert(!(0 > QStrongOrdering::Equal));
static_assert( (0 >= QStrongOrdering::Equal));
+
+ static_assert( is_eq (QStrongOrdering::Equivalent));
+ static_assert(!is_neq (QStrongOrdering::Equivalent));
+ static_assert(!is_lt (QStrongOrdering::Equivalent));
+ static_assert( is_lteq(QStrongOrdering::Equivalent));
+ static_assert(!is_gt (QStrongOrdering::Equivalent));
+ static_assert( is_gteq(QStrongOrdering::Equivalent));
+
static_assert( (QStrongOrdering::Equivalent == 0));
static_assert(!(QStrongOrdering::Equivalent != 0));
static_assert(!(QStrongOrdering::Equivalent < 0));
@@ -222,6 +296,14 @@ void tst_QCompare::strongOrdering()
static_assert(!(0 > QStrongOrdering::Equivalent));
static_assert( (0 >= QStrongOrdering::Equivalent));
+
+ static_assert(!is_eq (QStrongOrdering::Greater));
+ static_assert( is_neq (QStrongOrdering::Greater));
+ static_assert(!is_lt (QStrongOrdering::Greater));
+ static_assert(!is_lteq(QStrongOrdering::Greater));
+ static_assert( is_gt (QStrongOrdering::Greater));
+ static_assert( is_gteq(QStrongOrdering::Greater));
+
static_assert(!(QStrongOrdering::Greater == 0));
static_assert( (QStrongOrdering::Greater != 0));
static_assert(!(QStrongOrdering::Greater < 0));
@@ -366,5 +448,32 @@ void tst_QCompare::conversions()
}
+void tst_QCompare::is_eq_overloads()
+{
+#ifndef __cpp_lib_three_way_comparison
+ QSKIP("This test requires C++20 three-way-comparison support enabled in the stdlib.");
+#else
+ constexpr auto u = std::partial_ordering::unordered;
+ constexpr auto l = std::weak_ordering::less;
+ constexpr auto g = std::strong_ordering::greater;
+ constexpr auto e = std::weak_ordering::equivalent;
+ constexpr auto s = std::strong_ordering::equal;
+
+ // This is a compile-time check that unqualified name lookup of
+ // std::is_eq-like functions isn't ambiguous, so we can recommend it to our
+ // users for minimizing porting on the way to C++20.
+
+ // The goal is to check each std::ordering and each is_eq function at least
+ // once, not to test all combinations (we're not the stdlib test suite here).
+
+ QVERIFY(is_eq(s));
+ QVERIFY(is_neq(u));
+ QVERIFY(is_lt(l));
+ QVERIFY(is_gt(g));
+ QVERIFY(is_lteq(e));
+ QVERIFY(is_gteq(s));
+#endif // __cpp_lib_three_way_comparison
+}
+
QTEST_MAIN(tst_QCompare)
#include "tst_qcompare.moc"