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 }