summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2020-12-01 11:48:41 -0700
committerAndreas Kling <kling@serenityos.org>2020-12-02 13:02:04 +0100
commitc6230b746d635b99c489576f819985e0dcfe049d (patch)
tree405af243d269537c39bf171aa518959afcf14f5b /AK
parent9a2a673e5128b00cba80eb835fd6a803ebc27d97 (diff)
downloadserenity-c6230b746d635b99c489576f819985e0dcfe049d.zip
AK: Add insert_before/insert_after to InlineLinkedList
Diffstat (limited to 'AK')
-rw-r--r--AK/InlineLinkedList.h57
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()) {