subprojects/harfbuzz/src/hb-dsalgs.hh
static inline void sort_r_simple(void *base, size_t nel, size_t w,
				 int (*compar)(const void *_a, const void *_b,
					       void *_arg),
				 void *arg)
{
  char *b = (char *)base, *end = b + nel*w;
  if(nel < 7) {
    /* Insertion sort for arbitrarily small inputs */
    char *pi, *pj;
    for(pi = b+w; pi < end; pi += w) {
      for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {}
    }
  }
  else
  {
    /* nel > 6; Quicksort */

    /* Use median of first, middle and last items as pivot */
    char *x, *y, *xend, ch;
    char *pl, *pm, *pr;
    char *last = b+w*(nel-1), *tmp;
    char *l[3];
    l[0] = b;
    l[1] = b+w*(nel/2);
    l[2] = last;

    if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
    if(compar(l[1],l[2],arg) > 0) {
      tmp=l[1]; l[1]=l[2]; l[2]=tmp; /* swap(l[1],l[2]) */
      if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
    }

    /* swap l[id], l[2] to put pivot as last element */
    for(x = l[1], y = last, xend = x+w; x<xend; x++, y++) {
      ch = *x; *x = *y; *y = ch;
    }

    pl = b;
    pr = last;

    while(pl < pr) {
      pm = pl+((pr-pl+1)>>1);
      for(; pl < pm; pl += w) {
        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
          pr -= w; /* pivot now at pl */
          break;
        }
      }
      pm = pl+((pr-pl)>>1);
      for(; pm < pr; pr -= w) {
        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
          pl += w; /* pivot now at pr */
          break;
        }
      }
    }

    sort_r_simple(b, (pl-b)/w, w, compar, arg);
    sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg);
  }
}
/* Note: quicksort is not stable, equivalent values may be swapped */
quicksort is not stable, equivalent values may be swapped
quicksort is not stable equivalent values may be swapped
static inline void sort_r_simple(void *base, size_t nel, size_t w,
				 int (*compar)(const void *_a, const void *_b,
					       void *_arg),
				 void *arg)
{
  char *b = (char *)base, *end = b + nel*w;
  if(nel < 7) {
    char *pi, *pj;
    for(pi = b+w; pi < end; pi += w) {
      for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {}
    }
  }
  else
  {
    char *x, *y, *xend, ch;
    char *pl, *pm, *pr;
    char *last = b+w*(nel-1), *tmp;
    char *l[3];
    l[0] = b;
    l[1] = b+w*(nel/2);
    l[2] = last;
    if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
    if(compar(l[1],l[2],arg) > 0) {
      tmp=l[1]; l[1]=l[2]; l[2]=tmp; 
      if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
    }
    for(x = l[1], y = last, xend = x+w; x<xend; x++, y++) {
      ch = *x; *x = *y; *y = ch;
    }
    pl = b;
    pr = last;
    while(pl < pr) {
      pm = pl+((pr-pl+1)>>1);
      for(; pl < pm; pl += w) {
        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
          pr -= w; 
          break;
        }
      }
      pm = pl+((pr-pl)>>1);
      for(; pm < pr; pr -= w) {
        if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
          pl += w; 
          break;
        }
      }
    }
    sort_r_simple(b, (pl-b)/w, w, compar, arg);
    sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg);
  }
}
static inline void sort_r_simple ( void * base , size_t nel , size_t w , int ( * compar ) ( const void * _a , const void * _b , void * _arg ) , void * arg ) { char * b = ( char * ) base , * end = b + nel * w ; if ( nel < 7 ) { char * pi , * pj ; for ( pi = b + w ; pi < end ; pi += w ) { for ( pj = pi ; pj > b && sort_r_cmpswap ( pj - w , pj , w , compar , arg ) ; pj -= w ) { } } } else { char * x , * y , * xend , ch ; char * pl , * pm , * pr ; char * last = b + w * ( nel - 1 ) , * tmp ; char * l [ 3 ] ; l [ 0 ] = b ; l [ 1 ] = b + w * ( nel / 2 ) ; l [ 2 ] = last ; if ( compar ( l [ 0 ] , l [ 1 ] , arg ) > 0 ) { tmp = l [ 0 ] ; l [ 0 ] = l [ 1 ] ; l [ 1 ] = tmp ; } if ( compar ( l [ 1 ] , l [ 2 ] , arg ) > 0 ) { tmp = l [ 1 ] ; l [ 1 ] = l [ 2 ] ; l [ 2 ] = tmp ; if ( compar ( l [ 0 ] , l [ 1 ] , arg ) > 0 ) { tmp = l [ 0 ] ; l [ 0 ] = l [ 1 ] ; l [ 1 ] = tmp ; } } for ( x = l [ 1 ] , y = last , xend = x + w ; x < xend ; x ++ , y ++ ) { ch = * x ; * x = * y ; * y = ch ; } pl = b ; pr = last ; while ( pl < pr ) { pm = pl + ( ( pr - pl + 1 ) >> 1 ) ; for ( ; pl < pm ; pl += w ) { if ( sort_r_cmpswap ( pl , pr , w , compar , arg ) ) { pr -= w ; break ; } } pm = pl + ( ( pr - pl ) >> 1 ) ; for ( ; pm < pr ; pr -= w ) { if ( sort_r_cmpswap ( pl , pr , w , compar , arg ) ) { pl += w ; break ; } } } sort_r_simple ( b , ( pl - b ) / w , w , compar , arg ) ; sort_r_simple ( pl + w , ( end - ( pl + w ) ) / w , w , compar , arg ) ; } }
Note: quicksort is not stable, equivalent values may be swapped
Note : quicksort is not stable equivalent values may be swapped
/* Insertion sort for arbitrarily small inputs */ /* nel > 6; Quicksort */ /* Use median of first, middle and last items as pivot */ /* swap(l[1],l[2]) */ /* swap l[id], l[2] to put pivot as last element */ /* pivot now at pl */ /* pivot now at pr */