Improved version:
pub fn dim(value: anytype, comptime level: usize) usize {
if (level == 0) {
return switch (@typeInfo(@TypeOf(value))) {
.array => |info| info.len,
.vector => |info| info.len,
else => @compileError("length not comptime known"),
};
} else {
return dim(@as(std.meta.Elem(@TypeOf(value)), undefined), level - 1);
}
}
And maybe even more clean, avoiding undefined trickery:
const std = @import("std");
pub fn typeDim(comptime T: type, comptime level: usize) usize {
if (level == 0) {
return switch (@typeInfo(T)) {
.array => |info| info.len,
.vector => |info| info.len,
else => @compileError("length not comptime known"),
};
} else {
return typeDim(std.meta.Elem(T), level - 1);
}
}
pub fn rows(value: anytype) usize {
return typeDim(@TypeOf(value), 0);
}
pub fn cols(value: anytype) usize {
return typeDim(@TypeOf(value), 1);
}
pub fn printDim(matrix: anytype) void {
std.debug.print("{}x{}\n", .{ rows(matrix), cols(matrix) });
}
pub fn main() void {
const a: [3][2]i32 = undefined;
const b: [3][0]i32 = undefined;
const c: [0][2]i32 = undefined;
const d: [0][0]i32 = undefined;
printDim(a);
printDim(b);
printDim(c);
printDim(d);
}