libdiscord

libdiscord.git
git clone git://git.lenczewski.org/libdiscord.git
Log | Files | Refs | README | LICENSE

list.h (2293B)


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