diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp index efffb1b9bd0..ac4aea9ef3e 100644 --- a/src/corelib/compat/removed_api.cpp +++ b/src/corelib/compat/removed_api.cpp @@ -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 diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index 4a3e929909f..54d587517ec 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -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(data_ptr().data()); - uchar *dst = reinterpret_cast(result.data_ptr().data()); + uchar *dst = reinterpret_cast(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(tmp.data()); + return tmp; + }()); uchar bitdiff = 8; if (n) diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h index a1dde3934c3..01afe29eaa8 100644 --- a/src/corelib/tools/qbitarray.h +++ b/src/corelib/tools/qbitarray.h @@ -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; } diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp index b205bb76eea..1431221fd5e 100644 --- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp +++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp @@ -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()