xref: /freebsd/lib/libc/stdlib/qsort.3 (revision 46cdc14062f7b52d86bd3791220019ebc8c9c120)
158f0484fSRodney W. Grimes.\" Copyright (c) 1990, 1991, 1993
258f0484fSRodney W. Grimes.\"	The Regents of the University of California.  All rights reserved.
358f0484fSRodney W. Grimes.\"
458f0484fSRodney W. Grimes.\" This code is derived from software contributed to Berkeley by
558f0484fSRodney W. Grimes.\" the American National Standards Committee X3, on Information
658f0484fSRodney W. Grimes.\" Processing Systems.
758f0484fSRodney W. Grimes.\"
858f0484fSRodney W. Grimes.\" Redistribution and use in source and binary forms, with or without
958f0484fSRodney W. Grimes.\" modification, are permitted provided that the following conditions
1058f0484fSRodney W. Grimes.\" are met:
1158f0484fSRodney W. Grimes.\" 1. Redistributions of source code must retain the above copyright
1258f0484fSRodney W. Grimes.\"    notice, this list of conditions and the following disclaimer.
1358f0484fSRodney W. Grimes.\" 2. Redistributions in binary form must reproduce the above copyright
1458f0484fSRodney W. Grimes.\"    notice, this list of conditions and the following disclaimer in the
1558f0484fSRodney W. Grimes.\"    documentation and/or other materials provided with the distribution.
16580b4d18SEd Maste.\" 3. Neither the name of the University nor the names of its contributors
1758f0484fSRodney W. Grimes.\"    may be used to endorse or promote products derived from this software
1858f0484fSRodney W. Grimes.\"    without specific prior written permission.
1958f0484fSRodney W. Grimes.\"
2058f0484fSRodney W. Grimes.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2158f0484fSRodney W. Grimes.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2258f0484fSRodney W. Grimes.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2358f0484fSRodney W. Grimes.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2458f0484fSRodney W. Grimes.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2558f0484fSRodney W. Grimes.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2658f0484fSRodney W. Grimes.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2758f0484fSRodney W. Grimes.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2858f0484fSRodney W. Grimes.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2958f0484fSRodney W. Grimes.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3058f0484fSRodney W. Grimes.\" SUCH DAMAGE.
3158f0484fSRodney W. Grimes.\"
3258f0484fSRodney W. Grimes.\"     @(#)qsort.3	8.1 (Berkeley) 6/4/93
337f3dea24SPeter Wemm.\" $FreeBSD$
3458f0484fSRodney W. Grimes.\"
358ce3e01eSGiorgos Keramidas.Dd February 20, 2013
3658f0484fSRodney W. Grimes.Dt QSORT 3
3758f0484fSRodney W. Grimes.Os
3858f0484fSRodney W. Grimes.Sh NAME
39*46cdc140SDavid Chisnall.Nm qsort , qsort_b , qsort_r , heapsort , heapsort_b , mergesort, mergesort_b
4058f0484fSRodney W. Grimes.Nd sort functions
4125bb73e0SAlexey Zelkin.Sh LIBRARY
4225bb73e0SAlexey Zelkin.Lb libc
4358f0484fSRodney W. Grimes.Sh SYNOPSIS
448aefde06SJeroen Ruigrok van der Werven.In stdlib.h
4558f0484fSRodney W. Grimes.Ft void
461798791dSRuslan Ermilov.Fo qsort
471798791dSRuslan Ermilov.Fa "void *base"
481798791dSRuslan Ermilov.Fa "size_t nmemb"
491798791dSRuslan Ermilov.Fa "size_t size"
501798791dSRuslan Ermilov.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]"
511798791dSRuslan Ermilov.Fc
52eca67d51SGarrett Wollman.Ft void
53*46cdc140SDavid Chisnall.Fo qsort_b
54*46cdc140SDavid Chisnall.Fa "void *base"
55*46cdc140SDavid Chisnall.Fa "size_t nmemb"
56*46cdc140SDavid Chisnall.Fa "size_t size"
57*46cdc140SDavid Chisnall.Fa "int \*[lp]^compar\*[rp]\*[lp]const void *, const void *\*[rp]"
58*46cdc140SDavid Chisnall.Fc
59*46cdc140SDavid Chisnall.Ft void
60eca67d51SGarrett Wollman.Fo qsort_r
61eca67d51SGarrett Wollman.Fa "void *base"
62eca67d51SGarrett Wollman.Fa "size_t nmemb"
63eca67d51SGarrett Wollman.Fa "size_t size"
64eca67d51SGarrett Wollman.Fa "void *thunk"
651798791dSRuslan Ermilov.Fa "int \*[lp]*compar\*[rp]\*[lp]void *, const void *, const void *\*[rp]"
66eca67d51SGarrett Wollman.Fc
6758f0484fSRodney W. Grimes.Ft int
681798791dSRuslan Ermilov.Fo heapsort
691798791dSRuslan Ermilov.Fa "void *base"
701798791dSRuslan Ermilov.Fa "size_t nmemb"
711798791dSRuslan Ermilov.Fa "size_t size"
721798791dSRuslan Ermilov.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]"
731798791dSRuslan Ermilov.Fc
7458f0484fSRodney W. Grimes.Ft int
75*46cdc140SDavid Chisnall.Fo heapsort_b
76*46cdc140SDavid Chisnall.Fa "void *base"
77*46cdc140SDavid Chisnall.Fa "size_t nmemb"
78*46cdc140SDavid Chisnall.Fa "size_t size"
79*46cdc140SDavid Chisnall.Fa "int \*[lp]^compar\*[rp]\*[lp]const void *, const void *\*[rp]"
80*46cdc140SDavid Chisnall.Fc
81*46cdc140SDavid Chisnall.Ft int
821798791dSRuslan Ermilov.Fo mergesort
831798791dSRuslan Ermilov.Fa "void *base"
841798791dSRuslan Ermilov.Fa "size_t nmemb"
851798791dSRuslan Ermilov.Fa "size_t size"
861798791dSRuslan Ermilov.Fa "int \*[lp]*compar\*[rp]\*[lp]const void *, const void *\*[rp]"
871798791dSRuslan Ermilov.Fc
88*46cdc140SDavid Chisnall.Ft int
89*46cdc140SDavid Chisnall.Fo mergesort_b
90*46cdc140SDavid Chisnall.Fa "void *base"
91*46cdc140SDavid Chisnall.Fa "size_t nmemb"
92*46cdc140SDavid Chisnall.Fa "size_t size"
93*46cdc140SDavid Chisnall.Fa "int \*[lp]^compar\*[rp]\*[lp]const void *, const void *\*[rp]"
94*46cdc140SDavid Chisnall.Fc
9558f0484fSRodney W. Grimes.Sh DESCRIPTION
9658f0484fSRodney W. GrimesThe
9758f0484fSRodney W. Grimes.Fn qsort
9858f0484fSRodney W. Grimesfunction is a modified partition-exchange sort, or quicksort.
9958f0484fSRodney W. GrimesThe
10058f0484fSRodney W. Grimes.Fn heapsort
10158f0484fSRodney W. Grimesfunction is a modified selection sort.
10258f0484fSRodney W. GrimesThe
10358f0484fSRodney W. Grimes.Fn mergesort
10458f0484fSRodney W. Grimesfunction is a modified merge sort with exponential search
10558f0484fSRodney W. Grimesintended for sorting data with pre-existing order.
10658f0484fSRodney W. Grimes.Pp
10758f0484fSRodney W. GrimesThe
10858f0484fSRodney W. Grimes.Fn qsort
10958f0484fSRodney W. Grimesand
11058f0484fSRodney W. Grimes.Fn heapsort
11158f0484fSRodney W. Grimesfunctions sort an array of
11258f0484fSRodney W. Grimes.Fa nmemb
11358f0484fSRodney W. Grimesobjects, the initial member of which is pointed to by
11458f0484fSRodney W. Grimes.Fa base .
11558f0484fSRodney W. GrimesThe size of each object is specified by
11658f0484fSRodney W. Grimes.Fa size .
1171fae73b1SRuslan ErmilovThe
1181fae73b1SRuslan Ermilov.Fn mergesort
1191fae73b1SRuslan Ermilovfunction
12058f0484fSRodney W. Grimesbehaves similarly, but
12158f0484fSRodney W. Grimes.Em requires
12258f0484fSRodney W. Grimesthat
12358f0484fSRodney W. Grimes.Fa size
12458f0484fSRodney W. Grimesbe greater than
12558f0484fSRodney W. Grimes.Dq "sizeof(void *) / 2" .
12658f0484fSRodney W. Grimes.Pp
12758f0484fSRodney W. GrimesThe contents of the array
12858f0484fSRodney W. Grimes.Fa base
12958f0484fSRodney W. Grimesare sorted in ascending order according to
13058f0484fSRodney W. Grimesa comparison function pointed to by
13158f0484fSRodney W. Grimes.Fa compar ,
13258f0484fSRodney W. Grimeswhich requires two arguments pointing to the objects being
13358f0484fSRodney W. Grimescompared.
13458f0484fSRodney W. Grimes.Pp
13558f0484fSRodney W. GrimesThe comparison function must return an integer less than, equal to, or
13658f0484fSRodney W. Grimesgreater than zero if the first argument is considered to be respectively
13758f0484fSRodney W. Grimesless than, equal to, or greater than the second.
13858f0484fSRodney W. Grimes.Pp
139eca67d51SGarrett WollmanThe
140eca67d51SGarrett Wollman.Fn qsort_r
141eca67d51SGarrett Wollmanfunction behaves identically to
142eca67d51SGarrett Wollman.Fn qsort ,
143eca67d51SGarrett Wollmanexcept that it takes an additional argument,
144eca67d51SGarrett Wollman.Fa thunk ,
145eca67d51SGarrett Wollmanwhich is passed unchanged as the first argument to function pointed to
146eca67d51SGarrett Wollman.Fa compar .
147eca67d51SGarrett WollmanThis allows the comparison function to access additional
148eca67d51SGarrett Wollmandata without using global variables, and thus
149eca67d51SGarrett Wollman.Fn qsort_r
150eca67d51SGarrett Wollmanis suitable for use in functions which must be reentrant.
151*46cdc140SDavid ChisnallThe
152*46cdc140SDavid Chisnall.Fn qsort_b
153*46cdc140SDavid Chisnallfunction behaves identically to
154*46cdc140SDavid Chisnall.Fn qsort ,
155*46cdc140SDavid Chisnallexcept that it takes a block, rather than a function pointer.
156eca67d51SGarrett Wollman.Pp
157eca67d51SGarrett WollmanThe algorithms implemented by
158eca67d51SGarrett Wollman.Fn qsort ,
159eca67d51SGarrett Wollman.Fn qsort_r ,
16058f0484fSRodney W. Grimesand
16158f0484fSRodney W. Grimes.Fn heapsort
16258f0484fSRodney W. Grimesare
16358f0484fSRodney W. Grimes.Em not
16458f0484fSRodney W. Grimesstable, that is, if two members compare as equal, their order in
16558f0484fSRodney W. Grimesthe sorted array is undefined.
166eca67d51SGarrett WollmanThe
167*46cdc140SDavid Chisnall.Fn heapsort_b
168*46cdc140SDavid Chisnallfunction behaves identically to
169*46cdc140SDavid Chisnall.Fn heapsort ,
170*46cdc140SDavid Chisnallexcept that it takes a block, rather than a function pointer.
171*46cdc140SDavid ChisnallThe
17258f0484fSRodney W. Grimes.Fn mergesort
173eca67d51SGarrett Wollmanalgorithm is stable.
174*46cdc140SDavid ChisnallThe
175*46cdc140SDavid Chisnall.Fn mergesort_b
176*46cdc140SDavid Chisnallfunction behaves identically to
177*46cdc140SDavid Chisnall.Fn mergesort ,
178*46cdc140SDavid Chisnallexcept that it takes a block, rather than a function pointer.
17958f0484fSRodney W. Grimes.Pp
18058f0484fSRodney W. GrimesThe
18158f0484fSRodney W. Grimes.Fn qsort
182eca67d51SGarrett Wollmanand
183eca67d51SGarrett Wollman.Fn qsort_r
1841a0a9345SRuslan Ermilovfunctions are an implementation of C.A.R.
1851a0a9345SRuslan ErmilovHoare's
1861798791dSRuslan Ermilov.Dq quicksort
1871798791dSRuslan Ermilovalgorithm,
1881a0a9345SRuslan Ermilova variant of partition-exchange sorting; in particular, see
1891a0a9345SRuslan Ermilov.An D.E. Knuth Ns 's
1901a0a9345SRuslan Ermilov.%T "Algorithm Q" .
191eca67d51SGarrett Wollman.Sy Quicksort
19258f0484fSRodney W. Grimestakes O N lg N average time.
19358f0484fSRodney W. GrimesThis implementation uses median selection to avoid its
19458f0484fSRodney W. GrimesO N**2 worst-case behavior.
19558f0484fSRodney W. Grimes.Pp
19658f0484fSRodney W. GrimesThe
19758f0484fSRodney W. Grimes.Fn heapsort
1981a0a9345SRuslan Ermilovfunction is an implementation of
1991a0a9345SRuslan Ermilov.An "J.W.J. William" Ns 's
2001798791dSRuslan Ermilov.Dq heapsort
2011798791dSRuslan Ermilovalgorithm,
2021a0a9345SRuslan Ermilova variant of selection sorting; in particular, see
2031a0a9345SRuslan Ermilov.An "D.E. Knuth" Ns 's
2041a0a9345SRuslan Ermilov.%T "Algorithm H" .
205eca67d51SGarrett Wollman.Sy Heapsort
20658f0484fSRodney W. Grimestakes O N lg N worst-case time.
20758f0484fSRodney W. GrimesIts
20858f0484fSRodney W. Grimes.Em only
20958f0484fSRodney W. Grimesadvantage over
21058f0484fSRodney W. Grimes.Fn qsort
21158f0484fSRodney W. Grimesis that it uses almost no additional memory; while
21258f0484fSRodney W. Grimes.Fn qsort
21358f0484fSRodney W. Grimesdoes not allocate memory, it is implemented using recursion.
21458f0484fSRodney W. Grimes.Pp
21558f0484fSRodney W. GrimesThe function
21658f0484fSRodney W. Grimes.Fn mergesort
21758f0484fSRodney W. Grimesrequires additional memory of size
21858f0484fSRodney W. Grimes.Fa nmemb *
21958f0484fSRodney W. Grimes.Fa size
22058f0484fSRodney W. Grimesbytes; it should be used only when space is not at a premium.
2211fae73b1SRuslan ErmilovThe
2221fae73b1SRuslan Ermilov.Fn mergesort
2231fae73b1SRuslan Ermilovfunction
22458f0484fSRodney W. Grimesis optimized for data with pre-existing order; its worst case
22558f0484fSRodney W. Grimestime is O N lg N; its best case is O N.
22658f0484fSRodney W. Grimes.Pp
22758f0484fSRodney W. GrimesNormally,
22858f0484fSRodney W. Grimes.Fn qsort
22958f0484fSRodney W. Grimesis faster than
23058f0484fSRodney W. Grimes.Fn mergesort
23158f0484fSRodney W. Grimesis faster than
23258f0484fSRodney W. Grimes.Fn heapsort .
23358f0484fSRodney W. GrimesMemory availability and pre-existing order in the data can make this
23458f0484fSRodney W. Grimesuntrue.
23558f0484fSRodney W. Grimes.Sh RETURN VALUES
23658f0484fSRodney W. GrimesThe
23758f0484fSRodney W. Grimes.Fn qsort
238eca67d51SGarrett Wollmanand
239eca67d51SGarrett Wollman.Fn qsort_r
240eca67d51SGarrett Wollmanfunctions
241eca67d51SGarrett Wollmanreturn no value.
24258f0484fSRodney W. Grimes.Pp
243d6002fefSRuslan Ermilov.Rv -std heapsort mergesort
2448ce3e01eSGiorgos Keramidas.Sh EXAMPLES
2458ce3e01eSGiorgos KeramidasA sample program that sorts an array of
2468ce3e01eSGiorgos Keramidas.Vt int
2478ce3e01eSGiorgos Keramidasvalues in place using
2488ce3e01eSGiorgos Keramidas.Fn qsort ,
2498ce3e01eSGiorgos Keramidasand then prints the sorted array to standard output is:
2508ce3e01eSGiorgos Keramidas.Bd -literal
2518ce3e01eSGiorgos Keramidas#include <stdio.h>
2528ce3e01eSGiorgos Keramidas#include <stdlib.h>
2538ce3e01eSGiorgos Keramidas
2548ce3e01eSGiorgos Keramidas/*
2558ce3e01eSGiorgos Keramidas * Custom comparison function that can compare 'int' values through pointers
2568ce3e01eSGiorgos Keramidas * passed by qsort(3).
2578ce3e01eSGiorgos Keramidas */
2588ce3e01eSGiorgos Keramidasstatic int
2598ce3e01eSGiorgos Keramidasint_compare(const void *p1, const void *p2)
2608ce3e01eSGiorgos Keramidas{
261302318d5SGiorgos Keramidas        int left = *(const int *)p1;
262302318d5SGiorgos Keramidas        int right = *(const int *)p2;
2638ce3e01eSGiorgos Keramidas
264302318d5SGiorgos Keramidas        return ((left > right) - (left < right));
2658ce3e01eSGiorgos Keramidas}
2668ce3e01eSGiorgos Keramidas
2678ce3e01eSGiorgos Keramidas/*
2688ce3e01eSGiorgos Keramidas * Sort an array of 'int' values and print it to standard output.
2698ce3e01eSGiorgos Keramidas */
2708ce3e01eSGiorgos Keramidasint
2718ce3e01eSGiorgos Keramidasmain(void)
2728ce3e01eSGiorgos Keramidas{
2738ce3e01eSGiorgos Keramidas       int int_array[] = { 4, 5, 9, 3, 0, 1, 7, 2, 8, 6 };
274302318d5SGiorgos Keramidas       const size_t array_size = sizeof(int_array) / sizeof(int_array[0]);
275302318d5SGiorgos Keramidas       size_t k;
2768ce3e01eSGiorgos Keramidas
277302318d5SGiorgos Keramidas       qsort(&int_array, array_size, sizeof(int_array[0]), int_compare);
2788ce3e01eSGiorgos Keramidas       for (k = 0; k < array_size; k++)
2798ce3e01eSGiorgos Keramidas                printf(" %d", int_array[k]);
280302318d5SGiorgos Keramidas        puts("");
281302318d5SGiorgos Keramidas        return (EXIT_SUCCESS);
2828ce3e01eSGiorgos Keramidas}
2838ce3e01eSGiorgos Keramidas.Ed
284954349a6SJoel Dahl.Sh COMPATIBILITY
285954349a6SJoel DahlPrevious versions of
286954349a6SJoel Dahl.Fn qsort
287954349a6SJoel Dahldid not permit the comparison routine itself to call
288954349a6SJoel Dahl.Fn qsort 3 .
289954349a6SJoel DahlThis is no longer true.
29058f0484fSRodney W. Grimes.Sh ERRORS
29158f0484fSRodney W. GrimesThe
29258f0484fSRodney W. Grimes.Fn heapsort
2938d2c3c32SRobert Nordierand
2948d2c3c32SRobert Nordier.Fn mergesort
2958d2c3c32SRobert Nordierfunctions succeed unless:
29658f0484fSRodney W. Grimes.Bl -tag -width Er
29758f0484fSRodney W. Grimes.It Bq Er EINVAL
29858f0484fSRodney W. GrimesThe
29958f0484fSRodney W. Grimes.Fa size
30058f0484fSRodney W. Grimesargument is zero, or,
30158f0484fSRodney W. Grimesthe
30258f0484fSRodney W. Grimes.Fa size
30358f0484fSRodney W. Grimesargument to
30458f0484fSRodney W. Grimes.Fn mergesort
30558f0484fSRodney W. Grimesis less than
30658f0484fSRodney W. Grimes.Dq "sizeof(void *) / 2" .
30758f0484fSRodney W. Grimes.It Bq Er ENOMEM
3081fae73b1SRuslan ErmilovThe
3091fae73b1SRuslan Ermilov.Fn heapsort
31058f0484fSRodney W. Grimesor
31158f0484fSRodney W. Grimes.Fn mergesort
3121fae73b1SRuslan Ermilovfunctions
31358f0484fSRodney W. Grimeswere unable to allocate memory.
31458f0484fSRodney W. Grimes.El
31558f0484fSRodney W. Grimes.Sh SEE ALSO
31658f0484fSRodney W. Grimes.Xr sort 1 ,
31758f0484fSRodney W. Grimes.Xr radixsort 3
31858f0484fSRodney W. Grimes.Rs
31958f0484fSRodney W. Grimes.%A Hoare, C.A.R.
32058f0484fSRodney W. Grimes.%D 1962
32158f0484fSRodney W. Grimes.%T "Quicksort"
32258f0484fSRodney W. Grimes.%J "The Computer Journal"
32358f0484fSRodney W. Grimes.%V 5:1
32458f0484fSRodney W. Grimes.%P pp. 10-15
32558f0484fSRodney W. Grimes.Re
32658f0484fSRodney W. Grimes.Rs
32758f0484fSRodney W. Grimes.%A Williams, J.W.J
32858f0484fSRodney W. Grimes.%D 1964
32958f0484fSRodney W. Grimes.%T "Heapsort"
33058f0484fSRodney W. Grimes.%J "Communications of the ACM"
33158f0484fSRodney W. Grimes.%V 7:1
33258f0484fSRodney W. Grimes.%P pp. 347-348
33358f0484fSRodney W. Grimes.Re
33458f0484fSRodney W. Grimes.Rs
33558f0484fSRodney W. Grimes.%A Knuth, D.E.
33658f0484fSRodney W. Grimes.%D 1968
33758f0484fSRodney W. Grimes.%B "The Art of Computer Programming"
33858f0484fSRodney W. Grimes.%V Vol. 3
33958f0484fSRodney W. Grimes.%T "Sorting and Searching"
34058f0484fSRodney W. Grimes.%P pp. 114-123, 145-149
34158f0484fSRodney W. Grimes.Re
34258f0484fSRodney W. Grimes.Rs
3435e24a424STim J. Robbins.%A McIlroy, P.M.
34458f0484fSRodney W. Grimes.%T "Optimistic Sorting and Information Theoretic Complexity"
34558f0484fSRodney W. Grimes.%J "Fourth Annual ACM-SIAM Symposium on Discrete Algorithms"
34658f0484fSRodney W. Grimes.%V January 1992
34758f0484fSRodney W. Grimes.Re
34858f0484fSRodney W. Grimes.Rs
34958f0484fSRodney W. Grimes.%A Bentley, J.L.
3505e24a424STim J. Robbins.%A McIlroy, M.D.
35158f0484fSRodney W. Grimes.%T "Engineering a Sort Function"
3525e24a424STim J. Robbins.%J "Software--Practice and Experience"
3535e24a424STim J. Robbins.%V Vol. 23(11)
3545e24a424STim J. Robbins.%P pp. 1249-1265
3555e24a424STim J. Robbins.%D November\ 1993
35658f0484fSRodney W. Grimes.Re
35758f0484fSRodney W. Grimes.Sh STANDARDS
35858f0484fSRodney W. GrimesThe
35958f0484fSRodney W. Grimes.Fn qsort
36058f0484fSRodney W. Grimesfunction
36158f0484fSRodney W. Grimesconforms to
362588a200cSRuslan Ermilov.St -isoC .
363*46cdc140SDavid Chisnall.Sh HISTORY
364*46cdc140SDavid ChisnallThe variants of these functions that take blocks as arguments first appeared in
365*46cdc140SDavid ChisnallMac OS X.
366*46cdc140SDavid ChisnallThis implementation was created by David Chisnall.
367