QHash tryEmplace-try_emplace compat

Let users use either type

Change-Id: Ica22a329df679352ab828aa96102a30fc9eedf79
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Mårten Nordheim 2024-11-28 13:08:25 +01:00
parent 056e78f456
commit 154fe8d803
2 changed files with 52 additions and 12 deletions

View File

@ -1255,6 +1255,24 @@ public:
{
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)
@ -1387,26 +1405,22 @@ public:
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:
@ -1557,14 +1571,12 @@ public:
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);
}
};

View File

@ -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