1 /* -*- mode: c; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; c-file-style: "stroustrup"; -*-
4 * This file is part of Gromacs Copyright (c) 1991-2010
5 * David van der Spoel, Erik Lindahl, Berk Hess, University of Groningen.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * To help us fund GROMACS development, we humbly ask that you cite
13 * the research papers on the package. Check out http://www.gromacs.org
16 * Gnomes, ROck Monsters And Chili Sauce
28 qsort_swapfunc(void * a
,
45 for( ; n
> 0; ia
+= 1, ib
+= 1, n
-= sizeof(int))
56 for( ; n
> 0; ca
+= 1, cb
+= 1, n
-= 1)
70 int (*compar
) (const void *a
, const void *b
))
76 else if(compar(a
,c
) < 0)
85 else if(compar(a
,c
) > 0)
94 gmx_qsort(void * base
,
97 int (*compar
)(const void *, const void *))
99 #define QSORT_EXCH(a, b, t) (t = a, a = b, b = t);
100 #define QSORT_SWAP(a, b) swaptype != 0 ? qsort_swapfunc(a, b, size, swaptype) : \
101 (void)QSORT_EXCH(*(int *)(a), *(int *)(b), t)
103 char *pa
, *pb
, *pc
, *pd
, *pl
, *pm
, *pn
, *pv
, *cbase
;
108 cbase
= (char *)base
;
110 swaptype
= (size_t)(cbase
- (char *)0) % sizeof(int) || size
% sizeof(int) ? 2 : size
== sizeof(int)? 0 : 1;
114 /* Insertion sort on smallest arrays */
115 for (pm
= cbase
+ size
; pm
< cbase
+ nmemb
*size
; pm
+= size
)
117 for (pl
= pm
; (pl
> cbase
) && compar((void *)(pl
-size
),(void *) pl
) > 0; pl
-= size
)
119 QSORT_SWAP(pl
, pl
-size
);
125 /* Small arrays, middle element */
126 pm
= cbase
+ (nmemb
/2)*size
;
131 pn
= cbase
+ (nmemb
-1)*size
;
134 /* Big arrays, pseudomedian of 9 */
136 pl
= (char *)qsort_med3((void *)pl
, (void *)((size_t)pl
+s
), (void *)((size_t)pl
+2*s
), compar
);
137 pm
= (char *)qsort_med3((void *)((size_t)pm
-s
), (void *)pm
, (void *)((size_t)pm
+s
), compar
);
138 pn
= (char *)qsort_med3((void *)((size_t)pn
-2*s
), (void *)((size_t)pn
-s
), (void *)pn
, compar
);
140 /* Mid-size, med of 3 */
141 pm
= (char *)qsort_med3((void *)pl
, (void *)pm
, (void *)pn
, compar
);
144 /* pv points to partition value */
152 pv
= (char*)(void*)&v
;
157 pc
= pd
= cbase
+ (nmemb
-1)*size
;
161 while (pb
<= pc
&& (r
= compar((void *)pb
,(void *) pv
)) <= 0)
170 while (pc
>= pb
&& (r
= compar((void *)pc
,(void *) pv
)) >= 0)
187 pn
= cbase
+ nmemb
*size
;
198 qsort_swapfunc(cbase
, pb
-s
, s
, swaptype
);
210 qsort_swapfunc(pb
, pn
-s
, s
, swaptype
);
213 if ((s
= pb
-pa
) > size
)
215 gmx_qsort(cbase
, s
/size
, size
, compar
);
218 if ((s
= pd
-pc
) > size
)
220 gmx_qsort(pn
-s
, s
/size
, size
, compar
);