1
  
2
  
3
  
4
  
5
  
6
  
7
  
8
  
9
  
10
  
11
  
12
  
13
  
14
  
15
  
16
  
17
  
18
  
19
  
20
  
21
  
22
  
23
  
24
  
25
  
26
  
27
  
28
  
29
  
30
  
31
  
32
  
33
  
34
  
35
  
36
  
37
  
38
  
39
  
40
  
41
  
42
  
43
  
44
  
45
  
46
  
47
  
48
  
49
  
50
  
51
  
52
  
53
  
54
  
55
  
56
  
57
  
58
  
59
  
60
  
61
  
62
  
63
  
64
  
65
  
66
  
67
  
68
  
69
  
70
  
71
  
72
  
73
  
74
  
75
  
76
  
77
  
78
  
79
  
80
  
81
  
82
  
83
  
84
  
85
  
86
  
87
  
88
  
89
  
90
  
91
  
92
  
93
  
94
  
95
  
96
  
97
  
98
  
99
  
100
  
101
  
102
  
103
  
104
  
105
  
106
  
107
  
108
  
109
  
110
  
111
  
112
  
113
  
114
  
115
  
116
  
117
  
118
  
119
  
120
  
121
  
122
  
123
  
124
  
125
  
126
  
127
  
/* 
|| This file is part of Pike. For copyright information see COPYRIGHT. 
|| Pike is distributed under GPL, LGPL and MPL. See the file COPYING 
|| for more information. 
*/ 
 
/* fsort- a smarter quicksort /Hubbe */ 
/* Optimized for minimum amount of compares */ 
 
#include "global.h" 
#include "pike_error.h" 
#include "fsort.h" 
#include "pike_embed.h" 
#include "pike_macros.h" 
 
#define CMP(X,Y) ( (*cmpfun)((void *)(X),(void *)(Y)) ) 
#define EXTRA_ARGS ,fsortfun cmpfun 
#define XARGS ,cmpfun 
 
#define ID fsort_1 
#define TYPE B1_T 
#include "fsort_template.h" 
#undef ID 
#undef TYPE 
 
#ifdef B2_T 
#define ID fsort_2 
#define TYPE B2_T 
#include "fsort_template.h" 
#undef ID 
#undef TYPE 
#endif 
 
#ifdef B4_T 
#define ID fsort_4 
#define TYPE B4_T 
#include "fsort_template.h" 
#undef ID 
#undef TYPE 
#endif 
 
 
#ifdef B8_T 
#define ID fsort_8 
#define TYPE B8_T 
#include "fsort_template.h" 
#undef ID 
#undef TYPE 
#endif 
 
 
#ifdef B16_T 
#define ID fsort_16 
#define TYPE B16_T 
#include "fsort_template.h" 
#undef ID 
#undef TYPE 
#endif 
 
 
#undef EXTRA_ARGS 
#undef XARGS 
 
#define EXTRA_ARGS , fsortfun cmpfun, char *tmp_area, long size 
#define XARGS , cmpfun, tmp_area, size 
 
#define SWAP(X,Y) do { \ 
    memcpy(tmp_area,X,size); \ 
    memcpy(X,Y,size); \ 
    memcpy(Y,tmp_area,size); \ 
 } while(0) 
 
#define STEP(X,Y) ((X)+(Y)*size) 
#define TYPE char 
#define ID fsort_n 
#define TMP_AREA 
#include "fsort_template.h" 
#undef ID 
#undef TYPE 
#undef EXTRA_ARGS 
#undef XARGS 
 
PMOD_EXPORT void fsort(void *base, 
                       long elms, 
                       long elmSize, 
                       fsortfun cmpfunc) 
{ 
 
  if(elms<=0) return; 
 
#ifdef HANDLES_UNALIGNED_MEMORY_ACCESS 
  switch(elmSize) 
#else 
  switch( (((size_t)base) % elmSize) ? 0 : elmSize ) 
#endif 
  { 
  case  1:  fsort_1(( B1_T *)base,(elms-1)+( B1_T *)base, cmpfunc); break; 
#ifdef B2_T 
  case  2:  fsort_2(( B2_T *)base,(elms-1)+( B2_T *)base, cmpfunc); break; 
#endif 
#ifdef B4_T 
  case  4:  fsort_4(( B4_T *)base,(elms-1)+( B4_T *)base, cmpfunc); break; 
#endif 
#ifdef B8_T 
  case  8:  fsort_8(( B8_T *)base,(elms-1)+( B8_T *)base, cmpfunc); break; 
#endif 
#ifdef B16_T 
  case 16: fsort_16((B16_T *)base,(elms-1)+(B16_T *)base, cmpfunc); break; 
#endif 
  default: 
    { 
      /* NOTE: We need to put the alloca'd value in a variable, 
       *       otherwise cc/HPUX will generate broken code. 
       *       Hmm, that didn't work, but reordering the arguments, 
       *       putting size last seems to have fixed the problem... 
       *       /grubba hunting compiler bugs 2002-09-03 
       */ 
      char *buf = alloca(elmSize); 
 
      fsort_n((char *)base,((char *)base) + elmSize * (elms - 1), 
              cmpfunc, buf, elmSize); 
    } 
  } 
 
}