diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 132791fa390..66dec2979c4 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1004,6 +1004,7 @@ static constexpr struct : QMetaTypeModuleHelper using LongLong = qlonglong; using ULong = unsigned long; using ULongLong = qulonglong; + using Float16 = qfloat16; using Float = float; using Double = double; using Bool = bool; @@ -1028,7 +1029,7 @@ static constexpr struct : QMetaTypeModuleHelper if constexpr(std::is_integral_v) \ result = source.toInteger(); \ else \ - result = source.toDouble(); \ + result = To(source.toDouble()); \ } \ return true; \ ); \ @@ -1043,7 +1044,7 @@ static constexpr struct : QMetaTypeModuleHelper if constexpr(std::is_integral_v) \ result = source.toInteger(); \ else \ - result = source.toDouble(); \ + result = To(source.toDouble()); \ } \ return true; \ ) @@ -1064,6 +1065,7 @@ static constexpr struct : QMetaTypeModuleHelper QMETATYPE_CONVERTER_ASSIGN(To, ULong); \ QMETATYPE_CONVERTER_ASSIGN(To, LongLong); \ QMETATYPE_CONVERTER_ASSIGN(To, ULongLong); \ + QMETATYPE_CONVERTER(To, Float16, result = qRound64(source); return true;); \ QMETATYPE_CONVERTER(To, Float, result = qRound64(source); return true;); \ QMETATYPE_CONVERTER(To, Double, result = qRound64(source); return true;); \ QMETATYPE_CONVERTER(To, QChar, result = source.unicode(); return true;); \ @@ -1102,16 +1104,17 @@ static constexpr struct : QMetaTypeModuleHelper QMETATYPE_CONVERTER_ASSIGN(To, ULong); \ QMETATYPE_CONVERTER_ASSIGN(To, LongLong); \ QMETATYPE_CONVERTER_ASSIGN(To, ULongLong); \ + QMETATYPE_CONVERTER_ASSIGN(To, Float16); \ QMETATYPE_CONVERTER_ASSIGN(To, Float); \ QMETATYPE_CONVERTER_ASSIGN(To, Double); \ QMETATYPE_CONVERTER(To, QString, \ bool ok = false; \ - result = source.toDouble(&ok); \ + result = To(source.toDouble(&ok)); \ return ok; \ ); \ QMETATYPE_CONVERTER(To, QByteArray, \ bool ok = false; \ - result = source.toDouble(&ok); \ + result = To(source.toDouble(&ok)); \ return ok; \ ); \ CONVERT_CBOR_AND_JSON(To) @@ -1131,6 +1134,7 @@ static constexpr struct : QMetaTypeModuleHelper INTEGRAL_CONVERTER(ULong); INTEGRAL_CONVERTER(LongLong); INTEGRAL_CONVERTER(ULongLong); + FLOAT_CONVERTER(Float16); FLOAT_CONVERTER(Float); FLOAT_CONVERTER(Double); @@ -1182,6 +1186,10 @@ static constexpr struct : QMetaTypeModuleHelper QMETATYPE_CONVERTER_ASSIGN_NUMBER(QString, ULong); QMETATYPE_CONVERTER_ASSIGN_NUMBER(QString, UInt); QMETATYPE_CONVERTER_ASSIGN_NUMBER(QString, ULongLong); + QMETATYPE_CONVERTER(QString, Float16, + result = QString::number(source, 'g', QLocale::FloatingPointShortest); + return true; + ); QMETATYPE_CONVERTER(QString, Float, result = QString::number(source, 'g', QLocale::FloatingPointShortest); return true; @@ -1250,6 +1258,10 @@ static constexpr struct : QMetaTypeModuleHelper QMETATYPE_CONVERTER_ASSIGN_NUMBER(QByteArray, ULong); QMETATYPE_CONVERTER_ASSIGN_NUMBER(QByteArray, UInt); QMETATYPE_CONVERTER_ASSIGN_NUMBER(QByteArray, ULongLong); + QMETATYPE_CONVERTER(QByteArray, Float16, + result = QByteArray::number(source, 'g', QLocale::FloatingPointShortest); + return true; + ); QMETATYPE_CONVERTER(QByteArray, Float, result = QByteArray::number(source, 'g', QLocale::FloatingPointShortest); return true; @@ -1393,6 +1405,7 @@ static constexpr struct : QMetaTypeModuleHelper QMETATYPE_CONVERTER_ASSIGN(QCborValue, Short); QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QCborValue, Double); QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QCborValue, Float); + QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QCborValue, Float16); QMETATYPE_CONVERTER(QCborValue, QStringList, result = QCborArray::fromStringList(source); return true; @@ -1583,6 +1596,7 @@ static constexpr struct : QMetaTypeModuleHelper QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QJsonValue, UInt); QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QJsonValue, Double); QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QJsonValue, Float); + QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QJsonValue, Float16); QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QJsonValue, ULong); QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QJsonValue, Long); QMETATYPE_CONVERTER_ASSIGN_DOUBLE(QJsonValue, LongLong); diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 3cf9058a59d..2c69870c7b4 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -2210,6 +2210,7 @@ static bool qIsNumericType(uint tp) Q_UINT64_C(1) << QMetaType::QString | Q_UINT64_C(1) << QMetaType::Bool | Q_UINT64_C(1) << QMetaType::Double | + Q_UINT64_C(1) << QMetaType::Float16 | Q_UINT64_C(1) << QMetaType::Float | Q_UINT64_C(1) << QMetaType::Char | Q_UINT64_C(1) << QMetaType::Char16 | diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 0967bdb9470..62f6c30b60a 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -260,6 +260,9 @@ private slots: void toFloat_data(); void toFloat(); + void toFloat16_data(); + void toFloat16(); + void toPointF_data(); void toPointF(); @@ -893,6 +896,7 @@ template static void addNumberConversions() addNumber(0x8000'0000UL); addNumber(-0x1'0000'0000LL); addNumber(0x1'0000'000'0000ULL); + addNumber(qfloat16(-3.1415927f)); addNumber(-3.1415927f); addNumber(-3.1415927); @@ -1145,8 +1149,10 @@ void tst_QVariant::toBool_data() QTest::newRow( "uint1" ) << QVariant( 123u ) << true; QTest::newRow( "double0" ) << QVariant( 0.0 ) << false; QTest::newRow( "float0" ) << QVariant( 0.0f ) << false; + QTest::newRow( "float16_0" ) << QVariant::fromValue( qfloat16() ) << false; QTest::newRow( "double1" ) << QVariant( 3.1415927 ) << true; QTest::newRow( "float1" ) << QVariant( 3.1415927f ) << true; + QTest::newRow( "float16_1" ) << QVariant::fromValue( qfloat16(3.1415927f) ) << true; QTest::newRow( "string0" ) << QVariant( QString("3") ) << true; QTest::newRow( "string1" ) << QVariant( QString("true") ) << true; QTest::newRow( "string2" ) << QVariant( QString("0") ) << false; @@ -1238,6 +1244,16 @@ void tst_QVariant::toFloat() checkNumberConversions(&QVariant::toFloat); } +void tst_QVariant::toFloat16_data() +{ + addNumberConversions(); +} + +void tst_QVariant::toFloat16() +{ + checkNumberConversions(nullptr); +} + void tst_QVariant::toSChar_data() { addNumberConversions(); @@ -3020,6 +3036,7 @@ void tst_QVariant::compareNumerics_data() const addCompareToInvalid(ulong(0)); addCompareToInvalid(qint64(0)); addCompareToInvalid(quint64(0)); + addCompareToInvalid(qfloat16(0.f)); addCompareToInvalid(0.f); addCompareToInvalid(0.0); addCompareToInvalid(QCborSimpleType{}); @@ -3060,7 +3077,7 @@ QT_WARNING_POP T one = T(zero + 1); T min = std::numeric_limits::min(); T max = std::numeric_limits::max(); - T mid = max / 2 + 1; + T mid = T(max / 2 + 1); if (min != zero) addList(std::array{zero, one, min, mid, max}); else @@ -3079,6 +3096,7 @@ QT_WARNING_POP addSingleType(quint32(0)); addSingleType(qint64(0)); addSingleType(quint64(0)); + addSingleType(qfloat16(0.f)); addSingleType(0.f); addSingleType(0.0); addList(std::array{ EnumTest_Enum0{}, EnumTest_Enum0_value, EnumTest_Enum0_negValue }); @@ -3138,6 +3156,22 @@ QT_WARNING_POP // addComparePair(LLONG_MIN, LLONG_MAX); // already added by addSingleType() // floating point + addComparePair(qfloat16(0.f), 0); + addComparePair(qfloat16(0.f), 0U); + addComparePair(qfloat16(0.f), Q_INT64_C(0)); + addComparePair(qfloat16(0.f), Q_UINT64_C(0)); + addComparePair(qfloat16(0.f), 0.f); + addComparePair(qfloat16(0.f), 1.f); + addComparePair(qfloat16(0.f), 0.); + addComparePair(qfloat16(0.f), 1.); + addComparePair(qfloat16(1 << 11), 1 << 11); + addComparePair(qfloat16(1 << 11) - 1, (1 << 11) - 1); + addComparePair(-qfloat16(1 << 11), 1 << 11); + addComparePair(-qfloat16(1 << 11) + 1, -(1 << 11) + 1); + addComparePair(std::numeric_limits::infinity(), qInf()); + addComparePair(std::numeric_limits::infinity(), -qInf()); + addComparePair(std::numeric_limits::quiet_NaN(), std::numeric_limits::quiet_NaN()); + addComparePair(0.f, 0); addComparePair(0.f, 0U); addComparePair(0.f, Q_INT64_C(0)); @@ -3150,7 +3184,7 @@ QT_WARNING_POP addComparePair(-float(1 << 24) + 1, -(1 << 24) + 1); addComparePair(HUGE_VALF, qInf()); addComparePair(HUGE_VALF, -qInf()); - addComparePair(qQNaN(), std::numeric_limits::quiet_NaN()); + addComparePair(std::numeric_limits::quiet_NaN(), qQNaN()); if (sizeof(qreal) == sizeof(double)) { addComparePair(std::numeric_limits::min(), std::numeric_limits::min()); addComparePair(std::numeric_limits::min(), std::numeric_limits::max());