12 #define check_list(list) \
13 assert((list->len == 0 && !list->top && !list->bottom) || \
14 (list->len > 0 && list->top && list->bottom))
20 d_list_t *list = malloc(sizeof(d_list_t));
29 list_ref(d_list_t *list)
35 list_unref(d_list_t *list)
37 if (list && --list->ref == 0) {
39 list_delete_link(list, list->top);
45 list_prepend(d_list_t *list, void *data)
47 d_list_it_t *n = malloc(sizeof(d_list_it_t));
52 if (n->next) n->next->prev = n;
55 if (!list->bottom) list->bottom = n;
61 list_delete_link(d_list_t *list, d_list_it_t *pos)
63 d_list_it_t *prev = pos->prev;
64 d_list_it_t *next = pos->next;
71 assert(list->bottom == pos);
75 assert(list->top == pos);
85 list_move_before(d_list_t *list, d_list_it_t *move, d_list_it_t *before)
87 d_list_it_t *prev, *next;
89 /* these won't move it anywhere */
90 if (move == before || move->next == before) return;
95 /* remove it from the list */
96 if (next) next->prev = prev;
97 else list->bottom = prev;
98 if (prev) prev->next = next;
99 else list->top = next;
104 move->prev = before->prev;
105 move->next->prev = move;
106 if (move->prev) move->prev->next = move;
109 /* after the bottom */
110 move->prev = list->bottom;
112 if (move->prev) move->prev->next = move;
116 if (!move->prev) list->top = move;
120 list_remove(d_list_t *list, void *data)
122 d_list_it_t *it = list_find(list, data);
123 if (it) list_delete_link(list, it);
127 list_length(d_list_t *list)
133 list_top(d_list_t *list)
139 list_bottom(d_list_t *list)
145 list_nth(d_list_t *list, int n)
151 assert(n < list->len);
154 for (i = 0; i < n; ++i)
160 list_find(d_list_t *list, void *data)
164 for (it = list->top; it; it = it->next)
165 if (it->data == data) return it;