From 0d85d0a72fd0136bd89e201d0cc1bf7fac2c24c8 Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Mon, 30 Oct 2023 18:43:20 +0100 Subject: [PATCH] qfloat16: extend comparison with integral types qfloat16 implemented comparison with int, but not with other integral types. As a result, comparing qfloat16 vs qint64 or short was ambiguous, because the compiler had (at least) two options: * qint64 -> int * qint64 -> float Fix it by explicitly introducing comparison operators for other integral types. Use the new compare helper macros for that, and implement helper methods as templates restricted on integral types. Note that we have to manually extend the std::is_integral type trait because libstdc++ only treats __{u}int128_t types as integral when compiling in -std=gnu++XX mode, and we compile Qt in -std=c++XX mode. Fixes: QTBUG-117637 Change-Id: Id0c074af1e9ccc2c2492eb2cc4ee62a4a7131b07 Reviewed-by: Marc Mutz Reviewed-by: Qt CI Bot Reviewed-by: Edward Welbourne --- src/corelib/global/qfloat16.h | 36 +++++++++++++++-- .../corelib/global/qfloat16/tst_qfloat16.cpp | 39 +++++++++++++++++-- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/src/corelib/global/qfloat16.h b/src/corelib/global/qfloat16.h index f9625a72b9e..43521846a47 100644 --- a/src/corelib/global/qfloat16.h +++ b/src/corelib/global/qfloat16.h @@ -14,6 +14,7 @@ #include #include +#include #if defined(QT_COMPILER_SUPPORTS_F16C) && defined(__AVX2__) && !defined(__F16C__) // All processors that support AVX2 do support F16C too, so we could enable the @@ -51,6 +52,19 @@ class qfloat16 constexpr inline explicit Wrap(int value) : b16(quint16(value)) {} }; +#ifdef QT_SUPPORTS_INT128 + template + using IsIntegral = std::disjunction, + std::is_same, qint128>, + std::is_same, quint128>>; +#else + template + using IsIntegral = std::is_integral; +#endif + template + using if_type_is_integral = std::enable_if_t>::value, + bool>; + public: using NativeType = QtPrivate::NativeFloat16Type; @@ -189,11 +203,27 @@ QT_WARNING_DISABLE_FLOAT_COMPARE #endif #undef QF16_MAKE_ORDER_OP_FP - friend bool comparesEqual(const qfloat16 &lhs, int rhs) noexcept + template = true> + friend bool comparesEqual(const qfloat16 &lhs, T rhs) noexcept { return static_cast(lhs) == static_cast(rhs); } - friend Qt::partial_ordering compareThreeWay(const qfloat16 &lhs, int rhs) noexcept + template = true> + friend Qt::partial_ordering compareThreeWay(const qfloat16 &lhs, T rhs) noexcept { return Qt::compareThreeWay(static_cast(lhs), static_cast(rhs)); } - Q_DECLARE_PARTIALLY_ORDERED(qfloat16, int) + + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, qint8) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, quint8) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, qint16) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, quint16) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, qint32) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, quint32) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, long) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, unsigned long) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, qint64) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, quint64) +#ifdef QT_SUPPORTS_INT128 + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, qint128) + Q_DECLARE_PARTIALLY_ORDERED(qfloat16, quint128) +#endif QT_WARNING_POP diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp index e93d5d1838d..ddd2058558d 100644 --- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp +++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp @@ -62,6 +62,22 @@ void tst_qfloat16::compareCompiles() QTestPrivate::testAllComparisonOperatorsCompile(); #endif QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); +#ifdef QT_SUPPORTS_INT128 + QTestPrivate::testAllComparisonOperatorsCompile(); + QTestPrivate::testAllComparisonOperatorsCompile(); +#endif } void tst_qfloat16::ordering_data() @@ -142,10 +158,25 @@ void tst_qfloat16::ordering() if (qIsFinite(right)) { CHECK_INT(int); - // These fail because of QTBUG-117637. Will be fixed in a follow-up patch. - // CHECK_INT(qint8); - // CHECK_INT(qint16); - // CHECK_INT(qint64); + CHECK_INT(qint8); + CHECK_INT(signed char); + CHECK_INT(qint16); + CHECK_INT(qint32); + CHECK_INT(qint64); +#if QT_SUPPORTS_INT128 + CHECK_INT(qint128); +#endif + if (right >= 0) { + CHECK_INT(unsigned int); + CHECK_INT(quint8); + CHECK_INT(unsigned char); + CHECK_INT(quint16); + CHECK_INT(quint32); + CHECK_INT(quint64); + #if QT_SUPPORTS_INT128 + CHECK_INT(quint128); + #endif + } } #undef CHECK_INT