Skip to content

Commit

Permalink
QHash tryEmplace-try_emplace compat
Browse files Browse the repository at this point in the history
Let users use either type

Change-Id: Ica22a329df679352ab828aa96102a30fc9eedf79
Reviewed-by: Thiago Macieira <[email protected]>
  • Loading branch information
Morten242 committed Dec 5, 2024
1 parent 056e78f commit 154fe8d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 12 deletions.
36 changes: 24 additions & 12 deletions src/corelib/tools/qhash.h
Original file line number Diff line number Diff line change
Expand Up @@ -1255,6 +1255,24 @@ class QHash
{
QHash::iterator iterator;
bool inserted;

TryEmplaceResult() = default;
// Generated SMFs are fine!
TryEmplaceResult(QHash::iterator it, bool b)
: iterator(it), inserted(b)
{
}

// Implicit conversion _from_ the return-type of try_emplace:
Q_IMPLICIT TryEmplaceResult(const std::pair<key_value_iterator, bool> &p)
: iterator(p.first.base()), inserted(p.second)
{
}
// Implicit conversion _to_ the return-type of try_emplace:
Q_IMPLICIT operator std::pair<key_value_iterator, bool>()
{
return { key_value_iterator(iterator), inserted };
}
};

iterator erase(const_iterator it)
Expand Down Expand Up @@ -1387,26 +1405,22 @@ class QHash
template <typename... Args>
std::pair<key_value_iterator, bool> try_emplace(const Key &key, Args &&...args)
{
auto r = tryEmplace_impl(key, std::forward<Args>(args)...);
return {key_value_iterator(r.iterator), r.inserted};
return tryEmplace_impl(key, std::forward<Args>(args)...);
}
template <typename... Args>
std::pair<key_value_iterator, bool> try_emplace(Key &&key, Args &&...args)
{
auto r = tryEmplace_impl(std::move(key), std::forward<Args>(args)...);
return {key_value_iterator(r.iterator), r.inserted};
return tryEmplace_impl(std::move(key), std::forward<Args>(args)...);
}
template <typename... Args>
key_value_iterator try_emplace(const_iterator /*hint*/, const Key &key, Args &&...args)
{
auto r = tryEmplace_impl(key, std::forward<Args>(args)...);
return key_value_iterator(r.iterator);
return key_value_iterator(tryEmplace_impl(key, std::forward<Args>(args)...).iterator);
}
template <typename... Args>
key_value_iterator try_emplace(const_iterator /*hint*/, Key &&key, Args &&...args)
{
auto r = tryEmplace_impl(std::move(key), std::forward<Args>(args)...);
return key_value_iterator(r.iterator);
return key_value_iterator(tryEmplace_impl(std::move(key), std::forward<Args>(args)...).iterator);
}

private:
Expand Down Expand Up @@ -1557,14 +1571,12 @@ class QHash
template <typename K, typename... Args, if_heterogeneously_searchable<K> = true, if_key_constructible_from<K> = true>
std::pair<key_value_iterator, bool> try_emplace(K &&key, Args &&...args)
{
auto r = tryEmplace_impl(std::forward<K>(key), std::forward<Args>(args)...);
return { key_value_iterator(r.iterator), r.inserted };
return tryEmplace_impl(std::forward<K>(key), std::forward<Args>(args)...);
}
template <typename K, typename... Args, if_heterogeneously_searchable<K> = true, if_key_constructible_from<K> = true>
key_value_iterator try_emplace(const_iterator /*hint*/, K &&key, Args &&...args)
{
auto r = tryEmplace_impl(std::forward<K>(key), std::forward<Args>(args)...);
return key_value_iterator(r.iterator);
return key_value_iterator(tryEmplace_impl(std::forward<K>(key), std::forward<Args>(args)...).iterator);
}
};

Expand Down
28 changes: 28 additions & 0 deletions tests/auto/corelib/tools/qhash/tst_qhash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2862,6 +2862,34 @@ void tst_QHash::tryEmplace()
QCOMPARE(hash[0], 0);
QVERIFY(!inserted2);
QCOMPARE(it->second, 0);

using KVIterator = decltype(hash)::key_value_iterator;
using PairReturn = std::pair<KVIterator, bool>; // Return-value of try_emplace

// Handle conversion _from_ the try_emplace return type.
QHash<int, int>::TryEmplaceResult t = hash.try_emplace(2, 2);
QCOMPARE(t.inserted, true);
QCOMPARE(t.iterator.value(), 2);
QCOMPARE(hash.size(), 3);

t = hash.try_emplace(2, -1);
QCOMPARE(t.inserted, false);
QCOMPARE(t.iterator.value(), 2);
QCOMPARE(hash.size(), 3);

// Handle conversion _to_ the try_emplace return type.
PairReturn p = hash.tryEmplace(1, -1);
QCOMPARE_NE(p.first, hash.keyValueEnd());
QCOMPARE(hash.size(), 3);

QVERIFY(!p.second);
QCOMPARE(p.first->second, 1);

p = hash.try_emplace(cref, -1);
QCOMPARE_NE(p.first, hash.keyValueEnd());
QCOMPARE(hash.size(), 3);
QVERIFY(!p.second);
QCOMPARE(p.first->second, 0);
}
{
// Make sure any kind of resize is properly handled
Expand Down

0 comments on commit 154fe8d

Please sign in to comment.