mirror of
https://github.com/ziglang/zig.git
synced 2024-11-17 01:23:54 +00:00
Merge pull request #6416 from MasterQ32/meta-tuple
Implements std.meta.Tuple(), implements #4607 in userland.
This commit is contained in:
commit
3342e28784
@ -807,7 +807,7 @@ pub fn sizeof(target: anytype) usize {
|
||||
// TODO to get the correct result we have to translate
|
||||
// `1073741824 * 4` as `int(1073741824) *% int(4)` since
|
||||
// sizeof(1073741824 * 4) != sizeof(4294967296).
|
||||
|
||||
|
||||
// TODO test if target fits in int, long or long long
|
||||
return @sizeOf(c_int);
|
||||
},
|
||||
@ -826,3 +826,65 @@ test "sizeof" {
|
||||
testing.expect(sizeof(E.One) == @sizeOf(c_int));
|
||||
testing.expect(sizeof(S) == 4);
|
||||
}
|
||||
|
||||
/// For a given anonymous list of types, returns a new tuple type
|
||||
/// with those types as fields.
|
||||
///
|
||||
/// Examples:
|
||||
/// - `Tuple(&[_]type {})` ⇒ `tuple { }`
|
||||
/// - `Tuple(&[_]type {f32})` ⇒ `tuple { f32 }`
|
||||
/// - `Tuple(&[_]type {f32,u32})` ⇒ `tuple { f32, u32 }`
|
||||
pub fn Tuple(comptime types: []const type) type {
|
||||
var tuple_fields: [types.len]std.builtin.TypeInfo.StructField = undefined;
|
||||
inline for (types) |T, i| {
|
||||
@setEvalBranchQuota(10_000);
|
||||
var num_buf: [128]u8 = undefined;
|
||||
tuple_fields[i] = std.builtin.TypeInfo.StructField{
|
||||
.name = std.fmt.bufPrint(&num_buf, "{d}", .{i}) catch unreachable,
|
||||
.field_type = T,
|
||||
.default_value = @as(?T, null),
|
||||
.is_comptime = false,
|
||||
};
|
||||
}
|
||||
|
||||
return @Type(std.builtin.TypeInfo{
|
||||
.Struct = std.builtin.TypeInfo.Struct{
|
||||
.is_tuple = true,
|
||||
.layout = .Auto,
|
||||
.decls = &[_]std.builtin.TypeInfo.Declaration{},
|
||||
.fields = &tuple_fields,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
test "Tuple" {
|
||||
const T = struct {
|
||||
fn assertTypeEqual(comptime Expected: type, comptime Actual: type) void {
|
||||
if (Expected != Actual)
|
||||
@compileError("Expected type " ++ @typeName(Expected) ++ ", but got type " ++ @typeName(Actual));
|
||||
}
|
||||
|
||||
fn assertTuple(comptime expected: anytype, comptime Actual: type) void {
|
||||
const info = @typeInfo(Actual);
|
||||
if (info != .Struct)
|
||||
@compileError("Expected struct type");
|
||||
if (!info.Struct.is_tuple)
|
||||
@compileError("Struct type must be a tuple type");
|
||||
|
||||
const fields_list = std.meta.fields(Actual);
|
||||
if (expected.len != fields_list.len)
|
||||
@compileError("Argument count mismatch");
|
||||
|
||||
inline for (fields_list) |fld, i| {
|
||||
if (expected[i] != fld.field_type) {
|
||||
@compileError("Field " ++ fld.name ++ " expected to be type " ++ @typeName(expected[i]) ++ ", but was type " ++ @typeName(fld.field_type));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
T.assertTuple(.{}, Tuple(&[_]type{}));
|
||||
T.assertTuple(.{u32}, Tuple(&[_]type{u32}));
|
||||
T.assertTuple(.{ u32, f16 }, Tuple(&[_]type{ u32, f16 }));
|
||||
T.assertTuple(.{ u32, f16, []const u8 }, Tuple(&[_]type{ u32, f16, []const u8 }));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user