OurOS 0.1
Operating System built by McGill Students
 
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1#include <stddef.h>
2#include <stdalign.h>
3#include <stdbool.h>
4
5/**
6 * @brief Doubly-linked List Node
7 *
8 * @warning It's actually a circular doubly-linked list. Thus, it is recommended to use
9 * methods like @ref list_next or @ref list_prev to access next and previous nodes.
10 *
11 * @note Make sure the node is initialized with @ref list_init_node, and is not already
12 * in a list when putting it in another list.
13 *
14 */
15struct list_node {
16 struct list_node *next;
17 struct list_node *prev;
18};
19
20/**
21 * @brief Anchor for @ref list_node.
22 */
23struct list_head {
25};
26
27/**
28 * @brief Initializes @p head as an empty list.
29 */
30struct list_head *list_init_head(struct list_head *head);
31
32/**
33 * @brief Initializes `node`.
34 */
35struct list_node *list_init_node(struct list_node *node);
36
37/**
38 * @return `true` if `head`'s list is empty, otherwise `false`.
39 */
40bool list_is_empty(const struct list_head *head);
41
42/**
43 * @brief Inserts @p node at the end of `head`'s list (aka stack push).
44 * @return @p node
45 */
46struct list_node *list_append(struct list_head *head, struct list_node *node);
47/**
48 * @brief Inserts @p node before @p before in the list of `before`.
49 * @return @p node
50 */
51struct list_node *list_insert_before(struct list_node *before, struct list_node *node);
52/**
53 * @brief Inserts @p node after @p after in the list of `after`.
54 * @return @p node
55 */
56struct list_node *list_insert_after(struct list_node *after, struct list_node *node);
57
58/**
59 * @brief Merges @p head2 unto @p head1 at the end of @p head1 and returns `head1`.
60 * @warning This will modify `head2`, so @p head2 should be discarded or
61 * reinitialized afterwards.
62 * @return @p head1
63 */
64struct list_head *list_extend(struct list_head *head1, struct list_head *head2);
65
66/**
67 * @return The first node of `head`'s list, otherwise `NULL`.
68 */
69struct list_node *list_first(struct list_head *head);
70/**
71 * @return The last node of `head`'s list, otherwise `NULL`.
72 */
73struct list_node *list_last(struct list_head *head);
74
75/**
76 * @brief Removes @p node from `head`'s list.
77 * @note @p node is not modified.
78 * @warning @p node must already be in a list, otherwise there might be unintended
79 * consequences.
80 * @return @p node
81 */
82struct list_node *list_remove(struct list_node *node);
83/**
84 * @brief Removes the last node of `head`'s list (aka stack pop with respect
85 * to @ref list_append).
86 * @note The node returned is not modified.
87 * @return The removed node if the list of @p head is not empty, otherwise `NULL`.
88 */
89struct list_node *list_pop_last(struct list_head *head);
90/**
91 * @brief Removes the first node of `head`'s list (aka deque with respect
92 * to @ref list_append).
93 * @note The node returned is not modified.
94 * @return The removed node if the list of @p head is not empty, otherwise `NULL`.
95 */
96struct list_node *list_pop_first(struct list_head *head);
97
98/**
99 * @return The node right after @p node in the `head`'s list, otherwise `NULL`.
100 */
101struct list_node *list_next(struct list_head *head, struct list_node *node);
102/**
103 * @return The node right before @p node in the `head`'s list, otherwise `NULL`.
104 */
105struct list_node *list_prev(struct list_head *head, struct list_node *node);
106
107/**
108 * @return The length of `head`'s list.
109 */
110size_t list_length(struct list_head *head);
111
112/**
113 * @brief A preprocessor for iterating over `head`'s list. @p iter is the current node
114 * in the iteration. Methods like @ref list_remove is safe to use on `iter`.
115 */
116#define LIST_FOREACH(head, iter) \
117 for (\
118 struct list_node *iter = list_first(head), *iter##_next = list_first(head) ? list_next(head, list_first(head)) : NULL; \
119 iter; \
120 iter = iter##_next, iter##_next = iter##_next ? list_next(head, iter##_next) : NULL\
121 )
struct list_node * list_pop_first(struct list_head *head)
Removes the first node of head's list (aka deque with respect to list_append).
Definition list.c:67
struct list_head * list_extend(struct list_head *head1, struct list_head *head2)
Merges head2 unto head1 at the end of head1 and returns head1.
Definition list.c:39
struct list_node * list_append(struct list_head *head, struct list_node *node)
Inserts node at the end of head's list (aka stack push).
Definition list.c:35
struct list_node * list_first(struct list_head *head)
Definition list.c:53
struct list_node * list_last(struct list_head *head)
Definition list.c:57
struct list_node * list_next(struct list_head *head, struct list_node *node)
Definition list.c:74
bool list_is_empty(const struct list_head *head)
Definition list.c:17
struct list_head * list_init_head(struct list_head *head)
Initializes head as an empty list.
Definition list.c:6
struct list_node * list_insert_before(struct list_node *before, struct list_node *node)
Inserts node before before in the list of before.
Definition list.c:31
struct list_node * list_remove(struct list_node *node)
Removes node from head's list.
Definition list.c:61
struct list_node * list_init_node(struct list_node *node)
Initializes node.
Definition list.c:11
struct list_node * list_prev(struct list_head *head, struct list_node *node)
Definition list.c:77
size_t list_length(struct list_head *head)
Definition list.c:81
struct list_node * list_insert_after(struct list_node *after, struct list_node *node)
Inserts node after after in the list of after.
Definition list.c:21
struct list_node * list_pop_last(struct list_head *head)
Removes the last node of head's list (aka stack pop with respect to list_append).
Definition list.c:70
Anchor for list_node.
Definition list.h:23
Doubly-linked List Node.
Definition list.h:15
struct list_node * next
Definition list.h:16
struct list_node * prev
Definition list.h:17