fix radsort multi-inclusion

This commit is contained in:
Ryan Fleury
2025-06-10 15:15:54 -07:00
parent b8c0a6c4f0
commit 0ad3bb1550
+25 -20
View File
@@ -1,5 +1,8 @@
// New radsort. // New radsort.
#if !defined(RADSORT_H)
#define RADSORT_H
// To Use: // To Use:
// Create a less_than function and then call radsort. // Create a less_than function and then call radsort.
// //
@@ -49,7 +52,7 @@ typedef struct bytes8 { char b[8]; } bytes8;
static RSFORCEINLINE void radsortswapper( void * a, void * b, size_t size ) static RSFORCEINLINE void radsortswapper( void * a, void * b, size_t size )
{ {
#define RSSWAPMEM(type) ( size >= sizeof(type) ) { type v = *(type const*)a; *(type*)a = *(type const*)b; *(type*)b = v; a=rsadd_ptr(a,sizeof(type)); b=rsadd_ptr(b,sizeof(type)); size -= sizeof(type); } #define RSSWAPMEM(type) ( size >= sizeof(type) ) { type v = *(type const*)a; *(type*)a = *(type const*)b; *(type*)b = v; a=rsadd_ptr(a,sizeof(type)); b=rsadd_ptr(b,sizeof(type)); size -= sizeof(type); }
while RSSWAPMEM(bytes64); while RSSWAPMEM(bytes64);
if RSSWAPMEM(bytes32); if RSSWAPMEM(bytes32);
@@ -59,13 +62,13 @@ static RSFORCEINLINE void radsortswapper( void * a, void * b, size_t size )
if RSSWAPMEM(short); if RSSWAPMEM(short);
if RSSWAPMEM(char); if RSSWAPMEM(char);
#undef RSSWAPMEM #undef RSSWAPMEM
} }
// since size is always constant, this big function compiles down to 4 to 12 instructions (for normal structs 4-6) // since size is always constant, this big function compiles down to 4 to 12 instructions (for normal structs 4-6)
static RSFORCEINLINE void radsortmover( void * a, void * b, size_t size ) static RSFORCEINLINE void radsortmover( void * a, void * b, size_t size )
{ {
#define RSMOVEMEM(type) ( size >= sizeof(type) ) { *(type*)a = *(type const*)b; a=rsadd_ptr(a,sizeof(type)); b=rsadd_ptr(b,sizeof(type)); size -= sizeof(type); } #define RSMOVEMEM(type) ( size >= sizeof(type) ) { *(type*)a = *(type const*)b; a=rsadd_ptr(a,sizeof(type)); b=rsadd_ptr(b,sizeof(type)); size -= sizeof(type); }
while RSMOVEMEM(bytes64); while RSMOVEMEM(bytes64);
if RSMOVEMEM(bytes32); if RSMOVEMEM(bytes32);
@@ -75,7 +78,7 @@ static RSFORCEINLINE void radsortmover( void * a, void * b, size_t size )
if RSMOVEMEM(short); if RSMOVEMEM(short);
if RSMOVEMEM(char); if RSMOVEMEM(char);
#undef RSMOVEMEM #undef RSMOVEMEM
} }
// these macros generate tiny move/swap routines that don't go through the generic function above (mostly for debug build performance) // these macros generate tiny move/swap routines that don't go through the generic function above (mostly for debug build performance)
@@ -110,17 +113,17 @@ typedef void rs_small_sort_func( void * left, size_t n, size_t element_size, is_
typedef struct RS_MAX_BUBBLE_BUF { char b[RS_SMALL_FLIP_TO_INSERTION_GT_SIZE]; } RS_MAX_BUBBLE_BUF; typedef struct RS_MAX_BUBBLE_BUF { char b[RS_SMALL_FLIP_TO_INSERTION_GT_SIZE]; } RS_MAX_BUBBLE_BUF;
#define radsort( start, len, is_before_func ) \ #define radsort( start, len, is_before_func ) \
do { \ do { \
char __rs_tmp[ sizeof( (start)[0] ) ]; \ char __rs_tmp[ sizeof( (start)[0] ) ]; \
radsortinternal( start, len, sizeof( (start)[0] ), \ radsortinternal( start, len, sizeof( (start)[0] ), \
is_before_func, \ is_before_func, \
radsortswapsize( sizeof( (start)[0] ) ), \ radsortswapsize( sizeof( (start)[0] ) ), \
radsortmovesize( sizeof( (start)[0] ) ), \ radsortmovesize( sizeof( (start)[0] ) ), \
( sizeof( (start)[0] ) > RS_SMALL_FLIP_TO_INSERTION_GT_SIZE ) ? radinsertionsort : radbubble2sort, \ ( sizeof( (start)[0] ) > RS_SMALL_FLIP_TO_INSERTION_GT_SIZE ) ? radinsertionsort : radbubble2sort, \
( sizeof( (start)[0] ) > RS_SMALL_FLIP_TO_INSERTION_GT_SIZE ) ? RSS_FLIP_TO_SMALL_SORT_INSERTION : RSS_FLIP_TO_SMALL_SORT_BUBBLE2, \ ( sizeof( (start)[0] ) > RS_SMALL_FLIP_TO_INSERTION_GT_SIZE ) ? RSS_FLIP_TO_SMALL_SORT_INSERTION : RSS_FLIP_TO_SMALL_SORT_BUBBLE2, \
&__rs_tmp \ &__rs_tmp \
); \ ); \
} while (0) } while (0)
#define radheapsort( start, len, is_before_func ) do { radheapsortinteral( start, len, sizeof( ((start)[0]) ), is_before_func, radsortswapsize( sizeof( ((start)[0]) ) ) ); } while (0) #define radheapsort( start, len, is_before_func ) do { radheapsortinteral( start, len, sizeof( ((start)[0]) ), is_before_func, radsortswapsize( sizeof( ((start)[0]) ) ) ); } while (0)
@@ -227,7 +230,7 @@ static RSFORCEINLINE void radsortgetmedian9( void * output, void * left, void *
{ {
RS_MAX_SIMPLE_BUF mb0,mb1,mb2,mb3,mb4,mb5,mb6,mb7,mb8; // todo, temp mem! RS_MAX_SIMPLE_BUF mb0,mb1,mb2,mb3,mb4,mb5,mb6,mb7,mb8; // todo, temp mem!
#ifdef RS_PREFETCH #ifdef RS_PREFETCH
RS_PREFETCH( left ); RS_PREFETCH( left );
RS_PREFETCH( right ); RS_PREFETCH( right );
RS_PREFETCH( rsadd_ptr_elements( left, length >> 3 ) ); RS_PREFETCH( rsadd_ptr_elements( left, length >> 3 ) );
@@ -237,7 +240,7 @@ static RSFORCEINLINE void radsortgetmedian9( void * output, void * left, void *
RS_PREFETCH( rsadd_ptr_elements( left, (length >> 1) + (0 >> 3) ) ); RS_PREFETCH( rsadd_ptr_elements( left, (length >> 1) + (0 >> 3) ) );
RS_PREFETCH( rsadd_ptr_elements( left, length - (length >> 2) ) ); RS_PREFETCH( rsadd_ptr_elements( left, length - (length >> 2) ) );
RS_PREFETCH( rsadd_ptr_elements( left, length - (length >> 3) ) ); RS_PREFETCH( rsadd_ptr_elements( left, length - (length >> 3) ) );
#endif #endif
mover( &mb0, left, element_size ); mover( &mb0, left, element_size );
mover( &mb1, rsadd_ptr_elements( left, length >> 3 ), element_size ); mover( &mb1, rsadd_ptr_elements( left, length >> 3 ), element_size );
@@ -302,7 +305,7 @@ static RSFORCEINLINE void radbubble2sort( void * left, size_t n, size_t element_
void * s = rsadd_ptr_elements( left, 2 ); void * s = rsadd_ptr_elements( left, 2 );
RS_MAX_BUBBLE_BUF x, y, z; RS_MAX_BUBBLE_BUF x, y, z;
#define rsbubbleswap( X, Y ) { int cond; cond = is_before( &Y, &X); mover( tmp, &X, element_size ); if ( cond ) mover( &X, &Y, element_size ); if ( cond ) mover( &Y, tmp, element_size ); } #define rsbubbleswap( X, Y ) { int cond; cond = is_before( &Y, &X); mover( tmp, &X, element_size ); if ( cond ) mover( &X, &Y, element_size ); if ( cond ) mover( &Y, tmp, element_size ); }
for ( i = rsadd_ptr_elements( left, (int)n - 1 ) ; i > left ; i = rsadd_ptr_elements( i, -2 ) ) for ( i = rsadd_ptr_elements( left, (int)n - 1 ) ; i > left ; i = rsadd_ptr_elements( i, -2 ) )
{ {
@@ -428,10 +431,10 @@ RSFORCEINLINE void radsortinternal( void * start, size_t len, size_t element_siz
if ( len <= 1 ) if ( len <= 1 )
return; return;
#if _DEBUG #if _DEBUG
if ( element_size > sizeof( RS_MAX_SIMPLE_BUF ) ) if ( element_size > sizeof( RS_MAX_SIMPLE_BUF ) )
__debugbreak(); __debugbreak();
#endif #endif
// stack for no recursion // stack for no recursion
typedef struct stks typedef struct stks
@@ -605,3 +608,5 @@ RSFORCEINLINE void radsortinternal( void * start, size_t len, size_t element_siz
#undef rsadd_ptr #undef rsadd_ptr
#undef rsadd_ptr_elements #undef rsadd_ptr_elements
#undef rsdiff_ptr_elements #undef rsdiff_ptr_elements
#endif // RADSORT_H