mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
AK: Introduce AK::enumerate
Co-Authored-By: Tim Flynn <trflynn89@pm.me>
This commit is contained in:
parent
2d11fc6d44
commit
45a0ba2167
Notes:
sideshowbarker
2024-07-17 00:25:35 +09:00
Author: https://github.com/DanShaders Commit: https://github.com/SerenityOS/serenity/commit/45a0ba2167 Pull-request: https://github.com/SerenityOS/serenity/pull/23545
3 changed files with 117 additions and 0 deletions
65
AK/Enumerate.h
Normal file
65
AK/Enumerate.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Tim Flynn <trflynn89@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/StdLibExtras.h>
|
||||||
|
|
||||||
|
namespace AK {
|
||||||
|
|
||||||
|
namespace Detail {
|
||||||
|
template<typename Iterable>
|
||||||
|
class Enumerator {
|
||||||
|
using IteratorType = decltype(declval<Iterable>().begin());
|
||||||
|
using ValueType = decltype(*declval<IteratorType>());
|
||||||
|
|
||||||
|
struct Enumeration {
|
||||||
|
size_t index { 0 };
|
||||||
|
ValueType value;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Enumerator(Iterable&& iterable)
|
||||||
|
: m_iterable(forward<Iterable>(iterable))
|
||||||
|
, m_iterator(m_iterable.begin())
|
||||||
|
, m_end(m_iterable.end())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Enumerator const& begin() const { return *this; }
|
||||||
|
Enumerator const& end() const { return *this; }
|
||||||
|
|
||||||
|
Enumeration operator*() { return { m_index, *m_iterator }; }
|
||||||
|
Enumeration operator*() const { return { m_index, *m_iterator }; }
|
||||||
|
|
||||||
|
bool operator!=(Enumerator const&) const { return m_iterator != m_end; }
|
||||||
|
|
||||||
|
void operator++()
|
||||||
|
{
|
||||||
|
++m_index;
|
||||||
|
++m_iterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Iterable m_iterable;
|
||||||
|
|
||||||
|
size_t m_index { 0 };
|
||||||
|
IteratorType m_iterator;
|
||||||
|
IteratorType const m_end;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
auto enumerate(T&& range)
|
||||||
|
{
|
||||||
|
return Detail::Enumerator<T> { forward<T>(range) };
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USING_AK_GLOBALLY
|
||||||
|
using AK::enumerate;
|
||||||
|
#endif
|
|
@ -25,6 +25,7 @@ set(AK_TEST_SOURCES
|
||||||
TestDoublyLinkedList.cpp
|
TestDoublyLinkedList.cpp
|
||||||
TestEndian.cpp
|
TestEndian.cpp
|
||||||
TestEnumBits.cpp
|
TestEnumBits.cpp
|
||||||
|
TestEnumerate.cpp
|
||||||
TestFind.cpp
|
TestFind.cpp
|
||||||
TestFixedArray.cpp
|
TestFixedArray.cpp
|
||||||
TestFixedPoint.cpp
|
TestFixedPoint.cpp
|
||||||
|
|
51
Tests/AK/TestEnumerate.cpp
Normal file
51
Tests/AK/TestEnumerate.cpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <LibTest/TestCase.h>
|
||||||
|
|
||||||
|
#include <AK/Enumerate.h>
|
||||||
|
#include <AK/Span.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
|
struct IndexAndValue {
|
||||||
|
size_t index;
|
||||||
|
int value;
|
||||||
|
|
||||||
|
bool operator==(IndexAndValue const&) const = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE(enumerate)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Vector<IndexAndValue> result;
|
||||||
|
for (auto [i, value] : enumerate(Vector { 1, 2, 3, 4 })) {
|
||||||
|
result.append({ i, value });
|
||||||
|
}
|
||||||
|
EXPECT_EQ(result, (Vector<IndexAndValue> { { 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 } }));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Vector<IndexAndValue> result;
|
||||||
|
Vector<int> values = { 9, 8, 7, 6 };
|
||||||
|
for (auto [i, value] : enumerate(values)) {
|
||||||
|
static_assert(SameAs<decltype(value), int&>);
|
||||||
|
result.append({ i, value });
|
||||||
|
value = static_cast<int>(i);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(result, (Vector<IndexAndValue> { { 0, 9 }, { 1, 8 }, { 2, 7 }, { 3, 6 } }));
|
||||||
|
EXPECT_EQ(values, (Vector<int> { 0, 1, 2, 3 }));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Vector<IndexAndValue> result;
|
||||||
|
Vector<int> const& values = { 9, 8, 7, 6 };
|
||||||
|
for (auto [i, value] : enumerate(values)) {
|
||||||
|
static_assert(SameAs<decltype(value), int const&>);
|
||||||
|
result.append({ i, value });
|
||||||
|
}
|
||||||
|
EXPECT_EQ(result, (Vector<IndexAndValue> { { 0, 9 }, { 1, 8 }, { 2, 7 }, { 3, 6 } }));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue