mirror of
https://github.com/RGBCube/serenity
synced 2025-07-12 21:07:36 +00:00
AK: Add reverse iterator support to AK::IntrusiveList
In order for IntrusiveList to be capable of replacing InlineLinkedList, it needs to support reverse iteration. InlineLinkedList currently supports manual reverse iteration by calling list->last() followed by node->prev().
This commit is contained in:
parent
e37f39d980
commit
ef4fdcf76f
1 changed files with 52 additions and 0 deletions
|
@ -89,6 +89,34 @@ public:
|
||||||
Iterator begin();
|
Iterator begin();
|
||||||
Iterator end() { return Iterator {}; }
|
Iterator end() { return Iterator {}; }
|
||||||
|
|
||||||
|
class ReverseIterator {
|
||||||
|
public:
|
||||||
|
ReverseIterator() = default;
|
||||||
|
ReverseIterator(T* value)
|
||||||
|
: m_value(move(value))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator*() const { return *m_value; }
|
||||||
|
auto operator->() const { return m_value; }
|
||||||
|
T& operator*() { return *m_value; }
|
||||||
|
auto operator->() { return m_value; }
|
||||||
|
bool operator==(const ReverseIterator& other) const { return other.m_value == m_value; }
|
||||||
|
bool operator!=(const ReverseIterator& other) const { return !(*this == other); }
|
||||||
|
ReverseIterator& operator++()
|
||||||
|
{
|
||||||
|
m_value = IntrusiveList<T, Container, member>::prev(m_value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
ReverseIterator& erase();
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* m_value { nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
ReverseIterator rbegin();
|
||||||
|
ReverseIterator rend() { return ReverseIterator {}; }
|
||||||
|
|
||||||
class ConstIterator {
|
class ConstIterator {
|
||||||
public:
|
public:
|
||||||
ConstIterator() = default;
|
ConstIterator() = default;
|
||||||
|
@ -116,7 +144,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static T* next(T* current);
|
static T* next(T* current);
|
||||||
|
static T* prev(T* current);
|
||||||
static const T* next(const T* current);
|
static const T* next(const T* current);
|
||||||
|
static const T* prev(const T* current);
|
||||||
static T* node_to_value(IntrusiveListNode<T, Container>& node);
|
static T* node_to_value(IntrusiveListNode<T, Container>& node);
|
||||||
IntrusiveListStorage<T, Container> m_storage;
|
IntrusiveListStorage<T, Container> m_storage;
|
||||||
};
|
};
|
||||||
|
@ -278,6 +308,14 @@ inline const T* IntrusiveList<T, Container, member>::next(const T* current)
|
||||||
return nextstruct;
|
return nextstruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||||
|
inline const T* IntrusiveList<T, Container, member>::prev(const T* current)
|
||||||
|
{
|
||||||
|
auto& prevnode = (current->*member).m_prev;
|
||||||
|
const T* prevstruct = prevnode ? node_to_value(*prevnode) : nullptr;
|
||||||
|
return prevstruct;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||||
inline T* IntrusiveList<T, Container, member>::next(T* current)
|
inline T* IntrusiveList<T, Container, member>::next(T* current)
|
||||||
{
|
{
|
||||||
|
@ -286,12 +324,26 @@ inline T* IntrusiveList<T, Container, member>::next(T* current)
|
||||||
return nextstruct;
|
return nextstruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||||
|
inline T* IntrusiveList<T, Container, member>::prev(T* current)
|
||||||
|
{
|
||||||
|
auto& prevnode = (current->*member).m_prev;
|
||||||
|
T* prevstruct = prevnode ? node_to_value(*prevnode) : nullptr;
|
||||||
|
return prevstruct;
|
||||||
|
}
|
||||||
|
|
||||||
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||||
inline typename IntrusiveList<T, Container, member>::Iterator IntrusiveList<T, Container, member>::begin()
|
inline typename IntrusiveList<T, Container, member>::Iterator IntrusiveList<T, Container, member>::begin()
|
||||||
{
|
{
|
||||||
return m_storage.m_first ? Iterator(node_to_value(*m_storage.m_first)) : Iterator();
|
return m_storage.m_first ? Iterator(node_to_value(*m_storage.m_first)) : Iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||||
|
inline typename IntrusiveList<T, Container, member>::ReverseIterator IntrusiveList<T, Container, member>::rbegin()
|
||||||
|
{
|
||||||
|
return m_storage.m_last ? ReverseIterator(node_to_value(*m_storage.m_last)) : ReverseIterator();
|
||||||
|
}
|
||||||
|
|
||||||
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
template<class T, typename Container, IntrusiveListNode<T, Container> T::*member>
|
||||||
inline typename IntrusiveList<T, Container, member>::ConstIterator IntrusiveList<T, Container, member>::begin() const
|
inline typename IntrusiveList<T, Container, member>::ConstIterator IntrusiveList<T, Container, member>::begin() const
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue