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 ///
38 unittest {
39 	import std.meta : AliasSeq;
40 	const n = 10_000;
41 	foreach (ix, T; AliasSeq!(byte, short))
42 	{
43 		import std.container : Array;
44 		import std.algorithm : isSorted, swap;
45 		import nxt.random_ex : randInPlace;
46 
47 		auto a = Array!T();
48 		a.length = n;
49 
50 		randInPlace(a[]);
51 
52 		auto b = a.dup;
53 
54 		hybridSort(a[]);
55 		assert(a[].isSorted);
56 
57 		import std.algorithm.sorting : sort;
58 		sort(b[]);
59 		assert(b[].isSorted);
60 
61 		assert(a == b);
62 
63 		swap(a, b);
64 	}
65 }