@@ -676,44 +676,43 @@ private static EnumFieldInfo[] TopologicalSortEnumFields(EnumFieldInfo[] enumFie
676676 return enumFields ;
677677 }
678678
679- var indices = new int [ enumFields . Length ] ;
679+ var indices = new long [ enumFields . Length ] ;
680680 for ( int i = 0 ; i < enumFields . Length ; i ++ )
681681 {
682- indices [ i ] = i ;
682+ // we want values with more bits set to come first so negate the pop count
683+ int popCount = - PopCount ( enumFields [ i ] . Key ) ;
684+ // pack into a long with the pop count in the high bits and the index in the low bits
685+ // this allows us to sort by pop count and then by index in case of ties
686+ indices [ i ] = ( ( long ) popCount << 32 ) | ( uint ) i ;
683687 }
684688
685- Array . Sort ( indices , ( i , j ) => GetComparisonKey ( i ) . CompareTo ( GetComparisonKey ( j ) ) ) ;
689+ indices . AsSpan ( ) . Sort ( ) ;
686690
687691 var sortedFields = new EnumFieldInfo [ enumFields . Length ] ;
688692 for ( int i = 0 ; i < indices . Length ; i ++ )
689693 {
690- sortedFields [ i ] = enumFields [ indices [ i ] ] ;
694+ // extract the index from the long, which is the low bits
695+ // the high bits are the pop count, which we don't need anymore
696+ int index = ( int ) ( uint ) indices [ i ] ;
697+ sortedFields [ i ] = enumFields [ index ] ;
691698 }
692699
693700 return sortedFields ;
701+ }
694702
695- ( int PopCount , int Index ) GetComparisonKey ( int i )
696- {
697- // Sort by descending pop count of the enum value.
698- // Since Array.Sort isn't a stable algorithm
699- // append the current index to the comparison key.
700- return ( - PopCount ( enumFields [ i ] . Key ) , i ) ;
701- }
702-
703- static int PopCount ( ulong value )
704- {
703+ private static int PopCount ( ulong value )
704+ {
705705#if NET
706- return ( int ) ulong . PopCount ( value ) ;
706+ return ( int ) ulong . PopCount ( value ) ;
707707#else
708- int count = 0 ;
709- while ( value != 0 )
710- {
711- value &= value - 1 ;
712- count ++ ;
713- }
714- return count ;
715- #endif
708+ int count = 0 ;
709+ while ( value != 0 )
710+ {
711+ value &= value - 1 ;
712+ count ++ ;
716713 }
714+ return count ;
715+ #endif
717716 }
718717
719718 private enum EnumFieldNameKind
0 commit comments