1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 1997-9, 2000, 2010, 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 /* Copyright (C) 2001 Free Software Foundation, Inc.
19 This file is part of the GNU ISO C++ Library. This library is free
20 software; you can redistribute it and/or modify it under the
21 terms of the GNU General Public License as published by the
22 Free Software Foundation; either version 2, or (at your option)
25 This library is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 GNU General Public License for more details.
30 You should have received a copy of the GNU General Public License
31 along with this program. If not, see <http://www.gnu.org/licenses/>.
33 As a special exception, you may use this file as part of a free software
34 library without restriction. Specifically, if other files instantiate
35 templates or use macros or inline functions from this file, or you compile
36 this file and link it with other files to produce an executable, this
37 file does not by itself cause the resulting executable to be covered by
38 the GNU General Public License. This exception does not however
39 invalidate any other reasons why the executable file might be covered by
40 the GNU General Public License. */
45 * Hewlett-Packard Company
47 * Permission to use, copy, modify, distribute and sell this software
48 * and its documentation for any purpose is hereby granted without fee,
49 * provided that the above copyright notice appear in all copies and
50 * that both that copyright notice and this permission notice appear
51 * in supporting documentation. Hewlett-Packard Company makes no
52 * representations about the suitability of this software for any
53 * purpose. It is provided "as is" without express or implied warranty.
57 * Silicon Graphics Computer Systems, Inc.
59 * Permission to use, copy, modify, distribute and sell this software
60 * and its documentation for any purpose is hereby granted without fee,
61 * provided that the above copyright notice appear in all copies and
62 * that both that copyright notice and this permission notice appear
63 * in supporting documentation. Silicon Graphics makes no
64 * representations about the suitability of this software for any
65 * purpose. It is provided "as is" without express or implied warranty.
68 /* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc.
69 This file is part of the GNU C Library.
70 Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
72 The GNU C Library is free software; you can redistribute it and/or
73 modify it under the terms of the GNU Lesser General Public
74 License as published by the Free Software Foundation; either
75 version 2.1 of the License, or (at your option) any later version.
77 The GNU C Library is distributed in the hope that it will be useful,
78 but WITHOUT ANY WARRANTY; without even the implied warranty of
79 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
80 Lesser General Public License for more details.
82 You should have received a copy of the GNU Lesser General Public
83 License along with the GNU C Library. If not, see
84 <http://www.gnu.org/licenses/>. */
94 #include "libpspp/assertion.h"
96 #include "gl/xalloc.h"
97 #include "gl/minmax.h"
99 /* Finds an element in ARRAY, which contains COUNT elements of
100 SIZE bytes each, using COMPARE for comparisons. Returns the
101 first element in ARRAY that matches TARGET, or a null pointer
102 on failure. AUX is passed to each comparison as auxiliary
105 find (const void *array, size_t count, size_t size,
107 algo_compare_func *compare, const void *aux)
109 const char *element = array;
113 if (compare (target, element, aux) == 0)
114 return (void *) element;
122 /* Counts and return the number of elements in ARRAY, which
123 contains COUNT elements of SIZE bytes each, which are equal to
124 ELEMENT as compared with COMPARE. AUX is passed as auxiliary
127 count_equal (const void *array, size_t count, size_t size,
129 algo_compare_func *compare, const void *aux)
131 const char *first = array;
132 size_t equal_cnt = 0;
136 if (compare (element, first, aux) == 0)
145 /* Counts and return the number of elements in ARRAY, which
146 contains COUNT elements of SIZE bytes each, for which
147 PREDICATE returns true. AUX is passed as auxiliary data to
150 count_if (const void *array, size_t count, size_t size,
151 algo_predicate_func *predicate, const void *aux)
153 const char *first = array;
158 if (predicate (first, aux) != 0)
167 /* Byte-wise swap objects A and B, each SIZE bytes. */
169 swap (void *a_, void *b_, size_t size)
181 /* Makes the elements in ARRAY unique, by moving up duplicates,
182 and returns the new number of elements in the array. Sorted
183 arrays only. Arguments same as for sort() above. */
185 unique (void *array, size_t count, size_t size,
186 algo_compare_func *compare, const void *aux)
189 char *last = first + size * count;
190 char *result = array;
197 assert (adjacent_find_equal (array, count,
198 size, compare, aux) == NULL);
202 if (compare (result, first, aux))
206 memcpy (result, first, size);
213 /* Helper function that calls sort(), then unique(). */
215 sort_unique (void *array, size_t count, size_t size,
216 algo_compare_func *compare, const void *aux)
218 sort (array, count, size, compare, aux);
219 return unique (array, count, size, compare, aux);
222 /* Reorders ARRAY, which contains COUNT elements of SIZE bytes
223 each, so that the elements for which PREDICATE returns true
224 precede those for which PREDICATE returns zero. AUX is
225 passed to each predicate as auxiliary data. Returns the
226 number of elements for which PREDICATE returns true. Not
229 partition (void *array, size_t count, size_t size,
230 algo_predicate_func *predicate, const void *aux)
232 size_t true_cnt = count;
234 char *last = first + true_cnt * size;
238 /* Move FIRST forward to point to first element that fails
244 else if (!predicate (first, aux))
251 /* Move LAST backward to point to last element that passes
259 else if (predicate (last, aux))
265 /* By swapping FIRST and LAST we extend the starting and
266 ending sequences that pass and fail, respectively,
268 swap (first, last, size);
273 assert (is_partitioned (array, count, size, true_cnt, predicate, aux));
277 /* Checks whether ARRAY, which contains COUNT elements of SIZE
278 bytes each, is partitioned such that PREDICATE returns true
279 for the first TRUE_CNT elements and zero for the remaining
280 elements. AUX is passed as auxiliary data to PREDICATE. */
282 is_partitioned (const void *array, size_t count, size_t size,
284 algo_predicate_func *predicate, const void *aux)
286 const char *first = array;
289 assert (true_cnt <= count);
290 for (idx = 0; idx < true_cnt; idx++)
291 if (predicate (first + idx * size, aux) == 0)
293 for (idx = true_cnt; idx < count; idx++)
294 if (predicate (first + idx * size, aux) != 0)
299 /* Copies the COUNT elements of SIZE bytes each from ARRAY to
300 RESULT, except that elements for which PREDICATE is false are
301 not copied. Returns the number of elements copied. AUX is
302 passed to PREDICATE as auxiliary data. */
304 copy_if (const void *array, size_t count, size_t size,
306 algo_predicate_func *predicate, const void *aux)
308 const char *input = array;
309 const char *last = input + size * count;
310 char *output = result;
311 size_t nonzero_cnt = 0;
315 if (predicate (input, aux))
317 memcpy (output, input, size);
325 assert (nonzero_cnt == count_if (array, count, size, predicate, aux));
326 assert (nonzero_cnt == count_if (result, nonzero_cnt, size, predicate, aux));
331 /* Removes N elements starting at IDX from ARRAY, which consists
332 of COUNT elements of SIZE bytes each, by shifting the elements
333 following them, if any, into its position. */
335 remove_range (void *array_, size_t count, size_t size,
336 size_t idx, size_t n)
338 char *array = array_;
340 assert (array != NULL);
341 assert (idx <= count);
342 assert (idx + n <= count);
345 memmove (array + idx * size, array + (idx + n) * size,
346 size * (count - idx - n));
349 /* Removes element IDX from ARRAY, which consists of COUNT
350 elements of SIZE bytes each, by shifting the elements
351 following it, if any, into its position. */
353 remove_element (void *array, size_t count, size_t size,
356 remove_range (array, count, size, idx, 1);
359 /* Makes room for N elements starting at IDX in ARRAY, which
360 initially consists of COUNT elements of SIZE bytes each, by
361 shifting elements IDX...COUNT (exclusive) to the right by N
364 insert_range (void *array_, size_t count, size_t size,
365 size_t idx, size_t n)
367 char *array = array_;
369 assert (idx <= count);
370 memmove (array + (idx + n) * size, array + idx * size, (count - idx) * size);
373 /* Makes room for a new element at IDX in ARRAY, which initially
374 consists of COUNT elements of SIZE bytes each, by shifting
375 elements IDX...COUNT (exclusive) to the right by one
378 insert_element (void *array, size_t count, size_t size,
381 insert_range (array, count, size, idx, 1);
384 /* Moves an element in ARRAY, which consists of COUNT elements of
385 SIZE bytes each, from OLD_IDX to NEW_IDX, shifting around
386 other elements as needed. Runs in O(abs(OLD_IDX - NEW_IDX))
389 move_element (void *array_, size_t count, size_t size,
390 size_t old_idx, size_t new_idx)
392 assert (array_ != NULL || count == 0);
393 assert (old_idx < count);
394 assert (new_idx < count);
396 if (old_idx != new_idx)
398 char *array = array_;
399 char *element = xmalloc (size);
400 char *new = array + new_idx * size;
401 char *old = array + old_idx * size;
403 memcpy (element, old, size);
405 memmove (new + size, new, (old_idx - new_idx) * size);
407 memmove (old, old + size, (new_idx - old_idx) * size);
408 memcpy (new, element, size);
414 /* Moves N elements in ARRAY starting at OLD_IDX, which consists
415 of COUNT elements of SIZE bytes each, so that they now start
416 at NEW_IDX, shifting around other elements as needed. */
418 move_range (void *array_, size_t count, size_t size,
419 size_t old_idx, size_t new_idx, size_t n)
421 assert (array_ != NULL || count == 0);
423 assert (old_idx + n <= count);
424 assert (new_idx + n <= count);
426 if (old_idx != new_idx && n > 0)
428 char *array = array_;
429 char *range = xmalloc (size * n);
430 char *new = array + new_idx * size;
431 char *old = array + old_idx * size;
433 memcpy (range, old, size * n);
435 memmove (new + size * n, new, (old_idx - new_idx) * size);
437 memmove (old, old + size * n, (new_idx - old_idx) * size);
438 memcpy (new, range, size * n);
444 /* A predicate and its auxiliary data. */
447 algo_predicate_func *predicate;
452 not (const void *data, const void *pred_aux_)
454 const struct pred_aux *pred_aux = pred_aux_;
456 return !pred_aux->predicate (data, pred_aux->aux);
459 /* Removes elements equal to ELEMENT from ARRAY, which consists
460 of COUNT elements of SIZE bytes each. Returns the number of
461 remaining elements. AUX is passed to COMPARE as auxiliary
464 remove_equal (void *array, size_t count, size_t size,
466 algo_compare_func *compare, const void *aux)
469 char *last = first + count * size;
476 if (compare (first, element, aux) == 0)
490 if (compare (first, element, aux) == 0)
496 memcpy (result, first, size);
501 assert (count_equal (array, count, size, element, compare, aux) == 0);
505 /* Copies the COUNT elements of SIZE bytes each from ARRAY to
506 RESULT, except that elements for which PREDICATE is true are
507 not copied. Returns the number of elements copied. AUX is
508 passed to PREDICATE as auxiliary data. */
510 remove_copy_if (const void *array, size_t count, size_t size,
512 algo_predicate_func *predicate, const void *aux)
514 struct pred_aux pred_aux;
515 pred_aux.predicate = predicate;
517 return copy_if (array, count, size, result, not, &pred_aux);
520 /* Searches ARRAY, which contains COUNT of SIZE bytes each, using
521 a binary search. Returns any element that equals VALUE, if
522 one exists, or a null pointer otherwise. ARRAY must ordered
523 according to COMPARE. AUX is passed to COMPARE as auxiliary
526 binary_search (const void *array, size_t count, size_t size,
528 algo_compare_func *compare, const void *aux)
530 assert (array != NULL || count == 0);
531 assert (count <= INT_MAX);
532 assert (compare != NULL);
536 const char *first = array;
538 int high = count - 1;
542 int middle = (low + high) / 2;
543 const char *element = first + middle * size;
544 int cmp = compare (value, element, aux);
551 return (void *) element;
555 expensive_assert (find (array, count, size, value, compare, aux) == NULL);
559 /* Lexicographically compares ARRAY1, which contains COUNT1
560 elements of SIZE bytes each, to ARRAY2, which contains COUNT2
561 elements of SIZE bytes, according to COMPARE. Returns a
562 strcmp()-type result. AUX is passed to COMPARE as auxiliary
565 lexicographical_compare_3way (const void *array1, size_t count1,
566 const void *array2, size_t count2,
568 algo_compare_func *compare, const void *aux)
570 const char *first1 = array1;
571 const char *first2 = array2;
572 size_t min_count = count1 < count2 ? count1 : count2;
574 while (min_count > 0)
576 int cmp = compare (first1, first2, aux);
585 return count1 < count2 ? -1 : count1 > count2;
588 /* If you consider tuning this algorithm, you should consult first:
589 Engineering a sort function; Jon Bentley and M. Douglas McIlroy;
590 Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */
596 /* Discontinue quicksort algorithm when partition gets below this size.
597 This particular magic number was chosen to work best on a Sun 4/260. */
600 /* Stack node declarations used to store unfulfilled partition obligations. */
607 /* The next 4 #defines implement a very fast in-line stack abstraction. */
608 /* The stack needs log (total_elements) entries (we could even subtract
609 log(MAX_THRESH)). Since total_elements has type size_t, we get as
610 upper bound for log (total_elements):
611 bits per byte (CHAR_BIT) * sizeof(size_t). */
612 #define STACK_SIZE (CHAR_BIT * sizeof(size_t))
613 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
614 #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
615 #define STACK_NOT_EMPTY (stack < top)
618 /* Order size using quicksort. This implementation incorporates
619 four optimizations discussed in Sedgewick:
621 1. Non-recursive, using an explicit stack of pointer that store the
622 next array partition to sort. To save time, this maximum amount
623 of space required to store an array of SIZE_MAX is allocated on the
624 stack. Assuming a 32-bit (64 bit) integer for size_t, this needs
625 only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).
626 Pretty cheap, actually.
628 2. Chose the pivot element using a median-of-three decision tree.
629 This reduces the probability of selecting a bad pivot value and
630 eliminates certain extraneous comparisons.
632 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
633 insertion sort to order the MAX_THRESH items within each partition.
634 This is a big win, since insertion sort is faster for small, mostly
635 sorted array segments.
637 4. The larger of the two sub-partitions is always pushed onto the
638 stack first, with the algorithm then concentrating on the
639 smaller partition. This *guarantees* no more than log (total_elems)
640 stack size is needed (actually O(1) in this case)! */
643 sort (void *array, size_t count, size_t size,
644 algo_compare_func *compare, const void *aux)
646 char *const first = array;
647 const size_t max_thresh = MAX_THRESH * size;
650 /* Avoid lossage with unsigned arithmetic below. */
653 if (count > MAX_THRESH)
656 char *hi = &lo[size * (count - 1)];
657 stack_node stack[STACK_SIZE];
658 stack_node *top = stack + 1;
660 while (STACK_NOT_EMPTY)
665 /* Select median value from among LO, MID, and HI. Rearrange
666 LO and HI so the three values are sorted. This lowers the
667 probability of picking a pathological pivot value and
668 skips a comparison for both the LEFT_PTR and RIGHT_PTR in
671 char *mid = lo + size * ((hi - lo) / size >> 1);
673 if (compare (mid, lo, aux) < 0)
674 swap (mid, lo, size);
675 if (compare (hi, mid, aux) < 0)
676 swap (mid, hi, size);
679 if (compare (mid, lo, aux) < 0)
680 swap (mid, lo, size);
683 left_ptr = lo + size;
684 right_ptr = hi - size;
686 /* Here's the famous ``collapse the walls'' section of quicksort.
687 Gotta like those tight inner loops! They are the main reason
688 that this algorithm runs much faster than others. */
691 while (compare (left_ptr, mid, aux) < 0)
694 while (compare (mid, right_ptr, aux) < 0)
697 if (left_ptr < right_ptr)
699 swap (left_ptr, right_ptr, size);
702 else if (mid == right_ptr)
707 else if (left_ptr == right_ptr)
714 while (left_ptr <= right_ptr);
716 /* Set up pointers for next iteration. First determine whether
717 left and right partitions are below the threshold size. If so,
718 ignore one or both. Otherwise, push the larger partition's
719 bounds on the stack and continue sorting the smaller one. */
721 if ((size_t) (right_ptr - lo) <= max_thresh)
723 if ((size_t) (hi - left_ptr) <= max_thresh)
724 /* Ignore both small partitions. */
727 /* Ignore small left partition. */
730 else if ((size_t) (hi - left_ptr) <= max_thresh)
731 /* Ignore small right partition. */
733 else if ((right_ptr - lo) > (hi - left_ptr))
735 /* Push larger left partition indices. */
736 PUSH (lo, right_ptr);
741 /* Push larger right partition indices. */
748 /* Once the FIRST array is partially sorted by quicksort the rest
749 is completely sorted using insertion sort, since this is efficient
750 for partitions below MAX_THRESH size. FIRST points to the beginning
751 of the array to sort, and END_PTR points at the very last element in
752 the array (*not* one beyond it!). */
755 char *const end_ptr = &first[size * (count - 1)];
756 char *tmp_ptr = first;
757 char *thresh = MIN (end_ptr, first + max_thresh);
758 register char *run_ptr;
760 /* Find smallest element in first threshold and place it at the
761 array's beginning. This is the smallest array element,
762 and the operation speeds up insertion sort's inner loop. */
764 for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
765 if (compare (run_ptr, tmp_ptr, aux) < 0)
768 if (tmp_ptr != first)
769 swap (tmp_ptr, first, size);
771 /* Insertion sort, running from left-hand-side up to right-hand-side. */
773 run_ptr = first + size;
774 while ((run_ptr += size) <= end_ptr)
776 tmp_ptr = run_ptr - size;
777 while (compare (run_ptr, tmp_ptr, aux) < 0)
781 if (tmp_ptr != run_ptr)
785 trav = run_ptr + size;
786 while (--trav >= run_ptr)
791 for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
799 assert (is_sorted (array, count, size, compare, aux));
802 /* Tests whether ARRAY, which contains COUNT elements of SIZE
803 bytes each, is sorted in order according to COMPARE. AUX is
804 passed to COMPARE as auxiliary data. */
806 is_sorted (const void *array, size_t count, size_t size,
807 algo_compare_func *compare, const void *aux)
809 const char *first = array;
812 for (idx = 0; idx + 1 < count; idx++)
813 if (compare (first + idx * size, first + (idx + 1) * size, aux) > 0)
819 /* Computes the generalized set difference, ARRAY1 minus ARRAY2,
820 into RESULT, and returns the number of elements written to
821 RESULT. If a value appears M times in ARRAY1 and N times in
822 ARRAY2, then it will appear max(M - N, 0) in RESULT. ARRAY1
823 and ARRAY2 must be sorted, and RESULT is sorted and stable.
824 ARRAY1 consists of COUNT1 elements, ARRAY2 of COUNT2 elements,
825 each SIZE bytes. AUX is passed to COMPARE as auxiliary
827 size_t set_difference (const void *array1, size_t count1,
828 const void *array2, size_t count2,
831 algo_compare_func *compare, const void *aux)
833 const char *first1 = array1;
834 const char *last1 = first1 + count1 * size;
835 const char *first2 = array2;
836 const char *last2 = first2 + count2 * size;
837 char *result = result_;
838 size_t result_count = 0;
840 while (first1 != last1 && first2 != last2)
842 int cmp = compare (first1, first2, aux);
845 memcpy (result, first1, size);
859 while (first1 != last1)
861 memcpy (result, first1, size);
870 /* Finds the first pair of adjacent equal elements in ARRAY,
871 which has COUNT elements of SIZE bytes. Returns the first
872 element in ARRAY such that COMPARE returns zero when it and
873 its successor element are compared, or a null pointer if no
874 such element exists. AUX is passed to COMPARE as auxiliary
877 adjacent_find_equal (const void *array, size_t count, size_t size,
878 algo_compare_func *compare, const void *aux)
880 const char *first = array;
881 const char *last = first + count * size;
883 while (first < last && first + size < last)
885 if (compare (first, first + size, aux) == 0)
886 return (void *) first;
893 /* ARRAY contains COUNT elements of SIZE bytes each. Initially
894 the first COUNT - 1 elements of these form a heap, followed by
895 a single element not part of the heap. This function adds the
896 final element, forming a heap of COUNT elements in ARRAY.
897 Uses COMPARE to compare elements, passing AUX as auxiliary
900 push_heap (void *array, size_t count, size_t size,
901 algo_compare_func *compare, const void *aux)
906 expensive_assert (count < 1 || is_heap (array, count - 1,
907 size, compare, aux));
908 for (i = count; i > 1; i /= 2)
910 char *parent = first + (i / 2 - 1) * size;
911 char *element = first + (i - 1) * size;
912 if (compare (parent, element, aux) < 0)
913 swap (parent, element, size);
917 expensive_assert (is_heap (array, count, size, compare, aux));
920 /* ARRAY contains COUNT elements of SIZE bytes each. Initially
921 the children of ARRAY[idx - 1] are heaps, but ARRAY[idx - 1]
922 may be smaller than its children. This function fixes that,
923 so that ARRAY[idx - 1] itself is a heap. Uses COMPARE to
924 compare elements, passing AUX as auxiliary data. */
926 heapify (void *array, size_t count, size_t size,
928 algo_compare_func *compare, const void *aux)
934 size_t left = 2 * idx;
935 size_t right = left + 1;
936 size_t largest = idx;
939 && compare (first + size * (left - 1),
940 first + size * (idx - 1), aux) > 0)
944 && compare (first + size * (right - 1),
945 first + size * (largest - 1), aux) > 0)
951 swap (first + size * (idx - 1), first + size * (largest - 1), size);
956 /* ARRAY contains COUNT elements of SIZE bytes each. Initially
957 all COUNT elements form a heap. This function moves the
958 largest element in the heap to the final position in ARRAY and
959 reforms a heap of the remaining COUNT - 1 elements at the
960 beginning of ARRAY. Uses COMPARE to compare elements, passing
961 AUX as auxiliary data. */
963 pop_heap (void *array, size_t count, size_t size,
964 algo_compare_func *compare, const void *aux)
968 expensive_assert (is_heap (array, count, size, compare, aux));
969 swap (first, first + (count - 1) * size, size);
970 heapify (first, count - 1, size, 1, compare, aux);
971 expensive_assert (count < 1 || is_heap (array, count - 1,
972 size, compare, aux));
975 /* Turns ARRAY, which contains COUNT elements of SIZE bytes, into
976 a heap. Uses COMPARE to compare elements, passing AUX as
979 make_heap (void *array, size_t count, size_t size,
980 algo_compare_func *compare, const void *aux)
984 for (idx = count / 2; idx >= 1; idx--)
985 heapify (array, count, size, idx, compare, aux);
986 expensive_assert (count < 1 || is_heap (array, count, size, compare, aux));
989 /* ARRAY contains COUNT elements of SIZE bytes each. Initially
990 all COUNT elements form a heap. This function turns the heap
991 into a fully sorted array. Uses COMPARE to compare elements,
992 passing AUX as auxiliary data. */
994 sort_heap (void *array, size_t count, size_t size,
995 algo_compare_func *compare, const void *aux)
1000 expensive_assert (is_heap (array, count, size, compare, aux));
1001 for (idx = count; idx >= 2; idx--)
1003 swap (first, first + (idx - 1) * size, size);
1004 heapify (array, idx - 1, size, 1, compare, aux);
1006 expensive_assert (is_sorted (array, count, size, compare, aux));
1009 /* ARRAY contains COUNT elements of SIZE bytes each. This
1010 function tests whether ARRAY is a heap and returns true if so,
1011 false otherwise. Uses COMPARE to compare elements, passing
1012 AUX as auxiliary data. */
1014 is_heap (const void *array, size_t count, size_t size,
1015 algo_compare_func *compare, const void *aux)
1017 const char *first = array;
1020 for (child = 2; child <= count; child++)
1022 size_t parent = child / 2;
1023 if (compare (first + (parent - 1) * size,
1024 first + (child - 1) * size, aux) < 0)
1031 /* Reverses the order of ARRAY, which contains COUNT elements of SIZE bytes
1034 reverse_array (void *array_, size_t count, size_t size)
1036 uint8_t *array = array_;
1037 uint8_t *first = array;
1038 uint8_t *last = array + (count - 1) * size;
1039 for (size_t i = 0; i < count / 2; i++)
1041 swap (first, last, size);