QBitArray: replace the member operator~ with a hidden friend

Which takes the array to be inverted by value, so we get free move
semantics and allowing us to perform the negation in-place.

[ChangeLog][Potentially Source-Incompatible Changes] The bitwise AND,
OR, XOR, and NOT operator functions on QBitArray are now hidden
friends. This may cause source-incompatibility in unusual coding styles
(like 'array.operator~()') or with classes that have a casting 'operator
QBitArray()'.

Change-Id: I85b3fc2dd45c4693be13fffd1795ba1fbaf23769
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
Thiago Macieira 2023-11-08 10:44:39 -08:00
parent 9b176281df
commit db991cb4e1
4 changed files with 28 additions and 6 deletions

View File

@ -618,6 +618,13 @@ QStringView QXmlStreamAttributes::value(QLatin1StringView qualifiedName) const
#if QT_CORE_REMOVED_SINCE(6, 7)
#include "qbitarray.h"
QBitArray QBitArray::operator~() const
{
return QBitArray(*this).inverted_inplace();
}
#include "qbytearray.h"
QByteArray QByteArray::left(qsizetype len) const

View File

@ -583,8 +583,9 @@ QBitArray &QBitArray::operator^=(const QBitArray &other)
}
/*!
Returns a bit array that contains the inverted bits of this bit
array.
\fn QBitArray QBitArray::operator~(QBitArray a)
Returns a bit array that contains the inverted bits of the bit
array \a a.
Example:
\snippet code/src_corelib_tools_qbitarray.cpp 11
@ -592,12 +593,19 @@ QBitArray &QBitArray::operator^=(const QBitArray &other)
\sa operator&(), operator|(), operator^()
*/
QBitArray QBitArray::operator~() const
Q_NEVER_INLINE QBitArray QBitArray::inverted_inplace() &&
{
qsizetype n = d.size();
QBitArray result(QByteArrayData(n, n));
const uchar *src = reinterpret_cast<const uchar *>(data_ptr().data());
uchar *dst = reinterpret_cast<uchar *>(result.data_ptr().data());
uchar *dst = reinterpret_cast<uchar *>(data_ptr().data());
const uchar *src = dst;
QBitArray result([&] {
if (d.isDetached() || n == 0)
return std::move(d.data_ptr()); // invert in-place
QByteArrayData tmp(n, n);
dst = reinterpret_cast<uchar *>(tmp.data());
return tmp;
}());
uchar bitdiff = 8;
if (n)

View File

@ -16,6 +16,8 @@ class Q_CORE_EXPORT QBitArray
friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QBitArray &);
#endif
friend Q_CORE_EXPORT size_t qHash(const QBitArray &key, size_t seed) noexcept;
friend QBitArray operator~(QBitArray a)
{ return std::move(a).inverted_inplace(); }
QByteArray d;
QBitArray(QByteArrayData &&dd) : d(std::move(dd)) {}
@ -32,6 +34,8 @@ class Q_CORE_EXPORT QBitArray
return R{ ba.d[1 + byteIdx], uchar(1U << bitIdx) };
}
QBitArray inverted_inplace() &&;
public:
inline QBitArray() noexcept {}
explicit QBitArray(qsizetype size, bool val = false);
@ -78,7 +82,9 @@ public:
QBitArray &operator&=(const QBitArray &);
QBitArray &operator|=(const QBitArray &);
QBitArray &operator^=(const QBitArray &);
#if QT_CORE_REMOVED_SINCE(6, 7)
QBitArray operator~() const;
#endif
inline bool operator==(const QBitArray &other) const { return d == other.d; }
inline bool operator!=(const QBitArray &other) const { return d != other.d; }

View File

@ -454,6 +454,7 @@ void tst_QBitArray::operator_neg()
input = ~input;
QCOMPARE(input, res);
QCOMPARE(~~input, res); // performs two in-place negations
}
void tst_QBitArray::datastream_data()