summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp')
-rw-r--r--tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp324
1 files changed, 284 insertions, 40 deletions
diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
index 263083972c..5fcf444485 100644
--- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
+++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#include <QTest>
#include <QtCore/QBuffer>
@@ -32,16 +7,19 @@
#include "qbitarray.h"
+#include <QtCore/qelapsedtimer.h>
+#include <QtCore/qscopeguard.h>
+
/**
* Helper function to initialize a bitarray from a string
*/
static QBitArray QStringToQBitArray(const QString &str)
{
QBitArray ba;
- ba.resize(str.length());
+ ba.resize(str.size());
int i;
QChar tru('1');
- for (i = 0; i < str.length(); i++)
+ for (i = 0; i < str.size(); i++)
{
if (str.at(i) == tru)
{
@@ -51,10 +29,17 @@ static QBitArray QStringToQBitArray(const QString &str)
return ba;
}
+static QBitArray detached(QBitArray a)
+{
+ a.detach();
+ return a;
+}
+
class tst_QBitArray : public QObject
{
Q_OBJECT
private slots:
+ void canHandleIntMaxBits();
void size_data();
void size();
void countBits_data();
@@ -68,12 +53,21 @@ private slots:
// operator &=
void operator_andeq_data();
void operator_andeq();
+ // operator &
+ void operator_and_data() { operator_andeq_data(); }
+ void operator_and();
// operator |=
void operator_oreq_data();
void operator_oreq();
+ // operator |
+ void operator_or_data() { operator_oreq_data(); }
+ void operator_or();
// operator ^=
void operator_xoreq_data();
void operator_xoreq();
+ // operator ^
+ void operator_xor_data() { operator_xoreq_data(); }
+ void operator_xor();
// operator ~
void operator_neg_data();
void operator_neg();
@@ -91,6 +85,54 @@ private slots:
void toUInt32();
};
+void tst_QBitArray::canHandleIntMaxBits()
+{
+ QElapsedTimer timer;
+ timer.start();
+ const auto print = qScopeGuard([&] {
+ qDebug("Function took %lldms", qlonglong(timer.elapsed()));
+ });
+
+ try {
+ constexpr qsizetype Size1 = sizeof(void*) > sizeof(int) ? qsizetype(INT_MAX) + 2 :
+ INT_MAX - 2;
+ constexpr qsizetype Size2 = Size1 + 2;
+
+ QBitArray ba(Size1, true);
+ QCOMPARE(ba.size(), Size1);
+ QCOMPARE(ba.at(Size1 - 1), true);
+
+ ba.resize(Size2);
+ QCOMPARE(ba.size(), Size2);
+ QCOMPARE(ba.at(Size1 - 1), true);
+ QCOMPARE(ba.at(Size1), false);
+ QCOMPARE(ba.at(Size2 - 1), false);
+
+ QByteArray serialized;
+ if constexpr (sizeof(void*) > sizeof(int)) {
+ QDataStream ds(&serialized, QIODevice::WriteOnly);
+ ds.setVersion(QDataStream::Qt_5_15);
+ ds << ba;
+ QCOMPARE(ds.status(), QDataStream::Status::SizeLimitExceeded);
+ serialized.clear();
+ }
+ {
+ QDataStream ds(&serialized, QIODevice::WriteOnly);
+ ds << ba;
+ QCOMPARE(ds.status(), QDataStream::Status::Ok);
+ }
+ {
+ QDataStream ds(serialized);
+ QBitArray ba2;
+ ds >> ba2;
+ QCOMPARE(ds.status(), QDataStream::Status::Ok);
+ QCOMPARE(ba, ba2);
+ }
+ } catch (const std::bad_alloc &) {
+ QSKIP("Failed to allocate sufficient memory");
+ }
+}
+
void tst_QBitArray::size_data()
{
//create the testtable instance and define the elements
@@ -150,7 +192,6 @@ void tst_QBitArray::countBits_data()
QTest::newRow("11111111111111111111111111111111") << QString("11111111111111111111111111111111") << 32 << 32;
QTest::newRow("11111111111111111111111111111111111111111111111111111111")
<< QString("11111111111111111111111111111111111111111111111111111111") << 56 << 56;
- QTest::newRow("00000000000000000000000000000000000") << QString("00000000000000000000000000000000000") << 35 << 0;
QTest::newRow("00000000000000000000000000000000") << QString("00000000000000000000000000000000") << 32 << 0;
QTest::newRow("00000000000000000000000000000000000000000000000000000000")
<< QString("00000000000000000000000000000000000000000000000000000000") << 56 << 0;
@@ -168,6 +209,8 @@ void tst_QBitArray::countBits()
bits.setBit(i);
}
+ QCOMPARE(bits.size(), numBits);
+ // NOLINTNEXTLINE(qt-port-to-std-compatible-api): We want to test count() and size()
QCOMPARE(bits.count(), numBits);
QCOMPARE(bits.count(true), onBits);
QCOMPARE(bits.count(false), numBits - onBits);
@@ -325,9 +368,64 @@ void tst_QBitArray::operator_andeq()
QFETCH(QBitArray, input2);
QFETCH(QBitArray, res);
- input1&=input2;
+ QBitArray result = input1;
+ result &= input2;
+ QCOMPARE(result, res);
+ result = input1;
+ result &= std::move(input2);
+ QCOMPARE(result, res);
+ result = input1;
+ result &= detached(input2);
+ QCOMPARE(result, res);
+
+ // operation is commutative
+ result = input2;
+ result &= input1;
+ QCOMPARE(result, res);
+ result = input2;
+ result &= std::move(input1);
+ QCOMPARE(result, res);
+ result = input2;
+ result &= detached(input1);
+ QCOMPARE(result, res);
+
+ // operation is idempotent
+ result &= result;
+ QCOMPARE(result, res);
+ result &= std::move(result);
+ QCOMPARE(result, res);
+ result &= detached(result);
+ QCOMPARE(result, res);
+}
- QCOMPARE(input1, res);
+void tst_QBitArray::operator_and()
+{
+ QFETCH(QBitArray, input1);
+ QFETCH(QBitArray, input2);
+ QFETCH(QBitArray, res);
+
+ 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()
@@ -376,9 +474,64 @@ void tst_QBitArray::operator_oreq()
QFETCH(QBitArray, input2);
QFETCH(QBitArray, res);
- input1|=input2;
+ QBitArray result = input1;
+ result |= input2;
+ QCOMPARE(result, res);
+ result = input1;
+ result |= QBitArray(input2);
+ QCOMPARE(result, res);
+ result = input1;
+ result |= detached(input2);
+ QCOMPARE(result, res);
+
+ // operation is commutative
+ result = input2;
+ result |= input1;
+ QCOMPARE(result, res);
+ result = input2;
+ result |= QBitArray(input1);
+ QCOMPARE(result, res);
+ result = input2;
+ result |= detached(input1);
+ QCOMPARE(result, res);
+
+ // operation is idempotent
+ result |= result;
+ QCOMPARE(result, res);
+ result |= QBitArray(result);
+ QCOMPARE(result, res);
+ result |= detached(result);
+ QCOMPARE(result, res);
+}
- QCOMPARE(input1, res);
+void tst_QBitArray::operator_or()
+{
+ QFETCH(QBitArray, input1);
+ QFETCH(QBitArray, input2);
+ QFETCH(QBitArray, res);
+
+ 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()
@@ -425,11 +578,102 @@ void tst_QBitArray::operator_xoreq()
QFETCH(QBitArray, input2);
QFETCH(QBitArray, res);
- input1^=input2;
-
- QCOMPARE(input1, res);
+ QBitArray result = input1;
+ result ^= input2;
+ QCOMPARE(result, res);
+ result = input1;
+ result ^= QBitArray(input2);
+ QCOMPARE(result, res);
+ result = input1;
+ result ^= detached(input2);
+ QCOMPARE(result, res);
+
+ // operation is commutative
+ result = input2;
+ result ^= input1;
+ QCOMPARE(result, res);
+ result = input2;
+ result ^= QBitArray(input1);
+ QCOMPARE(result, res);
+ result = input2;
+ result ^= detached(input1);
+ QCOMPARE(result, res);
+
+ // XORing with oneself is nilpotent
+ result = input1;
+ result ^= input1;
+ QCOMPARE(result, QBitArray(input1.size()));
+ result = input1;
+ result ^= QBitArray(result);
+ QCOMPARE(result, QBitArray(input1.size()));
+ result = input1;
+ result ^= detached(result);
+ QCOMPARE(result, QBitArray(input1.size()));
+
+ result = input2;
+ result ^= input2;
+ QCOMPARE(result, QBitArray(input2.size()));
+ result = input2;
+ result ^= QBitArray(input2);
+ QCOMPARE(result, QBitArray(input2.size()));
+ result = input2;
+ result ^= detached(input2);
+ QCOMPARE(result, QBitArray(input2.size()));
+
+ result = res;
+ result ^= res;
+ QCOMPARE(result, QBitArray(res.size()));
+ result = res;
+ result ^= QBitArray(res);
+ QCOMPARE(result, QBitArray(res.size()));
+ result = res;
+ result ^= detached(res);
+ QCOMPARE(result, QBitArray(res.size()));
}
+void tst_QBitArray::operator_xor()
+{
+ QFETCH(QBitArray, input1);
+ QFETCH(QBitArray, input2);
+ QFETCH(QBitArray, res);
+
+ 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()
{
@@ -478,6 +722,7 @@ void tst_QBitArray::operator_neg()
input = ~input;
QCOMPARE(input, res);
+ QCOMPARE(~~input, res); // performs two in-place negations
}
void tst_QBitArray::datastream_data()
@@ -497,7 +742,6 @@ void tst_QBitArray::datastream_data()
QTest::newRow("11111111111111111111111111111111") << QString("11111111111111111111111111111111") << 32 << 32;
QTest::newRow("11111111111111111111111111111111111111111111111111111111")
<< QString("11111111111111111111111111111111111111111111111111111111") << 56 << 56;
- QTest::newRow("00000000000000000000000000000000000") << QString("00000000000000000000000000000000000") << 35 << 0;
QTest::newRow("00000000000000000000000000000000") << QString("00000000000000000000000000000000") << 32 << 0;
QTest::newRow("00000000000000000000000000000000000000000000000000000000")
<< QString("00000000000000000000000000000000000000000000000000000000") << 56 << 0;
@@ -519,7 +763,7 @@ void tst_QBitArray::datastream()
bits.setBit(i);
}
- QCOMPARE(bits.count(), numBits);
+ QCOMPARE(bits.size(), numBits);
QCOMPARE(bits.count(true), onBits);
QCOMPARE(bits.count(false), numBits - onBits);
@@ -534,7 +778,7 @@ void tst_QBitArray::datastream()
QBitArray array1, array2, array3;
stream2 >> array1 >> array2 >> array3;
- QCOMPARE(array1.count(), numBits);
+ QCOMPARE(array1.size(), numBits);
QCOMPARE(array1.count(true), onBits);
QCOMPARE(array1.count(false), numBits - onBits);