diff options
author | Tom <tomut@yahoo.com> | 2020-12-01 11:48:41 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-02 13:02:04 +0100 |
commit | c6230b746d635b99c489576f819985e0dcfe049d (patch) | |
tree | 405af243d269537c39bf171aa518959afcf14f5b /AK | |
parent | 9a2a673e5128b00cba80eb835fd6a803ebc27d97 (diff) | |
download | serenity-c6230b746d635b99c489576f819985e0dcfe049d.zip |
AK: Add insert_before/insert_after to InlineLinkedList
Diffstat (limited to 'AK')
-rw-r--r-- | AK/InlineLinkedList.h | 57 |
1 files changed, 57 insertions, 0 deletions
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<T>&); + void insert_before(T*, T*); + void insert_after(T*, T*); bool contains_slow(T* value) const { @@ -130,6 +132,17 @@ public: return false; } + template<typename F> + 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<T>; friend Iterator; Iterator begin() { return Iterator(m_head); } @@ -200,6 +213,50 @@ inline void InlineLinkedList<T>::append(T* node) } template<typename T> +inline void InlineLinkedList<T>::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<typename T> +inline void InlineLinkedList<T>::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<typename T> inline void InlineLinkedList<T>::remove(T* node) { if (node->prev()) { |