1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2006, 2009 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Embedded, circular doubly linked list. */
19 /* These library routines have no external dependencies other
20 than the standard C library.
22 If you add routines in this file, please add a corresponding
23 test to ll-test.c. This test program should achieve 100%
24 coverage of lines and branches in this code, as reported by
31 #include <libpspp/ll.h>
34 /* Returns the number of nodes in LIST (not counting the null
35 node). Executes in O(n) time in the length of the list. */
37 ll_count (const struct ll_list *list)
39 return ll_count_range (ll_head (list), ll_null (list));
42 /* Removes R0...R1 from their current list
43 and inserts them just before BEFORE. */
45 ll_splice (struct ll *before, struct ll *r0, struct ll *r1)
47 if (before != r0 && r0 != r1)
49 /* Change exclusive range to inclusive. */
52 /* Remove R0...R1 from its list. */
53 r0->prev->next = r1->next;
54 r1->next->prev = r0->prev;
56 /* Insert R0...R1 before BEFORE. */
57 r0->prev = before->prev;
59 before->prev->next = r0;
64 /* Exchanges the positions of A and B,
65 which may be in the same list or different lists. */
67 ll_swap (struct ll *a, struct ll *b)
73 struct ll *a_next = ll_remove (a);
74 struct ll *b_next = ll_remove (b);
75 ll_insert (b_next, a);
76 ll_insert (a_next, b);
86 /* Exchanges the positions of A0...A1 and B0...B1,
87 which may be in the same list or different lists but must not
90 ll_swap_range (struct ll *a0, struct ll *a1, struct ll *b0, struct ll *b1)
92 if (a0 == a1 || a1 == b0)
93 ll_splice (a0, b0, b1);
94 else if (b0 == b1 || b1 == a0)
95 ll_splice (b0, a0, a1);
98 struct ll *x0 = ll_prev (a0), *x1 = a1;
99 struct ll *y0 = ll_prev (b0), *y1 = b1;
113 /* Removes from R0...R1 all the nodes that equal TARGET
114 according to COMPARE given auxiliary data AUX.
115 Returns the number of nodes removed. */
117 ll_remove_equal (struct ll *r0, struct ll *r1, struct ll *target,
118 ll_compare_func *compare, void *aux)
124 for (x = r0; x != r1; )
125 if (compare (x, target, aux) == 0)
136 /* Removes from R0...R1 all the nodes for which PREDICATE returns
137 true given auxiliary data AUX.
138 Returns the number of nodes removed. */
140 ll_remove_if (struct ll *r0, struct ll *r1,
141 ll_predicate_func *predicate, void *aux)
147 for (x = r0; x != r1; )
148 if (predicate (x, aux))
159 /* Returns the first node in R0...R1 that equals TARGET
160 according to COMPARE given auxiliary data AUX.
161 Returns R1 if no node in R0...R1 equals TARGET. */
163 ll_find_equal (const struct ll *r0, const struct ll *r1,
164 const struct ll *target,
165 ll_compare_func *compare, void *aux)
169 for (x = r0; x != r1; x = ll_next (x))
170 if (compare (x, target, aux) == 0)
172 return CONST_CAST (struct ll *, x);
175 /* Returns the first node in R0...R1 for which PREDICATE returns
176 true given auxiliary data AUX.
177 Returns R1 if PREDICATE does not return true for any node in
180 ll_find_if (const struct ll *r0, const struct ll *r1,
181 ll_predicate_func *predicate, void *aux)
185 for (x = r0; x != r1; x = ll_next (x))
186 if (predicate (x, aux))
188 return CONST_CAST (struct ll *, x);
191 /* Compares each pair of adjacent nodes in R0...R1
192 using COMPARE with auxiliary data AUX
193 and returns the first node of the first pair that compares
195 Returns R1 if no pair compares equal. */
197 ll_find_adjacent_equal (const struct ll *r0, const struct ll *r1,
198 ll_compare_func *compare, void *aux)
202 const struct ll *x, *y;
204 for (x = r0, y = ll_next (x); y != r1; x = y, y = ll_next (y))
205 if (compare (x, y, aux) == 0)
206 return CONST_CAST (struct ll *, x);
209 return CONST_CAST (struct ll *, r1);
212 /* Returns the number of nodes in R0...R1.
213 Executes in O(n) time in the return value. */
215 ll_count_range (const struct ll *r0, const struct ll *r1)
221 for (x = r0; x != r1; x = ll_next (x))
226 /* Counts and returns the number of nodes in R0...R1 that equal
227 TARGET according to COMPARE given auxiliary data AUX. */
229 ll_count_equal (const struct ll *r0, const struct ll *r1,
230 const struct ll *target,
231 ll_compare_func *compare, void *aux)
237 for (x = r0; x != r1; x = ll_next (x))
238 if (compare (x, target, aux) == 0)
243 /* Counts and returns the number of nodes in R0...R1 for which
244 PREDICATE returns true given auxiliary data AUX. */
246 ll_count_if (const struct ll *r0, const struct ll *r1,
247 ll_predicate_func *predicate, void *aux)
253 for (x = r0; x != r1; x = ll_next (x))
254 if (predicate (x, aux))
259 /* Returns the greatest node in R0...R1 according to COMPARE
260 given auxiliary data AUX.
261 Returns the first of multiple, equal maxima. */
263 ll_max (const struct ll *r0, const struct ll *r1,
264 ll_compare_func *compare, void *aux)
266 const struct ll *max = r0;
271 for (x = ll_next (r0); x != r1; x = ll_next (x))
272 if (compare (x, max, aux) > 0)
275 return CONST_CAST (struct ll *, max);
278 /* Returns the least node in R0...R1 according to COMPARE given
280 Returns the first of multiple, equal minima. */
282 ll_min (const struct ll *r0, const struct ll *r1,
283 ll_compare_func *compare, void *aux)
285 const struct ll *min = r0;
290 for (x = ll_next (r0); x != r1; x = ll_next (x))
291 if (compare (x, min, aux) < 0)
294 return CONST_CAST (struct ll *, min);
297 /* Lexicographically compares A0...A1 to B0...B1.
298 Returns negative if A0...A1 < B0...B1,
299 zero if A0...A1 == B0...B1, and
300 positive if A0...A1 > B0...B1
301 according to COMPARE given auxiliary data AUX. */
303 ll_lexicographical_compare_3way (const struct ll *a0, const struct ll *a1,
304 const struct ll *b0, const struct ll *b1,
305 ll_compare_func *compare, void *aux)
314 int cmp = compare (a0, b0, aux);
323 /* Calls ACTION with auxiliary data AUX
324 for every node in R0...R1 in order. */
326 ll_apply (struct ll *r0, struct ll *r1, ll_action_func *action, void *aux)
330 for (ll = r0; ll != r1; ll = ll_next (ll))
334 /* Reverses the order of nodes R0...R1. */
336 ll_reverse (struct ll *r0, struct ll *r1)
338 if (r0 != r1 && ll_next (r0) != r1)
342 for (ll = r0; ll != r1; ll = ll->prev)
344 struct ll *tmp = ll->next;
348 r0->next->next = r1->prev;
349 r1->prev->prev = r0->next;
355 /* Arranges R0...R1 into the lexicographically next greater
356 permutation. Returns true if successful.
357 If R0...R1 is already the lexicographically greatest
358 permutation of its elements (i.e. ordered from greatest to
359 smallest), arranges them into the lexicographically least
360 permutation (i.e. ordered from smallest to largest) and
362 COMPARE with auxiliary data AUX is used to compare nodes. */
364 ll_next_permutation (struct ll *r0, struct ll *r1,
365 ll_compare_func *compare, void *aux)
369 struct ll *i = ll_prev (r1);
373 if (compare (i, ll_next (i), aux) < 0)
376 for (j = ll_prev (r1); compare (i, j, aux) >= 0; j = ll_prev (j))
379 ll_reverse (ll_next (j), r1);
390 /* Arranges R0...R1 into the lexicographically next lesser
391 permutation. Returns true if successful.
392 If R0...R1 is already the lexicographically least
393 permutation of its elements (i.e. ordered from smallest to
394 greatest), arranges them into the lexicographically greatest
395 permutation (i.e. ordered from largest to smallest) and
397 COMPARE with auxiliary data AUX is used to compare nodes. */
399 ll_prev_permutation (struct ll *r0, struct ll *r1,
400 ll_compare_func *compare, void *aux)
404 struct ll *i = ll_prev (r1);
408 if (compare (i, ll_next (i), aux) > 0)
411 for (j = ll_prev (r1); compare (i, j, aux) <= 0; j = ll_prev (j))
414 ll_reverse (ll_next (j), r1);
425 /* Sorts R0...R1 into ascending order
426 according to COMPARE given auxiliary data AUX.
427 In use, keep in mind that R0 may move during the sort, so that
428 afterward R0...R1 may denote a different range.
429 (On the other hand, R1 is fixed in place.)
430 The sort is stable; that is, it will not change the relative
431 order of nodes that compare equal.
432 Runs in O(n lg n) time in the number of nodes in the range. */
434 ll_sort (struct ll *r0, struct ll *r1, ll_compare_func *compare, void *aux)
437 size_t output_run_cnt;
439 if (r0 == r1 || ll_next (r0) == r1)
442 pre_r0 = ll_prev (r0);
445 struct ll *a0 = ll_next (pre_r0);
446 for (output_run_cnt = 1; ; output_run_cnt++)
448 struct ll *a1 = ll_find_run (a0, r1, compare, aux);
449 struct ll *a2 = ll_find_run (a1, r1, compare, aux);
453 a0 = ll_merge (a0, a1, a1, a2, compare, aux);
456 while (output_run_cnt > 1);
459 /* Finds the extent of a run of nodes of increasing value
460 starting at R0 and extending no farther than R1.
461 Returns the first node in R0...R1 that is less than the
462 preceding node, or R1 if R0...R1 are arranged in nondecreasing
465 ll_find_run (const struct ll *r0, const struct ll *r1,
466 ll_compare_func *compare, void *aux)
474 while (r0 != r1 && compare (ll_prev (r0), r0, aux) <= 0);
477 return CONST_CAST (struct ll *, r0);
480 /* Merges B0...B1 into A0...A1 according to COMPARE given
482 The ranges may be in the same list or different lists, but
484 Returns the end of the merged range.
485 The merge is "stable" if A0...A1 is considered to precede
486 B0...B1, regardless of their actual ordering.
487 Runs in O(n) time in the total number of nodes in the ranges. */
489 ll_merge (struct ll *a0, struct ll *a1, struct ll *b0, struct ll *b1,
490 ll_compare_func *compare, void *aux)
492 if (a0 != a1 && b0 != b1)
497 if (compare (a0, b0, aux) <= 0)
501 ll_splice (ll_next (a0), b0, ll_next (b1));
516 ll_splice (a0, b0, ll_next (b0));
523 ll_splice (a0, b0, b1);
528 /* Returns true if R0...R1 is sorted in ascending order according
529 to COMPARE given auxiliary data AUX, false otherwise. */
531 ll_is_sorted (const struct ll *r0, const struct ll *r1,
532 ll_compare_func *compare, void *aux)
534 return ll_find_run (r0, r1, compare, aux) == r1;
537 /* Removes all but the first in each group of sequential
538 duplicates in R0...R1. Duplicates are determined using
539 COMPARE given auxiliary data AUX. Removed duplicates are
540 inserted before DUPS if it is nonnull; otherwise, their
542 Only sequential duplicates are removed. ll_sort() may be used
543 to bring duplicates together, or ll_sort_unique() can do both
546 ll_unique (struct ll *r0, struct ll *r1, struct ll *dups,
547 ll_compare_func *compare, void *aux)
556 struct ll *y = ll_next (x);
563 if (compare (x, y, aux) == 0)
580 /* Sorts R0...R1 and removes duplicates.
581 Removed duplicates are inserted before DUPS if it is nonnull;
582 otherwise, their identities are lost.
583 Comparisons are made with COMPARE given auxiliary data AUX.
584 In use, keep in mind that R0 may move during the sort, so that
585 afterward R0...R1 may denote a different range.
586 (On the other hand, R1 is fixed in place.)
587 Runs in O(n lg n) time in the number of nodes in the range. */
589 ll_sort_unique (struct ll *r0, struct ll *r1, struct ll *dups,
590 ll_compare_func *compare, void *aux)
592 struct ll *pre_r0 = ll_prev (r0);
593 ll_sort (r0, r1, compare, aux);
594 ll_unique (ll_next (pre_r0), r1, dups, compare, aux);
597 /* Inserts NEW_ELEM in the proper position in R0...R1, which must
598 be sorted according to COMPARE given auxiliary data AUX.
599 If NEW_ELEM is equal to one or more existing nodes in R0...R1,
600 then it is inserted after the existing nodes it equals.
601 Runs in O(n) time in the number of nodes in the range. */
603 ll_insert_ordered (struct ll *r0, struct ll *r1, struct ll *new_elem,
604 ll_compare_func *compare, void *aux)
608 for (x = r0; x != r1; x = ll_next (x))
609 if (compare (x, new_elem, aux) > 0)
611 ll_insert (x, new_elem);
614 /* Partitions R0...R1 into those nodes for which PREDICATE given
615 auxiliary data AUX returns true, followed by those for which
616 PREDICATE returns false.
617 Returns the first node in the "false" group, or R1 if
618 PREDICATE is true for every node in R0...R1.
619 The partition is "stable" in that the nodes in each group
620 retain their original relative order.
621 Runs in O(n) time in the number of nodes in the range. */
623 ll_partition (struct ll *r0, struct ll *r1,
624 ll_predicate_func *predicate, void *aux)
632 else if (!predicate (r0, aux))
638 for (t0 = r0;; t0 = t1)
646 while (!predicate (t0, aux));
654 ll_splice (r0, t0, t1);
658 while (predicate (t1, aux));
660 ll_splice (r0, t0, t1);
664 /* Verifies that R0...R1 is parititioned into a sequence of nodes
665 for which PREDICATE given auxiliary data AUX returns true,
666 followed by those for which PREDICATE returns false.
667 Returns a null pointer if R0...R1 is not partitioned this way.
668 Otherwise, returns the first node in the "false" group, or R1
669 if PREDICATE is true for every node in R0...R1. */
671 ll_find_partition (const struct ll *r0, const struct ll *r1,
672 ll_predicate_func *predicate, void *aux)
674 const struct ll *partition, *x;
676 for (partition = r0; partition != r1; partition = ll_next (partition))
677 if (!predicate (partition, aux))
680 for (x = partition; x != r1; x = ll_next (x))
681 if (predicate (x, aux))
684 return CONST_CAST (struct ll *, partition);