summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp')
-rw-r--r--tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp297
1 files changed, 261 insertions, 36 deletions
diff --git a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
index 35d7dbccf0..7acf8c2cf6 100644
--- a/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
+++ b/tests/auto/corelib/global/qfloat16/tst_qfloat16.cpp
@@ -1,34 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Copyright (C) 2016 by Southwest Research Institute (R)
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// Copyright (C) 2016 by Southwest Research Institute (R)
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QFloat16>
+#include <QMetaType>
+#include <QTextStream>
+
+#include <private/qcomparisontesthelper_p.h>
#include <math.h>
@@ -41,6 +20,10 @@ class tst_qfloat16: public QObject
Q_OBJECT
private slots:
+ void compareCompiles();
+ void relationalOperatorsAreConstexpr();
+ void ordering_data();
+ void ordering();
void fuzzyCompare_data();
void fuzzyCompare();
void fuzzyIsNull_data();
@@ -66,8 +49,180 @@ private slots:
void properties();
void limits();
void mantissaOverflow();
+ void dataStream();
+ void textStream();
};
+void tst_qfloat16::compareCompiles()
+{
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, float>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, double>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, long double>();
+#if QFLOAT16_IS_NATIVE
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qfloat16::NativeType>();
+#endif
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, int>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint8>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint8>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint16>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint16>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, char16_t>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, long>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, unsigned long>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, wchar_t>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint32>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint32>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint64>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint64>();
+#ifdef QT_SUPPORTS_INT128
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, qint128>();
+ QTestPrivate::testAllComparisonOperatorsCompile<qfloat16, quint128>();
+#endif
+}
+
+void tst_qfloat16::relationalOperatorsAreConstexpr()
+{
+#if QFLOAT16_IS_NATIVE
+
+#define CHECK_CONSTEXPR(Type) \
+ do { \
+ constexpr qfloat16 lhs = qfloat16(0.0f); \
+ constexpr Type rhs = 1; \
+ static_assert(lhs < rhs); \
+ static_assert(rhs >= lhs); \
+ } while (false)
+
+ CHECK_CONSTEXPR(qfloat16);
+ CHECK_CONSTEXPR(float);
+ CHECK_CONSTEXPR(double);
+ CHECK_CONSTEXPR(long double);
+ CHECK_CONSTEXPR(qfloat16::NativeType);
+ CHECK_CONSTEXPR(qint8);
+ CHECK_CONSTEXPR(quint8);
+ CHECK_CONSTEXPR(qint16);
+ CHECK_CONSTEXPR(quint16);
+ CHECK_CONSTEXPR(qint32);
+ CHECK_CONSTEXPR(quint32);
+ CHECK_CONSTEXPR(long);
+ CHECK_CONSTEXPR(unsigned long);
+ CHECK_CONSTEXPR(qint64);
+ CHECK_CONSTEXPR(quint64);
+#ifdef QT_SUPPORTS_INT128
+ CHECK_CONSTEXPR(qint128);
+ CHECK_CONSTEXPR(quint128);
+#endif
+
+#undef CHECK_CONSTEXPR
+
+#else
+ QSKIP("This check is only relevant for native float16 types");
+#endif // QFLOAT16_IS_NATIVE
+}
+
+void tst_qfloat16::ordering_data()
+{
+ QTest::addColumn<float>("left");
+ QTest::addColumn<float>("right");
+
+ auto row = [](float left, float right) {
+ QTest::addRow("%f_vs_%f", left, right) << left << right;
+ };
+
+ row(0.0f, 0.0f);
+ row(0.000001f, 0.0f);
+ row(0.0f, 0.000001f);
+ row(-1.000001f, 1.000001f);
+ const float nan = std::numeric_limits<float>::quiet_NaN();
+ const float inf = std::numeric_limits<float>::infinity();
+ row(nan, nan);
+ row(nan, inf);
+ row(inf, nan);
+ row(-inf, nan);
+ row(nan, -inf);
+ row(-inf, inf);
+ row(inf, -inf);
+ row(-inf, 0.0f);
+ row(0.0f, inf);
+ row(0.0f, nan);
+ row(nan, 0.0f);
+ row(2.0f, 314.159f);
+ row(-314.159f, 2.0f);
+ row(-2.0f, 314.159f);
+ row(nan, 314.159f);
+ row(-314.159f, inf);
+ row(-inf, 314.159f);
+ row(2.0f, -inf);
+ row(-2.0f, nan);
+ row(-inf, -2.0f);
+ // testing with values outside qfloat16 range
+ row(0.0f, 13e5f);
+ // generateRow(inf, 13e5f); // fails qfloat16 vs qfloat16 and qfloat16 vs int (QTBUG-118193)
+ row(0.0f, -13e5f);
+ // generateRow(-inf, -13e5f); // fails qfloat16 vs qfloat16 and qfloat16 vs int (QTBUG-118193)
+}
+
+void tst_qfloat16::ordering()
+{
+ QFETCH(float, left);
+ QFETCH(float, right);
+
+ const auto expectedOrder = Qt::compareThreeWay(left, right);
+ const auto lhs = qfloat16(left);
+
+#define POSTCHECK(msg) \
+ if (QTest::currentTestFailed()) { qDebug(msg); return; }
+
+#define CHECK_FP(RHS) \
+ do { \
+ QTestPrivate::testAllComparisonOperators(lhs, static_cast<RHS>(right), expectedOrder); \
+ POSTCHECK("qfloat16 vs " #RHS " comparison failed") \
+ } while (false) \
+ /* END */
+
+ CHECK_FP(qfloat16);
+ CHECK_FP(float);
+ CHECK_FP(double);
+ CHECK_FP(long double);
+
+#undef CHECK_FP
+
+#define CHECK_INT(RHS) \
+ do { \
+ const auto rhs = static_cast<RHS>(right); \
+ const auto expectedRes = Qt::compareThreeWay(left, rhs); \
+ QTestPrivate::testAllComparisonOperators(lhs, rhs, expectedRes); \
+ POSTCHECK("qfloat16 vs " #RHS " comparison failed") \
+ } while (false) \
+ /* END */
+
+ if (qIsFinite(right)) {
+ CHECK_INT(int);
+ 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
+#undef POSTCHECK
+}
+
void tst_qfloat16::fuzzyCompare_data()
{
QTest::addColumn<qfloat16>("val1");
@@ -213,13 +368,7 @@ void tst_qfloat16::qNaN()
QVERIFY(qIsNaN(nan));
QVERIFY(qIsNaN(nan + one));
QVERIFY(qIsNaN(-nan));
-#ifdef Q_CC_INTEL
- QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue);
-#endif
QVERIFY(qIsNaN(nan * zero));
-#ifdef Q_CC_INTEL
- QEXPECT_FAIL("", "ICC optimizes zero * anything to zero", Continue);
-#endif
QVERIFY(qIsNaN(Bounds::infinity() * zero));
QVERIFY(!nan.isNormal());
@@ -332,7 +481,7 @@ void tst_qfloat16::promotionTests()
QCOMPARE(sizeof(double),sizeof(qfloat16(1.f)*1));
QCOMPARE(sizeof(double),sizeof(qfloat16(1.f)/1));
- QCOMPARE(QString::number(1.f),QString::number(qfloat16(1.f)));
+ QCOMPARE(QString::number(1.f),QString::number(double(qfloat16(1.f))));
}
void tst_qfloat16::arithOps_data()
@@ -540,14 +689,35 @@ void tst_qfloat16::properties()
QVERIFY(Bounds::is_signed);
QVERIFY(!Bounds::is_integer);
QVERIFY(!Bounds::is_exact);
+
+ // While we'd like to check for __STDC_IEC_559__, as per ISO/IEC 9899:2011
+ // Annex F (C11, normative for C++11), there are a few corner cases regarding
+ // denormals where GHS compiler is relying hardware behavior that is not IEC
+ // 559 compliant.
+
+ // On GHS the compiler reports std::numeric_limits<float>::is_iec559 as false.
+ // and the same supposed to be for qfloat16.
+#if !defined(Q_CC_GHS)
QVERIFY(Bounds::is_iec559);
+#endif //Q_CC_GHS
+#if QT_CONFIG(signaling_nan)
+ // Technically, presence of NaN and infinities are implied from the above check, but that checkings GHS compiler complies.
+ QVERIFY(Bounds::has_infinity && Bounds::has_quiet_NaN && Bounds::has_signaling_NaN);
+#endif
QVERIFY(Bounds::is_bounded);
QVERIFY(!Bounds::is_modulo);
QVERIFY(!Bounds::traps);
QVERIFY(Bounds::has_infinity);
QVERIFY(Bounds::has_quiet_NaN);
+#if QT_CONFIG(signaling_nan)
QVERIFY(Bounds::has_signaling_NaN);
+#endif
+#if !defined(Q_CC_GHS)
QCOMPARE(Bounds::has_denorm, std::denorm_present);
+#else
+ // For GHS compiler the "denorm_indeterminite" is the expected return value.
+ QCOMPARE(Bounds::has_denorm, std::denorm_indeterminate);
+#endif // Q_CC_GHS
QCOMPARE(Bounds::round_style, std::round_to_nearest);
QCOMPARE(Bounds::radix, 2);
// Untested: has_denorm_loss
@@ -634,12 +804,67 @@ void tst_qfloat16::mantissaOverflow()
float f;
memcpy(&f, &in, 4);
- qfloat16 f16 = f;
+ qfloat16 f16 = qfloat16(f);
qfloat16 f16s[1];
qFloatToFloat16(f16s, &f, 1);
QCOMPARE(f16, f16s[0]);
QVERIFY(qIsNaN(f16));
}
+void tst_qfloat16::dataStream()
+{
+ QByteArray ba;
+ QDataStream ds(&ba, QIODevice::ReadWrite);
+ ds << qfloat16(1.5) << qfloat16(-1);
+ QCOMPARE(ba.size(), 4);
+ QCOMPARE(ds.status(), QDataStream::Ok);
+ QCOMPARE(ba, QByteArray("\x3e\0\xbc\0", 4));
+
+ ds.device()->seek(0);
+ ds.resetStatus();
+ ds.setByteOrder(QDataStream::LittleEndian);
+ ds << qfloat16(0) << qfloat16(-1);
+ QCOMPARE(ds.status(), QDataStream::Ok);
+ QCOMPARE(ba, QByteArray("\0\0\0\xbc", 4));
+
+ ds.device()->seek(0);
+ ds.resetStatus();
+ qfloat16 zero = 1;
+ ds >> zero;
+ QCOMPARE(ds.status(), QDataStream::Ok);
+ QCOMPARE(zero, qfloat16(0));
+
+ ds.device()->seek(0);
+ ds.resetStatus();
+ QMetaType mt = QMetaType(QMetaType::Float16);
+ QVERIFY(mt.save(ds, &zero));
+
+ ds.device()->seek(0);
+ ds.resetStatus();
+ zero = -1;
+ QVERIFY(mt.load(ds, &zero));
+ QCOMPARE(zero, qfloat16(0));
+}
+
+void tst_qfloat16::textStream()
+{
+ QString buffer;
+ {
+ QTextStream ts(&buffer);
+ ts << qfloat16(0) << Qt::endl << qfloat16(1.5);
+ QCOMPARE(ts.status(), QTextStream::Ok);
+ }
+ QCOMPARE(buffer, "0\n1.5");
+
+ {
+ QTextStream ts(&buffer);
+ qfloat16 zero = qfloat16(-2.5), threehalves = 1234;
+ ts >> zero >> threehalves;
+ QCOMPARE(ts.status(), QTextStream::Ok);
+ QCOMPARE(zero, qfloat16(0));
+ QCOMPARE(threehalves, 1.5);
+ }
+}
+
QTEST_APPLESS_MAIN(tst_qfloat16)
#include "tst_qfloat16.moc"