list.h (2187B)
1 #ifndef LIST_H 2 #define LIST_H 3 4 #include <stddef.h> 5 #include <stdint.h> 6 7 #define TO_PARENT(ptr, T, member) \ 8 ((T *) ((uintptr_t) ptr - offsetof(T, member))) 9 10 struct list_node { 11 struct list_node *prev, *next; 12 }; 13 14 #define FROM_LIST_NODE(node, T, member) \ 15 TO_PARENT((node), T, member) 16 17 #define LIST_INIT(list) \ 18 ((struct list_node) { &(list), &(list), }) 19 20 #define LIST_HEAD(list) ((list)->next) 21 #define LIST_TAIL(list) ((list)->prev) 22 23 #define LIST_EMPTY(list) \ 24 (LIST_HEAD((list)) == (list) && LIST_TAIL((list)) == (list)) 25 26 #define LIST_NODE_ITER(list, it) \ 27 for ((it) = LIST_HEAD((list)); (it) != (list); (it) = (it)->next) 28 29 #define LIST_NODE_RITER(list, it) \ 30 for ((it) = LIST_TAIL((list)); (it) != (list); (it) = (it)->prev) 31 32 #define LIST_NODE_ENTRY(node, it, member) \ 33 FROM_LIST_NODE((node), __typeof__ (*(it)), member) 34 35 #define LIST_ENTRY_ITER(list, it, member) \ 36 for ((it) = LIST_NODE_ENTRY(LIST_HEAD((list)), (it), member); \ 37 &(it)->member != (list); \ 38 (it) = LIST_NODE_ENTRY((it)->member.next, (it), member)) 39 40 #define LIST_ENTRY_RITER(list, it, member) \ 41 for ((it) = LIST_NODE_ENTRY(LIST_TAIL((list)), (it), member); \ 42 &(it)->member != (list); \ 43 (it) = LIST_NODE_ENTRY((it)->member.prev, (it), member)) 44 45 static inline void 46 list_node_link(struct list_node *node, struct list_node *prev, struct list_node *next) 47 { 48 prev->next = node; 49 node->prev = prev; 50 next->prev = node; 51 node->next = next; 52 } 53 54 static inline struct list_node * 55 list_node_unlink(struct list_node *node) 56 { 57 node->prev->next = node->next; 58 node->next->prev = node->prev; 59 return node; 60 } 61 62 static inline void 63 list_push_head(struct list_node *list, struct list_node *node) 64 { 65 list_node_link(node, list, LIST_HEAD(list)); 66 } 67 68 static inline void 69 list_push_tail(struct list_node *list, struct list_node *node) 70 { 71 list_node_link(node, LIST_TAIL(list), list); 72 } 73 74 static inline struct list_node * 75 list_pop_head(struct list_node *list) 76 { 77 struct list_node *res = list_node_unlink(LIST_HEAD(list)); 78 return res; 79 } 80 81 static inline struct list_node * 82 list_pop_tail(struct list_node *list) 83 { 84 struct list_node *res = list_node_unlink(LIST_TAIL(list)); 85 return res; 86 } 87 88 #endif /* LIST_H */