AmendHub

Download

cyberslak

/

lightsout

/

list.h

 

(View History)

cyberslak   Add LICENSE information Latest amendment: 22 on 2025-03-15

1 // SPDX-License-Identifier: MIT
2
3 /** list.h - intrusive linked lists
4 */
5 #pragma once
6
7 // offsetof
8 #include <stddef.h>
9
10 typedef struct list
11 {
12 struct list *next;
13 struct list *prev;
14 } list_t;
15
16 #define LIST_INIT(x) { (&x), (&x) }
17
18 #define container_of(ptr, ty, field) \
19 ((ty*)((char*)(ptr)-offsetof(ty, field)))
20
21 // Iterate over a list. Note that items cannot be
22 // deleted while in this macro, because this will
23 // break the next link in the chain. If you wish
24 // to delete items, use list_foreach_safe at the
25 // expense of having to separately store the next ptr.
26 #define list_foreach(head, node) \
27 for (node = (head)->next; node != (head); node = (node)->next)
28
29
30 // Iterate over a list. Requires an extra next ptr
31 // to make deletion safe.
32 #define list_foreach_safe(head, node, next_) \
33 for (node = (head)->next, next_ = node->next; \
34 node != (head); \
35 node = next_, next_ = node->next)
36
37 #define list_foreach_safe_rev(head, node, prev_) \
38 for (node = (head)->prev, prev_ = node->prev; \
39 node != (head); \
40 node = prev_, prev_ = node->prev)
41
42 static inline void list_init(list_t* lst)
43 {
44 lst->next = lst->prev = lst;
45 }
46
47 static inline short list_empty(list_t* head)
48 {
49 return head->next == head;
50 }
51
52 static inline list_t* list_head(list_t* head)
53 {
54 return (head->next == head) ? NULL : head->next;
55 }
56
57 static inline list_t* list_tail(list_t* head)
58 {
59 return (head->prev == head) ? NULL : head->prev;
60 }
61
62 static inline list_t* list_next(list_t* head, list_t* node)
63 {
64 return (node->next == head) ? NULL : node->next;
65 }
66
67 static inline list_t* list_prev(list_t* head, list_t* node)
68 {
69 return (node->prev == head) ? NULL : node->prev;
70 }
71
72 void list_del(list_t* node);
73
74 void list_add(list_t* node, list_t* to_insert);
75 void list_add_tail(list_t* node, list_t* to_insert);
76
77 list_t* list_pop(list_t* head);
78 list_t* list_pop_tail(list_t* head);
79
80 void list_move(list_t* dst, list_t* src);