diff options
-rw-r--r-- | src/corelib/tools/qmap.h | 21 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qmap/tst_qmap.cpp | 57 |
2 files changed, 78 insertions, 0 deletions
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 8c15afd9f8..c030a76666 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -913,6 +913,27 @@ Q_OUTOFLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::erase(iterato Q_ASSERT_X(isValidIterator(const_iterator(it)), "QMap::erase", "The specified iterator argument 'it' is invalid"); + if (d->ref.isShared()) { + const_iterator oldBegin = constBegin(); + const_iterator old = const_iterator(it); + int backStepsWithSameKey = 0; + + while (old != oldBegin) { + --old; + if (qMapLessThanKey(old.key(), it.key())) + break; + ++backStepsWithSameKey; + } + + it = find(old.key()); // ensures detach + Q_ASSERT_X(it != iterator(d->end()), "QMap::erase", "Unable to locate same key in erase after detach."); + + while (backStepsWithSameKey > 0) { + ++it; + --backStepsWithSameKey; + } + } + Node *n = it.i; ++it; d->deleteNode(n); diff --git a/tests/auto/corelib/tools/qmap/tst_qmap.cpp b/tests/auto/corelib/tools/qmap/tst_qmap.cpp index 0742f19a5e..de9fa41feb 100644 --- a/tests/auto/corelib/tools/qmap/tst_qmap.cpp +++ b/tests/auto/corelib/tools/qmap/tst_qmap.cpp @@ -87,6 +87,7 @@ private slots: void initializerList(); void testInsertWithHint(); void testInsertMultiWithHint(); + void eraseValidIteratorOnSharedMap(); }; typedef QMap<QString, QString> StringMap; @@ -1289,6 +1290,62 @@ void tst_QMap::testInsertMultiWithHint() QCOMPARE(map.size(), 14); } +void tst_QMap::eraseValidIteratorOnSharedMap() +{ + QMap<int, int> a, b; + a.insert(10, 10); + a.insertMulti(10, 40); + a.insertMulti(10, 25); + a.insertMulti(10, 30); + a.insert(20, 20); + + QMap<int, int>::iterator i = a.begin(); + while (i.value() != 25) + ++i; + + b = a; + a.erase(i); + + QCOMPARE(b.size(), 5); + QCOMPARE(a.size(), 4); + + for (i = a.begin(); i != a.end(); ++i) + QVERIFY(i.value() != 25); + + int itemsWith10 = 0; + for (i = b.begin(); i != b.end(); ++i) + itemsWith10 += (i.key() == 10); + + QCOMPARE(itemsWith10, 4); + + // Border cases + QMap <QString, QString> ms1, ms2, ms3; + ms1.insert("foo", "bar"); + ms1.insertMulti("foo", "quux"); + ms1.insertMulti("foo", "bar"); + + QMap <QString, QString>::iterator si = ms1.begin(); + ms2 = ms1; + ms1.erase(si); + si = ms1.begin(); + QCOMPARE(si.value(), QString("quux")); + ++si; + QCOMPARE(si.value(), QString("bar")); + + si = ms2.begin(); + ++si; + ++si; + ms3 = ms2; + ms2.erase(si); + si = ms2.begin(); + QCOMPARE(si.value(), QString("bar")); + ++si; + QCOMPARE(si.value(), QString("quux")); + + QCOMPARE(ms1.size(), 2); + QCOMPARE(ms2.size(), 2); + QCOMPARE(ms3.size(), 3); +} QTEST_APPLESS_MAIN(tst_QMap) #include "tst_qmap.moc" |