QFlags: add test(Any)Flag(s)

QFlags was lacking a named function for testing whether a QFlags object
contains _any_ of the bits set by a given enumerator/other QFlags.

Drive-by, add testFlags taking a QFlags, not just an object of the
enumeration; and simplify the implementation of testFlags to more
closely follow what its documentation says it does.

[ChangeLog][QtCore][QFlags] The testFlags, testAnyFlag and
testAnyFlags functions have been added.

Change-Id: Ie8688c8b0dd393d34d32bc7786cdcee3eba24d1c
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Giuseppe D'Angelo 2021-05-03 01:20:55 +02:00
parent 78e6b54cde
commit c4947c1c4c
3 changed files with 100 additions and 1 deletions

View File

@ -145,7 +145,10 @@ public:
constexpr inline bool operator!() const noexcept { return !i; }
constexpr inline bool testFlag(Enum flag) const noexcept { return (i & Int(flag)) == Int(flag) && (Int(flag) != 0 || i == Int(0) ); }
constexpr inline bool testFlag(Enum flag) const noexcept { return testFlags(flag); }
constexpr inline bool testFlags(QFlags flags) const noexcept { return flags.i ? ((i & flags.i) == flags.i) : i == Int(0); }
constexpr inline bool testAnyFlag(Enum flag) const noexcept { return testAnyFlags(flag); }
constexpr inline bool testAnyFlags(QFlags flags) const noexcept { return (i & flags.i) != Int(0); }
constexpr inline QFlags &setFlag(Enum flag, bool on = true) noexcept
{
return on ? (*this |= flag) : (*this &= ~QFlags(flag));

View File

@ -510,6 +510,44 @@ static_assert(sizeof(qint64) == 8, "Internal error, qint64 is misdefined");
no bits set to 1 (that is, its value as a integer is 0), then this
function will return \c true if and only if this flags object also
has no bits set to 1.
\sa testAnyFlag()
*/
/*!
\fn template <typename Enum> bool QFlags<Enum>::testFlags(QFlags flags) const noexcept
\since 6.2
Returns \c true if this flags object matches the given \a flags.
If \a flags has any flags set, this flags object matches precisely
if all flags set in \a flags are also set in this flags object.
Otherwise, when \a flags has no flags set, this flags object only
matches if it also has no flags set.
\sa testAnyFlags()
*/
/*!
\fn template <typename Enum> bool QFlags<Enum>::testAnyFlag(Enum flag) const noexcept
\since 6.2
Returns \c true if \b any flag set in \a flag is also set in this
flags object, otherwise \c false. If \a flag has no flags set, the
return will always be \c false.
\sa testFlag()
*/
/*!
\fn template <typename Enum> bool QFlags<Enum>::testAnyFlags(QFlags flags) const noexcept
\since 6.2
Returns \c true if \b any flag set in \a flags is also set in this
flags object, otherwise \c false. If \a flags has no flags set, the
return will always be \c false.
\sa testFlags()
*/
/*!

View File

@ -36,6 +36,8 @@ private slots:
void testFlag() const;
void testFlagZeroFlag() const;
void testFlagMultiBits() const;
void testFlags();
void testAnyFlag();
void constExpr();
void signedness();
void classEnum();
@ -91,6 +93,62 @@ void tst_QFlags::testFlagMultiBits() const
}
}
void tst_QFlags::testFlags()
{
using Int = Qt::TextInteractionFlags::Int;
constexpr Int Zero(0);
Qt::TextInteractionFlags flags;
QCOMPARE(flags.toInt(), Zero);
QVERIFY(flags.testFlags(flags));
QVERIFY(Qt::TextInteractionFlags::fromInt(Zero).testFlags(flags));
QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse));
QVERIFY(!flags.testFlags(Qt::TextSelectableByKeyboard));
QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard));
QVERIFY(flags.testFlags(Qt::TextInteractionFlags::fromInt(Zero)));
QVERIFY(flags.testFlags(Qt::TextInteractionFlags(Qt::TextSelectableByMouse) & ~Qt::TextSelectableByMouse));
flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard;
QVERIFY(flags.toInt() != Zero);
QVERIFY(flags.testFlags(flags));
QVERIFY(flags.testFlags(Qt::TextSelectableByMouse));
QVERIFY(flags.testFlags(Qt::TextSelectableByKeyboard));
QVERIFY(flags.testFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse));
QVERIFY(!flags.testFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse | Qt::TextEditable));
QVERIFY(!flags.testFlags(Qt::TextInteractionFlags()));
QVERIFY(!flags.testFlags(Qt::TextInteractionFlags::fromInt(Zero)));
QVERIFY(!flags.testFlags(Qt::TextEditable));
QVERIFY(!flags.testFlags(Qt::TextSelectableByMouse | Qt::TextEditable));
}
void tst_QFlags::testAnyFlag()
{
Qt::TextInteractionFlags flags;
QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction));
QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByMouse));
QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByKeyboard));
QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard));
QVERIFY(!flags.testAnyFlag(Qt::TextEditorInteraction));
QVERIFY(!flags.testAnyFlag(Qt::TextBrowserInteraction));
flags = Qt::TextSelectableByMouse;
QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction));
QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse));
QVERIFY(!flags.testAnyFlags(Qt::TextSelectableByKeyboard));
QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard));
QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction));
QVERIFY(flags.testAnyFlag(Qt::TextBrowserInteraction));
flags = Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard;
QVERIFY(!flags.testAnyFlags(Qt::NoTextInteraction));
QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse));
QVERIFY(flags.testAnyFlags(Qt::TextSelectableByKeyboard));
QVERIFY(flags.testAnyFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard));
QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction));
QVERIFY(flags.testAnyFlag(Qt::TextEditorInteraction));
QVERIFY(flags.testAnyFlag(Qt::TextBrowserInteraction));
}
template <unsigned int N, typename T> bool verifyConstExpr(T n) { return n == N; }
constexpr Qt::MouseButtons testRelaxedConstExpr()