diff --git a/src/fsort.c b/src/fsort.c index 7cf6896a6c838eb8c768bb0eafc990c068cb3165..71256c7121681011c22b59e1f9876e44a0196ae7 100644 --- a/src/fsort.c +++ b/src/fsort.c @@ -14,89 +14,62 @@ static long size; static char *tmp_area; #define SWAP(X,Y) { tmp=*(X); *(X)=*(Y); *(Y)=tmp; } +#define STEP(X,Y) ((X)+(Y)) -#define FSORT(ID,TYPE) \ -static void ID(register TYPE *bas,register TYPE *last) \ -{ \ - register TYPE *a,*b, tmp; \ - if(bas >= last) return; \ - a = bas + 1; \ - if(a == last) \ - { \ - if( (*cmpfun)((void *)bas,(void *)last) > 0) SWAP(bas,last); \ - }else{ \ - b=bas+((last-bas)>>1); \ - SWAP(bas,b); \ - b=last; \ - while(a < b) \ - { \ - while(a<=b && (*cmpfun)((void *)a,(void *)bas) < 0) a++; \ - while(a< b && (*cmpfun)((void *)bas,(void *)b) < 0) b--; \ - if(a<b) \ - { \ - SWAP(a,b); \ - a++; \ - if(b > a+1) b--; \ - } \ - } \ - a--; \ - SWAP(a,bas); \ - a--; \ - ID(bas,a); \ - ID(b,last); \ - } \ -} +#define ID fsort_1 +typedef struct a1 { char b[1]; } b1; +#define TYPE b1 +#include "fsort_template.h" +#undef ID +#undef TYPE -#define FSWAP(X,Y) \ - { \ - MEMCPY(tmp_area,X,size); \ - MEMCPY(X,Y,size); \ - MEMCPY(Y,tmp_area,size); \ - } +#define ID fsort_2 +typedef struct a2 { char b[2]; } b2; +#define TYPE b2 +#include "fsort_template.h" +#undef ID +#undef TYPE -static void fsort_n(register char *bas,register char *last) -{ - register char *a,*b; - register int dum; +#define ID fsort_4 +typedef struct a4 { char b[4]; } b4; +#define TYPE b4 +#include "fsort_template.h" +#undef ID +#undef TYPE - if(bas>=last) return; - a=bas+size; - if(a==last) - { - if((*cmpfun)(bas,last) > 0) FSWAP(bas,last); - }else{ - dum=(last-bas)>>1; - dum-=dum % size; - FSWAP(bas,bas+dum); - b=last; - while(a<b) - { - while(a<=b && (*cmpfun)(a,bas) < 0) a+=size; - while(a< b && (*cmpfun)(bas,b) < 0) b-=size; - if(a<b) - { - FSWAP(a,b); - a+=size; - if(b-a>size) b-=size; - } - } - a-=size; - FSWAP(bas,a); - a-=size; - fsort_n(bas,a); - fsort_n(b,last); - } -} -typedef struct a { char b[1]; } onebyte; -typedef struct b { char b[2]; } twobytes; -typedef struct c { char b[4]; } fourbytes; -typedef struct d { char b[8]; } eightbytes; +#define ID fsort_8 +typedef struct a8 { char b[8]; } b8; +#define TYPE b8 +#include "fsort_template.h" +#undef ID +#undef TYPE + +#define ID fsort_16 +typedef struct a16 { char b[16]; } b16; +#define TYPE b16 +#include "fsort_template.h" +#undef ID +#undef TYPE + +#undef SWAP +#undef STEP + + +#define SWAP(X,Y) do { \ + MEMCPY(tmp_area,X,size); \ + MEMCPY(X,Y,size); \ + MEMCPY(Y,tmp_area,size); \ + } while(0) -FSORT(fsort_1, onebyte) -FSORT(fsort_2, twobytes) -FSORT(fsort_4, fourbytes) -FSORT(fsort_8, eightbytes) +#define STEP(X,Y) ((X)+(Y)*size) +#define TYPE char +#define ID fsort_n +#include "fsort_template.h" +#undef ID +#undef TYPE +#undef SWAP +#undef STEP void fsort(void *base, long elms, @@ -110,10 +83,11 @@ void fsort(void *base, switch(elmSize) { - case 1: fsort_1((onebyte *)base,(elms-1)+(onebyte *)base); break; - case 2: fsort_2((twobytes *)base,(elms-1)+(twobytes *)base); break; - case 4: fsort_4((fourbytes *)base,(elms-1)+(fourbytes *)base); break; - case 8: fsort_8((eightbytes *)base,(elms-1)+(eightbytes *)base); break; + case 1: fsort_1(( b1 *)base,(elms-1)+( b1 *)base); break; + case 2: fsort_2(( b2 *)base,(elms-1)+( b2 *)base); break; + case 4: fsort_4(( b4 *)base,(elms-1)+( b4 *)base); break; + case 8: fsort_8(( b8 *)base,(elms-1)+( b8 *)base); break; + case 16: fsort_16((b16 *)base,(elms-1)+(b16 *)base); break; default: tmp_area=(char *)alloca(elmSize); fsort_n((char *)base,((char *)base) + size * (elms - 1)); diff --git a/src/fsort_template.h b/src/fsort_template.h new file mode 100644 index 0000000000000000000000000000000000000000..6c0e9fc6123cc6142e57c45d0a2ffb0d9cbfc441 --- /dev/null +++ b/src/fsort_template.h @@ -0,0 +1,68 @@ +#define INC(X) X=STEP(X,1) +#define DEC(X) X=STEP(X,-1) +#define SIZE ((long)STEP((TYPE *)0,1)) + +static void ID(register TYPE *bas, register TYPE *last) +{ + register TYPE *a,*b, tmp; + if(bas >= last) return; + a = STEP(bas,1); + if(a == last) + { + if( (*cmpfun)((void *)bas,(void *)last) > 0) SWAP(bas,last); + }else{ + b=STEP(bas,((((char *)last)-((char *)bas))/SIZE)>>1); + SWAP(bas,b); + b=last; + while(a < b) + { +#if 1 + while(a<b) + { + while(1) + { + if(a<=b && (*cmpfun)((void *)a,(void *)bas) <= 0) + INC(a); + else + { + while(a< b && (*cmpfun)((void *)bas,(void *)b) <= 0) DEC(b); + break; + } + if(a< b && (*cmpfun)((void *)bas,(void *)b) <= 0) + DEC(b); + else + { + while(a<=b && (*cmpfun)((void *)a,(void *)bas) <= 0) INC(a); + break; + } + } + + if(a<b) + { + SWAP(a,b); + INC(a); + if(b > STEP(a,1)) DEC(b); + } + } +#else + while(a<=b && (*cmpfun)((void *)a,(void *)bas) < 0) INC(a); + while(a< b && (*cmpfun)((void *)bas,(void *)b) < 0) DEC(b); + if(a<b) + { + SWAP(a,b); + INC(a); + if(b > STEP(a,1)) DEC(b); + } +#endif + } + DEC(a); + SWAP(a,bas); + DEC(a); + ID(bas,a); + ID(b,last); + } +} + +#undef INC +#undef DEC +#undef SIZE