7 #define CHECK(x) (void)(x)
9 #define CHECK(x) _check(x)
14 list_item *head, *tail;
20 static void _check(const list *l);
21 static list_item * _merge(list_item *, list_item *,
22 comparator *, void *);
23 static list_item * _bisect(list_item *);
24 static list_item * _sort(list_item *,
25 comparator *, void *);
30 list *l = malloc(sizeof *l);
38 void l_dtor(list *l, dtor *elt_dtor, void *dtor_aux)
42 l->elt_dtor = elt_dtor;
43 l->dtor_aux = dtor_aux;
54 l_length(const list *l)
56 return l ? l->length : 0;
60 l_is_empty(const list *l)
62 return !l || !l->head;
66 l_first(const list *l)
68 return l ? l->head : NULL;
74 return l ? l->tail : NULL;
78 l_find(const list *l, const void *needle,
79 comparator *cmp, void *aux)
83 for (list_item *li = l_first(l); li; li = li->next)
84 if (cmp(li->data, needle, aux) == 0)
90 l_find_last(const list *l, const void *needle,
91 comparator *cmp, void *aux)
95 for (list_item *li = l_last(l); li; li = li->prev)
96 if (cmp(li->data, needle, aux) == 0)
102 l_append(list *l, void *data)
104 return l_insert_after(l, l_last(l), data);
108 l_prepend(list *l, void *data)
110 return l_insert(l, l_first(l), data);
114 l_remove_first(list *l)
116 list_item *old_head = l_first(l);
117 void *data = old_head ? old_head->data : NULL;
118 l_remove(l, old_head);
123 l_remove_last(list *l)
125 list_item *old_tail = l_last(l);
126 void *data = old_tail ? old_tail->data : NULL;
127 l_remove(l, old_tail);
132 l_remove(list *l, list_item *li)
134 if (!l || !li || l->length < 1)
136 list_item *p = li->prev, *n = li->next;
153 l_insert(list *l, list_item *pos, void *data)
159 list_item *li = malloc(sizeof *li);
163 .prev = pos ? pos->prev : NULL,
170 pos->prev->next = li;
175 l->head = l->tail = li;
176 else if (pos == l->head)
185 l_insert_after(list *l, list_item *pos, void *data)
191 list_item *li = malloc(sizeof *li);
196 .next = pos ? pos->next : NULL,
202 pos->next->prev = li;
207 l->head = l->tail = li;
208 else if (pos == l->tail)
221 list_item *li = l_first(l);
224 list_item *n = li->next;
226 l->elt_dtor(li->data, l->dtor_aux);
230 l->head = l->tail = NULL;
238 l_sort(list *l, comparator *cmp, void *aux)
245 l->head = _sort(l->head, cmp, aux);
246 list_item *t = l->head;
258 _check(const list *l)
261 assert( (!l->head && l->length == 0) ||
262 ( l->head && l->length != 0) );
263 assert( (!l->head && !l->tail) ||
264 ( l->head && l->tail) );
266 list_item *li = l_first(l);
267 while (li && li->next)
269 assert(li == l_last(l));
272 while (li && li->prev)
274 assert(li == l_first(l));
278 _merge(list_item *a, list_item *b,
279 comparator *cmp, void *aux)
286 if (cmp(a->data, b->data, aux) <= 0)
289 n = _merge(a->next, b, cmp, aux);
294 n = _merge(a, b->next, cmp, aux);
302 _bisect(list_item *li)
305 list_item *fast = li;
306 while (fast && fast->next)
309 fast = fast->next->next;
311 if (li->prev) /* cut in twain */
312 li->prev = li->prev->next = NULL;
317 _sort(list_item *l, comparator *cmp, void *aux)
323 list_item *r = _bisect(l);
324 l = _sort(l, cmp, aux);
325 r = _sort(r, cmp, aux);
326 return _merge(l, r, cmp, aux);