summaryrefslogtreecommitdiffstats
path: root/firmware/include
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2014-04-28 10:17:38 -0400
committerMichael Sevakis <jethead71@rockbox.org>2014-08-16 00:27:01 -0400
commiteb63d8b4a2a7cbe4e98216b48a75391718fcebd7 (patch)
tree225c00b2edcd1a071f262aa181603e0c8775b249 /firmware/include
parent278e8664a7393f2ca3050660c85d2142c38a4790 (diff)
downloadrockbox-eb63d8b4a2a7cbe4e98216b48a75391718fcebd7.tar.gz
rockbox-eb63d8b4a2a7cbe4e98216b48a75391718fcebd7.tar.bz2
rockbox-eb63d8b4a2a7cbe4e98216b48a75391718fcebd7.zip
Add common linked list functions
Forms implemented to a greater or lesser degree at the moment: ll_* = singly-linked list lld_* = doubly-linked list lldc_* = doubly-linked circular list Change-Id: Ieed5af50fc59165c8b14c3513b3b5d0e6f7de9fa
Diffstat (limited to 'firmware/include')
-rw-r--r--firmware/include/linked_list.h114
1 files changed, 114 insertions, 0 deletions
diff --git a/firmware/include/linked_list.h b/firmware/include/linked_list.h
new file mode 100644
index 0000000000..c678cfa7eb
--- /dev/null
+++ b/firmware/include/linked_list.h
@@ -0,0 +1,114 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2014 by Michael Sevakis
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef LINKED_LIST_H
+#define LINKED_LIST_H
+
+/***
+ ** NOTES:
+ ** Node field order chosen so that one type can alias the other for forward
+ ** list traveral by the same code.
+ **
+ ** Structures are separate, even if logically equivalent, to perform compile-
+ ** time type checking.
+ **
+ */
+
+
+/* (L)inked (L)ist
+ *
+ * Format:
+ *
+ * XX->YY->ZZ->0
+ * head--^ ^
+ * tail----------+
+ */
+struct ll_head
+{
+ struct ll_node *head; /* First list item */
+ struct ll_node *tail; /* Last list item (to make insert_last O(1)) */
+};
+
+struct ll_node
+{
+ struct ll_node *next; /* Next list item */
+};
+
+void ll_init(struct ll_head *list);
+void ll_insert_next(struct ll_head *list, struct ll_node *node,
+ struct ll_node *newnode);
+void ll_insert_last(struct ll_head *list, struct ll_node *node);
+void ll_remove_next(struct ll_head *list, struct ll_node *node);
+void ll_remove(struct ll_head *list, struct ll_node *node);
+void ll_insert_first(struct ll_head *list, struct ll_node *node);
+void ll_remove_first(struct ll_head *list);
+
+
+/* (L)inked (L)ist (D)double
+ *
+ * Format:
+ *
+ * 0<-XX<->YY<->ZZ->0
+ * head----^ ^
+ * tail--------------+
+ */
+struct lld_head
+{
+ struct lld_node *head; /* First list item */
+ struct lld_node *tail; /* Last list item (to make insert_last O(1)) */
+};
+
+struct lld_node
+{
+ struct lld_node *next; /* Next list item */
+ struct lld_node *prev; /* Previous list item */
+};
+
+void lld_init(struct lld_head *list);
+void lld_insert_first(struct lld_head *list, struct lld_node *node);
+void lld_insert_last(struct lld_head *list, struct lld_node *node);
+void lld_remove(struct lld_head *list, struct lld_node *node);
+
+
+/* (L)inked (L)ist (D)ouble (C)ircular
+ *
+ * Format:
+ * +----------------+
+ * | |
+ * +->XX<->YY<->ZZ<-+
+ * head------^
+ */
+struct lldc_head
+{
+ struct lldc_node *head; /* First list item */
+};
+
+struct lldc_node
+{
+ struct lldc_node *next; /* Next list item */
+ struct lldc_node *prev; /* Previous list item */
+};
+
+void lldc_init(struct lldc_head *list);
+void lldc_insert_first(struct lldc_head *list, struct lldc_node *node);
+void lldc_insert_last(struct lldc_head *list, struct lldc_node *node);
+void lldc_remove(struct lldc_head *list, struct lldc_node *node);
+
+#endif /* LINKED_LIST_H */