QHash: re-SCARY-fy value() and key() methods

This reverts commit ba24125cbfdbe78b48e8000ee6030f0d81a86491.

The funImpl() functions were specifically designed to be sharable
between the fun(key) and fun(key, def) overloads. Making the return
statement a template argument turns one function into two, duplicating
the executable code. It doesn't even improve readability much, so
revert to returning pointers as a poor-man's optional<>.

This re-SCARY-fies the functions, also adapting the code of the
heterogeneous lookup additions that were introduced later.

An alternative would have been to use qxp::function_ref, but that
produces a lot of code itself, as the recent removal of it from QtTest
has shown, and it's not required, either. KISS applies: the old
return-by-pointer was the most simple implementation possible. There
is no need for a type-erasing function wrapper here.

Change-Id: I8570ce5acd6d6e98321e4003919651cd97cad83e
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
(cherry picked from commit cdc04b96dd8a69d0310e1474008b48128d050450)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2024-08-26 13:37:56 +02:00 committed by Qt Cherry-pick Bot
parent 9ebc45c754
commit b819709c3a

View File

@ -1020,49 +1020,62 @@ public:
}
private:
template <typename Fn> Key keyImpl(const T &value, Fn &&defaultFn) const noexcept
const Key *keyImpl(const T &value) const noexcept
{
if (d) {
const_iterator i = begin();
while (i != end()) {
if (i.value() == value)
return i.key();
return &i.key();
++i;
}
}
return defaultFn();
return nullptr;
}
public:
Key key(const T &value) const noexcept
{
return keyImpl(value, [] { return Key(); });
if (auto *k = keyImpl(value))
return *k;
else
return Key();
}
Key key(const T &value, const Key &defaultKey) const noexcept
{
return keyImpl(value, [&] { return defaultKey; });
if (auto *k = keyImpl(value))
return *k;
else
return defaultKey;
}
private:
template <typename K, typename Fn> T valueImpl(const K &key, Fn &&defaultValue) const noexcept
template <typename K>
T *valueImpl(const K &key) const noexcept
{
if (d) {
Node *n = d->findNode(key);
if (n)
return n->value;
return &n->value;
}
return defaultValue();
return nullptr;
}
public:
T value(const Key &key) const noexcept
{
return valueImpl(key, [] { return T(); });
if (T *v = valueImpl(key))
return *v;
else
return T();
}
T value(const Key &key, const T &defaultValue) const noexcept
{
return valueImpl(key, [&] { return defaultValue; });
if (T *v = valueImpl(key))
return *v;
else
return defaultValue;
}
T &operator[](const Key &key)
@ -1384,11 +1397,17 @@ public:
}
T value(const QHashPrivate::HeterogeneouslySearchableWith<Key> auto &key) const noexcept
{
return valueImpl(key, [] { return T(); });
if (auto *v = valueImpl(key))
return *v;
else
return T();
}
T value(const QHashPrivate::HeterogeneouslySearchableWith<Key> auto &key, const T &defaultValue) const noexcept
{
return valueImpl(key, [&] { return defaultValue; });
if (auto *v = valueImpl(key))
return *v;
else
return defaultValue;
}
T &operator[](const QHashPrivate::HeterogeneouslySearchableWith<Key> auto &key)
{
@ -1670,50 +1689,63 @@ public:
}
private:
template <typename Fn> Key keyImpl(const T &value, Fn &&defaultValue) const noexcept
const Key *keyImpl(const T &value) const noexcept
{
if (d) {
auto i = d->begin();
while (i != d->end()) {
Chain *e = i.node()->value;
if (e->contains(value))
return i.node()->key;
return &i.node()->key;
++i;
}
}
return defaultValue();
return nullptr;
}
public:
Key key(const T &value) const noexcept
{
return keyImpl(value, [] { return Key(); });
if (auto *k = keyImpl(value))
return *k;
else
return Key();
}
Key key(const T &value, const Key &defaultKey) const noexcept
{
return keyImpl(value, [&] { return defaultKey; });
if (auto *k = keyImpl(value))
return *k;
else
return defaultKey;
}
private:
template <typename K, typename Fn> T valueImpl(const K &key, Fn &&defaultValue) const noexcept
template <typename K>
T *valueImpl(const K &key) const noexcept
{
if (d) {
Node *n = d->findNode(key);
if (n) {
Q_ASSERT(n->value);
return n->value->value;
return &n->value->value;
}
}
return defaultValue();
return nullptr;
}
public:
T value(const Key &key) const noexcept
{
return valueImpl(key, [] { return T(); });
if (auto *v = valueImpl(key))
return *v;
else
return T();
}
T value(const Key &key, const T &defaultValue) const noexcept
{
return valueImpl(key, [&] { return defaultValue; });
if (auto *v = valueImpl(key))
return *v;
else
return defaultValue;
}
T &operator[](const Key &key)
@ -2358,11 +2390,17 @@ public:
}
T value(const QHashPrivate::HeterogeneouslySearchableWith<Key> auto &key) const noexcept
{
return valueImpl(key, [] { return T(); });
if (auto *v = valueImpl(key))
return *v;
else
return T();
}
T value(const QHashPrivate::HeterogeneouslySearchableWith<Key> auto &key, const T &defaultValue) const noexcept
{
return valueImpl(key, [&] { return defaultValue; });
if (auto *v = valueImpl(key))
return *v;
else
return defaultValue;
}
T &operator[](const QHashPrivate::HeterogeneouslySearchableWith<Key> auto &key)
{