diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 0ce33759d0..e7cd4123fb 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -713,7 +713,7 @@ struct Data bool initialized; }; - InsertionResult findOrInsert(const Key &key) noexcept + template InsertionResult findOrInsert(const K &key) noexcept { Bucket it(static_cast(nullptr), 0); if (numBuckets > 0) { @@ -1062,16 +1062,22 @@ public: } T &operator[](const Key &key) + { + return operatorIndexImpl(key); + } +private: + template T &operatorIndexImpl(const K &key) { const auto copy = isDetached() ? QHash() : *this; // keep 'key' alive across the detach detach(); auto result = d->findOrInsert(key); Q_ASSERT(!result.it.atEnd()); if (!result.initialized) - Node::createInPlace(result.it.node(), key, T()); + Node::createInPlace(result.it.node(), Key(key), T()); return result.it.node()->value; } +public: const T operator[](const Key &key) const noexcept { return value(key); @@ -1380,6 +1386,10 @@ public: { return valueImpl(key, [&] { return defaultValue; }); } + T &operator[](const QHashPrivate::HeterogeneouslySearchableWith auto &key) + { + return operatorIndexImpl(key); + } const T operator[](const QHashPrivate::HeterogeneouslySearchableWith auto &key) const noexcept { return value(key); @@ -1700,18 +1710,24 @@ public: } T &operator[](const Key &key) + { + return operatorIndexImpl(key); + } +private: + template T &operatorIndexImpl(const K &key) { const auto copy = isDetached() ? QMultiHash() : *this; // keep 'key' alive across the detach detach(); auto result = d->findOrInsert(key); Q_ASSERT(!result.it.atEnd()); if (!result.initialized) { - Node::createInPlace(result.it.node(), key, T()); + Node::createInPlace(result.it.node(), Key(key), T()); ++m_size; } return result.it.node()->value->value; } +public: const T operator[](const Key &key) const noexcept { return value(key); @@ -2341,6 +2357,10 @@ public: { return valueImpl(key, [&] { return defaultValue; }); } + T &operator[](const QHashPrivate::HeterogeneouslySearchableWith auto &key) + { + return operatorIndexImpl(key); + } const T operator[](const QHashPrivate::HeterogeneouslySearchableWith auto &key) const noexcept { return value(key); diff --git a/tests/auto/corelib/tools/qhash/tst_qhash.cpp b/tests/auto/corelib/tools/qhash/tst_qhash.cpp index e31c22ab99..6b7b5955df 100644 --- a/tests/auto/corelib/tools/qhash/tst_qhash.cpp +++ b/tests/auto/corelib/tools/qhash/tst_qhash.cpp @@ -1262,6 +1262,15 @@ static void heterogeneousSearchTest(const QList> &ke std::make_pair(hash.constEnd(), hash.constEnd())); Helper::checkCounter(); + // non-const versions + QCOMPARE_EQ(hash[keyView], keys.size()); // already there + Helper::checkCounter(); + + QCOMPARE_EQ(hash[otherKeyView], 0); // inserts + Helper::resetCounter(); + hash[otherKeyView] = INT_MAX; + Helper::checkCounter(); + if constexpr (IsMultiHash) { hash.insert(key, keys.size()); QCOMPARE_EQ(hash.count(keyView), 2); @@ -1303,7 +1312,7 @@ static void heterogeneousSearchTest(const QList> &ke QCOMPARE_EQ(hash.remove(keyView), true); } - QCOMPARE_EQ(hash.take(otherKeyView), 0); + QCOMPARE_EQ(hash.take(otherKeyView), INT_MAX); QVERIFY(hash.isEmpty()); Helper::checkCounter();