From b819709c3a6b9ce11c0f02cec2f92b8eab9f81ea Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 26 Aug 2024 13:37:56 +0200 Subject: [PATCH] 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 Reviewed-by: Thiago Macieira Reviewed-by: Fabian Kosmale (cherry picked from commit cdc04b96dd8a69d0310e1474008b48128d050450) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/tools/qhash.h | 86 ++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 24 deletions(-) diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 198622a05cc..f9bb02017fd 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -1020,49 +1020,62 @@ public: } private: - template 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 T valueImpl(const K &key, Fn &&defaultValue) const noexcept + template + 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 auto &key) const noexcept { - return valueImpl(key, [] { return T(); }); + if (auto *v = valueImpl(key)) + return *v; + else + return T(); } T value(const QHashPrivate::HeterogeneouslySearchableWith 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 auto &key) { @@ -1670,50 +1689,63 @@ public: } private: - template 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 T valueImpl(const K &key, Fn &&defaultValue) const noexcept + template + 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 auto &key) const noexcept { - return valueImpl(key, [] { return T(); }); + if (auto *v = valueImpl(key)) + return *v; + else + return T(); } T value(const QHashPrivate::HeterogeneouslySearchableWith 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 auto &key) {