From 8247adeaed8afaafd60365a4f50141a873fe9a4f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 9 Nov 2023 19:22:18 -0800 Subject: [PATCH] QBitArray: add rvalue binary bitwise operators Now that the assignment-bitwise operators can reuse storage, we can make these operators also be capable of reusing storage. Change-Id: I85b3fc2dd45c4693be13fffd1795b893de65a5b8 Reviewed-by: Marc Mutz (cherry picked from commit 2b7908ac3ad437c209485dcf00d1e53c98d78cb3) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/tools/qbitarray.cpp | 15 ++++-- src/corelib/tools/qbitarray.h | 20 +++++++ .../corelib/tools/qbitarray/tst_qbitarray.cpp | 52 +++++++++++++++++++ 3 files changed, 84 insertions(+), 3 deletions(-) diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index 8459e64acc8..a1f091a06fa 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -686,7 +686,10 @@ Q_NEVER_INLINE QBitArray QBitArray::inverted_inplace() && } /*! - \relates QBitArray + \fn QBitArray QBitArray::operator&(const QBitArray &a1, const QBitArray &a2) + \fn QBitArray QBitArray::operator&(QBitArray &&a1, const QBitArray &a2) + \fn QBitArray QBitArray::operator&(const QBitArray &a1, QBitArray &&a2) + \fn QBitArray QBitArray::operator&(QBitArray &&a1, QBitArray &&a2) Returns a bit array that is the AND of the bit arrays \a a1 and \a a2. @@ -709,7 +712,10 @@ QBitArray operator&(const QBitArray &a1, const QBitArray &a2) } /*! - \relates QBitArray + \fn QBitArray QBitArray::operator|(const QBitArray &a1, const QBitArray &a2) + \fn QBitArray QBitArray::operator|(QBitArray &&a1, const QBitArray &a2) + \fn QBitArray QBitArray::operator|(const QBitArray &a1, QBitArray &&a2) + \fn QBitArray QBitArray::operator|(QBitArray &&a1, QBitArray &&a2) Returns a bit array that is the OR of the bit arrays \a a1 and \a a2. @@ -732,7 +738,10 @@ QBitArray operator|(const QBitArray &a1, const QBitArray &a2) } /*! - \relates QBitArray + \fn QBitArray QBitArray::operator^(const QBitArray &a1, const QBitArray &a2) + \fn QBitArray QBitArray::operator^(QBitArray &&a1, const QBitArray &a2) + \fn QBitArray QBitArray::operator^(const QBitArray &a1, QBitArray &&a2) + \fn QBitArray QBitArray::operator^(QBitArray &&a1, QBitArray &&a2) Returns a bit array that is the XOR of the bit arrays \a a1 and \a a2. diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h index f38ee3ddcd2..183be5fb5b2 100644 --- a/src/corelib/tools/qbitarray.h +++ b/src/corelib/tools/qbitarray.h @@ -12,8 +12,28 @@ class QBitRef; class Q_CORE_EXPORT QBitArray { Q_CORE_EXPORT friend QBitArray operator&(const QBitArray &a1, const QBitArray &a2); + friend QBitArray operator&(QBitArray &&a1, const QBitArray &a2) + { return a1 &= a2; } + friend QBitArray operator&(const QBitArray &a1, QBitArray &&a2) + { return a2 &= a1; } + friend QBitArray operator&(QBitArray &&a1, QBitArray &&a2) + { return a1 &= a2; } + Q_CORE_EXPORT friend QBitArray operator|(const QBitArray &a1, const QBitArray &a2); + friend QBitArray operator|(QBitArray &&a1, const QBitArray &a2) + { return a1 |= a2; } + friend QBitArray operator|(const QBitArray &a1, QBitArray &&a2) + { return a2 |= a1; } + friend QBitArray operator|(QBitArray &&a1, QBitArray &&a2) + { return a1 |= a2; } + Q_CORE_EXPORT friend QBitArray operator^(const QBitArray &a1, const QBitArray &a2); + friend QBitArray operator^(QBitArray &&a1, const QBitArray &a2) + { return a1 ^= a2; } + friend QBitArray operator^(const QBitArray &a1, QBitArray &&a2) + { return a2 ^= a1; } + friend QBitArray operator^(QBitArray &&a1, QBitArray &&a2) + { return a1 ^= a2; } #ifndef QT_NO_DATASTREAM friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QBitArray &); diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp index 5de1e9bb43e..be98f56164a 100644 --- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp +++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp @@ -26,6 +26,12 @@ static QBitArray QStringToQBitArray(const QString &str) return ba; } +static QBitArray detached(QBitArray a) +{ + a.detach(); + return a; +} + class tst_QBitArray : public QObject { Q_OBJECT @@ -323,14 +329,26 @@ void tst_QBitArray::operator_and() QBitArray result = input1 & input2; QCOMPARE(result, res); + result = input1 & QBitArray(input2); + QCOMPARE(result, res); + result = input1 & detached(input2); + QCOMPARE(result, res); // operation is commutative result = input2 & input1; QCOMPARE(result, res); + result = input2 & QBitArray(input1); + QCOMPARE(result, res); + result = input2 & detached(input1); + QCOMPARE(result, res); // operation is idempotent result = result & result; QCOMPARE(result, res); + result = result & QBitArray(result); + QCOMPARE(result, res); + result = result & detached(result); + QCOMPARE(result, res); } void tst_QBitArray::operator_oreq_data() @@ -392,14 +410,26 @@ void tst_QBitArray::operator_or() QBitArray result = input1 | input2; QCOMPARE(result, res); + result = input1 | QBitArray(input2); + QCOMPARE(result, res); + result = input1 | detached(input2); + QCOMPARE(result, res); // operation is commutative result = input2 | input1; QCOMPARE(result, res); + result = input2 | QBitArray(input1); + QCOMPARE(result, res); + result = input2 | detached(input1); + QCOMPARE(result, res); // operation is idempotent result = result | result; QCOMPARE(result, res); + result = result | QBitArray(result); + QCOMPARE(result, res); + result = result | detached(result); + QCOMPARE(result, res); } void tst_QBitArray::operator_xoreq_data() @@ -459,18 +489,40 @@ void tst_QBitArray::operator_xor() QBitArray result = input1 ^ input2; QCOMPARE(result, res); + result = input1 ^ QBitArray(input2); + QCOMPARE(result, res); + result = input1 ^ detached(input2); + QCOMPARE(result, res); // operation is commutative result = input2 ^ input1; QCOMPARE(result, res); + result = input2 ^ QBitArray(input1); + QCOMPARE(result, res); + result = input2 ^ detached(input1); + QCOMPARE(result, res); // XORing with oneself is nilpotent result = input1 ^ input1; QCOMPARE(result, QBitArray(input1.size())); + result = input1 ^ QBitArray(input1); + QCOMPARE(result, QBitArray(input1.size())); + result = input1 ^ detached(input1); + QCOMPARE(result, QBitArray(input1.size())); + result = input2 ^ input2; QCOMPARE(result, QBitArray(input2.size())); + result = input2 ^ QBitArray(input2); + QCOMPARE(result, QBitArray(input2.size())); + result = input2 ^ detached(input2); + QCOMPARE(result, QBitArray(input2.size())); + result = res ^ res; QCOMPARE(result, QBitArray(res.size())); + result = res ^ QBitArray(res); + QCOMPARE(result, QBitArray(res.size())); + result = res ^ detached(res); + QCOMPARE(result, QBitArray(res.size())); } void tst_QBitArray::operator_neg_data()