AK: Add an AK::find helper to return a reference to the found value

This is often more convenient than dealing with iterators.

This commit includes a couple conversions to find_value as examples.
This commit is contained in:
Timothy Flynn 2025-04-05 09:06:51 -04:00
parent dea76cf0bb
commit ba98f24eb7
5 changed files with 34 additions and 30 deletions

View file

@ -7,6 +7,7 @@
#pragma once
#include <AK/Concepts.h>
#include <AK/Optional.h>
#include <AK/Traits.h>
#include <AK/Types.h>
@ -36,10 +37,21 @@ requires(requires(TIterator it) { it.index(); })
return find_if(first, last, [&]<typename T>(T const& entry) { return Traits<T>::equals(entry, value); }).index();
}
template<IterableContainer Container, typename TUnaryPredicate>
[[nodiscard]] constexpr auto find_value(Container const& container, TUnaryPredicate&& pred)
-> Optional<decltype(*container.begin())>
{
auto it = find_if(container.begin(), container.end(), forward<TUnaryPredicate>(pred));
if (it != container.end())
return *it;
return {};
}
}
#if USING_AK_GLOBALLY
using AK::find;
using AK::find_if;
using AK::find_index;
using AK::find_value;
#endif

View file

@ -901,13 +901,11 @@ static KeyCodeData key_code_data(u32 code_point)
{ 0xE027, {}, UIEvents::KeyCode::Key_Minus, UIEvents::KeyModifier::Mod_Keypad },
});
auto it = find_if(key_code_data.begin(), key_code_data.end(), [&](auto const& data) {
auto data = find_value(key_code_data, [&](auto const& data) {
return data.key == code_point || data.alternate_key == code_point;
});
if (it == key_code_data.end())
return { .key = code_point };
return *it;
return data.value_or({ .key = code_point });
}
// https://w3c.github.io/webdriver/#dfn-shifted-character

View file

@ -29,14 +29,9 @@ ReadonlySpan<AutocompleteEngine> autocomplete_engines()
Optional<AutocompleteEngine const&> find_autocomplete_engine_by_name(StringView name)
{
auto it = AK::find_if(builtin_autocomplete_engines.begin(), builtin_autocomplete_engines.end(),
[&](auto const& engine) {
return engine.name == name;
});
if (it == builtin_autocomplete_engines.end())
return {};
return *it;
return find_value(builtin_autocomplete_engines, [&](auto const& engine) {
return engine.name == name;
});
}
Autocomplete::Autocomplete() = default;

View file

@ -30,28 +30,16 @@ ReadonlySpan<SearchEngine> search_engines()
Optional<SearchEngine const&> find_search_engine_by_name(StringView name)
{
auto it = AK::find_if(builtin_search_engines.begin(), builtin_search_engines.end(),
[&](auto const& engine) {
return engine.name == name;
});
if (it == builtin_search_engines.end())
return {};
return *it;
return find_value(builtin_search_engines, [&](auto const& engine) {
return engine.name == name;
});
}
Optional<SearchEngine const&> find_search_engine_by_query_url(StringView query_url)
{
auto it = AK::find_if(builtin_search_engines.begin(), builtin_search_engines.end(),
[&](auto const& engine) {
return engine.query_url == query_url;
});
if (it == builtin_search_engines.end())
return {};
return *it;
return find_value(builtin_search_engines, [&](auto const& engine) {
return engine.query_url == query_url;
});
}
String format_search_query_for_display(StringView query_url, StringView query)

View file

@ -51,3 +51,14 @@ TEST_CASE(should_return_index_to_first_predicate_matching_value_in_container)
EXPECT(4 == AK::find_index(a.begin(), a.end(), 0));
}
TEST_CASE(find_value)
{
static constexpr Array array { 1, 2, 3, 4, 0, 6, 7, 8, 0, 0 };
auto value = find_value(array, [](auto value) { return value > 5; });
EXPECT_EQ(value, 6);
value = find_value(array, [](auto value) { return value == 12389; });
EXPECT(!value.has_value());
}