QHash: implement the heterogeneous non-const operator[]
This complements the previous commit by adding the heterogeneous lookup in operator[]. Unlike the members of the previous commit, this one may insert into the hash, in which case it needs a way to cast from the heterogeneous type K to the actual Key type. Change-Id: I664b9f014ffc48cbb49bfffd17b037c1063dfb91 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>bb10
parent
b53c153a10
commit
9a2e21174a
|
|
@ -713,7 +713,7 @@ struct Data
|
|||
bool initialized;
|
||||
};
|
||||
|
||||
InsertionResult findOrInsert(const Key &key) noexcept
|
||||
template <typename K> InsertionResult findOrInsert(const K &key) noexcept
|
||||
{
|
||||
Bucket it(static_cast<Span *>(nullptr), 0);
|
||||
if (numBuckets > 0) {
|
||||
|
|
@ -1062,16 +1062,22 @@ public:
|
|||
}
|
||||
|
||||
T &operator[](const Key &key)
|
||||
{
|
||||
return operatorIndexImpl(key);
|
||||
}
|
||||
private:
|
||||
template <typename K> 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<Key> auto &key)
|
||||
{
|
||||
return operatorIndexImpl(key);
|
||||
}
|
||||
const T operator[](const QHashPrivate::HeterogeneouslySearchableWith<Key> auto &key) const noexcept
|
||||
{
|
||||
return value(key);
|
||||
|
|
@ -1700,18 +1710,24 @@ public:
|
|||
}
|
||||
|
||||
T &operator[](const Key &key)
|
||||
{
|
||||
return operatorIndexImpl(key);
|
||||
}
|
||||
private:
|
||||
template <typename K> 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<Key> auto &key)
|
||||
{
|
||||
return operatorIndexImpl(key);
|
||||
}
|
||||
const T operator[](const QHashPrivate::HeterogeneouslySearchableWith<Key> auto &key) const noexcept
|
||||
{
|
||||
return value(key);
|
||||
|
|
|
|||
|
|
@ -1262,6 +1262,15 @@ static void heterogeneousSearchTest(const QList<std::remove_const_t<String>> &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<std::remove_const_t<String>> &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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue