In zig 0.15.2, you could replicate the &.{ 1, 2, 3 } syntax with metaprogramming.
const a: []const usize = &.{100, 17};
std.debug.print("{any}\n", .{a});
const b: []const usize = &@Type(.{ .@"struct" = .{
.layout = .auto,
.backing_integer = null,
.fields = &.{
.{
.name = "0",
.type = comptime_int,
.default_value_ptr = &100,
.is_comptime = true,
.alignment = 0,
},
.{
.name = "1",
.type = comptime_int,
.default_value_ptr = &17,
.is_comptime = true,
.alignment = 0,
},
},
.decls = &.{},
.is_tuple = true,
}}){};
std.debug.print("{any}\n", .{b}); // This prints the same value
This can be used to generate constant data at compile time.
// This function generates a slice out of an integer. The length of the slice is
// equal to the bit length of the integer. At every position, the slice contains
// the value of the corresponding bit in the integer (e.g 32, 64, 128) if that
// bit is set, or 0 if the bit is not set. This function currently has no real
// world use and is only shown here as an example.
fn generateConstantData(value: anytype) []const u64 {
const bits = @typeInfo(@TypeOf(value)).int.bits;
var fields = [_]std.builtin.Type.StructField{ undefined } ** bits;
for (0..bits) |i| {
const bit: comptime_int = (value & (1 << i));
var buf: [8]u8 = undefined;
fields[i] = .{
.name = try std.fmt.bufPrintZ(&buf, "{}", .{i}),
.type = comptime_int,
.default_value_ptr = &bit,
.is_comptime = true,
.alignment = 0,
};
}
return &@Type(.{ .@"struct" = .{
.layout = .auto,
.backing_integer = null,
.fields = &fields,
.decls = &.{},
.is_tuple = true,
}}){};
}
const c: []const u64 = comptime generateConstantData(@as(u8, 223));
std.debug.print("{any}\n", .{c});
const d: []const u64 = &.{ 1, 2, 4, 8, 16, 0, 64, 128 };
std.debug.print("{any}\n", .{d});
std.debug.print("{}\n", .{std.mem.eql(u64, c, d)}); // true
Unfortunately, @Type was removed in 0.16.0 and I tried to replicate this with the new @Struct and @Tuple builtins, but neither of them worked. Is there any way to make this possible again?
Link to full code