7 #define CHECK(x) (void)(x)
9 #define CHECK(x) _check(x)
14 list_item *head, *tail;
15 void (*elt_dtor)(void *);
19 static void _check(const list *l);
20 static list_item * _merge(list_item *, list_item *,
21 comparator *, void *);
22 static list_item * _bisect(list_item *);
23 static list_item * _sort(list_item *,
24 comparator *, void *);
27 l_new(void (*elt_dtor)(void *))
29 list *l = malloc(sizeof *l);
32 *l = (list){.elt_dtor = elt_dtor};
45 l_length(const list *l)
47 return l ? l->length : 0;
51 l_is_empty(const list *l)
53 return !l || !l->head;
57 l_first(const list *l)
59 return l ? l->head : NULL;
65 return l ? l->tail : NULL;
69 l_find(const list *l, const void *needle,
70 comparator *cmp, void *aux)
74 for (list_item *li = l_first(l); li; li = li->next)
75 if (cmp(li->data, needle, aux) == 0)
81 l_find_last(const list *l, const void *needle,
82 comparator *cmp, void *aux)
86 for (list_item *li = l_last(l); li; li = li->prev)
87 if (cmp(li->data, needle, aux) == 0)
93 l_append(list *l, void *data)
95 return l_insert_after(l, l_last(l), data);
99 l_prepend(list *l, void *data)
101 return l_insert(l, l_first(l), data);
105 l_remove_first(list *l)
107 list_item *old_head = l_first(l);
108 return l_remove(l, old_head) ? old_head : NULL;
112 l_remove_last(list *l)
114 list_item *old_tail = l_last(l);
115 return l_remove(l, old_tail) ? old_tail : NULL;
119 l_remove(list *l, list_item *li)
121 if (!l || !li || l->length < 1)
123 list_item *p = li->prev, *n = li->next;
139 l_insert(list *l, list_item *pos, void *data)
145 list_item *li = malloc(sizeof *li);
149 .prev = pos ? pos->prev : NULL,
156 pos->prev->next = li;
161 l->head = l->tail = li;
162 else if (pos == l->head)
171 l_insert_after(list *l, list_item *pos, void *data)
177 list_item *li = malloc(sizeof *li);
182 .next = pos ? pos->next : NULL,
188 pos->next->prev = li;
193 l->head = l->tail = li;
194 else if (pos == l->tail)
207 list_item *li = l_first(l);
210 list_item *n = li->next;
212 l->elt_dtor(li->data);
216 l->head = l->tail = NULL;
224 l_sort(list *l, comparator *cmp, void *aux)
231 l->head = _sort(l->head, cmp, aux);
232 list_item *t = l->head;
244 _check(const list *l)
247 assert( (!l->head && l->length == 0) ||
248 ( l->head && l->length != 0) );
249 assert( (!l->head && !l->tail) ||
250 ( l->head && l->tail) );
252 list_item *li = l_first(l);
253 while (li && li->next)
255 assert(li == l_last(l));
258 while (li && li->prev)
260 assert(li == l_first(l));
264 _merge(list_item *a, list_item *b,
265 comparator *cmp, void *aux)
272 if (cmp(a->data, b->data, aux) <= 0)
275 n = _merge(a->next, b, cmp, aux);
280 n = _merge(a, b->next, cmp, aux);
288 _bisect(list_item *li)
291 list_item *fast = li;
292 while (fast && fast->next)
295 fast = fast->next->next;
297 if (li->prev) /* cut in twain */
298 li->prev = li->prev->next = NULL;
303 _sort(list_item *l, comparator *cmp, void *aux)
309 list_item *r = _bisect(l);
310 l = _sort(l, cmp, aux);
311 r = _sort(r, cmp, aux);
312 return _merge(l, r, cmp, aux);