summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp34
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h1
-rw-r--r--tests/auto/corelib/kernel/qtimer/BLACKLIST3
-rw-r--r--tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro10
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_arm64.pro3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro41
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro3
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro9
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp15
-rw-r--r--tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp26
-rw-r--r--tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp52
-rw-r--r--tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp36
-rw-r--r--tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp66
-rw-r--r--tests/auto/corelib/tools/qvector/tst_qvector.cpp108
15 files changed, 353 insertions, 57 deletions
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
index 6f608854ae..a6e1f49be2 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.cpp
@@ -2220,6 +2220,40 @@ void tst_QSortFilterProxyModel::changeSourceDataProxySendDataChanged_qtbug87781(
QCOMPARE(afterDataChangedSpy.size(), 1);
}
+void tst_QSortFilterProxyModel::changeSourceDataTreeModel()
+{
+ QStandardItemModel treeModel;
+ QSortFilterProxyModel treeProxyModelBefore;
+ QSortFilterProxyModel treeProxyModelAfter;
+
+ QSignalSpy treeBaseDataChangedSpy(&treeModel, &QStandardItemModel::dataChanged);
+ QSignalSpy treeBeforeDataChangedSpy(&treeProxyModelBefore, &QSortFilterProxyModel::dataChanged);
+ QSignalSpy treeAfterDataChangedSpy(&treeProxyModelAfter, &QSortFilterProxyModel::dataChanged);
+
+ QVERIFY(treeBaseDataChangedSpy.isValid());
+ QVERIFY(treeBeforeDataChangedSpy.isValid());
+ QVERIFY(treeAfterDataChangedSpy.isValid());
+
+ treeProxyModelBefore.setSourceModel(&treeModel);
+ QStandardItem treeNode1("data1");
+ QStandardItem treeNode11("data11");
+ QStandardItem treeNode111("data111");
+
+ treeNode1.appendRow(&treeNode11);
+ treeNode11.appendRow(&treeNode111);
+ treeModel.appendRow(&treeNode1);
+ treeProxyModelAfter.setSourceModel(&treeModel);
+
+ QCOMPARE(treeBaseDataChangedSpy.size(), 0);
+ QCOMPARE(treeBeforeDataChangedSpy.size(), 0);
+ QCOMPARE(treeAfterDataChangedSpy.size(), 0);
+
+ treeNode111.setData(QStringLiteral("new data"), Qt::DisplayRole);
+ QCOMPARE(treeBaseDataChangedSpy.size(), 1);
+ QCOMPARE(treeBeforeDataChangedSpy.size(), 1);
+ QCOMPARE(treeAfterDataChangedSpy.size(), 1);
+}
+
void tst_QSortFilterProxyModel::changeSourceDataProxyFilterSingleColumn()
{
enum modelRow { Row0, Row1, RowCount };
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
index 7bf87a86c2..97862e804b 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel_common/tst_qsortfilterproxymodel.h
@@ -91,6 +91,7 @@ private slots:
void changeSourceDataKeepsStableSorting_qtbug1548();
void changeSourceDataForwardsRoles_qtbug35440();
void changeSourceDataProxySendDataChanged_qtbug87781();
+ void changeSourceDataTreeModel();
void changeSourceDataProxyFilterSingleColumn();
void changeSourceDataProxyFilterMultipleColumns();
void resortingDoesNotBreakTreeModels();
diff --git a/tests/auto/corelib/kernel/qtimer/BLACKLIST b/tests/auto/corelib/kernel/qtimer/BLACKLIST
new file mode 100644
index 0000000000..2af0df9432
--- /dev/null
+++ b/tests/auto/corelib/kernel/qtimer/BLACKLIST
@@ -0,0 +1,3 @@
+[zeroTimer]
+ubuntu-20.04
+
diff --git a/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp b/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
index aa85a7c35b..0ad0fc7076 100644
--- a/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
+++ b/tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
@@ -228,6 +228,9 @@ static qsizetype locateMetadata(const uchar *data, qsizetype len)
void tst_QPlugin::scanInvalidPlugin()
{
+#if defined(Q_OS_MACOS) && defined(Q_PROCESSOR_ARM)
+ QSKIP("This test crashes on ARM macOS");
+#endif
const auto fileNames = dir.entryList({"*invalid*"}, QDir::Files);
QString invalidPluginName;
if (fileNames.isEmpty())
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
index 795dd89895..7cfb7920c0 100644
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest.pro
@@ -1,15 +1,11 @@
TEMPLATE = subdirs
SUBDIRS = \
- machtest_i386.pro \
+ machtest_arm64.pro \
machtest_x86_64.pro \
- machtest_ppc64.pro \
machtest_fat.pro
machtest_fat-pro.depends = \
- machtest_i386.pro \
- machtest_x86_64.pro \
- machtest_ppc64.pro
-
-machtest_ppc64-pro.depends = \
+ machtest_arm64.pro \
machtest_x86_64.pro
+
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_arm64.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_arm64.pro
new file mode 100644
index 0000000000..c2856a8af0
--- /dev/null
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_arm64.pro
@@ -0,0 +1,3 @@
+QMAKE_APPLE_DEVICE_ARCHS = arm64
+include(machtest.pri)
+
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro
index 9c34a873bc..57c6654984 100644
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_fat.pro
@@ -7,41 +7,42 @@ load(qt)
# Generate a fat binary with three architectures
fat_all.target = good.fat.all.dylib
fat_all.commands = lipo -create -output $@ \
- -arch ppc64 good.ppc64.dylib \
- -arch i386 good.i386.dylib \
+ -arch arm64 good.arm64.dylib \
-arch x86_64 good.x86_64.dylib
-fat_all.depends += good.i386.dylib good.x86_64.dylib good.ppc64.dylib
+fat_all.depends += good.arm64.dylib good.x86_64.dylib
-fat_no_i386.target = good.fat.no-i386.dylib
-fat_no_i386.commands = lipo -create -output $@ -arch x86_64 good.x86_64.dylib -arch ppc64 good.ppc64.dylib
-fat_no_i386.depends += good.x86_64.dylib good.ppc64.dylib
+fat_no_arm64.target = good.fat.no-arm64.dylib
+fat_no_arm64.commands = lipo -create -output $@ -arch x86_64 good.x86_64.dylib
+fat_no_arm64.depends += good.x86_64.dylib
fat_no_x86_64.target = good.fat.no-x86_64.dylib
-fat_no_x86_64.commands = lipo -create -output $@ -arch i386 good.i386.dylib -arch ppc64 good.ppc64.dylib
-fat_no_x86_64.depends += good.i386.dylib good.ppc64.dylib
+fat_no_x86_64.commands = lipo -create -output $@ -arch arm64 good.arm64.dylib
+fat_no_x86_64.depends += good.arm64.dylib
-stub_i386.commands = $$QMAKE_CXX -shared -arch i386 -o stub.i386.dylib $$PWD/stub.cpp
-stub_i386.depends += $$PWD/stub.cpp
+stub_flags = -L$$system(xcrun --show-sdk-path)/usr/lib/ -stdlib=libc++
-stub_x86_64.commands = $$QMAKE_CXX -shared -arch x86_64 -o stub.x86_64.dylib $$PWD/stub.cpp
+stub_arm64.commands = $$QMAKE_CXX $$stub_flags -shared -arch arm64 -o stub.arm64.dylib $$PWD/stub.cpp
+stub_arm64.depends += $$PWD/stub.cpp
+
+stub_x86_64.commands = $$QMAKE_CXX $$stub_flags -shared -arch x86_64 -o stub.x86_64.dylib $$PWD/stub.cpp
stub_x86_64.depends += $$PWD/stub.cpp
-fat_stub_i386.target = good.fat.stub-i386.dylib
-fat_stub_i386.commands = lipo -create -output $@ -arch ppc64 good.ppc64.dylib -arch i386 stub.i386.dylib
-fat_stub_i386.depends += stub_i386 good.x86_64.dylib good.ppc64.dylib
+fat_stub_arm64.target = good.fat.stub-arm64.dylib
+fat_stub_arm64.commands = lipo -create -output $@ -arch arm64 stub.arm64.dylib
+fat_stub_arm64.depends += stub_arm64 good.x86_64.dylib
fat_stub_x86_64.target = good.fat.stub-x86_64.dylib
-fat_stub_x86_64.commands = lipo -create -output $@ -arch ppc64 good.ppc64.dylib -arch x86_64 stub.x86_64.dylib
-fat_stub_x86_64.depends += stub_x86_64 good.i386.dylib good.ppc64.dylib
+fat_stub_x86_64.commands = lipo -create -output $@ -arch x86_64 stub.x86_64.dylib
+fat_stub_x86_64.depends += stub_x86_64 good.arm64.dylib
bad.commands = $$PWD/generate-bad.pl
bad.depends += $$PWD/generate-bad.pl
-MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_i386 \
- fat_stub_i386 fat_stub_x86_64 bad stub_i386 stub_x86_64
+MYTARGETS = $$fat_all.depends fat_all fat_no_x86_64 fat_no_arm64 \
+ fat_stub_arm64 fat_stub_x86_64 bad stub_arm64 stub_x86_64
all.depends += $$MYTARGETS
QMAKE_EXTRA_TARGETS += $$MYTARGETS all
-QMAKE_CLEAN += $$fat_all.target $$fat_no_i386.target $$fat_no_x86_64.target \
- $$fat_stub_i386.target $$fat_stub_x86_64.target \
+QMAKE_CLEAN += $$fat_all.target $$fat_no_arm64.target $$fat_no_x86_64.target \
+ $$fat_stub_arm64.target $$fat_stub_x86_64.target \
"bad*.dylib"
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro
deleted file mode 100644
index bfb2e0930c..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_i386.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-QMAKE_APPLE_DEVICE_ARCHS = i386
-include(machtest.pri)
-
diff --git a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro b/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro
deleted file mode 100644
index a73f97ccc6..0000000000
--- a/tests/auto/corelib/plugin/qpluginloader/machtest/machtest_ppc64.pro
+++ /dev/null
@@ -1,9 +0,0 @@
-QMAKE_APPLE_DEVICE_ARCHS = ppc64
-include(machtest.pri)
-
-OTHER_FILES += ppcconverter.pl
-
-# Current macOS toolchains have no compiler for PPC anymore
-# So we fake it by converting an x86-64 binary to (little-endian!) PPC64
-goodlib.commands = $$PWD/ppcconverter.pl $< $@
-goodlib.depends = good.x86_64.dylib $$PWD/ppcconverter.pl
diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
index 8d548f5260..ce8057372c 100644
--- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp
@@ -341,22 +341,19 @@ void tst_QPluginLoader::loadMachO_data()
# ifdef Q_PROCESSOR_X86_64
QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::QtMetaDataSection);
- QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.arm64.dylib") << int(QMachOParser::NotSuitable);
QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::QtMetaDataSection);
-# elif defined(Q_PROCESSOR_X86_32)
- QTest::newRow("machtest/good.i386.dylib") << int(QMachOParser::QtMetaDataSection);
+ QTest::newRow("machtest/good.fat.no-arm64.dylib") << int(QMachOParser::QtMetaDataSection);
+# elif defined(Q_PROCESSOR_ARM)
+ QTest::newRow("machtest/good.arm64.dylib") << int(QMachOParser::QtMetaDataSection);
QTest::newRow("machtest/good.x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.no-i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.no-arm64.dylib") << int(QMachOParser::NotSuitable);
QTest::newRow("machtest/good.fat.no-x86_64.dylib") << int(QMachOParser::QtMetaDataSection);
# endif
-# ifndef Q_PROCESSOR_POWER_64
- QTest::newRow("machtest/good.ppc64.dylib") << int(QMachOParser::NotSuitable);
-# endif
QTest::newRow("machtest/good.fat.all.dylib") << int(QMachOParser::QtMetaDataSection);
QTest::newRow("machtest/good.fat.stub-x86_64.dylib") << int(QMachOParser::NotSuitable);
- QTest::newRow("machtest/good.fat.stub-i386.dylib") << int(QMachOParser::NotSuitable);
+ QTest::newRow("machtest/good.fat.stub-arm64.dylib") << int(QMachOParser::NotSuitable);
QDir d(QFINDTESTDATA("machtest"));
QStringList badlist = d.entryList(QStringList() << "bad*.dylib");
diff --git a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp
index 88f8ea0bbb..b24243b98e 100644
--- a/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp
+++ b/tests/auto/corelib/text/qregularexpression/tst_qregularexpression.cpp
@@ -80,6 +80,7 @@ private slots:
void threadSafety_data();
void threadSafety();
+ void returnsViewsIntoOriginalString();
void wildcard_data();
void wildcard();
void testInvalidWildcard_data();
@@ -2188,6 +2189,31 @@ void tst_QRegularExpression::threadSafety()
}
}
+void tst_QRegularExpression::returnsViewsIntoOriginalString()
+{
+ // https://bugreports.qt.io/browse/QTBUG-98653
+
+ auto to_void = [](const QChar *p) -> const void* { return p; };
+
+ // GIVEN
+ // a QString with dynamically-allocated data:
+ const QString string = QLatin1String("A\nA\nB\nB\n\nC\nC"); // NOT QStringLiteral!
+ const auto stringDataAddress = to_void(string.data());
+
+ // and a view over said QString:
+ QStringView view(string);
+ const auto viewDataAddress = to_void(view.data());
+ QCOMPARE(stringDataAddress, viewDataAddress);
+
+ // WHEN
+ // we call view.split() with a temporary QRegularExpression object
+ const auto split = view.split(QRegularExpression( "(\r\n|\n|\r)" ), Qt::KeepEmptyParts);
+
+ // THEN
+ // the returned views should point into the underlying string:
+ QCOMPARE(to_void(split.front().data()), stringDataAddress);
+}
+
void tst_QRegularExpression::wildcard_data()
{
QTest::addColumn<QString>("pattern");
diff --git a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
index 2c7c8f6514..11f181a955 100644
--- a/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
+++ b/tests/auto/corelib/tools/containerapisymmetry/tst_containerapisymmetry.cpp
@@ -40,8 +40,10 @@
#include <algorithm>
#include <functional>
#include <vector> // for reference
+#include <iostream>
#include <list>
#include <set>
+#include <sstream>
#include <map>
// MSVC has these containers from the Standard Library, but it lacks
@@ -64,6 +66,28 @@
#include <unordered_map>
#endif
+QT_BEGIN_NAMESPACE
+std::ostream &operator<<(std::ostream &os, const QChar &c)
+{
+ Q_ASSERT(c == QLatin1Char{c.toLatin1()});
+ return os << c.toLatin1();
+}
+std::istream &operator>>(std::istream &os, QChar &c)
+{
+ char cL1;
+ os >> cL1;
+ c = QLatin1Char{cL1};
+ return os;
+}
+QT_END_NAMESPACE
+
+namespace {
+template <typename T>
+struct is_qlist : std::false_type {};
+template <typename T>
+struct is_qlist<QList<T>> : std::true_type {};
+}
+
struct Movable
{
explicit Movable(int i = 0) Q_DECL_NOTHROW
@@ -85,6 +109,11 @@ struct Movable
int i;
static int instanceCount;
+
+ friend std::ostream &operator<<(std::ostream &os, const Movable &m)
+ { return os << m.i; }
+ friend std::istream &operator>>(std::istream &os, Movable &m)
+ { return os >> m.i; }
};
int Movable::instanceCount = 0;
@@ -124,6 +153,11 @@ struct Complex
int i;
static int instanceCount;
+
+ friend std::ostream &operator<<(std::ostream &os, const Complex &c)
+ { return os << c.i; }
+ friend std::istream &operator>>(std::istream &os, Complex &c)
+ { return os >> c.i; }
};
int Complex::instanceCount = 0;
@@ -550,12 +584,30 @@ void tst_ContainerApiSymmetry::ranged_ctor_non_associative_impl() const
// from itself
const Container c4(reference.begin(), reference.end());
+ // from stringsteam (= pure input_iterator)
+ const Container c5 = [&] {
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) // QTBUG-99036
+ if constexpr (is_qlist<Container>::value) {
+ return c4;
+ } else
+#endif
+ {
+ std::stringstream ss;
+ for (auto &v : values1)
+ ss << v << ' ';
+ ss.seekg(0);
+ return Container(std::istream_iterator<V>{ss},
+ std::istream_iterator<V>{});
+ }
+ }();
+
QCOMPARE(c1, reference);
QCOMPARE(c2a, reference);
QCOMPARE(c2b, reference);
QCOMPARE(c3a, reference);
QCOMPARE(c3b, reference);
QCOMPARE(c4, reference);
+ QCOMPARE(c5, reference);
}
diff --git a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
index f76f3aa0c6..4eb8a97051 100644
--- a/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
+++ b/tests/auto/corelib/tools/qhashfunctions/tst_qhashfunctions.cpp
@@ -230,8 +230,14 @@ namespace SomeNamespace {
struct Hashable { int i; };
inline uint qHash(Hashable h, uint seed = 0)
{ return QT_PREPEND_NAMESPACE(qHash)(h.i, seed); }
-}
+ struct AdlHashable {
+ int i;
+ private:
+ friend size_t qHash(AdlHashable h, size_t seed = 0)
+ { return QT_PREPEND_NAMESPACE(qHash)(h.i, seed); }
+ };
+}
void tst_QHashFunctions::range()
{
static const int ints[] = {0, 1, 2, 3, 4, 5};
@@ -253,10 +259,16 @@ void tst_QHashFunctions::range()
QCOMPARE(qHashRange(ints, ints + numInts, seed), qHashRange(it, end, seed));
}
- SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
- static const size_t numHashables = sizeof hashables / sizeof *hashables;
- // compile check: is qHash() found using ADL?
- (void)qHashRange(hashables, hashables + numHashables, seed);
+ {
+ SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found using ADL?
+ [[maybe_unused]] auto r = qHashRange(std::begin(hashables), std::end(hashables), seed);
+ }
+ {
+ SomeNamespace::AdlHashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found as a hidden friend?
+ [[maybe_unused]] auto r = qHashRange(std::begin(hashables), std::end(hashables), seed);
+ }
}
void tst_QHashFunctions::rangeCommutative()
@@ -279,10 +291,16 @@ void tst_QHashFunctions::rangeCommutative()
QCOMPARE(qHashRangeCommutative(ints, ints + numInts, seed), qHashRangeCommutative(it, end, seed));
}
- SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
- static const size_t numHashables = sizeof hashables / sizeof *hashables;
- // compile check: is qHash() found using ADL?
- (void)qHashRangeCommutative(hashables, hashables + numHashables, seed);
+ {
+ SomeNamespace::Hashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found using ADL?
+ [[maybe_unused]] auto r = qHashRangeCommutative(std::begin(hashables), std::end(hashables), seed);
+ }
+ {
+ SomeNamespace::AdlHashable hashables[] = {{0}, {1}, {2}, {3}, {4}, {5}};
+ // compile check: is qHash() found as a hidden friend?
+ [[maybe_unused]] auto r = qHashRangeCommutative(std::begin(hashables), std::end(hashables), seed);
+ }
}
void tst_QHashFunctions::stdHash()
diff --git a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
index 5443cf120b..0174885cf3 100644
--- a/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
+++ b/tests/auto/corelib/tools/qvarlengtharray/tst_qvarlengtharray.cpp
@@ -29,6 +29,7 @@
#include <QtTest/QTest>
#include <qvarlengtharray.h>
#include <qvariant.h>
+#include <qscopedvaluerollback.h>
#include <memory>
@@ -36,10 +37,13 @@ class tst_QVarLengthArray : public QObject
{
Q_OBJECT
private slots:
+ void defaultConstructor_int() { defaultConstructor<int>(); }
+ void defaultConstructor_QString() { defaultConstructor<QString>(); }
void append();
void removeLast();
void oldTests();
void appendCausingRealloc();
+ void appendIsStronglyExceptionSafe();
void resize();
void realloc();
void reverseIterators();
@@ -61,6 +65,8 @@ private slots:
void implicitDefaultCtor();
private:
+ template <typename T>
+ void defaultConstructor();
template<typename T>
void initializeList();
};
@@ -80,6 +86,23 @@ struct Tracker
int Tracker::count = 0;
+template <typename T>
+void tst_QVarLengthArray::defaultConstructor()
+{
+ {
+ QVarLengthArray<T, 123> vla;
+ QCOMPARE(vla.size(), 0);
+ QVERIFY(vla.empty());
+ QVERIFY(vla.isEmpty());
+ QCOMPARE(vla.begin(), vla.end());
+ QCOMPARE(vla.capacity(), 123);
+ }
+ {
+ QVarLengthArray<T> vla;
+ QCOMPARE(vla.capacity(), 256); // notice, should we change the default
+ }
+}
+
void tst_QVarLengthArray::append()
{
QVarLengthArray<QString, 2> v;
@@ -245,6 +268,49 @@ void tst_QVarLengthArray::appendCausingRealloc()
d.append(i);
}
+void tst_QVarLengthArray::appendIsStronglyExceptionSafe()
+{
+#ifdef QT_NO_EXCEPTIONS
+ QSKIP("This test requires exception support enabled in the compiler.");
+#else
+ static bool throwOnCopyNow = false;
+ static bool throwOnMoveNow = false;
+ struct Thrower {
+ Thrower() = default;
+ Thrower(const Thrower &)
+ {
+ if (throwOnCopyNow)
+ throw 1;
+ }
+ Thrower &operator=(const Thrower &) = default;
+ Thrower(Thrower &&)
+ {
+ if (throwOnMoveNow)
+ throw 1;
+ }
+ Thrower &operator=(Thrower &&) = default;
+ ~Thrower() = default;
+ };
+
+ {
+ // ### TODO: QVLA isn't exception-safe when throwing during reallocation,
+ // ### so check with size() < capacity() for now
+ QVarLengthArray<Thrower, 2> vla(1);
+ {
+ Thrower t;
+ const QScopedValueRollback<bool> rb(throwOnCopyNow, true);
+ QVERIFY_EXCEPTION_THROWN(vla.push_back(t), int);
+ QCOMPARE(vla.size(), 1);
+ }
+ {
+ const QScopedValueRollback<bool> rb(throwOnMoveNow, true);
+ QVERIFY_EXCEPTION_THROWN(vla.push_back({}), int);
+ QCOMPARE(vla.size(), 1);
+ }
+ }
+#endif
+}
+
void tst_QVarLengthArray::resize()
{
//MOVABLE
diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
index 08d5a8cd50..01409bd188 100644
--- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp
+++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
@@ -183,6 +183,94 @@ inline uint qHash(const Custom &key, uint seed = 0) { return qHash(key.i, seed);
Q_DECLARE_METATYPE(Custom);
+// Similar to Custom but not default-constructible and has move constructor and assignment
+struct NonDefaultConstructible {
+ NonDefaultConstructible() = delete;
+ NonDefaultConstructible(char input)
+ : i(input)
+ , that(this)
+ , state(Constructed)
+ {
+ counter.fetchAndAddRelaxed(1);
+ }
+ NonDefaultConstructible(const NonDefaultConstructible &other)
+ : i(other.i)
+ , that(this)
+ , state(Constructed)
+ {
+ check(&other);
+ counter.fetchAndAddRelaxed(1);
+ }
+ NonDefaultConstructible(NonDefaultConstructible &&other)
+ : i(other.i)
+ , that(this)
+ , state(Constructed)
+ {
+ check(&other);
+ other.state = MovedFrom;
+ counter.fetchAndAddRelaxed(1);
+ }
+ ~NonDefaultConstructible()
+ {
+ check(this, true);
+ i = 0;
+ counter.fetchAndAddRelaxed(-1);
+ state = Destructed;
+ }
+
+ bool operator==(const NonDefaultConstructible &other) const
+ {
+ check(&other);
+ check(this);
+ return i == other.i;
+ }
+
+ bool operator<(const NonDefaultConstructible &other) const
+ {
+ check(&other);
+ check(this);
+ return i < other.i;
+ }
+
+ NonDefaultConstructible &operator=(const NonDefaultConstructible &other)
+ {
+ check(&other);
+ check(this, true);
+ i = other.i;
+ state = Constructed;
+ return *this;
+ }
+
+ NonDefaultConstructible &operator=(NonDefaultConstructible &&other)
+ {
+ check(&other);
+ check(this, true);
+ i = other.i;
+ state = Constructed;
+ other.state = MovedFrom;
+ return *this;
+ }
+ static QAtomicInt counter;
+
+ char i; // used to identify origin of an instance
+private:
+ NonDefaultConstructible *that; // used to catch copying using mem{cpy,move}()
+
+ enum State { Constructed = 106, Destructed = 110, MovedFrom = 120 };
+ State state;
+
+ static void check(const NonDefaultConstructible *c, bool movedOk = false)
+ {
+ // check if c object has been moved incorrectly
+ QCOMPARE(c, c->that);
+ if (!movedOk || c->state != MovedFrom)
+ QCOMPARE(c->state, Constructed);
+ }
+};
+QAtomicInt NonDefaultConstructible::counter = 0;
+
+inline uint qHash(const NonDefaultConstructible &key, uint seed = 0) { return qHash(key.i, seed); }
+
// tests depends on the fact that:
Q_STATIC_ASSERT(!QTypeInfo<int>::isStatic);
Q_STATIC_ASSERT(!QTypeInfo<int>::isComplex);
@@ -190,6 +278,8 @@ Q_STATIC_ASSERT(!QTypeInfo<Movable>::isStatic);
Q_STATIC_ASSERT(QTypeInfo<Movable>::isComplex);
Q_STATIC_ASSERT(QTypeInfo<Custom>::isStatic);
Q_STATIC_ASSERT(QTypeInfo<Custom>::isComplex);
+Q_STATIC_ASSERT(QTypeInfo<NonDefaultConstructible>::isStatic);
+Q_STATIC_ASSERT(QTypeInfo<NonDefaultConstructible>::isComplex);
class tst_QVector : public QObject
@@ -263,6 +353,7 @@ private slots:
void insertInt() const;
void insertMovable() const;
void insertCustom() const;
+ void insertNonDefaultConstructible() const;
void isEmpty() const;
void last() const;
void lastIndexOf() const;
@@ -273,6 +364,7 @@ private slots:
void prependInt() const;
void prependMovable() const;
void prependCustom() const;
+ void prependNonDefaultConstructible() const;
void qhashInt() const { qhash<int>(); }
void qhashMovable() const { qhash<Movable>(); }
void qhashCustom() const { qhash<Custom>(); }
@@ -390,6 +482,10 @@ template<>
const Movable SimpleValue<Movable>::Values[] = { 110, 105, 101, 114, 111, 98 };
template<>
const Custom SimpleValue<Custom>::Values[] = { 110, 105, 101, 114, 111, 98 };
+template<>
+const NonDefaultConstructible SimpleValue<NonDefaultConstructible>::Values[] =
+ { 110, 105, 101, 114, 111, 98 };
+
// Make some macros for the tests to use in order to be slightly more readable...
#define T_FOO SimpleValue<T>::at(0)
@@ -1592,6 +1688,11 @@ void tst_QVector::insertCustom() const
insert<Custom>();
}
+void tst_QVector::insertNonDefaultConstructible() const
+{
+ insert<NonDefaultConstructible>();
+}
+
void tst_QVector::isEmpty() const
{
QVector<QString> myvec;
@@ -1831,6 +1932,13 @@ void tst_QVector::prependCustom() const
QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
+void tst_QVector::prependNonDefaultConstructible() const
+{
+ const int instancesCount = NonDefaultConstructible::counter.loadAcquire();
+ prepend<NonDefaultConstructible>();
+ QCOMPARE(instancesCount, NonDefaultConstructible::counter.loadAcquire());
+}
+
void tst_QVector::removeAllWithAlias() const
{
QVector<QString> strings;