1 module nxt.hybridsort; 2 3 import nxt.bijections : IntegralBijectableTypes; 4 5 static immutable size_t[IntegralBijectableTypes.length] radixSortMinLength; 6 7 shared static this() 8 { 9 foreach (i, E; IntegralBijectableTypes) 10 { 11 // TODO Calculate radixSortMinLength for E 12 radixSortMinLength[i] = 0; // calulate limit 13 } 14 } 15 16 import std.range.primitives : isRandomAccessRange; 17 18 /** Perform either radix or standard sort depending on `ElementType` of `Range`. 19 */ 20 auto hybridSort(alias less = "a < b", Range)(Range r) 21 if (isRandomAccessRange!Range) 22 { 23 import std.range.primitives : ElementType; 24 import std.traits : isNumeric; 25 static if (isNumeric!(ElementType!Range)) 26 { 27 import nxt.integer_sorting : radixSort; 28 return radixSort(r); 29 } 30 else 31 { 32 import std.algorithm.sorting : sort; 33 return sort!less(r); 34 } 35 } 36 37 unittest 38 { 39 import std.meta : AliasSeq; 40 41 const n = 1_000_000; 42 43 foreach (ix, T; AliasSeq!(byte, short)) 44 { 45 import std.container : Array; 46 import std.algorithm : isSorted, swap; 47 import nxt.random_ex : randInPlace; 48 49 auto a = Array!T(); 50 a.length = n; 51 52 randInPlace(a[]); 53 54 auto b = a.dup; 55 56 hybridSort(a[]); 57 assert(a[].isSorted); 58 59 import std.algorithm.sorting : sort; 60 sort(b[]); 61 assert(b[].isSorted); 62 63 assert(a == b); 64 65 swap(a, b); 66 } 67 }