7 #define CHECK(x) (void)(x)
9 #define CHECK(x) _check(x)
14 list_item *head, *tail;
15 void (*elt_dtor)(void *);
23 assert( (!l->head && l->length == 0) ||
24 ( l->head && l->length != 0) );
25 assert( (!l->head && !l->tail) ||
26 ( l->head && l->tail) );
30 l_new(void (*elt_dtor)(void *))
32 list *l = malloc(sizeof *l);
35 *l = (list){.elt_dtor = elt_dtor};
50 l_length(const list *l)
52 return l ? l->length : 0;
56 l_is_empty(const list *l)
58 return !l || !l->head;
62 l_first(const list *l)
64 return l ? l->head : NULL;
70 return l ? l->tail : NULL;
74 l_append(list *l, void *data)
78 return l_insert_after(l, l->tail, data);
82 l_prepend(list *l, void *data)
86 return l_insert(l, l->head, data);
90 l_remove_first(list *l)
94 list_item *old_head = l->head;
97 l->head = old_head->next;
98 old_head->next = NULL;
106 l_remove_last(list *l)
110 list_item *old_tail = l->tail;
113 l->tail = old_tail->prev;
114 old_tail->prev = NULL;
115 l->tail->next = NULL;
122 l_insert(list *l, list_item *pos, void *data)
128 list_item *li = malloc(sizeof *li);
137 pos->prev->next = li;
141 l->head = l->tail = li;
142 else if (pos == l->head)
151 l_insert_after(list *l, list_item *pos, void *data)
157 list_item *li = malloc(sizeof *li);
166 pos->next->prev = li;
170 l->head = l->tail = li;
171 else if (pos == l->tail)