//! Utility struct for printing function names in comptime errors. //! Requires a bit of comptime gymnastics to get the function name. const std = @import("std"); const Allocator = std.mem.Allocator; const Alignment = std.mem.Alignment; pub fn funcName(func: anytype) []const u8 { const func_name = @typeName(Dummy(func)); const start = (std.mem.indexOfScalar(u8, func_name, '\'') orelse unreachable) + 1; const end = std.mem.indexOfScalarPos(u8, func_name, start, '\'') orelse unreachable; return func_name[start..end]; } pub fn fullFuncName(func: anytype) []const u8 { return @typeName(Dummy(func)); } fn Dummy(func: anytype) type { return struct { fn warpper() void { func(); } }; } pub const allocator: Allocator = .{ .ptr = undefined, .vtable = &.{ .alloc = &comptimeAlloc, .resize = &comptimeResize, .remap = &comptimeRemap, .free = &Allocator.noFree, }, }; fn comptimeAlloc(_: *anyopaque, len: usize, alignment: Alignment, _: usize) ?[*]u8 { if (!@inComptime()) @panic("comptimeAlloc called at runtime"); comptime { var buf: [len]u8 align(alignment.toByteUnits()) = undefined; return &buf; } } fn comptimeResize(_: *anyopaque, mem: []u8, _: Alignment, new_len: usize, _: usize) bool { if (!@inComptime()) @panic("comptimeResize called at runtime"); return new_len <= mem.len; // allow shrinking in-place } fn comptimeRemap(_: *anyopaque, mem: []u8, _: Alignment, new_len: usize, _: usize) ?[*]u8 { if (!@inComptime()) @panic("comptimeRemap called at runtime"); return if (new_len <= mem.len) mem.ptr else null; // allow shrinking in-place }