1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2006, 2009, 2011 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"
35 /* Returns the number of nodes in LIST (not counting the null
36 node). Executes in O(n) time in the length of the list. */
38 ll_count (const struct ll_list *list)
40 return ll_count_range (ll_head (list), ll_null (list));
43 /* Removes R0...R1 from their current list
44 and inserts them just before BEFORE. */
46 ll_splice (struct ll *before, struct ll *r0, struct ll *r1)
48 if (before != r0 && r0 != r1)
50 /* Change exclusive range to inclusive. */
53 /* Remove R0...R1 from its list. */
54 r0->prev->next = r1->next;
55 r1->next->prev = r0->prev;
57 /* Insert R0...R1 before BEFORE. */
58 r0->prev = before->prev;
60 before->prev->next = r0;
65 /* Exchanges the positions of A and B,
66 which may be in the same list or different lists. */
68 ll_swap (struct ll *a, struct ll *b)
74 struct ll *a_next = ll_remove (a);
75 struct ll *b_next = ll_remove (b);
76 ll_insert (b_next, a);
77 ll_insert (a_next, b);
87 /* Exchanges the positions of A0...A1 and B0...B1,
88 which may be in the same list or different lists but must not
91 ll_swap_range (struct ll *a0, struct ll *a1, struct ll *b0, struct ll *b1)
93 if (a0 == a1 || a1 == b0)
94 ll_splice (a0, b0, b1);
95 else if (b0 == b1 || b1 == a0)
96 ll_splice (b0, a0, a1);
99 struct ll *x0 = ll_prev (a0), *x1 = a1;
100 struct ll *y0 = ll_prev (b0), *y1 = b1;
114 /* Removes from R0...R1 all the nodes that equal TARGET
115 according to COMPARE given auxiliary data AUX.
116 Returns the number of nodes removed. */
118 ll_remove_equal (struct ll *r0, struct ll *r1, struct ll *target,
119 ll_compare_func *compare, void *aux)
125 for (x = r0; x != r1; )
126 if (compare (x, target, aux) == 0)
137 /* Removes from R0...R1 all the nodes for which PREDICATE returns
138 true given auxiliary data AUX.
139 Returns the number of nodes removed. */
141 ll_remove_if (struct ll *r0, struct ll *r1,
142 ll_predicate_func *predicate, void *aux)
148 for (x = r0; x != r1; )
149 if (predicate (x, aux))
160 /* Returns the first node in R0...R1 that equals TARGET
161 according to COMPARE given auxiliary data AUX.
162 Returns R1 if no node in R0...R1 equals TARGET. */
164 ll_find_equal (const struct ll *r0, const struct ll *r1,
165 const struct ll *target,
166 ll_compare_func *compare, void *aux)
170 for (x = r0; x != r1; x = ll_next (x))
171 if (compare (x, target, aux) == 0)
173 return CONST_CAST (struct ll *, x);
176 /* Returns the first node in R0...R1 for which PREDICATE returns
177 true given auxiliary data AUX.
178 Returns R1 if PREDICATE does not return true for any node in
181 ll_find_if (const struct ll *r0, const struct ll *r1,
182 ll_predicate_func *predicate, void *aux)
186 for (x = r0; x != r1; x = ll_next (x))
187 if (predicate (x, aux))
189 return CONST_CAST (struct ll *, x);
192 /* Compares each pair of adjacent nodes in R0...R1
193 using COMPARE with auxiliary data AUX
194 and returns the first node of the first pair that compares
196 Returns R1 if no pair compares equal. */
198 ll_find_adjacent_equal (const struct ll *r0, const struct ll *r1,
199 ll_compare_func *compare, void *aux)
203 const struct ll *x, *y;
205 for (x = r0, y = ll_next (x); y != r1; x = y, y = ll_next (y))
206 if (compare (x, y, aux) == 0)
207 return CONST_CAST (struct ll *, x);
210 return CONST_CAST (struct ll *, r1);
213 /* Returns the number of nodes in R0...R1.
214 Executes in O(n) time in the return value. */
216 ll_count_range (const struct ll *r0, const struct ll *r1)
222 for (x = r0; x != r1; x = ll_next (x))
227 /* Counts and returns the number of nodes in R0...R1 that equal
228 TARGET according to COMPARE given auxiliary data AUX. */
230 ll_count_equal (const struct ll *r0, const struct ll *r1,
231 const struct ll *target,
232 ll_compare_func *compare, void *aux)
238 for (x = r0; x != r1; x = ll_next (x))
239 if (compare (x, target, aux) == 0)
244 /* Counts and returns the number of nodes in R0...R1 for which
245 PREDICATE returns true given auxiliary data AUX. */
247 ll_count_if (const struct ll *r0, const struct ll *r1,
248 ll_predicate_func *predicate, void *aux)
254 for (x = r0; x != r1; x = ll_next (x))
255 if (predicate (x, aux))
260 /* Returns the greatest node in R0...R1 according to COMPARE
261 given auxiliary data AUX.
262 Returns the first of multiple, equal maxima. */
264 ll_max (const struct ll *r0, const struct ll *r1,
265 ll_compare_func *compare, void *aux)
267 const struct ll *max = r0;
272 for (x = ll_next (r0); x != r1; x = ll_next (x))
273 if (compare (x, max, aux) > 0)
276 return CONST_CAST (struct ll *, max);
279 /* Returns the least node in R0...R1 according to COMPARE given
281 Returns the first of multiple, equal minima. */
283 ll_min (const struct ll *r0, const struct ll *r1,
284 ll_compare_func *compare, void *aux)
286 const struct ll *min = r0;
291 for (x = ll_next (r0); x != r1; x = ll_next (x))
292 if (compare (x, min, aux) < 0)
295 return CONST_CAST (struct ll *, min);
298 /* Lexicographically compares A0...A1 to B0...B1.
299 Returns negative if A0...A1 < B0...B1,
300 zero if A0...A1 == B0...B1, and
301 positive if A0...A1 > B0...B1
302 according to COMPARE given auxiliary data AUX. */
304 ll_lexicographical_compare_3way (const struct ll *a0, const struct ll *a1,
305 const struct ll *b0, const struct ll *b1,
306 ll_compare_func *compare, void *aux)
315 int cmp = compare (a0, b0, aux);
324 /* Calls ACTION with auxiliary data AUX
325 for every node in R0...R1 in order. */
327 ll_apply (struct ll *r0, struct ll *r1, ll_action_func *action, void *aux)
331 for (ll = r0; ll != r1; ll = ll_next (ll))
335 /* Reverses the order of nodes R0...R1. */
337 ll_reverse (struct ll *r0, struct ll *r1)
339 if (r0 != r1 && ll_next (r0) != r1)
343 for (ll = r0; ll != r1; ll = ll->prev)
345 struct ll *tmp = ll->next;
349 r0->next->next = r1->prev;
350 r1->prev->prev = r0->next;
356 /* Arranges R0...R1 into the lexicographically next greater
357 permutation. Returns true if successful.
358 If R0...R1 is already the lexicographically greatest
359 permutation of its elements (i.e. ordered from greatest to
360 smallest), arranges them into the lexicographically least
361 permutation (i.e. ordered from smallest to largest) and
363 COMPARE with auxiliary data AUX is used to compare nodes. */
365 ll_next_permutation (struct ll *r0, struct ll *r1,
366 ll_compare_func *compare, void *aux)
370 struct ll *i = ll_prev (r1);
374 if (compare (i, ll_next (i), aux) < 0)
377 for (j = ll_prev (r1); compare (i, j, aux) >= 0; j = ll_prev (j))
380 ll_reverse (ll_next (j), r1);
391 /* Arranges R0...R1 into the lexicographically next lesser
392 permutation. Returns true if successful.
393 If R0...R1 is already the lexicographically least
394 permutation of its elements (i.e. ordered from smallest to
395 greatest), arranges them into the lexicographically greatest
396 permutation (i.e. ordered from largest to smallest) and
398 COMPARE with auxiliary data AUX is used to compare nodes. */
400 ll_prev_permutation (struct ll *r0, struct ll *r1,
401 ll_compare_func *compare, void *aux)
405 struct ll *i = ll_prev (r1);
409 if (compare (i, ll_next (i), aux) > 0)
412 for (j = ll_prev (r1); compare (i, j, aux) <= 0; j = ll_prev (j))
415 ll_reverse (ll_next (j), r1);
426 /* Sorts R0...R1 into ascending order
427 according to COMPARE given auxiliary data AUX.
428 In use, keep in mind that R0 may move during the sort, so that
429 afterward R0...R1 may denote a different range.
430 (On the other hand, R1 is fixed in place.)
431 The sort is stable; that is, it will not change the relative
432 order of nodes that compare equal.
433 Runs in O(n lg n) time in the number of nodes in the range. */
435 ll_sort (struct ll *r0, struct ll *r1, ll_compare_func *compare, void *aux)
438 size_t output_run_cnt;
440 if (r0 == r1 || ll_next (r0) == r1)
443 pre_r0 = ll_prev (r0);
446 struct ll *a0 = ll_next (pre_r0);
447 for (output_run_cnt = 1; ; output_run_cnt++)
449 struct ll *a1 = ll_find_run (a0, r1, compare, aux);
450 struct ll *a2 = ll_find_run (a1, r1, compare, aux);
454 a0 = ll_merge (a0, a1, a1, a2, compare, aux);
457 while (output_run_cnt > 1);
460 /* Finds the extent of a run of nodes of increasing value
461 starting at R0 and extending no farther than R1.
462 Returns the first node in R0...R1 that is less than the
463 preceding node, or R1 if R0...R1 are arranged in nondecreasing
466 ll_find_run (const struct ll *r0, const struct ll *r1,
467 ll_compare_func *compare, void *aux)
475 while (r0 != r1 && compare (ll_prev (r0), r0, aux) <= 0);
478 return CONST_CAST (struct ll *, r0);
481 /* Merges B0...B1 into A0...A1 according to COMPARE given
483 The ranges may be in the same list or different lists, but
485 Returns the end of the merged range.
486 The merge is "stable" if A0...A1 is considered to precede
487 B0...B1, regardless of their actual ordering.
488 Runs in O(n) time in the total number of nodes in the ranges. */
490 ll_merge (struct ll *a0, struct ll *a1, struct ll *b0, struct ll *b1,
491 ll_compare_func *compare, void *aux)
493 if (a0 != a1 && b0 != b1)
498 if (compare (a0, b0, aux) <= 0)
502 ll_splice (ll_next (a0), b0, ll_next (b1));
517 ll_splice (a0, b0, ll_next (b0));
524 ll_splice (a0, b0, b1);
529 /* Returns true if R0...R1 is sorted in ascending order according
530 to COMPARE given auxiliary data AUX, false otherwise. */
532 ll_is_sorted (const struct ll *r0, const struct ll *r1,
533 ll_compare_func *compare, void *aux)
535 return ll_find_run (r0, r1, compare, aux) == r1;
538 /* Removes all but the first in each group of sequential
539 duplicates in R0...R1. Duplicates are determined using
540 COMPARE given auxiliary data AUX. Removed duplicates are
541 inserted before DUPS if it is nonnull; otherwise, their
543 Only sequential duplicates are removed. ll_sort() may be used
544 to bring duplicates together, or ll_sort_unique() can do both
547 ll_unique (struct ll *r0, struct ll *r1, struct ll *dups,
548 ll_compare_func *compare, void *aux)
557 struct ll *y = ll_next (x);
564 if (compare (x, y, aux) == 0)
581 /* Sorts R0...R1 and removes duplicates.
582 Removed duplicates are inserted before DUPS if it is nonnull;
583 otherwise, their identities are lost.
584 Comparisons are made with COMPARE given auxiliary data AUX.
585 In use, keep in mind that R0 may move during the sort, so that
586 afterward R0...R1 may denote a different range.
587 (On the other hand, R1 is fixed in place.)
588 Runs in O(n lg n) time in the number of nodes in the range. */
590 ll_sort_unique (struct ll *r0, struct ll *r1, struct ll *dups,
591 ll_compare_func *compare, void *aux)
593 struct ll *pre_r0 = ll_prev (r0);
594 ll_sort (r0, r1, compare, aux);
595 ll_unique (ll_next (pre_r0), r1, dups, compare, aux);
598 /* Inserts NEW_ELEM in the proper position in R0...R1, which must
599 be sorted according to COMPARE given auxiliary data AUX.
600 If NEW_ELEM is equal to one or more existing nodes in R0...R1,
601 then it is inserted after the existing nodes it equals.
602 Runs in O(n) time in the number of nodes in the range. */
604 ll_insert_ordered (struct ll *r0, struct ll *r1, struct ll *new_elem,
605 ll_compare_func *compare, void *aux)
609 for (x = r0; x != r1; x = ll_next (x))
610 if (compare (x, new_elem, aux) > 0)
612 ll_insert (x, new_elem);
615 /* Partitions R0...R1 into those nodes for which PREDICATE given
616 auxiliary data AUX returns true, followed by those for which
617 PREDICATE returns false.
618 Returns the first node in the "false" group, or R1 if
619 PREDICATE is true for every node in R0...R1.
620 The partition is "stable" in that the nodes in each group
621 retain their original relative order.
622 Runs in O(n) time in the number of nodes in the range. */
624 ll_partition (struct ll *r0, struct ll *r1,
625 ll_predicate_func *predicate, void *aux)
633 else if (!predicate (r0, aux))
639 for (t0 = r0;; t0 = t1)
647 while (!predicate (t0, aux));
655 ll_splice (r0, t0, t1);
659 while (predicate (t1, aux));
661 ll_splice (r0, t0, t1);
665 /* Verifies that R0...R1 is parititioned into a sequence of nodes
666 for which PREDICATE given auxiliary data AUX returns true,
667 followed by those for which PREDICATE returns false.
668 Returns a null pointer if R0...R1 is not partitioned this way.
669 Otherwise, returns the first node in the "false" group, or R1
670 if PREDICATE is true for every node in R0...R1. */
672 ll_find_partition (const struct ll *r0, const struct ll *r1,
673 ll_predicate_func *predicate, void *aux)
675 const struct ll *partition, *x;
677 for (partition = r0; partition != r1; partition = ll_next (partition))
678 if (!predicate (partition, aux))
681 for (x = partition; x != r1; x = ll_next (x))
682 if (predicate (x, aux))
685 return CONST_CAST (struct ll *, partition);