00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef __fast_merge_sort_h
00024 #define __fast_merge_sort_h
00025
00026
00027
00176
00177
00178
00179 #if !defined(__GNUC__) || defined(__STRICT_ANSI__)
00180 #define FAST_MERGE_SORT(__LIST, __TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P) \
00181 __FAST_MERGE_SORT(1, 0, __LIST, __TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P)
00182 #define FAST_MERGE_SORT_APPEND(__ALREADY_SORTED, __LIST, \
00183 __TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P) \
00184 __FAST_MERGE_SORT(0, __ALREADY_SORTED, __LIST, \
00185 __TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P)
00186 #define __FAST_MERGE_SORT_LABEL(name) \
00187 __FAST_MERGE_SORT_LABEL2 (name,__LINE__)
00188 #define __FAST_MERGE_SORT_LABEL2(name,line) \
00189 __FAST_MERGE_SORT_LABEL3 (name,line)
00190 #ifdef __STDC__
00191 #define __FAST_MERGE_SORT_LABEL3(name,line) \
00192 __FAST_MERGE_SORT_ ## name ## _ ## line
00193 #else
00194 #define __FAST_MERGE_SORT_LABEL3(name,line) \
00195 __FAST_MERGE_SORT_name_line
00196 #endif
00197 #else
00198 #define FAST_MERGE_SORT(__LIST, __TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P) \
00199 do ({ \
00200 __label__ __merge_1, __merge_2, __merge_done, __final_merge, __empty_list;\
00201 __FAST_MERGE_SORT(1, 0, __LIST, __TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P); \
00202 }); while (0)
00203 #define FAST_MERGE_SORT_APPEND(__ALREADY_SORTED, __LIST, \
00204 __TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P) \
00205 do ({ \
00206 __label__ __merge_1, __merge_2, __merge_done, __final_merge, __empty_list;\
00207 __FAST_MERGE_SORT(0, __ALREADY_SORTED, __LIST, \
00208 __TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P); \
00209 }); while (0)
00210 #define __FAST_MERGE_SORT_LABEL(name) __ ## name
00211 #endif
00212
00213 #define __FAST_MERGE_SORT\
00214 (__ASG, __ALREADY_SORTED, __LIST, __NODE_TYPE, __NEXT, __LESS_THAN_OR_EQUAL_P)\
00215 do \
00216 { \
00217 __NODE_TYPE * _stack [8 * sizeof (unsigned long)]; \
00218 __NODE_TYPE ** _stack_ptr = _stack; \
00219 unsigned long _run_number = 0UL - 1; \
00220 register __NODE_TYPE * _list = (__LIST); \
00221 register __NODE_TYPE * _current_run = (__ALREADY_SORTED); \
00222 \
00223 \
00224 if (__ASG && (_list == 0 || _list->__NEXT == 0)) \
00225 break; \
00226 if (!__ASG && _list == 0) \
00227 goto __FAST_MERGE_SORT_LABEL (empty_list); \
00228 \
00229 while (_list != 0) \
00230 { \
00231
00232
00233 \
00234 *_stack_ptr++ = _current_run; \
00235 _current_run = _list; \
00236 \
00237 \
00238 if (_list->__NEXT != 0) \
00239 { \
00240 if (__LESS_THAN_OR_EQUAL_P (_list, (_list->__NEXT))) \
00241 _list = _list->__NEXT; \
00242 else \
00243 { \
00244 \
00245 _current_run = _list->__NEXT; \
00246 _list->__NEXT = _current_run->__NEXT; \
00247 _current_run->__NEXT = _list; \
00248 } \
00249 \
00250 \
00251 if (_list->__NEXT != 0) \
00252 { \
00253 if (__LESS_THAN_OR_EQUAL_P (_list, _list->__NEXT)) \
00254 _list = _list->__NEXT; \
00255 else \
00256 { \
00257 \
00258 __NODE_TYPE * _tmp = _list->__NEXT; \
00259 _list->__NEXT = _tmp->__NEXT; \
00260 \
00261 if (__LESS_THAN_OR_EQUAL_P (_current_run, _tmp)) \
00262 { \
00263 _tmp->__NEXT = _list; \
00264 _current_run->__NEXT = _tmp; \
00265 } \
00266 else \
00267 { \
00268 _tmp->__NEXT = _current_run; \
00269 _current_run->__NEXT = _list; \
00270 _current_run = _tmp; \
00271 } \
00272 } \
00273 \
00274 \
00275 while (_list->__NEXT != 0 \
00276 && __LESS_THAN_OR_EQUAL_P (_list, \
00277 (_list->__NEXT))) \
00278 _list = _list->__NEXT; \
00279 } \
00280 } \
00281 \
00282 { \
00283 __NODE_TYPE * _tmp = _list->__NEXT; \
00284 _list->__NEXT = 0; \
00285 _list = _tmp; \
00286 } \
00287 \
00288
00289
00290 \
00291 \
00292 if (!(++_run_number & 1)) \
00293 continue; \
00294 \
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 \
00310 \
00311 __FAST_MERGE_SORT_LABEL (final_merge): \
00312 { \
00313 unsigned long _tmp_run_number = _run_number; \
00314 \
00315 do \
00316 { \
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 \
00328 \
00329 register __NODE_TYPE * _other_run = *--_stack_ptr; \
00330 __NODE_TYPE * _output_run = _other_run; \
00331 register __NODE_TYPE ** _output_ptr = &_output_run; \
00332 \
00333 for (;;) \
00334 { \
00335 if (__LESS_THAN_OR_EQUAL_P (_other_run, _current_run)) \
00336 { \
00337 __FAST_MERGE_SORT_LABEL (merge_1): \
00338 _output_ptr = &_other_run->__NEXT; \
00339 _other_run = *_output_ptr; \
00340 if (_other_run != 0) \
00341 continue; \
00342 *_output_ptr = _current_run; \
00343 goto __FAST_MERGE_SORT_LABEL (merge_done); \
00344 } \
00345 *_output_ptr = _current_run; \
00346 goto __FAST_MERGE_SORT_LABEL (merge_2); \
00347 } \
00348 \
00349
00350 \
00351 \
00352 for (;;) \
00353 { \
00354 if (!__LESS_THAN_OR_EQUAL_P (_other_run, _current_run)) \
00355 { \
00356 __FAST_MERGE_SORT_LABEL (merge_2): \
00357 _output_ptr = &_current_run->__NEXT; \
00358 _current_run = *_output_ptr; \
00359 if (_current_run != 0) \
00360 continue; \
00361 *_output_ptr = _other_run; \
00362 goto __FAST_MERGE_SORT_LABEL (merge_done); \
00363 } \
00364 *_output_ptr = _other_run; \
00365 goto __FAST_MERGE_SORT_LABEL (merge_1); \
00366 } \
00367 \
00368 __FAST_MERGE_SORT_LABEL (merge_done): \
00369 _current_run = _output_run; \
00370 } \
00371 while ((_tmp_run_number >>= 1) & 1); \
00372 } \
00373 } \
00374 \
00375
00376
00377
00378
00379
00380
00381 \
00382 \
00383 _run_number = (1UL << (_stack_ptr \
00384 - (_stack + (__ASG || _stack [0] == 0)))) - 1; \
00385 if (_run_number) \
00386 goto __FAST_MERGE_SORT_LABEL (final_merge); \
00387 \
00388 __FAST_MERGE_SORT_LABEL (empty_list): \
00389 (__LIST) = _current_run; \
00390 } \
00391 while (0)
00392
00393 #endif
00394