summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qarraydata
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-11-10 20:02:47 +0100
committerLars Knoll <lars.knoll@qt.io>2020-11-17 11:47:02 +0100
commit168772fe8f1d83ffb480c3cc049595c82b4720df (patch)
tree0b0007972e9820b8ceda0fd7ff6a2525faf8997e /tests/auto/corelib/tools/qarraydata
parentf1db4d6e385deae976b6bf9b3cd392b794e09383 (diff)
Remove destructor calls from insert()
QList::insert() should never need to call a destructor. This requires that we construct the new items in the list in order and increment the size each time we constructed a new item. Not having a code path that potentially calls destructors should avoid the generation of lots of additional code for those operations. In addition, the forward and backwards code paths are now unified and only require somewhat different setup of some variables at the start. This gives us strong exception safety when appending one item, weak exception safety in all other cases (in line with std::vector). Change-Id: I6bf88365a34ea9e55ed1236be01a65499275d150 Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'tests/auto/corelib/tools/qarraydata')
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp178
1 files changed, 0 insertions, 178 deletions
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index f39389fa60..d9a964ee96 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -86,7 +86,6 @@ private slots:
void selfEmplaceForward();
#ifndef QT_NO_EXCEPTIONS
void exceptionSafetyPrimitives_constructor();
- void exceptionSafetyPrimitives_destructor();
void exceptionSafetyPrimitives_mover();
void exceptionSafetyPrimitives_displacer();
#endif
@@ -2507,183 +2506,6 @@ void tst_QArrayData::exceptionSafetyPrimitives_constructor()
}
}
-void tst_QArrayData::exceptionSafetyPrimitives_destructor()
-{
- using Prims = QtPrivate::QArrayExceptionSafetyPrimitives<ThrowingType>;
- using Destructor = typename Prims::Destructor;
-
- struct WatcherScope
- {
- WatcherScope() { throwingTypeWatcher().watch = true; }
- ~WatcherScope()
- {
- throwingTypeWatcher().watch = false;
- throwingTypeWatcher().destroyedIds.clear();
- }
- };
-
- // successful operation with no rollback, elements added from left to right
- {
- auto data = createDataPointer<ThrowingType>(20, 10);
- auto reference = createDataPointer<ThrowingType>(20, 10);
- reference->insert(reference.size, 2, ThrowingType(42));
-
- WatcherScope scope; Q_UNUSED(scope);
- {
- ThrowingType *where = data.end() - 1;
- Destructor destroyer(where);
- for (int i = 0; i < 2; ++i) {
- new (where + 1) ThrowingType(42);
- ++where;
- ++data.size;
- }
- destroyer.commit();
- }
-
- QCOMPARE(data.size, reference.size);
- for (qsizetype i = 0; i < data.size; ++i)
- QCOMPARE(data.data()[i], reference.data()[i]);
- QVERIFY(throwingTypeWatcher().destroyedIds.size() == 0);
- }
-
- // failed operation with rollback, elements added from left to right
- {
- auto data = createDataPointer<ThrowingType>(20, 10);
- auto reference = createDataPointer<ThrowingType>(20, 10);
-
- WatcherScope scope; Q_UNUSED(scope);
- try {
- ThrowingType *where = data.end() - 1;
- Destructor destroyer(where);
- for (int i = 0; i < 2; ++i) {
- new (where + 1) ThrowingType(42 + i);
- ++where;
- ThrowingType::throwOnce = 1;
- }
- QFAIL("Unreachable line!");
- destroyer.commit();
- } catch (const std::runtime_error &e) {
- QCOMPARE(std::string(e.what()), ThrowingType::throwString);
- QCOMPARE(data.size, reference.size);
- for (qsizetype i = 0; i < data.size; ++i)
- QCOMPARE(data.data()[i], reference.data()[i]);
- QVERIFY(throwingTypeWatcher().destroyedIds.size() == 1);
- QCOMPARE(throwingTypeWatcher().destroyedIds[0], 42);
- }
- }
-
- // successful operation with no rollback, elements added from right to left
- {
- auto data = createDataPointer<ThrowingType>(20, 10);
- auto reference = createDataPointer<ThrowingType>(20, 10);
- reference->erase(reference.begin(), reference.begin() + 2);
- reference->insert(0, 2, ThrowingType(42));
-
- data.begin()->~ThrowingType();
- data.begin()->~ThrowingType();
- data.size -= 2;
- WatcherScope scope; Q_UNUSED(scope);
- {
- ThrowingType *where = data.begin() + 2; // Note: not updated data ptr, so begin + 2
- Destructor destroyer(where);
- for (int i = 0; i < 2; ++i) {
- new (where - 1) ThrowingType(42);
- --where;
- ++data.size;
- }
- destroyer.commit();
- }
- QCOMPARE(data.size, reference.size);
- for (qsizetype i = 0; i < data.size; ++i)
- QCOMPARE(data.data()[i], reference.data()[i]);
- QVERIFY(throwingTypeWatcher().destroyedIds.size() == 0);
- }
-
- // failed operation with rollback, elements added from right to left
- {
- auto data = createDataPointer<ThrowingType>(20, 10);
- auto reference = createDataPointer<ThrowingType>(20, 10);
- reference->erase(reference.begin(), reference.begin() + 2);
-
- data.begin()->~ThrowingType();
- data.begin()->~ThrowingType();
- data.size -= 2;
- WatcherScope scope; Q_UNUSED(scope);
- try {
- ThrowingType *where = data.begin() + 2; // Note: not updated data ptr, so begin + 2
- Destructor destroyer(where);
- for (int i = 0; i < 2; ++i) {
- new (where - 1) ThrowingType(42 + i);
- --where;
- ThrowingType::throwOnce = 1;
- }
- QFAIL("Unreachable line!");
- destroyer.commit();
- } catch (const std::runtime_error &e) {
- QCOMPARE(std::string(e.what()), ThrowingType::throwString);
- QCOMPARE(data.size, reference.size);
- for (qsizetype i = 0; i < data.size; ++i)
- QCOMPARE(data.data()[i + 2], reference.data()[i]);
- QVERIFY(throwingTypeWatcher().destroyedIds.size() == 1);
- QCOMPARE(throwingTypeWatcher().destroyedIds[0], 42);
- }
- }
-
- // extra: the very first operation throws - destructor has to do nothing,
- // since nothing is properly constructed
- {
- auto data = createDataPointer<ThrowingType>(20, 10);
- auto reference = createDataPointer<ThrowingType>(20, 10);
-
- WatcherScope scope; Q_UNUSED(scope);
- try {
- ThrowingType *where = data.end() - 1;
- Destructor destroyer(where);
- ThrowingType::throwOnce = 1;
- new (where + 1) ThrowingType(42);
- ++where;
- QFAIL("Unreachable line!");
- destroyer.commit();
- } catch (const std::runtime_error &e) {
- QCOMPARE(data.size, reference.size);
- for (qsizetype i = 0; i < data.size; ++i)
- QCOMPARE(data.data()[i], reference.data()[i]);
- QVERIFY(throwingTypeWatcher().destroyedIds.size() == 0);
- }
- }
-
- // extra: special case when iterator is intentionally out of bounds: this is
- // to cover the case when we work on the uninitialized memory region instead
- // of being near the border
- {
- auto data = createDataPointer<ThrowingType>(20, 10);
- auto reference = createDataPointer<ThrowingType>(20, 10);
- reference->erase(reference.begin(), reference.begin() + 2);
-
- data.begin()->~ThrowingType();
- data.begin()->~ThrowingType();
- data.size -= 2;
- WatcherScope scope; Q_UNUSED(scope);
- try {
- ThrowingType *where = data.begin() - 1; // Note: intentionally out of range
- Destructor destroyer(where);
- for (int i = 0; i < 2; ++i) {
- new (where + 1) ThrowingType(42);
- ++where;
- ThrowingType::throwOnce = 1;
- }
- QFAIL("Unreachable line!");
- destroyer.commit();
- } catch (const std::runtime_error &e) {
- QCOMPARE(data.size, reference.size);
- for (qsizetype i = 0; i < data.size; ++i)
- QCOMPARE(data.data()[i + 2], reference.data()[i]);
- QVERIFY(throwingTypeWatcher().destroyedIds.size() == 1);
- QVERIFY(throwingTypeWatcher().destroyedIds[0] == 42);
- }
- }
-}
-
void tst_QArrayData::exceptionSafetyPrimitives_mover()
{
QVERIFY(QTypeInfo<ThrowingType>::isRelocatable);