4 /* Our doubly linked lists have two header elements: the "head"
5 just before the first element and the "tail" just after the
6 last element. The `prev' link of the front header is null, as
7 is the `next' link of the back header. Their other two links
8 point toward each other via the interior elements of the list.
10 An empty list looks like this:
13 <---| head |<--->| tail |--->
16 A list with two elements in it looks like this:
18 +------+ +-------+ +-------+ +------+
19 <---| head |<--->| 1 |<--->| 2 |<--->| tail |<--->
20 +------+ +-------+ +-------+ +------+
22 The symmetry of this arrangement eliminates lots of special
23 cases in list processing. For example, take a look at
24 list_remove(): it takes only two pointer assignments and no
25 conditionals. That's a lot simpler than the code would be
26 without header elements.
28 (Because only one of the pointers in each header element is used,
29 we could in fact combine them into a single header element
30 without sacrificing this simplicity. But using two separate
31 elements allows us to do a little bit of checking on some
32 operations, which can be valuable.) */
34 /* Returns true if ELEM is a head, false otherwise. */
36 is_head (list_elem *elem)
38 return elem != NULL && elem->prev == NULL && elem->next != NULL;
41 /* Returns true if ELEM is an interior element,
44 is_interior (list_elem *elem)
46 return elem != NULL && elem->prev != NULL && elem->next != NULL;
49 /* Returns true if ELEM is a tail, false otherwise. */
51 is_tail (list_elem *elem)
53 return elem != NULL && elem->prev != NULL && elem->next == NULL;
56 /* Initializes LIST as an empty list. */
58 list_init (struct list *list)
60 ASSERT (list != NULL);
61 list->head.prev = NULL;
62 list->head.next = &list->tail;
63 list->tail.prev = &list->head;
64 list->tail.next = NULL;
67 /* Returns the beginning of LIST. */
69 list_begin (struct list *list)
71 ASSERT (list != NULL);
72 return list->head.next;
75 /* Returns the element after ELEM in its list. If ELEM is the
76 last element in its list, returns the list tail. Results are
77 undefined if ELEM is itself a list tail. */
79 list_next (list_elem *elem)
81 ASSERT (is_interior (elem));
85 /* Returns LIST's tail.
87 list_end() is often used in iterating through a list from
88 front to back. See the big comment at the top of list.h for
91 list_end (struct list *list)
93 ASSERT (list != NULL);
97 /* Returns the LIST's reverse beginning, for iterating through
98 LIST in reverse order, from back to front. */
100 list_rbegin (struct list *list)
102 ASSERT (list != NULL);
103 return list->tail.prev;
106 /* Returns LIST's head.
108 list_rend() is often used in iterating through a list in
109 reverse order, from back to front. Here's typical usage,
110 following the example from the top of list.h:
112 for (e = list_rbegin (&foo_list); e != list_rend (&foo_list);
115 struct foo *f = list_entry (e, struct foo, elem);
116 ...do something with f...
120 list_rend (struct list *list)
122 ASSERT (list != NULL);
126 /* Returns the element before ELEM in its list. If ELEM is the
127 first element in its list, returns the list head. Results are
128 undefined if ELEM is itself a list head. */
130 list_prev (list_elem *elem)
132 ASSERT (is_interior (elem) || is_tail (elem));
136 /* Inserts ELEM just before BEFORE, which may be either an
137 interior element or a tail. The latter case is equivalent to
140 list_insert (list_elem *before, list_elem *elem)
142 ASSERT (is_interior (before) || is_tail (before));
143 ASSERT (elem != NULL);
145 elem->prev = before->prev;
147 before->prev->next = elem;
151 /* Removes elements FIRST though LAST (exclusive) from their
152 current list, then inserts them just before BEFORE, which may
153 be either an interior element or a tail. */
155 list_splice (list_elem *before,
156 list_elem *first, list_elem *last)
158 ASSERT (is_interior (before) || is_tail (before));
161 last = list_prev (last);
163 ASSERT (is_interior (first));
164 ASSERT (is_interior (last));
166 /* Cleanly remove FIRST...LAST from its current list. */
167 first->prev->next = last->next;
168 last->next->prev = first->prev;
170 /* Splice FIRST...LAST into new list. */
171 first->prev = before->prev;
173 before->prev->next = first;
177 /* Inserts ELEM at the beginning of LIST, so that it becomes the
180 list_push_front (struct list *list, list_elem *elem)
182 list_insert (list_begin (list), elem);
185 /* Inserts ELEM at the end of LIST, so that it becomes the
188 list_push_back (struct list *list, list_elem *elem)
190 list_insert (list_end (list), elem);
193 /* Removes ELEM from its list. Undefined behavior if ELEM is not
196 list_remove (list_elem *elem)
198 ASSERT (is_interior (elem));
199 elem->prev->next = elem->next;
200 elem->next->prev = elem->prev;
204 /* Removes the front element from LIST and returns it.
205 Undefined behavior if LIST is empty before removal. */
207 list_pop_front (struct list *list)
209 ASSERT (list != NULL);
210 return list_remove (list_front (list));
213 /* Removes the back element from LIST and returns it.
214 Undefined behavior if LIST is empty before removal. */
216 list_pop_back (struct list *list)
218 ASSERT (list != NULL);
219 return list_remove (list_back (list));
222 /* Returns the front element in LIST.
223 Undefined behavior if LIST is empty. */
225 list_front (struct list *list)
227 ASSERT (!list_empty (list));
228 return list->head.next;
231 /* Returns the back element in LIST.
232 Undefined behavior if LIST is empty. */
234 list_back (struct list *list)
236 ASSERT (!list_empty (list));
237 return list->tail.prev;
240 /* Returns the number of elements in LIST.
241 Runs in O(n) in the number of elements. */
243 list_size (struct list *list)
248 for (e = list_begin (list); e != list_end (list); e = list_next (e))
253 /* Returns true if LIST is empty, false otherwise. */
255 list_empty (struct list *list)
257 return list_begin (list) == list_end (list);
260 /* Reverses the order of LIST. */
262 list_reverse (struct list *list)
266 /* Swap the prev and next pointers in each element of LIST. */
267 for (e = &list->head; e != NULL; e = e->prev)
269 list_elem *tep = e->prev;
274 /* Swap the head and tail. */
276 list->head = list->tail;
280 /* Merges lists AL and BL, which must each be sorted according to
281 LESS given auxiliary data AUX, by inserting each element of BL
282 at the proper place in AL to preserve the ordering.
283 Runs in O(n) in the combined length of AL and BL. */
285 list_merge (struct list *al, struct list *bl,
286 list_less_func *less, void *aux)
292 ASSERT (less != NULL);
295 while (a != list_end (al))
297 list_elem *b = list_begin (bl);
298 if (less (b, a, aux))
300 list_splice (a, b, list_next (b));
307 list_splice (list_end (al), list_begin (bl), list_end (bl));
310 /* Sorts LIST according to LESS given auxiliary data AUX.
311 Runs in O(n lg n) in the number of elements in LIST. */
313 list_sort (struct list *list,
314 list_less_func *less, void *aux)
317 list_elem *middle, *last;
319 ASSERT (list != NULL);
320 ASSERT (less != NULL);
322 /* Empty and 1-element lists are already sorted. */
323 if (list_empty (list) || list_next (list_begin (list)) == list_end (list))
326 /* Find middle of LIST. (We're not interested in the end of
327 the list but it's incidentally needed.) */
328 middle = list_begin (list);
329 last = list_next (middle);
330 while (last != list_end (list) && list_next (last) != list_end (list))
332 middle = list_next (middle);
333 last = list_next (list_next (last));
336 /* Extract first half of LIST into a temporary list. */
338 list_splice (list_begin (&tmp), list_begin (list), middle);
340 /* Sort each half-list and merge the result. */
341 list_sort (&tmp, less, aux);
342 list_sort (list, less, aux);
343 list_merge (list, &tmp, less, aux);
346 /* Inserts ELEM in the proper position in LIST, which must be
347 sorted according to LESS given auxiliary data AUX.
348 Runs in O(n) average case in the number of elements in LIST. */
350 list_insert_ordered (struct list *list, list_elem *elem,
351 list_less_func *less, void *aux)
355 ASSERT (list != NULL);
356 ASSERT (elem != NULL);
357 ASSERT (less != NULL);
359 for (e = list_begin (list); e != list_end (list); e = list_next (e))
360 if (less (elem, e, aux))
362 return list_insert (e, elem);
365 /* Iterates through LIST and removes all but the first in each
366 set of adjacent elements that are equal according to LESS
367 given auxiliary data AUX. If DUPLICATES is non-null, then the
368 elements from LIST are appended to DUPLICATES. */
370 list_unique (struct list *list, struct list *duplicates,
371 list_less_func *less, void *aux)
373 list_elem *elem, *next;
375 ASSERT (list != NULL);
376 ASSERT (less != NULL);
377 if (list_empty (list))
380 elem = list_begin (list);
381 while ((next = list_next (elem)) != list_end (list))
382 if (!less (elem, next, aux) && !less (next, elem, aux))
385 if (duplicates != NULL)
386 list_push_back (duplicates, next);