4 /* Linux inspired doubly linked-list implementation. */
9 typedef struct list_node
11 struct list_node
*prev
, *next
;
14 #define get_offset(type, member) (uintptr_t)&(((type*)0)->member)
15 #define get_container(entry, type, member) (type*)((uintptr_t)(entry) - get_offset(type, member))
17 #define EMPTY_LIST(name) { &name, &name }
21 * list_node_t *list -> list to initialize.
23 static inline void list_init(list_node_t
*list
)
25 list
->prev
= list
->next
= list
;
29 * Check whether a node is in a list.
30 * const list_node_t *node.
35 static inline bool list_in_list(const list_node_t
*node
)
37 return !((node
->prev
== 0) || (node
->next
== 0));
42 * const list_node_t *list -> list.
47 static inline list_node_t
* list_get_head(const list_node_t
*list
)
49 if (list
->next
!= list
) {
56 #define list_get_head_type(list, type, element) ({ \
57 list_node_t *__node = list_get_head(list); \
60 __instance = get_container(__node, type, element); \
62 __instance = (type *)0; \
68 * const list_node_t *list -> list.
73 static inline list_node_t
* list_get_tail(const list_node_t
*list
)
75 if (list
->prev
!= list
) {
82 #define list_get_tail_type(list, type, element) ({ \
83 list_node_t *__node = list_get_tail(list); \
86 __instance = get_container(__node, type, element); \
88 __instance = (type *)0; \
93 * Internal implementation to add a new member.
94 * list_node_t *node -> node to add.
95 * list_node_t *prev -> prev node.
96 * list_node_t *next -> next node.
98 static inline void __list_add(list_node_t
*node
, list_node_t
*prev
, list_node_t
*next
)
107 #define list_add_head(list, node) __list_add((node), (list), (list)->next)
108 #define list_add_tail(list, node) __list_add((node), (list)->prev, (list))
109 #define list_add_after(cur, node) list_add_head((cur), (node))
110 #define list_add_before(cur, node) list_add_tail((cur), (node))
113 * Internal implementation to remove a member.
114 * list_node_t *prev -> prev node.
115 * list_node_t *next -> next node.
117 static inline void __list_rem(list_node_t
*prev
, list_node_t
*next
)
125 * list_node_t *node -> node to delete.
127 static inline void list_delete(list_node_t
*node
)
129 __list_rem(node
->prev
, node
->next
);
130 node
->prev
= node
->next
= 0;
134 * Delete the head of a list.
135 * list_node_t *list -> the list.
138 * list_node_t* -> the node deleted.
140 static inline list_node_t
* list_delete_head(list_node_t
*list
)
143 if ((node
= list
->next
) != list
) {
152 * Delete the tail of a list.
153 * list_node_t *list -> the list.
156 * list_node_t* -> the node deleted.
158 static inline list_node_t
* list_delete_tail(list_node_t
*list
)
161 if ((node
= list
->prev
) != list
) {
170 * Check if list is empty, or not.
171 * const list_node_t *list -> the list.
174 * bool -> true if empty.
176 static inline bool list_is_emtpy(const list_node_t
*list
)
178 return (list
->next
== list
);
182 * Check if node is the last element in the list.
183 * const list_node_t *list -> the list.
184 * const list_node_t *node -> the node to check.
187 * bool -> true if last.
189 static inline bool list_is_last(const list_node_t
*list
, const list_node_t
*node
)
191 return (list
->prev
== node
);
195 #define list_foreach(list, type, member, iterator) for (\
196 (iterator) = get_container((list)->next, type, member); \
197 &(iterator)->member != (list); \
198 (iterator) = get_container((iterator)->member.next, type, member))
201 #define list_foreach_safe(list, type, member, iterator, temp_iter) for (\
202 (iterator) = get_container((list)->next, type, member), \
203 (temp_iter) = get_container((iterator)->member.next, type, member); \
204 &(iterator)->member != (list); \
205 (iterator) = (temp_iter), \
206 (temp_iter) = get_container((iterator)->member.next, type, member))