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};
48 l_length(const list *l)
50 return l ? l->length : 0;
54 l_is_empty(const list *l)
56 return !l || !l->head;
60 l_first(const list *l)
62 return l ? l->head : NULL;
68 return l ? l->tail : NULL;
72 l_append(list *l, void *data)
74 return l_insert_after(l, l_last(l), data);
78 l_prepend(list *l, void *data)
80 return l_insert(l, l_first(l), data);
84 l_remove_first(list *l)
86 list_item *old_head = l_first(l);
87 return l_remove(l, old_head) ? old_head : NULL;
91 l_remove_last(list *l)
93 list_item *old_tail = l_last(l);
94 return l_remove(l, old_tail) ? old_tail : NULL;
98 l_remove(list *l, list_item *li)
100 if (!l || !li || l->length < 1)
102 list_item *p = li->prev, *n = li->next;
118 l_insert(list *l, list_item *pos, void *data)
124 list_item *li = malloc(sizeof *li);
133 pos->prev->next = li;
137 l->head = l->tail = li;
138 else if (pos == l->head)
147 l_insert_after(list *l, list_item *pos, void *data)
153 list_item *li = malloc(sizeof *li);
162 pos->next->prev = li;
166 l->head = l->tail = li;
167 else if (pos == l->tail)
180 list_item *li = l_first(l);
183 list_item *n = li->next;
185 l->elt_dtor(li->data);
189 l->head = l->tail = NULL;