Linked list
include/structures/list.h View source View on GitHubStructs
Section titled “Structs”list_node
Section titled “list_node” struct list_node (1 field) source
Circular doubly linked list.
We use two different types here since a unified list_head proved problematic for readability and semantics. It’s largely symbolic and for type safety.
struct list_node is the link struct list_head is the head/anchor of the list.
list_head_* operations take the list_head, list_node_* operations a list_node, list_root_* operations technically take a list_node, but this is meant to be the list_head’s root member, and is used as convenience.
Thus, swapping arguments like list_add(&parent->node, &child->node); is not possible and fails to compile.
list_head
Section titled “list_head”slist_node
Section titled “slist_node” struct slist_node (1 field) source
struct slist_node *next slist_head
Section titled “slist_head” struct slist_head (2 fields) source
struct slist_node *first struct slist_node *last Type Aliases
Section titled “Type Aliases”list_cmp_fn
Section titled “list_cmp_fn”Functions
Section titled “Functions”list_add_check
Section titled “list_add_check”list_del_check
Section titled “list_del_check”list_splice_check
Section titled “list_splice_check”list_add_check
Section titled “list_add_check”list_del_check
Section titled “list_del_check”list_splice_check
Section titled “list_splice_check”list_node_init
Section titled “list_node_init”list_head_init
Section titled “list_head_init”list_node_is_linked
Section titled “list_node_is_linked”list_node_next
Section titled “list_node_next”list_node_prev
Section titled “list_node_prev”list_head_sentinel
Section titled “list_head_sentinel”list_node_as_head
Section titled “list_node_as_head”Treat a node as if it’s the head. Should only be used in headless lists where one of the middle members is also the anchor
list_node_link_between
Section titled “list_node_link_between”list_node_unlink_between
Section titled “list_node_unlink_between”list_node_insert_after
Section titled “list_node_insert_after”list_node_insert_before
Section titled “list_node_insert_before”list_node_delete
Section titled “list_node_delete”list_node_delete_init
Section titled “list_node_delete_init”list_head_empty
Section titled “list_head_empty”list_head_push_front
Section titled “list_head_push_front”list_head_push_back
Section titled “list_head_push_back”list_root_pop_front
Section titled “list_root_pop_front”root_*, For direct sentinel manipulation
list_root_pop_back
Section titled “list_root_pop_back”list_head_peek_front
Section titled “list_head_peek_front”list_head_peek_back
Section titled “list_head_peek_back”list_head_pop_front
Section titled “list_head_pop_front”list_head_pop_back
Section titled “list_head_pop_back”list_head_pop_front_init
Section titled “list_head_pop_front_init”list_head_pop_back_init
Section titled “list_head_pop_back_init”list_splice_between
Section titled “list_splice_between”list_head_splice_front_init
Section titled “list_head_splice_front_init”Move everyone from src to the front of dst
list_head_splice_back_init
Section titled “list_head_splice_back_init”Move everyone from src to the back of dst
list_root_sort
Section titled “list_root_sort”void list_root_sort(struct list_node *root, list_cmp_fn cmp) source list_head_sort
Section titled “list_head_sort”void list_head_sort(struct list_head *h, list_cmp_fn cmp) source slist_head_init
Section titled “slist_head_init”void slist_head_init(struct slist_head *h) source slist_empty
Section titled “slist_empty”int slist_empty(const struct slist_head *h) source slist_push_head
Section titled “slist_push_head”void slist_push_head(struct slist_head *h, struct slist_node *n) source slist_push_tail
Section titled “slist_push_tail”void slist_push_tail(struct slist_head *h, struct slist_node *n) source slist_pop_head
Section titled “slist_pop_head”struct slist_node * slist_pop_head(struct slist_head *h) source slist_remove_node_after
Section titled “slist_remove_node_after”void slist_remove_node_after(
struct slist_head *h,
struct slist_node *prev,
struct slist_node *target
) source Macros
Section titled “Macros”LIST_NODE_INIT
Section titled “LIST_NODE_INIT”#define LIST_NODE_INIT(name) source Expansion
#define LIST_NODE_INIT(name) {&(name), &(name)} LIST_HEAD_INIT
Section titled “LIST_HEAD_INIT”#define LIST_HEAD_INIT(name) source Expansion
#define LIST_HEAD_INIT(name) \
{ \
.root = { &(name).root, &(name).root } \
} LIST_HEAD
Section titled “LIST_HEAD”#define LIST_HEAD(name) source Expansion
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) list_root
Section titled “list_root”list_entry
Section titled “list_entry”#define list_entry(ptr, type, member) source Expansion
#define list_entry(ptr, type, member) container_of(ptr, type, member) list_entry_safe
Section titled “list_entry_safe”#define list_entry_safe(ptr, type, member) source Expansion
#define list_entry_safe(ptr, type, member) \
({ \
__auto_type __list_ptr = (ptr); \
__list_ptr ? list_entry(__list_ptr, type, member) : NULL; \
}) list_for_each
Section titled “list_for_each”#define list_for_each(pos, head) source Expansion
#define list_for_each(pos, head) \
for (pos = list_root(head)->next; pos != list_root(head); pos = pos->next) list_for_each_rev
Section titled “list_for_each_rev”#define list_for_each_rev(pos, head) source Expansion
#define list_for_each_rev(pos, head) \
for (pos = list_root(head)->prev; pos != list_root(head); pos = pos->prev) list_for_each_safe
Section titled “list_for_each_safe”#define list_for_each_safe(pos, n, head) source Expansion
#define list_for_each_safe(pos, n, head) \
for (pos = list_root(head)->next, n = pos->next; pos != list_root(head); \
pos = n, n = pos->next) list_for_each_rev_safe
Section titled “list_for_each_rev_safe”#define list_for_each_rev_safe(pos, n, head) source Expansion
#define list_for_each_rev_safe(pos, n, head) \
for (pos = list_root(head)->prev, n = pos->prev; pos != list_root(head); \
pos = n, n = pos->prev) list_for_each_entry
Section titled “list_for_each_entry”#define list_for_each_entry(pos, head, member) source Expansion
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry(list_root(head)->next, typeof(*pos), member); \
&pos->member != list_root(head); \
pos = list_entry(pos->member.next, typeof(*pos), member)) list_for_each_entry_rev
Section titled “list_for_each_entry_rev”#define list_for_each_entry_rev(pos, head, member) source Expansion
#define list_for_each_entry_rev(pos, head, member) \
for (pos = list_entry(list_root(head)->prev, typeof(*pos), member); \
&pos->member != list_root(head); \
pos = list_entry(pos->member.prev, typeof(*pos), member)) list_first_entry
Section titled “list_first_entry”#define list_first_entry(ptr, type, member) source Expansion
#define list_first_entry(ptr, type, member) \
list_entry(list_root(ptr)->next, type, member) list_last_entry
Section titled “list_last_entry”#define list_last_entry(ptr, type, member) source Expansion
#define list_last_entry(ptr, type, member) \
list_entry(list_root(ptr)->prev, type, member) list_for_each_entry_safe
Section titled “list_for_each_entry_safe”#define list_for_each_entry_safe(pos, n, head, member) source Expansion
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry(list_root(head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != list_root(head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member)) list_for_each_entry_safe_rev
Section titled “list_for_each_entry_safe_rev”#define list_for_each_entry_safe_rev(pos, n, head, member) source Expansion
#define list_for_each_entry_safe_rev(pos, n, head, member) \
for (pos = list_entry(list_root(head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != list_root(head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member)) list_for_each_entry_safe_continue
Section titled “list_for_each_entry_safe_continue”#define list_for_each_entry_safe_continue(pos, n, head, member) source Expansion
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != list_root(head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member)) list_for_each_entry_safe_continue_rev
Section titled “list_for_each_entry_safe_continue_rev”#define list_for_each_entry_safe_continue_rev(pos, n, head, member) source Expansion
#define list_for_each_entry_safe_continue_rev(pos, n, head, member) \
for (pos = list_entry(pos->member.prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != list_root(head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))