summaryrefslogtreecommitdiff
path: root/cesar/lib/src/list.c
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/lib/src/list.c')
-rw-r--r--cesar/lib/src/list.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/cesar/lib/src/list.c b/cesar/lib/src/list.c
new file mode 100644
index 0000000000..61771b2c53
--- /dev/null
+++ b/cesar/lib/src/list.c
@@ -0,0 +1,181 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file lib/src/list.c
+ * \brief Double linked list.
+ * \ingroup lib
+ */
+#include "common/std.h"
+#include "lib/list.h"
+
+void
+list_init (list_t *list)
+{
+ dbg_assert (list);
+ list_init_node (&list->nil);
+}
+
+void
+list_init_node (list_node_t *node)
+{
+ dbg_assert (node);
+ node->next = node->prev = node;
+}
+
+list_node_t *
+list_begin (list_t *list)
+{
+ dbg_assert (list);
+ return list->nil.next;
+}
+
+list_node_t *
+list_end (list_t *list)
+{
+ dbg_assert (list);
+ return &list->nil;
+}
+
+list_node_t *
+list_rbegin (list_t *list)
+{
+ dbg_assert (list);
+ return list->nil.prev;
+}
+
+list_node_t *
+list_rend (list_t *list)
+{
+ dbg_assert (list);
+ return &list->nil;
+}
+
+list_node_t *
+list_next (list_node_t *node)
+{
+ dbg_assert (node);
+ return node->next;
+}
+
+list_node_t *
+list_prev (list_node_t *node)
+{
+ dbg_assert (node);
+ return node->prev;
+}
+
+bool
+list_empty (list_t *list)
+{
+ dbg_assert (list);
+ return list->nil.next == &list->nil;
+}
+
+void
+list_push (list_t *list, list_node_t *node)
+{
+ dbg_assert (list);
+ dbg_assert (node && node->next == node && node->prev == node);
+ node->prev = list->nil.prev;
+ node->next = &list->nil;
+ list->nil.prev->next = node;
+ list->nil.prev = node;
+}
+
+void
+list_unshift (list_t *list, list_node_t *node)
+{
+ dbg_assert (list);
+ dbg_assert (node && node->next == node && node->prev == node);
+ node->next = list->nil.next;
+ node->prev = &list->nil;
+ list->nil.next->prev = node;
+ list->nil.next = node;
+}
+
+list_node_t *
+list_pop (list_t *list)
+{
+ list_node_t *node;
+ dbg_assert (list && !list_empty (list));
+ node = list->nil.prev;
+ dbg_assert (node && node->prev && node->next == &list->nil);
+ list->nil.prev = node->prev;
+ node->prev->next = &list->nil;
+ node->next = node->prev = node;
+ return node;
+}
+
+list_node_t *
+list_shift (list_t *list)
+{
+ list_node_t *node;
+ dbg_assert (list && !list_empty (list));
+ node = list->nil.next;
+ dbg_assert (node && node->next && node->prev == &list->nil);
+ list->nil.next = node->next;
+ node->next->prev = &list->nil;
+ node->next = node->prev = node;
+ return node;
+}
+
+void
+list_remove (list_t *list, list_node_t *node)
+{
+ dbg_assert (list && !list_empty (list));
+ dbg_assert (node && node->next && node->next != node
+ && node->prev && node->prev != node);
+ node->prev->next = node->next;
+ node->next->prev = node->prev;
+ node->next = node->prev = node;
+}
+
+void
+list_insert (list_t *list, list_node_t *before, list_node_t *node)
+{
+ dbg_assert (list);
+ dbg_assert (before && before->prev);
+ dbg_assert (node && node->next == node && node->prev == node);
+ node->next = before;
+ node->prev = before->prev;
+ before->prev->next = node;
+ before->prev = node;
+}
+
+void
+list_push_range (list_t *to, list_t *from,
+ list_node_t *first, list_node_t *last)
+{
+ dbg_assert (to);
+ list_insert_range (to, from, &to->nil, first, last);
+}
+
+void
+list_unshift_range (list_t *to, list_t *from,
+ list_node_t *first, list_node_t *last)
+{
+ dbg_assert (to);
+ list_insert_range (to, from, to->nil.next, first, last);
+}
+
+void
+list_insert_range (list_t *to, list_t *from, list_node_t *before,
+ list_node_t *first, list_node_t *last)
+{
+ list_node_t *before_last;
+ dbg_assert (to && from && !list_empty (from));
+ dbg_assert (before && first && last);
+ first->prev->next = last;
+ before_last = last->prev;
+ last->prev = first->prev;
+ first->prev = before->prev;
+ before_last->next = before;
+ before->prev->next = first;
+ before->prev = before_last;
+}
+