authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-07-11 18:16:58+12:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-07-11 18:44:30+12:00
log9b054e73f6b9f946a404a7f0c8b6a90d83e4b928
tree2f5fe1ebbdf54f3e2d1847444f04c4450e99f4be
parentc6c49389ebd1503de38d9bb6ff6d9f6fba94d63b

Add generic comparator generator functions for sorting

- Copy-by-value instead of pointer where appropriate - Clean up old zig fmt issues

2 files changed, 87 insertions(+), 240 deletions(-)

std/macho.zig+1-1
...@@ -42,7 +42,7 @@ pub const Symbol = struct {...@@ -42,7 +42,7 @@ pub const Symbol = struct {
42 name: []const u8,42 name: []const u8,
43 address: u64,43 address: u64,
4444
45 fn addressLessThan(lhs: *const Symbol, rhs: *const Symbol) bool {45 fn addressLessThan(lhs: Symbol, rhs: Symbol) bool {
46 return lhs.address < rhs.address;46 return lhs.address < rhs.address;
47 }47 }
48};48};
std/sort.zig+86-239
...@@ -5,7 +5,7 @@ const math = std.math;...@@ -5,7 +5,7 @@ const math = std.math;
5const builtin = @import("builtin");5const builtin = @import("builtin");
66
7/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).7/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).
8pub fn insertionSort(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *const T) bool) void {8pub fn insertionSort(comptime T: type, items: []T, lessThan: fn (lhs: T, rhs: T) bool) void {
9 {9 {
10 var i: usize = 1;10 var i: usize = 1;
11 while (i < items.len) : (i += 1) {11 while (i < items.len) : (i += 1) {
...@@ -30,7 +30,7 @@ const Range = struct {...@@ -30,7 +30,7 @@ const Range = struct {
30 };30 };
31 }31 }
3232
33 fn length(self: *const Range) usize {33 fn length(self: Range) usize {
34 return self.end - self.start;34 return self.end - self.start;
35 }35 }
36};36};
...@@ -108,7 +108,7 @@ const Pull = struct {...@@ -108,7 +108,7 @@ const Pull = struct {
108108
109/// Stable in-place sort. O(n) best case, O(n*log(n)) worst case and average case. O(1) memory (no allocator required).109/// Stable in-place sort. O(n) best case, O(n*log(n)) worst case and average case. O(1) memory (no allocator required).
110/// Currently implemented as block sort.110/// Currently implemented as block sort.
111pub fn sort(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *const T) bool) void {111pub fn sort(comptime T: type, items: []T, lessThan: fn (lhs: T, rhs: T) bool) void {
112 // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c112 // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c
113 var cache: [512]T = undefined;113 var cache: [512]T = undefined;
114114
...@@ -131,16 +131,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *con...@@ -131,16 +131,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *con
131 // http://pages.ripco.net/~jgamble/nw.html131 // http://pages.ripco.net/~jgamble/nw.html
132 var iterator = Iterator.init(items.len, 4);132 var iterator = Iterator.init(items.len, 4);
133 while (!iterator.finished()) {133 while (!iterator.finished()) {
134 var order = []u8{134 var order = []u8{ 0, 1, 2, 3, 4, 5, 6, 7 };
135 0,
136 1,
137 2,
138 3,
139 4,
140 5,
141 6,
142 7,
143 };
144 const range = iterator.nextRange();135 const range = iterator.nextRange();
145136
146 const sliced_items = items[range.start..];137 const sliced_items = items[range.start..];
...@@ -741,7 +732,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *con...@@ -741,7 +732,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *con
741}732}
742733
743// merge operation without a buffer734// merge operation without a buffer
744fn mergeInPlace(comptime T: type, items: []T, A_arg: *const Range, B_arg: *const Range, lessThan: fn (*const T, *const T) bool) void {735fn mergeInPlace(comptime T: type, items: []T, A_arg: Range, B_arg: Range, lessThan: fn (T, T) bool) void {
745 if (A_arg.length() == 0 or B_arg.length() == 0) return;736 if (A_arg.length() == 0 or B_arg.length() == 0) return;
746737
747 // this just repeatedly binary searches into B and rotates A into position.738 // this just repeatedly binary searches into B and rotates A into position.
...@@ -762,8 +753,8 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: *const Range, B_arg: *const...@@ -762,8 +753,8 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: *const Range, B_arg: *const
762 // again, this is NOT a general-purpose solution – it only works well in this case!753 // again, this is NOT a general-purpose solution – it only works well in this case!
763 // kind of like how the O(n^2) insertion sort is used in some places754 // kind of like how the O(n^2) insertion sort is used in some places
764755
765 var A = A_arg.*;756 var A = A_arg;
766 var B = B_arg.*;757 var B = B_arg;
767758
768 while (true) {759 while (true) {
769 // find the first place in B where the first item in A needs to be inserted760 // find the first place in B where the first item in A needs to be inserted
...@@ -783,7 +774,7 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: *const Range, B_arg: *const...@@ -783,7 +774,7 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: *const Range, B_arg: *const
783}774}
784775
785// merge operation using an internal buffer776// merge operation using an internal buffer
786fn mergeInternal(comptime T: type, items: []T, A: *const Range, B: *const Range, lessThan: fn (*const T, *const T) bool, buffer: *const Range) void {777fn mergeInternal(comptime T: type, items: []T, A: Range, B: Range, lessThan: fn (T, T) bool, buffer: Range) void {
787 // whenever we find a value to add to the final array, swap it with the value that's already in that spot778 // whenever we find a value to add to the final array, swap it with the value that's already in that spot
788 // when this algorithm is finished, 'buffer' will contain its original contents, but in a different order779 // when this algorithm is finished, 'buffer' will contain its original contents, but in a different order
789 var A_count: usize = 0;780 var A_count: usize = 0;
...@@ -819,7 +810,7 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s...@@ -819,7 +810,7 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s
819810
820// combine a linear search with a binary search to reduce the number of comparisons in situations811// combine a linear search with a binary search to reduce the number of comparisons in situations
821// where have some idea as to how many unique values there are and where the next value might be812// where have some idea as to how many unique values there are and where the next value might be
822fn findFirstForward(comptime T: type, items: []T, value: *const T, range: *const Range, lessThan: fn (*const T, *const T) bool, unique: usize) usize {813fn findFirstForward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
823 if (range.length() == 0) return range.start;814 if (range.length() == 0) return range.start;
824 const skip = math.max(range.length() / unique, usize(1));815 const skip = math.max(range.length() / unique, usize(1));
825816
...@@ -833,7 +824,7 @@ fn findFirstForward(comptime T: type, items: []T, value: *const T, range: *const...@@ -833,7 +824,7 @@ fn findFirstForward(comptime T: type, items: []T, value: *const T, range: *const
833 return binaryFirst(T, items, value, Range.init(index - skip, index), lessThan);824 return binaryFirst(T, items, value, Range.init(index - skip, index), lessThan);
834}825}
835826
836fn findFirstBackward(comptime T: type, items: []T, value: *const T, range: *const Range, lessThan: fn (*const T, *const T) bool, unique: usize) usize {827fn findFirstBackward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
837 if (range.length() == 0) return range.start;828 if (range.length() == 0) return range.start;
838 const skip = math.max(range.length() / unique, usize(1));829 const skip = math.max(range.length() / unique, usize(1));
839830
...@@ -847,7 +838,7 @@ fn findFirstBackward(comptime T: type, items: []T, value: *const T, range: *cons...@@ -847,7 +838,7 @@ fn findFirstBackward(comptime T: type, items: []T, value: *const T, range: *cons
847 return binaryFirst(T, items, value, Range.init(index, index + skip), lessThan);838 return binaryFirst(T, items, value, Range.init(index, index + skip), lessThan);
848}839}
849840
850fn findLastForward(comptime T: type, items: []T, value: *const T, range: *const Range, lessThan: fn (*const T, *const T) bool, unique: usize) usize {841fn findLastForward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
851 if (range.length() == 0) return range.start;842 if (range.length() == 0) return range.start;
852 const skip = math.max(range.length() / unique, usize(1));843 const skip = math.max(range.length() / unique, usize(1));
853844
...@@ -861,7 +852,7 @@ fn findLastForward(comptime T: type, items: []T, value: *const T, range: *const...@@ -861,7 +852,7 @@ fn findLastForward(comptime T: type, items: []T, value: *const T, range: *const
861 return binaryLast(T, items, value, Range.init(index - skip, index), lessThan);852 return binaryLast(T, items, value, Range.init(index - skip, index), lessThan);
862}853}
863854
864fn findLastBackward(comptime T: type, items: []T, value: *const T, range: *const Range, lessThan: fn (*const T, *const T) bool, unique: usize) usize {855fn findLastBackward(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool, unique: usize) usize {
865 if (range.length() == 0) return range.start;856 if (range.length() == 0) return range.start;
866 const skip = math.max(range.length() / unique, usize(1));857 const skip = math.max(range.length() / unique, usize(1));
867858
...@@ -875,7 +866,7 @@ fn findLastBackward(comptime T: type, items: []T, value: *const T, range: *const...@@ -875,7 +866,7 @@ fn findLastBackward(comptime T: type, items: []T, value: *const T, range: *const
875 return binaryLast(T, items, value, Range.init(index, index + skip), lessThan);866 return binaryLast(T, items, value, Range.init(index, index + skip), lessThan);
876}867}
877868
878fn binaryFirst(comptime T: type, items: []T, value: *const T, range: *const Range, lessThan: fn (*const T, *const T) bool) usize {869fn binaryFirst(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool) usize {
879 var start = range.start;870 var start = range.start;
880 var end = range.end - 1;871 var end = range.end - 1;
881 if (range.start >= range.end) return range.end;872 if (range.start >= range.end) return range.end;
...@@ -893,7 +884,7 @@ fn binaryFirst(comptime T: type, items: []T, value: *const T, range: *const Rang...@@ -893,7 +884,7 @@ fn binaryFirst(comptime T: type, items: []T, value: *const T, range: *const Rang
893 return start;884 return start;
894}885}
895886
896fn binaryLast(comptime T: type, items: []T, value: *const T, range: *const Range, lessThan: fn (*const T, *const T) bool) usize {887fn binaryLast(comptime T: type, items: []T, value: T, range: Range, lessThan: fn (T, T) bool) usize {
897 var start = range.start;888 var start = range.start;
898 var end = range.end - 1;889 var end = range.end - 1;
899 if (range.start >= range.end) return range.end;890 if (range.start >= range.end) return range.end;
...@@ -911,7 +902,7 @@ fn binaryLast(comptime T: type, items: []T, value: *const T, range: *const Range...@@ -911,7 +902,7 @@ fn binaryLast(comptime T: type, items: []T, value: *const T, range: *const Range
911 return start;902 return start;
912}903}
913904
914fn mergeInto(comptime T: type, from: []T, A: *const Range, B: *const Range, lessThan: fn (*const T, *const T) bool, into: []T) void {905fn mergeInto(comptime T: type, from: []T, A: Range, B: Range, lessThan: fn (T, T) bool, into: []T) void {
915 var A_index: usize = A.start;906 var A_index: usize = A.start;
916 var B_index: usize = B.start;907 var B_index: usize = B.start;
917 const A_last = A.end;908 const A_last = A.end;
...@@ -941,7 +932,7 @@ fn mergeInto(comptime T: type, from: []T, A: *const Range, B: *const Range, less...@@ -941,7 +932,7 @@ fn mergeInto(comptime T: type, from: []T, A: *const Range, B: *const Range, less
941 }932 }
942}933}
943934
944fn mergeExternal(comptime T: type, items: []T, A: *const Range, B: *const Range, lessThan: fn (*const T, *const T) bool, cache: []T) void {935fn mergeExternal(comptime T: type, items: []T, A: Range, B: Range, lessThan: fn (T, T) bool, cache: []T) void {
945 // A fits into the cache, so use that instead of the internal buffer936 // A fits into the cache, so use that instead of the internal buffer
946 var A_index: usize = 0;937 var A_index: usize = 0;
947 var B_index: usize = B.start;938 var B_index: usize = B.start;
...@@ -969,27 +960,32 @@ fn mergeExternal(comptime T: type, items: []T, A: *const Range, B: *const Range,...@@ -969,27 +960,32 @@ fn mergeExternal(comptime T: type, items: []T, A: *const Range, B: *const Range,
969 mem.copy(T, items[insert_index..], cache[A_index..A_last]);960 mem.copy(T, items[insert_index..], cache[A_index..A_last]);
970}961}
971962
972fn swap(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *const T) bool, order: *[8]u8, x: usize, y: usize) void {963fn swap(comptime T: type, items: []T, lessThan: fn (lhs: T, rhs: T) bool, order: *[8]u8, x: usize, y: usize) void {
973 if (lessThan(items[y], items[x]) or ((order.*)[x] > (order.*)[y] and !lessThan(items[x], items[y]))) {964 if (lessThan(items[y], items[x]) or ((order.*)[x] > (order.*)[y] and !lessThan(items[x], items[y]))) {
974 mem.swap(T, &items[x], &items[y]);965 mem.swap(T, &items[x], &items[y]);
975 mem.swap(u8, &(order.*)[x], &(order.*)[y]);966 mem.swap(u8, &(order.*)[x], &(order.*)[y]);
976 }967 }
977}968}
978969
979fn i32asc(lhs: *const i32, rhs: *const i32) bool {970// Use these to generate a comparator function for a given type. e.g. `sort(u8, slice, asc(u8))`.
980 return lhs.* < rhs.*;971pub fn asc(comptime T: type) fn (T, T) bool {
981}972 const impl = struct {
973 fn inner(a: T, b: T) bool {
974 return a < b;
975 }
976 };
982977
983fn i32desc(lhs: *const i32, rhs: *const i32) bool {978 return impl.inner;
984 return rhs.* < lhs.*;
985}979}
986980
987fn u8asc(lhs: *const u8, rhs: *const u8) bool {981pub fn desc(comptime T: type) fn (T, T) bool {
988 return lhs.* < rhs.*;982 const impl = struct {
989}983 fn inner(a: T, b: T) bool {
984 return a > b;
985 }
986 };
990987
991fn u8desc(lhs: *const u8, rhs: *const u8) bool {988 return impl.inner;
992 return rhs.* < lhs.*;
993}989}
994990
995test "stable sort" {991test "stable sort" {
...@@ -998,119 +994,38 @@ test "stable sort" {...@@ -998,119 +994,38 @@ test "stable sort" {
998}994}
999fn testStableSort() void {995fn testStableSort() void {
1000 var expected = []IdAndValue{996 var expected = []IdAndValue{
1001 IdAndValue{997 IdAndValue{ .id = 0, .value = 0 },
1002 .id = 0,998 IdAndValue{ .id = 1, .value = 0 },
1003 .value = 0,999 IdAndValue{ .id = 2, .value = 0 },
1004 },1000 IdAndValue{ .id = 0, .value = 1 },
1005 IdAndValue{1001 IdAndValue{ .id = 1, .value = 1 },
1006 .id = 1,1002 IdAndValue{ .id = 2, .value = 1 },
1007 .value = 0,1003 IdAndValue{ .id = 0, .value = 2 },
1008 },1004 IdAndValue{ .id = 1, .value = 2 },
1009 IdAndValue{1005 IdAndValue{ .id = 2, .value = 2 },
1010 .id = 2,
1011 .value = 0,
1012 },
1013 IdAndValue{
1014 .id = 0,
1015 .value = 1,
1016 },
1017 IdAndValue{
1018 .id = 1,
1019 .value = 1,
1020 },
1021 IdAndValue{
1022 .id = 2,
1023 .value = 1,
1024 },
1025 IdAndValue{
1026 .id = 0,
1027 .value = 2,
1028 },
1029 IdAndValue{
1030 .id = 1,
1031 .value = 2,
1032 },
1033 IdAndValue{
1034 .id = 2,
1035 .value = 2,
1036 },
1037 };1006 };
1038 var cases = [][9]IdAndValue{1007 var cases = [][9]IdAndValue{
1039 []IdAndValue{1008 []IdAndValue{
1040 IdAndValue{1009 IdAndValue{ .id = 0, .value = 0 },
1041 .id = 0,1010 IdAndValue{ .id = 0, .value = 1 },
1042 .value = 0,1011 IdAndValue{ .id = 0, .value = 2 },
1043 },1012 IdAndValue{ .id = 1, .value = 0 },
1044 IdAndValue{1013 IdAndValue{ .id = 1, .value = 1 },
1045 .id = 0,1014 IdAndValue{ .id = 1, .value = 2 },
1046 .value = 1,1015 IdAndValue{ .id = 2, .value = 0 },
1047 },1016 IdAndValue{ .id = 2, .value = 1 },
1048 IdAndValue{1017 IdAndValue{ .id = 2, .value = 2 },
1049 .id = 0,
1050 .value = 2,
1051 },
1052 IdAndValue{
1053 .id = 1,
1054 .value = 0,
1055 },
1056 IdAndValue{
1057 .id = 1,
1058 .value = 1,
1059 },
1060 IdAndValue{
1061 .id = 1,
1062 .value = 2,
1063 },
1064 IdAndValue{
1065 .id = 2,
1066 .value = 0,
1067 },
1068 IdAndValue{
1069 .id = 2,
1070 .value = 1,
1071 },
1072 IdAndValue{
1073 .id = 2,
1074 .value = 2,
1075 },
1076 },1018 },
1077 []IdAndValue{1019 []IdAndValue{
1078 IdAndValue{1020 IdAndValue{ .id = 0, .value = 2 },
1079 .id = 0,1021 IdAndValue{ .id = 0, .value = 1 },
1080 .value = 2,1022 IdAndValue{ .id = 0, .value = 0 },
1081 },1023 IdAndValue{ .id = 1, .value = 2 },
1082 IdAndValue{1024 IdAndValue{ .id = 1, .value = 1 },
1083 .id = 0,1025 IdAndValue{ .id = 1, .value = 0 },
1084 .value = 1,1026 IdAndValue{ .id = 2, .value = 2 },
1085 },1027 IdAndValue{ .id = 2, .value = 1 },
1086 IdAndValue{1028 IdAndValue{ .id = 2, .value = 0 },
1087 .id = 0,
1088 .value = 0,
1089 },
1090 IdAndValue{
1091 .id = 1,
1092 .value = 2,
1093 },
1094 IdAndValue{
1095 .id = 1,
1096 .value = 1,
1097 },
1098 IdAndValue{
1099 .id = 1,
1100 .value = 0,
1101 },
1102 IdAndValue{
1103 .id = 2,
1104 .value = 2,
1105 },
1106 IdAndValue{
1107 .id = 2,
1108 .value = 1,
1109 },
1110 IdAndValue{
1111 .id = 2,
1112 .value = 0,
1113 },
1114 },1029 },
1115 };1030 };
1116 for (cases) |*case| {1031 for (cases) |*case| {
...@@ -1125,8 +1040,8 @@ const IdAndValue = struct {...@@ -1125,8 +1040,8 @@ const IdAndValue = struct {
1125 id: usize,1040 id: usize,
1126 value: i32,1041 value: i32,
1127};1042};
1128fn cmpByValue(a: *const IdAndValue, b: *const IdAndValue) bool {1043fn cmpByValue(a: IdAndValue, b: IdAndValue) bool {
1129 return i32asc(a.value, b.value);1044 return asc(i32)(a.value, b.value);
1130}1045}
11311046
1132test "std.sort" {1047test "std.sort" {
...@@ -1161,7 +1076,7 @@ test "std.sort" {...@@ -1161,7 +1076,7 @@ test "std.sort" {
1161 var buf: [8]u8 = undefined;1076 var buf: [8]u8 = undefined;
1162 const slice = buf[0..case[0].len];1077 const slice = buf[0..case[0].len];
1163 mem.copy(u8, slice, case[0]);1078 mem.copy(u8, slice, case[0]);
1164 sort(u8, slice, u8asc);1079 sort(u8, slice, asc(u8));
1165 assert(mem.eql(u8, slice, case[1]));1080 assert(mem.eql(u8, slice, case[1]));
1166 }1081 }
11671082
...@@ -1175,48 +1090,20 @@ test "std.sort" {...@@ -1175,48 +1090,20 @@ test "std.sort" {
1175 []i32{1},1090 []i32{1},
1176 },1091 },
1177 [][]const i32{1092 [][]const i32{
1178 []i32{1093 []i32{ 0, 1 },
1179 0,1094 []i32{ 0, 1 },
1180 1,
1181 },
1182 []i32{
1183 0,
1184 1,
1185 },
1186 },1095 },
1187 [][]const i32{1096 [][]const i32{
1188 []i32{1097 []i32{ 1, 0 },
1189 1,1098 []i32{ 0, 1 },
1190 0,
1191 },
1192 []i32{
1193 0,
1194 1,
1195 },
1196 },1099 },
1197 [][]const i32{1100 [][]const i32{
1198 []i32{1101 []i32{ 1, -1, 0 },
1199 1,1102 []i32{ -1, 0, 1 },
1200 -1,
1201 0,
1202 },
1203 []i32{
1204 -1,
1205 0,
1206 1,
1207 },
1208 },1103 },
1209 [][]const i32{1104 [][]const i32{
1210 []i32{1105 []i32{ 2, 1, 3 },
1211 2,1106 []i32{ 1, 2, 3 },
1212 1,
1213 3,
1214 },
1215 []i32{
1216 1,
1217 2,
1218 3,
1219 },
1220 },1107 },
1221 };1108 };
12221109
...@@ -1224,7 +1111,7 @@ test "std.sort" {...@@ -1224,7 +1111,7 @@ test "std.sort" {
1224 var buf: [8]i32 = undefined;1111 var buf: [8]i32 = undefined;
1225 const slice = buf[0..case[0].len];1112 const slice = buf[0..case[0].len];
1226 mem.copy(i32, slice, case[0]);1113 mem.copy(i32, slice, case[0]);
1227 sort(i32, slice, i32asc);1114 sort(i32, slice, asc(i32));
1228 assert(mem.eql(i32, slice, case[1]));1115 assert(mem.eql(i32, slice, case[1]));
1229 }1116 }
1230}1117}
...@@ -1240,48 +1127,20 @@ test "std.sort descending" {...@@ -1240,48 +1127,20 @@ test "std.sort descending" {
1240 []i32{1},1127 []i32{1},
1241 },1128 },
1242 [][]const i32{1129 [][]const i32{
1243 []i32{1130 []i32{ 0, 1 },
1244 0,1131 []i32{ 1, 0 },
1245 1,
1246 },
1247 []i32{
1248 1,
1249 0,
1250 },
1251 },1132 },
1252 [][]const i32{1133 [][]const i32{
1253 []i32{1134 []i32{ 1, 0 },
1254 1,1135 []i32{ 1, 0 },
1255 0,
1256 },
1257 []i32{
1258 1,
1259 0,
1260 },
1261 },1136 },
1262 [][]const i32{1137 [][]const i32{
1263 []i32{1138 []i32{ 1, -1, 0 },
1264 1,1139 []i32{ 1, 0, -1 },
1265 -1,
1266 0,
1267 },
1268 []i32{
1269 1,
1270 0,
1271 -1,
1272 },
1273 },1140 },
1274 [][]const i32{1141 [][]const i32{
1275 []i32{1142 []i32{ 2, 1, 3 },
1276 2,1143 []i32{ 3, 2, 1 },
1277 1,
1278 3,
1279 },
1280 []i32{
1281 3,
1282 2,
1283 1,
1284 },
1285 },1144 },
1286 };1145 };
12871146
...@@ -1289,28 +1148,16 @@ test "std.sort descending" {...@@ -1289,28 +1148,16 @@ test "std.sort descending" {
1289 var buf: [8]i32 = undefined;1148 var buf: [8]i32 = undefined;
1290 const slice = buf[0..case[0].len];1149 const slice = buf[0..case[0].len];
1291 mem.copy(i32, slice, case[0]);1150 mem.copy(i32, slice, case[0]);
1292 sort(i32, slice, i32desc);1151 sort(i32, slice, desc(i32));
1293 assert(mem.eql(i32, slice, case[1]));1152 assert(mem.eql(i32, slice, case[1]));
1294 }1153 }
1295}1154}
12961155
1297test "another sort case" {1156test "another sort case" {
1298 var arr = []i32{1157 var arr = []i32{ 5, 3, 1, 2, 4 };
1299 5,1158 sort(i32, arr[0..], asc(i32));
1300 3,1159
1301 1,1160 assert(mem.eql(i32, arr, []i32{ 1, 2, 3, 4, 5 }));
1302 2,
1303 4,
1304 };
1305 sort(i32, arr[0..], i32asc);
1306
1307 assert(mem.eql(i32, arr, []i32{
1308 1,
1309 2,
1310 3,
1311 4,
1312 5,
1313 }));
1314}1161}
13151162
1316test "sort fuzz testing" {1163test "sort fuzz testing" {
...@@ -1345,7 +1192,7 @@ fn fuzzTest(rng: *std.rand.Random) void {...@@ -1345,7 +1192,7 @@ fn fuzzTest(rng: *std.rand.Random) void {
1345 }1192 }
1346}1193}
13471194
1348pub fn min(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *const T) bool) T {1195pub fn min(comptime T: type, items: []T, lessThan: fn (lhs: T, rhs: T) bool) T {
1349 var i: usize = 0;1196 var i: usize = 0;
1350 var smallest = items[0];1197 var smallest = items[0];
1351 for (items[1..]) |item| {1198 for (items[1..]) |item| {
...@@ -1356,7 +1203,7 @@ pub fn min(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *cons...@@ -1356,7 +1203,7 @@ pub fn min(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *cons
1356 return smallest;1203 return smallest;
1357}1204}
13581205
1359pub fn max(comptime T: type, items: []T, lessThan: fn (lhs: *const T, rhs: *const T) bool) T {1206pub fn max(comptime T: type, items: []T, lessThan: fn (lhs: T, rhs: T) bool) T {
1360 var i: usize = 0;1207 var i: usize = 0;
1361 var biggest = items[0];1208 var biggest = items[0];
1362 for (items[1..]) |item| {1209 for (items[1..]) |item| {