diff --git a/AK/IntrusiveList.h b/AK/IntrusiveList.h index fe37e4a669..deadad169d 100644 --- a/AK/IntrusiveList.h +++ b/AK/IntrusiveList.h @@ -89,6 +89,34 @@ public: Iterator begin(); 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::prev(m_value); + return *this; + } + ReverseIterator& erase(); + + private: + T* m_value { nullptr }; + }; + + ReverseIterator rbegin(); + ReverseIterator rend() { return ReverseIterator {}; } + class ConstIterator { public: ConstIterator() = default; @@ -116,7 +144,9 @@ public: private: static T* next(T* current); + static T* prev(T* current); static const T* next(const T* current); + static const T* prev(const T* current); static T* node_to_value(IntrusiveListNode& node); IntrusiveListStorage m_storage; }; @@ -278,6 +308,14 @@ inline const T* IntrusiveList::next(const T* current) return nextstruct; } +template T::*member> +inline const T* IntrusiveList::prev(const T* current) +{ + auto& prevnode = (current->*member).m_prev; + const T* prevstruct = prevnode ? node_to_value(*prevnode) : nullptr; + return prevstruct; +} + template T::*member> inline T* IntrusiveList::next(T* current) { @@ -286,12 +324,26 @@ inline T* IntrusiveList::next(T* current) return nextstruct; } +template T::*member> +inline T* IntrusiveList::prev(T* current) +{ + auto& prevnode = (current->*member).m_prev; + T* prevstruct = prevnode ? node_to_value(*prevnode) : nullptr; + return prevstruct; +} + template T::*member> inline typename IntrusiveList::Iterator IntrusiveList::begin() { return m_storage.m_first ? Iterator(node_to_value(*m_storage.m_first)) : Iterator(); } +template T::*member> +inline typename IntrusiveList::ReverseIterator IntrusiveList::rbegin() +{ + return m_storage.m_last ? ReverseIterator(node_to_value(*m_storage.m_last)) : ReverseIterator(); +} + template T::*member> inline typename IntrusiveList::ConstIterator IntrusiveList::begin() const {