5 list_init (struct list *list)
7 list->head.prev = NULL;
8 list->head.next = &list->tail;
9 list->tail.prev = &list->head;
10 list->tail.next = NULL;
14 list_begin (struct list *list)
16 return list->head.next;
20 list_end (struct list *list)
26 is_head (struct list_elem *elem)
28 return elem != NULL && elem->prev == NULL && elem->next != NULL;
32 is_real (struct list_elem *elem)
34 return elem != NULL && elem->prev != NULL && elem->next != NULL;
38 is_tail (struct list_elem *elem)
40 return elem != NULL && elem->prev != NULL && elem->next == NULL;
44 list_next (struct list_elem *elem)
46 ASSERT (is_real (elem));
51 list_prev (struct list_elem *elem)
53 ASSERT (is_real (elem) || is_tail (elem));
58 list_insert (struct list_elem *before, struct list_elem *elem)
60 ASSERT (is_real (before) || is_tail (before));
61 ASSERT (elem != NULL);
63 elem->prev = before->prev;
65 before->prev->next = elem;
70 list_splice (struct list_elem *target,
71 struct list_elem *first, struct list_elem *last)
73 ASSERT (is_real (target) || is_tail (target));
76 last = list_prev (last);
78 ASSERT (is_real (first));
79 ASSERT (is_real (last));
81 /* Cleanly remove FIRST...LAST from its current list. */
82 first->prev->next = last->next;
83 last->next->prev = first->prev;
85 /* Splice FIRST...LAST into new list. */
86 first->prev = target->prev;
88 target->prev->next = first;
93 list_push_front (struct list *list, struct list_elem *elem)
95 list_insert (list_begin (list), elem);
99 list_push_back (struct list *list, struct list_elem *elem)
101 list_insert (list_end (list), elem);
104 static struct list_elem *
105 remove_item (struct list_elem *elem)
107 ASSERT (is_real (elem));
108 elem->prev->next = elem->next;
109 elem->next->prev = elem->prev;
114 list_remove (struct list_elem *elem)
120 list_pop_front (struct list *list)
122 return remove_item (list_front (list));
126 list_pop_back (struct list *list)
128 return remove_item (list_back (list));
132 list_front (struct list *list)
134 return list_begin (list);
138 list_back (struct list *list)
140 return list_prev (list_end (list));
144 list_size (struct list *list)
146 struct list_elem *elem;
149 for (elem = list_begin (list); elem != list_end (list); elem = elem->next)
155 list_empty (struct list *list)
157 return list_begin (list) == list_end (list);
161 list_reverse (struct list *list)
166 for (e = &list->head; e != NULL; e = e->prev)
168 struct list_elem *tep = e->prev;
174 list->head = list->tail;
179 list_merge (struct list *al, struct list *bl,
180 list_less_func *less, void *aux)
186 ASSERT (less != NULL);
189 while (a != list_end (al))
191 struct list_elem *b = list_begin (bl);
192 if (less (b, a, aux))
194 list_splice (a, b, list_next (b));
201 list_splice (list_end (al), list_begin (bl), list_end (bl));
205 list_sort (struct list *list,
206 list_less_func *less, void *aux)
209 struct list_elem *middle, *last;
211 ASSERT (list != NULL);
212 ASSERT (less != NULL);
214 /* Empty and 1-element lists are already sorted. */
215 if (list_empty (list) || list_next (list_begin (list)) == list_end (list))
218 /* Find middle of LIST. (We're not interested in the end of
219 the list but it's incidentally needed.) */
220 middle = list_begin (list);
221 last = list_next (middle);
222 while (last != list_end (list) && list_next (last) != list_end (list))
224 middle = list_next (middle);
225 last = list_next (list_next (last));
228 /* Extract first half of LIST into a temporary list. */
230 list_splice (list_begin (&tmp), list_begin (list), middle);
232 /* Sort each half-list and merge the result. */
233 list_sort (&tmp, less, aux);
234 list_sort (list, less, aux);
235 list_merge (list, &tmp, less, aux);
239 list_insert_ordered (struct list *list, struct list_elem *elem,
240 list_less_func *less, void *aux)
244 ASSERT (list != NULL);
245 ASSERT (elem != NULL);
246 ASSERT (less != NULL);
248 for (e = list_begin (list); e != list_end (list); e = list_next (e))
249 if (less (elem, e, aux))
251 return list_insert (e, elem);
255 list_unique (struct list *list,
256 list_less_func *less, void *aux)
258 struct list_elem *elem, *next;
260 ASSERT (list != NULL);
261 ASSERT (less != NULL);
262 if (list_empty (list))
265 elem = list_begin (list);
266 while ((next = list_next (elem)) != list_end (list))
267 if (!less (elem, next, aux) && !less (next, elem, aux))