AK: Add Span<T>::index_of(ReadonlySpan)

This will be used for case-sensitive substring index matches in a later
commit.
This commit is contained in:
Jelle Raaijmakers 2025-06-10 15:11:08 +02:00 committed by Jelle Raaijmakers
commit b558b4dba6
Notes: github-actions[bot] 2025-06-13 13:11:07 +00:00
2 changed files with 33 additions and 0 deletions

View file

@ -307,6 +307,24 @@ public:
return { data(), size() }; return { data(), size() };
} }
Optional<size_t> index_of(ReadonlySpan<T> other, size_t start_offset = 0) const
{
Checked maximum_offset { start_offset };
maximum_offset += other.size();
if (maximum_offset.has_overflow() || maximum_offset.value() > size())
return {};
if (other.is_empty())
return start_offset;
for (size_t index = start_offset; index <= size() - other.size(); ++index) {
if (TypedTransfer<T>::compare(data() + index, other.data(), other.size()))
return index;
}
return {};
}
template<typename TUnaryPredicate> template<typename TUnaryPredicate>
Optional<T&> last_matching(TUnaryPredicate const& predicate) Optional<T&> last_matching(TUnaryPredicate const& predicate)
{ {

View file

@ -180,3 +180,18 @@ TEST_CASE(compare_different_constness)
EXPECT_EQ(array, vector.span()); EXPECT_EQ(array, vector.span());
} }
TEST_CASE(index_of)
{
constexpr Array haystack { 1, 2, 3, 4, 5 };
constexpr Array needle_1 { 2, 3, 4 };
constexpr Array needle_2 { 2, 4 };
constexpr Array<int, 0> needle_3 {};
EXPECT_EQ(1u, haystack.span().index_of(needle_1.span()).value());
EXPECT(!haystack.span().index_of(needle_1.span(), 2).has_value());
EXPECT(!haystack.span().index_of(needle_2.span()).has_value());
EXPECT_EQ(0u, haystack.span().index_of(needle_3.span()));
EXPECT_EQ(1u, haystack.span().index_of(needle_3.span(), 1));
EXPECT(!haystack.span().index_of(needle_3.span(), 16).has_value());
}