The following is some code I’ve been playing around with. The key function is
getUniqueId
, which returns a unique id for any given type:
const std = @import("std");
const Error = error{failure_is_success};
fn fail(comptime _: type) !void {
return Error.failure_is_success;
}
fn getUniqueNumber(comptime T: type) usize {
fail(T) catch {
if (@errorReturnTrace()) |trace| {
return trace.instruction_addresses[0];
}
};
unreachable;
}
const base_opaque = opaque {};
fn getUniqueId(comptime T: type) usize {
const base = getUniqueNumber(base_opaque);
return getUniqueNumber(T) - base;
}
fn Point(comptime T: type) type {
return struct {
x: T,
y: T,
};
}
pub fn main() void {
const types = .{
u32,
i32,
[]u8,
[*:0]u8,
Point(f32),
Point(f64),
@TypeOf(.{ .evil_turtles = "on the loose", .stage = 1 }),
@TypeOf(.{ .evil_turtles = "on the loose", .stage = 2 }),
@TypeOf(Point),
opaque {},
opaque {},
};
inline for (1..3) |round| {
std.debug.print("Round {d}:\n", .{round});
inline for (types) |T| {
const id = getUniqueId(T);
std.debug.print("{s} => {d}\n", .{ @typeName(T), id });
}
std.debug.print("\n", .{});
}
}
Round 1:
u32 => 16
i32 => 352
[]u8 => 688
[*:0]u8 => 1024
opaque.Point(f32) => 1360
opaque.Point(f64) => 1696
struct{comptime evil_turtles: *const [12:0]u8 = "on the loose", comptime stage: comptime_int = 1} => 2032
struct{comptime evil_turtles: *const [12:0]u8 = "on the loose", comptime stage: comptime_int = 2} => 2368
fn (comptime type) type => 2704
opaque.main__opaque_3394 => 3040
opaque.main__opaque_3395 => 3376
Round 2:
u32 => 16
i32 => 352
[]u8 => 688
[*:0]u8 => 1024
opaque.Point(f32) => 1360
opaque.Point(f64) => 1696
struct{comptime evil_turtles: *const [12:0]u8 = "on the loose", comptime stage: comptime_int = 1} => 2032
struct{comptime evil_turtles: *const [12:0]u8 = "on the loose", comptime stage: comptime_int = 2} => 2368
fn (comptime type) type => 2704
opaque.main__opaque_3394 => 3040
opaque.main__opaque_3395 => 3376
Totally hackish but seems to work. Got any idea on how to accomplish the same thing in a cleaner manner?