mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-24 08:30:21 +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
|
||||
TestEndian.cpp
|
||||
TestEnumBits.cpp
|
||||
TestEnumerate.cpp
|
||||
TestFind.cpp
|
||||
TestFixedArray.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