mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:37:45 +00:00
Vector: Implement find
, find_if
, find_first_matching
in terms of AK::find*
Problem: - The implementation of `find` is coupled to the implementation of `Vector`. - `Vector::find` takes the predicate by value which might be expensive. Solution: - Decouple the implementation of `find` from `Vector` by using a generic `find` algorithm. - Change the name of `find` with a predicate to `find_if` so that a binding reference can be used and the predicate can be forwarded to avoid copies. - Change all the `find(pred)` call sites to use `find_if`.
This commit is contained in:
parent
4333a9a8d6
commit
f99d1d3bd7
10 changed files with 48 additions and 29 deletions
31
AK/Vector.h
31
AK/Vector.h
|
@ -27,6 +27,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Find.h>
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/Iterator.h>
|
||||
#include <AK/Optional.h>
|
||||
|
@ -538,41 +539,33 @@ public:
|
|||
ConstIterator end() const { return ConstIterator::end(*this); }
|
||||
Iterator end() { return Iterator::end(*this); }
|
||||
|
||||
template<typename Finder>
|
||||
ConstIterator find(Finder finder) const
|
||||
template<typename TUnaryPredicate>
|
||||
ConstIterator find_if(TUnaryPredicate&& finder) const
|
||||
{
|
||||
for (size_t i = 0; i < m_size; ++i) {
|
||||
if (finder(at(i)))
|
||||
return ConstIterator(*this, i);
|
||||
}
|
||||
return end();
|
||||
return AK::find_if(begin(), end(), forward<TUnaryPredicate>(finder));
|
||||
}
|
||||
|
||||
template<typename Finder>
|
||||
Iterator find(Finder finder)
|
||||
template<typename TUnaryPredicate>
|
||||
Iterator find_if(TUnaryPredicate&& finder)
|
||||
{
|
||||
for (size_t i = 0; i < m_size; ++i) {
|
||||
if (finder(at(i)))
|
||||
return Iterator { *this, i };
|
||||
}
|
||||
return end();
|
||||
return AK::find_if(begin(), end(), forward<TUnaryPredicate>(finder));
|
||||
}
|
||||
|
||||
ConstIterator find(const T& value) const
|
||||
{
|
||||
return find([&](auto& other) { return Traits<T>::equals(value, other); });
|
||||
return AK::find(begin(), end(), value);
|
||||
}
|
||||
|
||||
Iterator find(const T& value)
|
||||
{
|
||||
return find([&](auto& other) { return Traits<T>::equals(value, other); });
|
||||
return AK::find(begin(), end(), value);
|
||||
}
|
||||
|
||||
Optional<size_t> find_first_index(const T& value)
|
||||
{
|
||||
for (size_t i = 0; i < m_size; ++i) {
|
||||
if (Traits<T>::equals(value, at(i)))
|
||||
return i;
|
||||
if (const auto index = AK::find_index(begin(), end(), value);
|
||||
index < size()) {
|
||||
return index;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue