44 static constexpr 
int kRadixBits = 8;
 
   45 static constexpr 
size_t kInsertSortThreshold = 64;
 
   46 static constexpr 
int kRadixMask = (1 << kRadixBits) - 1;
 
   47 static constexpr 
int kRadixBin = 1 << kRadixBits;
 
   52 struct RadixTraitsUnsigned
 
   54   static constexpr 
int nBytes = 
sizeof(T);
 
   55   int kth_byte(
const T& x, 
int k) { 
return (x >> (kRadixBits * k)) & kRadixMask; }
 
   56   bool compare(
const T& x, 
const T& y) { 
return x < y; }
 
   60 struct RadixTraitsSigned
 
   62   static constexpr 
int nBytes = 
sizeof(T);
 
   63   static const T kMSB = T(0x80) << ((
sizeof(T) - 1) * 8);
 
   64   int kth_byte(
const T& x, 
int k) { 
return ((x ^ kMSB) >> (kRadixBits * k)) & kRadixMask; }
 
   65   bool compare(
const T& x, 
const T& y) { 
return x < y; }
 
   68 template <
class RandomIt, 
class ValueType, 
class RadixTraits>
 
   69 inline void insert_sort_core_(RandomIt s, RandomIt e, RadixTraits radix_traits)
 
   71   for (RandomIt i = s + 1; i < e; ++i)
 
   73     if (radix_traits.compare(*i, *(i - 1)))
 
   78       for (j = i - 1; j > s && radix_traits.compare(tmp, *(j - 1)); --j)
 
   87 template <
class RandomIt, 
class ValueType, 
class RadixTraits, 
int kWhichByte>
 
   88 inline void radix_sort_core_(RandomIt s, RandomIt e, RadixTraits radix_traits)
 
   90   RandomIt last_[kRadixBin + 1];
 
   91   RandomIt* last = last_ + 1;
 
   92   size_t count[kRadixBin] = { 0 };
 
   94   for (RandomIt i = s; i < e; ++i)
 
   96     ++count[radix_traits.kth_byte(*i, kWhichByte)];
 
   99   last_[0] = last_[1] = s;
 
  101   for (
int i = 1; i < kRadixBin; ++i)
 
  103     last[i] = last[i - 1] + count[i - 1];
 
  106   for (
int i = 0; i < kRadixBin; ++i)
 
  108     RandomIt end = last[i - 1] + count[i];
 
  114     while (last[i] != end)
 
  116       ValueType swapper = *last[i];
 
  117       int tag = radix_traits.kth_byte(swapper, kWhichByte);
 
  122           std::swap(swapper, *last[tag]++);
 
  123         } 
while ((tag = radix_traits.kth_byte(swapper, kWhichByte)) != i);
 
  132     for (
int i = 0; i < kRadixBin; ++i)
 
  134       if (count[i] > kInsertSortThreshold)
 
  136         radix_sort_core_<RandomIt, ValueType, RadixTraits, (kWhichByte > 0 ? (kWhichByte - 1) : 0)>(
 
  137           last[i - 1], last[i], radix_traits);
 
  139       else if (count[i] > 1)
 
  141         insert_sort_core_<RandomIt, ValueType, RadixTraits>(last[i - 1], last[i], radix_traits);
 
  147 template <
class RandomIt, 
class ValueType, 
class RadixTraits>
 
  148 inline void radix_sort_entry_(RandomIt s, RandomIt e, ValueType*, RadixTraits radix_traits)
 
  150   if (e - s <= (
int)kInsertSortThreshold)
 
  151     insert_sort_core_<RandomIt, ValueType, RadixTraits>(s, e, radix_traits);
 
  153     radix_sort_core_<RandomIt, ValueType, RadixTraits, RadixTraits::nBytes - 1>(s, e, radix_traits);
 
  156 template <
class RandomIt, 
class ValueType>
 
  157 inline void radix_sort_entry_(RandomIt s, RandomIt e, ValueType*)
 
  159   if (ValueType(-1) > ValueType(0))
 
  161     radix_sort_entry_(s, e, (ValueType*)(0), RadixTraitsUnsigned<ValueType>());
 
  165     radix_sort_entry_(s, e, (ValueType*)(0), RadixTraitsSigned<ValueType>());
 
  171 template <
class RandomIt, 
class RadixTraits>
 
  172 inline void radix_sort(RandomIt s, RandomIt e, RadixTraits radix_traits)
 
  174   typename std::iterator_traits<RandomIt>::value_type* dummy(0);
 
  175   radix_sort_entry_(s, e, dummy, radix_traits);
 
  178 template <
class RandomIt>
 
  179 inline void radix_sort(RandomIt s, RandomIt e)
 
  181   typename std::iterator_traits<RandomIt>::value_type* dummy(0);
 
  182   radix_sort_entry_(s, e, dummy);