23 #if !defined(ON_QSORT_FNAME) 24 #error Define ON_QSORT_FNAME macro before including opennurbs_quacksort_template.h 28 #if !defined(ON_SORT_TEMPLATE_TYPE) 30 #define BASETYPE void * 31 #define DATATYPE unsigned char 32 #define DATAWIDTH m_width 34 #define Swap(a,b) m_swapfunc(a,b,m_width) 36 #if defined(ON_SORT_TEMPLATE_USE_CONTEXT) 38 #define GreaterThan(A,B) m_compare(m_context,A,B) > 0 41 #define GreaterThan(A,B) m_compare(A,B) > 0 46 #define BASETYPE ON_SORT_TEMPLATE_TYPE * 47 #define DATATYPE ON_SORT_TEMPLATE_TYPE 50 #if defined(ON_SORT_TEMPLATE_USE_SWAP) 51 #define Swap(a,b) m_swapfunc(a,b,m_width) 54 #define Swap(a,b) ON_SORT_TEMPLATE_TYPE tmp = *a; *a = *b; *b = tmp 57 #if defined(ON_SORT_TEMPLATE_COMPARE) 59 #define GreaterThan(A,B) ON_SORT_TEMPLATE_COMPARE(A,B) > 0 62 #define GreaterThan(A,B) *A > *B 67 #if !defined(ON_QUACKSORT_SWAP_FUNCS_DEFINED) 68 #if !defined(ON_SORT_TEMPLATE_TYPE) || defined(ON_SORT_TEMPLATE_USE_SWAP) 73 #define ON_QUACKSORT_SWAP_FUNCS_DEFINED 75 static void SwapChars(
unsigned char* a,
unsigned char* b,
size_t width)
86 static void SwapInts(
unsigned char* a,
unsigned char* b,
size_t width)
88 ON__UINT32* ai = (ON__UINT32*)a;
89 ON__UINT32* bi = (ON__UINT32*)b;
100 static void SwapBigInts(
unsigned char* a,
unsigned char* b,
size_t width)
102 ON__UINT64* ai = (ON__UINT64*)a;
103 ON__UINT64* bi = (ON__UINT64*)b;
121 #
if !defined(ON_SORT_TEMPLATE_TYPE)
123 #
if defined(ON_SORT_TEMPLATE_USE_CONTEXT)
124 ,
int (*compar)(
void*,
const void *,
const void *)
127 ,
int (*compar)(
const void *,
const void *)
137 const size_t m_width;
138 int (*m_compar)(
const void *,
const void *);
139 void (*m_swapfunc)(
unsigned char *,
unsigned char *,
size_t width);
149 ,
int (*compar)(
const void *,
const void *)
151 : m_base((DATATYPE*)base)
159 if ( 0 == width%
sizeof(ON__UINT64))
160 m_swapfunc = SwapBigInts;
161 else if ( 0 == width%
sizeof(ON__UINT32))
162 m_swapfunc = SwapInts;
164 m_swapfunc = SwapChars;
169 DATATYPE* Pivot( DATATYPE* base,
size_t count)
181 unsigned int dice = (m_rnd>>16)&7;
192 return base + p*DATAWIDTH;
195 void SortSmallRange( DATATYPE* p0,
size_t count)
202 DATATYPE* p1 = p0 + DATAWIDTH;
203 if ( GreaterThan( p0, p1)) { Swap( p0, p1);}
208 DATATYPE* p1 = p0 + DATAWIDTH;
209 DATATYPE* p2 = p1 + DATAWIDTH;
211 if ( GreaterThan( p0, p1)) { Swap( p0, p1); b =
true;}
212 if ( GreaterThan( p1, p2)) { Swap( p1, p2); b =
true;}
213 if ( b && GreaterThan( p0, p1)) { Swap( p0, p1);}
218 DATATYPE* p1 = p0 + DATAWIDTH;
219 DATATYPE* p2 = p1 + DATAWIDTH;
220 DATATYPE* p3 = p2 + DATAWIDTH;
221 if ( GreaterThan( p0, p3)) { Swap( p0, p3);}
222 if ( GreaterThan( p1, p2)) { Swap( p1, p2);}
224 if ( GreaterThan( p2, p3)) { Swap( p2, p3); b =
true;}
225 if ( GreaterThan( p0, p1)) { Swap( p0, p1); b =
true;}
226 if ( b && GreaterThan( p1, p2)) { Swap( p1, p2);}
232 void SortRange( DATATYPE* left, DATATYPE* right)
236 size_t count = (right-left)/DATAWIDTH+1;
239 return SortSmallRange( left, count);
242 DATATYPE* pivotright;
246 pivotleft = Pivot( left, count);
249 Swap( left, pivotleft);
252 pivotright = right + DATAWIDTH;
258 pivotleft += DATAWIDTH;
259 if ( pivotleft >= pivotright)
261 if ( !GreaterThan( pivotleft, left))
267 pivotright -= DATAWIDTH;
268 if ( pivotleft >= pivotright)
271 while( GreaterThan( pivotright, left));
273 Swap( pivotleft, pivotright);
278 pivotright -= DATAWIDTH;
280 Swap( left, pivotright);
281 pivotleft = pivotright;
284 if ( pivotright >= right)
288 for ( pivotleft -= DATAWIDTH; pivotleft > left; pivotleft -= DATAWIDTH)
290 if ( GreaterThan( pivotright, pivotleft))
293 pivotleft += DATAWIDTH;
298 if ( pivotleft-left < right-pivotright)
301 SortRange( left, pivotleft-DATAWIDTH);
302 left = pivotright+DATAWIDTH;
307 SortRange( pivotright+DATAWIDTH, right);
308 right = pivotleft-DATAWIDTH;
315 SortRange( m_base, m_base + (m_nel-1)*DATAWIDTH);
319 if ( !base || nel < 2 )
321 #if !defined(ON_SORT_TEMPLATE_TYPE) 322 if ( width < 1 || !compar)
326 CSorter sorter( base, nel, width, compar);