summaryrefslogtreecommitdiffstats
path: root/src/list.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/list.h')
-rw-r--r--src/list.h150
1 files changed, 91 insertions, 59 deletions
diff --git a/src/list.h b/src/list.h
index 61d0e5b..276c610 100644
--- a/src/list.h
+++ b/src/list.h
@@ -83,13 +83,14 @@
#define BFS_LIST_H
#include "diag.h"
+
#include <stddef.h>
#include <string.h>
/**
* Initialize a singly-linked list.
*
- * @param list
+ * @list
* The list to initialize.
*
* ---
@@ -116,9 +117,9 @@
/**
* Initialize a singly-linked list item.
*
- * @param item
+ * @item
* The item to initialize.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.next rather than item->next.
*
* ---
@@ -200,7 +201,7 @@
/**
* Get the head of a singly-linked list.
*
- * @param list
+ * @list
* The list in question.
* @return
* The first item in the list.
@@ -227,9 +228,9 @@
/**
* Get the tail of a singly-linked list.
*
- * @param list
+ * @list
* The list in question.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.next rather than item->next.
* @return
* The last item in the list.
@@ -246,11 +247,11 @@
/**
* Check if an item is attached to a singly-linked list.
*
- * @param list
+ * @list
* The list to check.
- * @param item
+ * @item
* The item to check.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.next rather than item->next.
* @return
* Whether the item is attached to the list.
@@ -267,13 +268,13 @@
/**
* Insert an item into a singly-linked list.
*
- * @param list
+ * @list
* The list to modify.
- * @param cursor
+ * @cursor
* A pointer to the item to insert after, e.g. &list->head or list->tail.
- * @param item
+ * @item
* The item to insert.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.next rather than item->next.
* @return
* A cursor for the next item.
@@ -294,11 +295,11 @@
/**
* Add an item to the tail of a singly-linked list.
*
- * @param list
+ * @list
* The list to modify.
- * @param item
+ * @item
* The item to append.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.next rather than item->next.
*/
#define SLIST_APPEND(list, ...) \
@@ -310,11 +311,11 @@
/**
* Add an item to the head of a singly-linked list.
*
- * @param list
+ * @list
* The list to modify.
- * @param item
+ * @item
* The item to prepend.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.next rather than item->next.
*/
#define SLIST_PREPEND(list, ...) \
@@ -324,27 +325,43 @@
LIST_VOID_(SLIST_INSERT_(list, &(list)->head, item, __VA_ARGS__))
/**
+ * Splice a singly-linked list into another.
+ *
+ * @dest
+ * The destination list.
+ * @cursor
+ * A pointer to the item to splice after, e.g. &list->head or list->tail.
+ * @src
+ * The source list.
+ */
+#define SLIST_SPLICE(dest, cursor, src) \
+ LIST_VOID_(SLIST_SPLICE_((dest), (cursor), (src)))
+
+#define SLIST_SPLICE_(dest, cursor, src) \
+ *src->tail = *cursor, \
+ *cursor = src->head, \
+ dest->tail = *dest->tail ? src->tail : dest->tail, \
+ SLIST_INIT(src)
+
+/**
* Add an entire singly-linked list to the tail of another.
*
- * @param dest
+ * @dest
* The destination list.
- * @param src
+ * @src
* The source list.
*/
#define SLIST_EXTEND(dest, src) \
- SLIST_EXTEND_((dest), (src))
-
-#define SLIST_EXTEND_(dest, src) \
- (src->head ? (*dest->tail = src->head, dest->tail = src->tail, SLIST_INIT(src)) : (void)0)
+ SLIST_SPLICE(dest, (dest)->tail, src)
/**
* Remove an item from a singly-linked list.
*
- * @param list
+ * @list
* The list to modify.
- * @param cursor
+ * @cursor
* A pointer to the item to remove, either &list->head or &prev->next.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.next rather than item->next.
* @return
* The removed item.
@@ -357,10 +374,10 @@
#define SLIST_REMOVE__(list, cursor, next) \
(list->tail = (*cursor)->next ? list->tail : cursor, \
- slist_remove_impl(*cursor, cursor, &(*cursor)->next, sizeof(*cursor)))
+ slist_remove_(*cursor, cursor, &(*cursor)->next, sizeof(*cursor)))
// Helper for SLIST_REMOVE()
-static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_t size) {
+static inline void *slist_remove_(void *ret, void *cursor, void *next, size_t size) {
// ret = *cursor;
// *cursor = ret->next;
memcpy(cursor, next, size);
@@ -372,9 +389,9 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Pop the head off a singly-linked list.
*
- * @param list
+ * @list
* The list to modify.
- * @param node (optional)
+ * @node (optional)
* If specified, use head->node.next rather than head->next.
* @return
* The popped item, or NULL if the list was empty.
@@ -391,13 +408,13 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Loop over the items in a singly-linked list.
*
- * @param type
+ * @type
* The list item type.
- * @param item
+ * @item
* The induction variable name.
- * @param list
+ * @list
* The list to iterate.
- * @param node (optional)
+ * @node (optional)
* If specified, use head->node.next rather than head->next.
*/
#define for_slist(type, item, ...) \
@@ -412,9 +429,24 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
item = _next)
/**
+ * Loop over a singly-linked list, popping each item.
+ *
+ * @type
+ * The list item type.
+ * @item
+ * The induction variable name.
+ * @list
+ * The list to drain.
+ * @node (optional)
+ * If specified, use head->node.next rather than head->next.
+ */
+#define drain_slist(type, item, ...) \
+ for (type *item; (item = SLIST_POP(__VA_ARGS__));)
+
+/**
* Initialize a doubly-linked list.
*
- * @param list
+ * @list
* The list to initialize.
*/
#define LIST_INIT(list) \
@@ -433,9 +465,9 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Initialize a doubly-linked list item.
*
- * @param item
+ * @item
* The item to initialize.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.next rather than item->next.
*/
#define LIST_ITEM_INIT(...) \
@@ -465,11 +497,11 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Add an item to the tail of a doubly-linked list.
*
- * @param list
+ * @list
* The list to modify.
- * @param item
+ * @item
* The item to append.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.{prev,next} rather than item->{prev,next}.
*/
#define LIST_APPEND(list, ...) \
@@ -478,11 +510,11 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Add an item to the head of a doubly-linked list.
*
- * @param list
+ * @list
* The list to modify.
- * @param item
+ * @item
* The item to prepend.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.{prev,next} rather than item->{prev,next}.
*/
#define LIST_PREPEND(list, ...) \
@@ -491,11 +523,11 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Check if an item is attached to a doubly-linked list.
*
- * @param list
+ * @list
* The list to check.
- * @param item
+ * @item
* The item to check.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.{prev,next} rather than item->{prev,next}.
* @return
* Whether the item is attached to the list.
@@ -512,13 +544,13 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Insert into a doubly-linked list after the given cursor.
*
- * @param list
+ * @list
* The list to modify.
- * @param cursor
+ * @cursor
* Insert after this element.
- * @param item
+ * @item
* The item to insert.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.{prev,next} rather than item->{prev,next}.
*/
#define LIST_INSERT(list, cursor, ...) \
@@ -537,11 +569,11 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Remove an item from a doubly-linked list.
*
- * @param list
+ * @list
* The list to modify.
- * @param item
+ * @item
* The item to remove.
- * @param node (optional)
+ * @node (optional)
* If specified, use item->node.{prev,next} rather than item->{prev,next}.
*/
#define LIST_REMOVE(list, ...) \
@@ -558,13 +590,13 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_
/**
* Loop over the items in a doubly-linked list.
*
- * @param type
+ * @type
* The list item type.
- * @param item
+ * @item
* The induction variable name.
- * @param list
+ * @list
* The list to iterate.
- * @param node (optional)
+ * @node (optional)
* If specified, use head->node.next rather than head->next.
*/
#define for_list(type, item, ...) \