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 int (*)(const void*, const void*));
22 static list_item * _bisect(list_item *);
23 static list_item * _sort(list_item *,
24 int (*)(const void*, const 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_append(list *l, void *data)
71 return l_insert_after(l, l_last(l), data);
75 l_prepend(list *l, void *data)
77 return l_insert(l, l_first(l), data);
81 l_remove_first(list *l)
83 list_item *old_head = l_first(l);
84 return l_remove(l, old_head) ? old_head : NULL;
88 l_remove_last(list *l)
90 list_item *old_tail = l_last(l);
91 return l_remove(l, old_tail) ? old_tail : NULL;
95 l_remove(list *l, list_item *li)
97 if (!l || !li || l->length < 1)
99 list_item *p = li->prev, *n = li->next;
115 l_insert(list *l, list_item *pos, void *data)
121 list_item *li = malloc(sizeof *li);
125 .prev = pos ? pos->prev : NULL,
132 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);
158 .next = pos ? pos->next : NULL,
164 pos->next->prev = li;
169 l->head = l->tail = li;
170 else if (pos == l->tail)
183 list_item *li = l_first(l);
186 list_item *n = li->next;
188 l->elt_dtor(li->data);
192 l->head = l->tail = NULL;
200 l_sort(list *l, int (*cmp)(const void*, const void*))
207 l->head = _sort(l->head, cmp);
208 list_item *t = l->head;
220 _check(const list *l)
223 assert( (!l->head && l->length == 0) ||
224 ( l->head && l->length != 0) );
225 assert( (!l->head && !l->tail) ||
226 ( l->head && l->tail) );
228 list_item *li = l_first(l);
229 while (li && li->next)
231 assert(li == l_last(l));
234 while (li && li->prev)
236 assert(li == l_first(l));
240 _merge(list_item *a, list_item *b,
241 int (*cmp)(const void*, const void*))
248 if (cmp(a->data, b->data) <= 0)
251 n = _merge(a->next, b, cmp);
256 n = _merge(a, b->next, cmp);
264 _bisect(list_item *li)
267 list_item *fast = li;
268 while (fast && fast->next)
271 fast = fast->next->next;
273 if (li->prev) /* cut in twain */
274 li->prev = li->prev->next = NULL;
280 int (*cmp)(const void*, const void*))
286 list_item *r = _bisect(l);
289 return _merge(l, r, cmp);