From c6230b746d635b99c489576f819985e0dcfe049d Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 1 Dec 2020 11:48:41 -0700 Subject: [PATCH] AK: Add insert_before/insert_after to InlineLinkedList --- AK/InlineLinkedList.h | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/AK/InlineLinkedList.h b/AK/InlineLinkedList.h index 6f1a9b4fff..dfa9cd97e8 100644 --- a/AK/InlineLinkedList.h +++ b/AK/InlineLinkedList.h @@ -120,6 +120,8 @@ public: void append(T*); void remove(T*); void append(InlineLinkedList&); + void insert_before(T*, T*); + void insert_after(T*, T*); bool contains_slow(T* value) const { @@ -130,6 +132,17 @@ public: return false; } + template + IterationDecision for_each(F func) const + { + for (T* node = m_head; node; node = node->next()) { + IterationDecision decision = func(*node); + if (decision != IterationDecision::Continue) + return decision; + } + return IterationDecision::Continue; + } + using Iterator = InlineLinkedListIterator; friend Iterator; Iterator begin() { return Iterator(m_head); } @@ -199,6 +212,50 @@ inline void InlineLinkedList::append(T* node) m_tail = node; } +template +inline void InlineLinkedList::insert_before(T* before_node, T* node) +{ + ASSERT(before_node); + ASSERT(node); + ASSERT(before_node != node); + ASSERT(!is_empty()); + if (m_head == before_node) { + ASSERT(!before_node->prev()); + m_head = node; + node->set_prev(0); + node->set_next(before_node); + before_node->set_prev(node); + } else { + ASSERT(before_node->prev()); + node->set_prev(before_node->prev()); + before_node->prev()->set_next(node); + node->set_next(before_node); + before_node->set_prev(node); + } +} + +template +inline void InlineLinkedList::insert_after(T* after_node, T* node) +{ + ASSERT(after_node); + ASSERT(node); + ASSERT(after_node != node); + ASSERT(!is_empty()); + if (m_tail == after_node) { + ASSERT(!after_node->next()); + m_tail = node; + node->set_prev(after_node); + node->set_next(0); + after_node->set_next(node); + } else { + ASSERT(after_node->next()); + node->set_prev(after_node); + node->set_next(after_node->next()); + after_node->next()->set_prev(node); + after_node->set_next(node); + } +} + template inline void InlineLinkedList::remove(T* node) {