summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/global/qflags/tst_qflags.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/global/qflags/tst_qflags.cpp')
-rw-r--r--tests/auto/corelib/global/qflags/tst_qflags.cpp184
1 files changed, 141 insertions, 43 deletions
diff --git a/tests/auto/corelib/global/qflags/tst_qflags.cpp b/tests/auto/corelib/global/qflags/tst_qflags.cpp
index 3179cfc9d2..d226e8d6b4 100644
--- a/tests/auto/corelib/global/qflags/tst_qflags.cpp
+++ b/tests/auto/corelib/global/qflags/tst_qflags.cpp
@@ -1,38 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** 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$
-**
-****************************************************************************/
-#include <QTest>
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifdef QFLAGS_TEST_NO_TYPESAFE_FLAGS
+# ifdef QT_TYPESAFE_FLAGS
+# undef QT_TYPESAFE_FLAGS
+# endif
+#else
+# ifndef QT_TYPESAFE_FLAGS
+# define QT_TYPESAFE_FLAGS
+# endif
+#endif
-QT_WARNING_DISABLE_DEPRECATED
+#include <QTest>
class tst_QFlags: public QObject
{
Q_OBJECT
private slots:
+ void boolCasts() const;
+ void operators() const;
+ void mixingDifferentEnums() const;
void testFlag() const;
void testFlagZeroFlag() const;
void testFlagMultiBits() const;
@@ -46,6 +33,105 @@ private slots:
void adl();
};
+void tst_QFlags::boolCasts() const
+{
+ // This tests that the operator overloading is sufficient so that common
+ // idioms involving flags -> bool casts work as expected:
+
+ const Qt::Alignment nonNull = Qt::AlignCenter;
+ const Qt::Alignment null = {};
+
+ // basic premiss:
+ QVERIFY(bool(nonNull));
+ QVERIFY(!bool(null));
+
+ // The rest is just checking that stuff compiles:
+
+ // QVERIFY should compile:
+ QVERIFY(nonNull);
+ QVERIFY(!null);
+
+ // ifs should compile:
+ if (null) QFAIL("Can't contextually convert QFlags to bool!");
+ if (!nonNull) QFAIL("Missing operator! on QFlags (shouldn't be necessary).");
+
+ // ternary should compile:
+ QVERIFY(nonNull ? true : false);
+ QVERIFY(!null ? true : false);
+
+ // logical operators should compile:
+ QVERIFY(nonNull && true);
+ QVERIFY(nonNull || false);
+ QVERIFY(!null && true);
+ QVERIFY(!null || false);
+
+ // ... in both directions:
+ QVERIFY(true && nonNull);
+ QVERIFY(false || nonNull);
+ QVERIFY(true && !null);
+ QVERIFY(false || !null);
+
+ // ... and mixed:
+ QVERIFY(null || nonNull);
+ QVERIFY(!(null && nonNull));
+}
+
+void tst_QFlags::operators() const
+{
+#define CHECK(op, LHS, RHS, RES) \
+ do { \
+ QCOMPARE((LHS op RHS), (RES)); \
+ QCOMPARE(( /*CTAD*/ QFlags(LHS) op RHS), (RES)); \
+ QCOMPARE((LHS op QFlags(RHS)), (RES)); \
+ QCOMPARE((QFlags(LHS) op QFlags(RHS)), (RES)); \
+ QCOMPARE((QFlags(LHS) op ## = RHS), (RES)); \
+ QCOMPARE((QFlags(LHS) op ## = QFlags(RHS)), (RES)); \
+ } while (false)
+
+ CHECK(|, Qt::AlignHCenter, Qt::AlignVCenter, Qt::AlignCenter);
+ CHECK(|, Qt::AlignHCenter, Qt::AlignHCenter, Qt::AlignHCenter);
+ CHECK(&, Qt::AlignHCenter, Qt::AlignVCenter, Qt::Alignment());
+ CHECK(&, Qt::AlignHCenter, Qt::AlignHCenter, Qt::AlignHCenter);
+ CHECK(^, Qt::AlignHCenter, Qt::AlignVCenter, Qt::AlignCenter);
+ CHECK(^, Qt::AlignHCenter, Qt::AlignHCenter, Qt::Alignment());
+#undef CHECK
+}
+
+void tst_QFlags::mixingDifferentEnums() const
+{
+#define CHECK(op, LHS, RHS, RES) \
+ /* LHS must be QFlags'able */ \
+ do { \
+ QCOMPARE((LHS op RHS), (RES)); \
+ QCOMPARE((RHS op LHS), (RES)); \
+ /*QCOMPARE(( / *CTAD* / QFlags(LHS) op RHS), (RES));*/ \
+ /*QCOMPARE((QFlags(LHS) op ## = RHS), (RES));*/ \
+ } while (false)
+
+ // AlignmentFlags <-> TextFlags
+ {
+ CHECK(|, Qt::AlignCenter, Qt::TextSingleLine, 0x0184);
+ CHECK(&, Qt::AlignCenter, Qt::TextSingleLine, 0x0000);
+ CHECK(^, Qt::AlignCenter, Qt::TextSingleLine, 0x0184);
+ }
+ // QFlags<AlignmentFlags> <-> TextFlags
+ {
+#ifndef QT_TYPESAFE_FLAGS // QTBUG-101344
+ Qt::Alignment MyAlignCenter = Qt::AlignCenter; // convert enum to QFlags
+ CHECK(|, MyAlignCenter, Qt::TextSingleLine, 0x0184U); // yes, unsigned!
+ CHECK(&, MyAlignCenter, Qt::TextSingleLine, 0x0000U); // yes, unsigned!
+ CHECK(^, MyAlignCenter, Qt::TextSingleLine, 0x0184U); // yes, unsigned!
+#endif
+ }
+ // TextElideMode <-> TextFlags
+ {
+ CHECK(|, Qt::ElideNone, Qt::TextSingleLine, 0x0103);
+ CHECK(&, Qt::ElideNone, Qt::TextSingleLine, 0x0000);
+ CHECK(^, Qt::ElideNone, Qt::TextSingleLine, 0x0103);
+ }
+#undef CHECK
+}
+
void tst_QFlags::testFlag() const
{
Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton;
@@ -150,6 +236,7 @@ void tst_QFlags::testAnyFlag()
}
template <unsigned int N, typename T> bool verifyConstExpr(T n) { return n == N; }
+template <unsigned int N, typename T> bool verifyConstExpr(QFlags<T> n) { return n.toInt() == N; }
constexpr Qt::MouseButtons testRelaxedConstExpr()
{
@@ -164,25 +251,32 @@ constexpr Qt::MouseButtons testRelaxedConstExpr()
void tst_QFlags::constExpr()
{
Qt::MouseButtons btn = Qt::LeftButton | Qt::RightButton;
- switch (btn) {
+ switch (btn.toInt()) {
case Qt::LeftButton: QVERIFY(false); break;
case Qt::RightButton: QVERIFY(false); break;
- case int(Qt::LeftButton | Qt::RightButton): QVERIFY(true); break;
- default: QFAIL(qPrintable(QStringLiteral("Unexpected button: %1").arg(btn)));
+ case (Qt::LeftButton | Qt::RightButton).toInt(): QVERIFY(true); break;
+ default: QFAIL(qPrintable(QStringLiteral("Unexpected button: %1").arg(btn.toInt())));
}
- QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) & Qt::LeftButton)>(Qt::LeftButton));
- QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) & Qt::MiddleButton)>(0));
- QVERIFY(verifyConstExpr<uint((Qt::LeftButton | Qt::RightButton) | Qt::MiddleButton)>(Qt::LeftButton | Qt::RightButton | Qt::MiddleButton));
- QVERIFY(verifyConstExpr<uint(~(Qt::LeftButton | Qt::RightButton))>(~(Qt::LeftButton | Qt::RightButton)));
- QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::LeftButton) ^ Qt::RightButton)>(Qt::LeftButton ^ Qt::RightButton));
- QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(0))>(0));
- QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::RightButton) & 0xff)>(Qt::RightButton));
- QVERIFY(verifyConstExpr<uint(Qt::MouseButtons(Qt::RightButton) | 0xff)>(0xff));
+#define VERIFY_CONSTEXPR(expression, expected) \
+ QVERIFY(verifyConstExpr<(expression).toInt()>(expected))
+
+ VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) & Qt::LeftButton, Qt::LeftButton);
+ VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) & Qt::MiddleButton, 0);
+ VERIFY_CONSTEXPR((Qt::LeftButton | Qt::RightButton) | Qt::MiddleButton, Qt::LeftButton | Qt::RightButton | Qt::MiddleButton);
+ VERIFY_CONSTEXPR(~(Qt::LeftButton | Qt::RightButton), ~(Qt::LeftButton | Qt::RightButton));
+ VERIFY_CONSTEXPR(Qt::MouseButtons(Qt::LeftButton) ^ Qt::RightButton, Qt::LeftButton ^ Qt::RightButton);
+ VERIFY_CONSTEXPR(Qt::MouseButtons(0), 0);
+#ifndef QT_TYPESAFE_FLAGS
+ QVERIFY(verifyConstExpr<(Qt::MouseButtons(Qt::RightButton) & 0xff)>(Qt::RightButton));
+ QVERIFY(verifyConstExpr<(Qt::MouseButtons(Qt::RightButton) | 0xff)>(0xff));
+#endif
QVERIFY(!verifyConstExpr<Qt::RightButton>(~Qt::MouseButtons(Qt::LeftButton)));
- QVERIFY(verifyConstExpr<uint(testRelaxedConstExpr())>(Qt::MiddleButton));
+ VERIFY_CONSTEXPR(testRelaxedConstExpr(), Qt::MiddleButton);
+
+#undef VERIFY_CONSTEXPR
}
void tst_QFlags::signedness()
@@ -207,7 +301,7 @@ Q_DECLARE_FLAGS( MyStrictNoOpFlags, MyStrictNoOpEnum )
static_assert( !QTypeInfo<MyStrictFlags>::isComplex );
static_assert( QTypeInfo<MyStrictFlags>::isRelocatable );
-static_assert( !QTypeInfo<MyStrictFlags>::isPointer );
+static_assert( !std::is_pointer_v<MyStrictFlags> );
void tst_QFlags::classEnum()
{
@@ -233,11 +327,14 @@ void tst_QFlags::classEnum()
QVERIFY(!f0);
+#ifndef QT_TYPESAFE_FLAGS
QCOMPARE(f3 & int(1), 1);
QCOMPARE(f3 & uint(1), 1);
+#endif
QCOMPARE(f3 & MyStrictEnum::StrictOne, 1);
MyStrictFlags aux;
+#ifndef QT_TYPESAFE_FLAGS
aux = f3;
aux &= int(1);
QCOMPARE(aux, 1);
@@ -245,6 +342,7 @@ void tst_QFlags::classEnum()
aux = f3;
aux &= uint(1);
QCOMPARE(aux, 1);
+#endif
aux = f3;
aux &= MyStrictEnum::StrictOne;
@@ -377,7 +475,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS( MyFlags )
static_assert( !QTypeInfo<MyFlags>::isComplex );
static_assert( QTypeInfo<MyFlags>::isRelocatable );
-static_assert( !QTypeInfo<MyFlags>::isPointer );
+static_assert( !std::is_pointer_v<MyFlags> );
QTEST_MAIN(tst_QFlags)
#include "tst_qflags.moc"