Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #if !defined(ON_COMPILING_OPENNURBS_QSORT_FUNCTIONS)
00007
00008
00009
00010
00011 #error Do not compile openurbs_qsort_template.c directly.
00012 #endif
00013
00014 #define ON_QSORT_CUTOFF 8
00015
00016
00017
00018
00019
00020
00021
00022 #define ON_QSORT_STKSIZ (8*sizeof(void*) - 2)
00023
00024
00025
00026 #if !defined(ON_SORT_TEMPLATE_TYPE)
00027 #error Define ON_SORT_TEMPLATE_TYPE macro before including opennurbs_qsort_template.c
00028 #endif
00029
00030 #if !defined(ON_QSORT_FNAME)
00031 #error Define ON_QSORT_FNAME macro before including opennurbs_qsort_template.c
00032 #endif
00033
00034 #if defined(ON_SORT_TEMPLATE_COMPARE)
00035
00036 #define ON_QSORT_GT(A,B) ON_SORT_TEMPLATE_COMPARE(A,B) > 0
00037 #define ON_QSORT_LE(A,B) ON_SORT_TEMPLATE_COMPARE(A,B) <= 0
00038 #define ON_QSORT_EQ(A,B) ON_SORT_TEMPLATE_COMPARE(A,B) == 0
00039 #else
00040
00041 #define ON_QSORT_GT(A,B) *A > *B
00042 #define ON_QSORT_LE(A,B) *A <= *B
00043 #define ON_QSORT_EQ(A,B) *A == *B
00044 #endif
00045
00046 #if defined(ON_SORT_TEMPLATE_USE_MEMCPY)
00047 #define ON_QSORT_SWAP(A,B) memcpy(&tmp,A,sizeof(tmp));memcpy(A,B,sizeof(tmp));memcpy(B,&tmp,sizeof(tmp))
00048 #else
00049 #define ON_QSORT_SWAP(A,B) tmp = *A; *A = *B; *B = tmp
00050 #endif
00051
00052 static void ON_shortsort(ON_SORT_TEMPLATE_TYPE *, ON_SORT_TEMPLATE_TYPE *);
00053 static void ON_shortsort(ON_SORT_TEMPLATE_TYPE *lo, ON_SORT_TEMPLATE_TYPE *hi)
00054 {
00055 ON_SORT_TEMPLATE_TYPE *p;
00056 ON_SORT_TEMPLATE_TYPE *max;
00057 ON_SORT_TEMPLATE_TYPE tmp;
00058
00059
00060
00061
00062 while (hi > lo)
00063 {
00064
00065 max = lo;
00066 for (p = lo+1; p <= hi; p++)
00067 {
00068
00069 if ( ON_QSORT_GT(p,max) )
00070 {
00071 max = p;
00072 }
00073
00074 }
00075
00076
00077
00078 ON_QSORT_SWAP(max,hi);
00079
00080
00081
00082 hi--;
00083
00084
00085 }
00086
00087
00088 }
00089
00090
00091
00092
00093
00094 #if defined(ON_SORT_TEMPLATE_STATIC_FUNCTION)
00095 static
00096 #endif
00097 void
00098 ON_QSORT_FNAME (
00099 ON_SORT_TEMPLATE_TYPE *base,
00100 size_t num
00101 )
00102 {
00103 ON_SORT_TEMPLATE_TYPE *lo;
00104 ON_SORT_TEMPLATE_TYPE *hi;
00105 ON_SORT_TEMPLATE_TYPE *mid;
00106 ON_SORT_TEMPLATE_TYPE *loguy;
00107 ON_SORT_TEMPLATE_TYPE *higuy;
00108 ON_SORT_TEMPLATE_TYPE *lostk[ON_QSORT_STKSIZ];
00109 ON_SORT_TEMPLATE_TYPE *histk[ON_QSORT_STKSIZ];
00110 size_t size;
00111 int stkptr;
00112 ON_SORT_TEMPLATE_TYPE tmp;
00113
00114 if ( 0 == base || num < 2 )
00115 return;
00116
00117 stkptr = 0;
00118
00119 lo = base;
00120 hi = base + (num-1);
00121
00122
00123
00124
00125 recurse:
00126
00127 size = (hi - lo) + 1;
00128
00129
00130 if (size <= ON_QSORT_CUTOFF)
00131 {
00132 ON_shortsort(lo, hi);
00133 }
00134 else {
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 mid = lo + (size / 2);
00145
00146
00147 if ( ON_QSORT_GT(lo,mid) ) {ON_QSORT_SWAP(lo,mid);}
00148 if ( ON_QSORT_GT(lo,hi) ) {ON_QSORT_SWAP(lo,hi);}
00149 if ( ON_QSORT_GT(mid,hi) ) {ON_QSORT_SWAP(mid,hi);}
00150
00151
00152
00153
00154
00155
00156 loguy = lo;
00157 higuy = hi;
00158
00159
00160
00161 for (;;)
00162 {
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 if (mid > loguy)
00173 {
00174 do {
00175 loguy++;
00176 } while (loguy < mid && ON_QSORT_LE(loguy,mid));
00177 }
00178 if (mid <= loguy)
00179 {
00180 do {
00181 loguy++;
00182 } while (loguy <= hi && ON_QSORT_LE(loguy,mid));
00183 }
00184
00185
00186
00187
00188 do {
00189 higuy--;
00190 } while (higuy > mid && ON_QSORT_GT(higuy,mid));
00191
00192
00193
00194
00195 if (higuy < loguy)
00196 break;
00197
00198
00199
00200
00201
00202 ON_QSORT_SWAP(loguy,higuy);
00203
00204
00205
00206
00207
00208 if (mid == higuy)
00209 mid = loguy;
00210
00211
00212
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 higuy++;
00229 if (mid < higuy) {
00230 do {
00231 higuy--;
00232 } while (higuy > mid && ON_QSORT_EQ(higuy,mid));
00233 }
00234 if (mid >= higuy) {
00235 do {
00236 higuy--;
00237 } while (higuy > lo && ON_QSORT_EQ(higuy,mid));
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 if ( higuy - lo >= hi - loguy ) {
00254 if (lo < higuy) {
00255 lostk[stkptr] = lo;
00256 histk[stkptr] = higuy;
00257 ++stkptr;
00258 }
00259
00260 if (loguy < hi) {
00261 lo = loguy;
00262 goto recurse;
00263 }
00264 }
00265 else {
00266 if (loguy < hi) {
00267 lostk[stkptr] = loguy;
00268 histk[stkptr] = hi;
00269 ++stkptr;
00270 }
00271
00272 if (lo < higuy) {
00273 hi = higuy;
00274 goto recurse;
00275 }
00276 }
00277 }
00278
00279
00280
00281
00282 --stkptr;
00283 if (stkptr >= 0) {
00284 lo = lostk[stkptr];
00285 hi = histk[stkptr];
00286 goto recurse;
00287 }
00288 else
00289 return;
00290 }
00291
00292 #undef ON_QSORT_GT
00293 #undef ON_QSORT_LE
00294 #undef ON_QSORT_EQ
00295 #undef ON_QSORT_SWAP
00296 #undef ON_QSORT_CUTOFF
00297 #undef ON_QSORT_STKSIZ