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));
41 * Internal implementation to add a new member.
42 * list_node_t *node -> node to add.
43 * list_node_t *prev -> prev node.
44 * list_node_t *next -> next node.
46 static inline void __list_add(list_node_t
*node
, list_node_t
*prev
, list_node_t
*next
)
55 #define list_add_head(list, node) __list_add((node), (list), (list)->next)
56 #define list_add_tail(list, node) __list_add((node), (list)->prev, (list))
57 #define list_add_after(cur, node) list_add_head((cur), (node))
58 #define list_add_before(cur, node) list_add_tail((cur), (node))
61 * Internal implementation to remove a member.
62 * list_node_t *prev -> prev node.
63 * list_node_t *next -> next node.
65 static inline void __list_rem(list_node_t
*prev
, list_node_t
*next
)
73 * list_node_t *node -> node to delete.
75 static inline void list_delete(list_node_t
*node
)
77 __list_rem(node
->prev
, node
->next
);
78 node
->prev
= node
->next
= 0;
82 * Delete the head of a list.
83 * list_node_t *list -> the list.
86 * list_node_t* -> the node deleted.
88 static inline list_node_t
* list_delete_head(list_node_t
*list
)
91 if ((node
= list
->next
) != list
) {
100 * Delete the tail of a list.
101 * list_node_t *list -> the list.
104 * list_node_t* -> the node deleted.
106 static inline list_node_t
* list_delete_tail(list_node_t
*list
)
109 if ((node
= list
->prev
) != list
) {
118 * Check if list is empty, or not.
119 * const list_node_t *list -> the list.
122 * bool -> true if empty.
124 static inline bool list_is_emtpy(const list_node_t
*list
)
126 return (list
->next
== list
);
130 * Check if node is the last element in the list.
131 * const list_node_t *list -> the list.
132 * const list_node_t *node -> the node to check.
135 * bool -> true if last.
137 static inline bool list_is_last(const list_node_t
*list
, const list_node_t
*node
)
139 return (list
->prev
== node
);
143 #define list_foreach(list, type, member, iterator) for (\
144 (iterator) = get_container((list)->next, type, member); \
145 &(iterator)->member != (list); \
146 (iterator) = get_container((iterator)->member.next, type, member))
149 #define list_foreach_safe(list, type, member, iterator, temp_iter) for (\
150 (iterator) = get_container((list)->next, type, member), \
151 (temp_iter) = get_container((iterator)->member.next, type, member); \
152 &(iterator)->member != (list); \
153 (iterator) = (temp_iter), \
154 (temp_iter) = get_container((iterator)->member.next, type, member))