diff options
-rw-r--r-- | src/corelib/tools/qhash.h | 16 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qhash/tst_qhash.cpp | 30 |
2 files changed, 46 insertions, 0 deletions
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index ce9ab33903..3cd967c84b 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -850,6 +850,22 @@ Q_OUTOFLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::erase(itera if (it == iterator(e)) return it; + if (d->ref.isShared()) { + int bucketNum = (it.i->h % d->numBuckets); + const_iterator bucketIterator(*(d->buckets + bucketNum)); + int stepsFromBucketStartToIte = 0; + while (bucketIterator != it) { + ++stepsFromBucketStartToIte; + ++bucketIterator; + } + detach(); + it = iterator(*(d->buckets + bucketNum)); + while (stepsFromBucketStartToIte > 0) { + --stepsFromBucketStartToIte; + ++it; + } + } + iterator ret = it; ++ret; diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index 71428310b8..af1c7aed15 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -78,6 +78,7 @@ private slots: void qthash_data(); void qthash(); + void eraseValidIteratorOnSharedHash(); }; struct Foo { @@ -1352,5 +1353,34 @@ void tst_QHash::qthash() QTEST(result, "hash"); } +void tst_QHash::eraseValidIteratorOnSharedHash() +{ + QHash<int, int> a, b; + a.insert(10, 10); + a.insertMulti(10, 25); + a.insertMulti(10, 30); + a.insert(20, 20); + a.insert(40, 40); + + QHash<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, 3); +} + QTEST_APPLESS_MAIN(tst_QHash) #include "tst_qhash.moc" |