summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qmap.h21
-rw-r--r--tests/auto/corelib/tools/qmap/tst_qmap.cpp57
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"