summaryrefslogtreecommitdiffstats
path: root/src/list.h
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-01-07 12:11:04 -0500
committerTavian Barnes <tavianator@tavianator.com>2024-01-07 12:11:04 -0500
commit70acbc194fa1cc4972293d4e3affee5ba6fe5539 (patch)
tree3f020658300418353306aacb8b820685d482b276 /src/list.h
parentfc4b011dc2e5ce95ade6bd6e359cf1500b898204 (diff)
downloadbfs-70acbc194fa1cc4972293d4e3affee5ba6fe5539.tar.xz
list: New SLIST_HEAD() and SLIST_TAIL() macros
Diffstat (limited to 'src/list.h')
-rw-r--r--src/list.h43
1 files changed, 40 insertions, 3 deletions
diff --git a/src/list.h b/src/list.h
index 91f416f..02a7ba2 100644
--- a/src/list.h
+++ b/src/list.h
@@ -198,13 +198,50 @@
(void)sizeof(list->tail - &list->head)
/**
+ * Get the head of a singly-linked list.
+ *
+ * @param list
+ * The list in question.
+ * @return
+ * The first item in the list.
+ */
+#define SLIST_HEAD(list) \
+ SLIST_HEAD_((list))
+
+#define SLIST_HEAD_(list) \
+ (SLIST_CHECK_(list), list->head)
+
+/**
* Check if a singly-linked list is empty.
*/
#define SLIST_EMPTY(list) \
- SLIST_EMPTY_((list))
+ (!SLIST_HEAD(list))
+
+/**
+ * Like container_of(), but using the head pointer instead of offsetof() since
+ * we don't have the type around.
+ */
+#define SLIST_CONTAINER_(tail, head, next) \
+ (void *)((char *)tail - ((char *)&head->next - (char *)head))
+
+/**
+ * Get the tail of a singly-linked list.
+ *
+ * @param list
+ * The list in question.
+ * @param node (optional)
+ * If specified, use item->node.next rather than item->next.
+ * @return
+ * The last item in the list.
+ */
+#define SLIST_TAIL(...) \
+ SLIST_TAIL_(__VA_ARGS__, )
+
+#define SLIST_TAIL_(list, ...) \
+ SLIST_TAIL__((list), LIST_NEXT_(__VA_ARGS__))
-#define SLIST_EMPTY_(list) \
- (SLIST_CHECK_(list), !list->head)
+#define SLIST_TAIL__(list, next) \
+ (list->head ? SLIST_CONTAINER_(list->tail, list->head, next) : NULL)
/**
* Check if an item is attached to a singly-linked list.