Playing around with an insertion sort using the same arguments as std.mem.sort, I’m finding that my function works with a lessThanFn having anytype arguments, but I could not get std.mem.sort to allow such a function. Why does lessThan below work with my insertionSort but not with std.mem.sort?
Why would null, 1, and u16 be allowed as context by insertionSort, but not true or [_]u16{ 9001, 9002 } or {}, i.e., what do the working values have in common that is not shared by the failing values?
const std = @import("std");
const ElementType = u8;
fn lessThan(_: anytype, a: anytype, b: anytype) bool {
return a < b;
}
fn lessThanExplicit(_: void, a: ElementType, b: ElementType) bool {
return a < b;
}
pub fn main() !void {
var items = [_]ElementType{ 2, 1, 3, 6, 4, 5, 9, 7, 8 };
// All of these work.
insertionSort(ElementType, &items, null, lessThan);
// insertionSort(ElementType, &items, 1, lessThan);
// insertionSort(ElementType, &items, u16, lessThan);
// insertionSort(ElementType, &items, {}, lessThanExplicit);
// std.mem.sort(ElementType, &items, {}, lessThanExplicit);
// All of these fail.
// insertionSort(ElementType, &items, true, lessThan);
// insertionSort(ElementType, &items, [_]u16{ 9001, 9002 }, lessThan);
// insertionSort(ElementType, &items, {}, lessThan);
// std.mem.sort(ElementType, &items, null, lessThan);
// std.mem.sort(ElementType, &items, 1, lessThan);
// std.mem.sort(ElementType, &items, {}, lessThan);
const stdout_file = std.io.getStdOut().writer();
var bw = std.io.bufferedWriter(stdout_file);
const stdout = bw.writer();
try stdout.print("{any}\n", .{items}); // { 1, 2, 3, 4, 5, 6, 7, 8, 9 }
try bw.flush();
}
fn insertionSort(
comptime T: type,
items: []T,
context: anytype,
comptime lessThanFn: fn (@TypeOf(context), lhs: T, rhs: T) bool,
) void {
var i: usize = 1;
while (i < items.len) : (i += 1) {
var j = i;
while (j > 0 and lessThanFn(context, items[j], items[j - 1])) : (j -= 1) {
const t = items[j - 1];
items[j - 1] = items[j];
items[j] = t;
}
}
}