mirror of
https://github.com/ziglang/zig.git
synced 2025-12-18 12:13:20 +00:00
Merge pull request #6415 from MasterQ32/args-tuple
Implements std.meta.ArgsTuple.
This commit is contained in:
commit
3b478631fb
@ -827,6 +827,46 @@ test "sizeof" {
|
|||||||
testing.expect(sizeof(S) == 4);
|
testing.expect(sizeof(S) == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// For a given function type, returns a tuple type which fields will
|
||||||
|
/// correspond to the argument types.
|
||||||
|
///
|
||||||
|
/// Examples:
|
||||||
|
/// - `ArgsTuple(fn() void)` ⇒ `tuple { }`
|
||||||
|
/// - `ArgsTuple(fn(a: u32) u32)` ⇒ `tuple { u32 }`
|
||||||
|
/// - `ArgsTuple(fn(a: u32, b: f16) noreturn)` ⇒ `tuple { u32, f16 }`
|
||||||
|
pub fn ArgsTuple(comptime Function: type) type {
|
||||||
|
const info = @typeInfo(Function);
|
||||||
|
if (info != .Fn)
|
||||||
|
@compileError("ArgsTuple expects a function type");
|
||||||
|
|
||||||
|
const function_info = info.Fn;
|
||||||
|
if (function_info.is_generic)
|
||||||
|
@compileError("Cannot create ArgsTuple for generic function");
|
||||||
|
if (function_info.is_var_args)
|
||||||
|
@compileError("Cannot create ArgsTuple for variadic function");
|
||||||
|
|
||||||
|
var argument_field_list: [function_info.args.len]std.builtin.TypeInfo.StructField = undefined;
|
||||||
|
inline for (function_info.args) |arg, i| {
|
||||||
|
@setEvalBranchQuota(10_000);
|
||||||
|
var num_buf: [128]u8 = undefined;
|
||||||
|
argument_field_list[i] = std.builtin.TypeInfo.StructField{
|
||||||
|
.name = std.fmt.bufPrint(&num_buf, "{d}", .{i}) catch unreachable,
|
||||||
|
.field_type = arg.arg_type.?,
|
||||||
|
.default_value = @as(?(arg.arg_type.?), 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 = &argument_field_list,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// For a given anonymous list of types, returns a new tuple type
|
/// For a given anonymous list of types, returns a new tuple type
|
||||||
/// with those types as fields.
|
/// with those types as fields.
|
||||||
///
|
///
|
||||||
@ -857,8 +897,7 @@ pub fn Tuple(comptime types: []const type) type {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
test "Tuple" {
|
const TupleTester = struct {
|
||||||
const T = struct {
|
|
||||||
fn assertTypeEqual(comptime Expected: type, comptime Actual: type) void {
|
fn assertTypeEqual(comptime Expected: type, comptime Actual: type) void {
|
||||||
if (Expected != Actual)
|
if (Expected != Actual)
|
||||||
@compileError("Expected type " ++ @typeName(Expected) ++ ", but got type " ++ @typeName(Actual));
|
@compileError("Expected type " ++ @typeName(Expected) ++ ", but got type " ++ @typeName(Actual));
|
||||||
@ -881,10 +920,18 @@ test "Tuple" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
T.assertTuple(.{}, Tuple(&[_]type{}));
|
test "ArgsTuple" {
|
||||||
T.assertTuple(.{u32}, Tuple(&[_]type{u32}));
|
TupleTester.assertTuple(.{}, ArgsTuple(fn () void));
|
||||||
T.assertTuple(.{ u32, f16 }, Tuple(&[_]type{ u32, f16 }));
|
TupleTester.assertTuple(.{u32}, ArgsTuple(fn (a: u32) []const u8));
|
||||||
T.assertTuple(.{ u32, f16, []const u8 }, Tuple(&[_]type{ u32, f16, []const u8 }));
|
TupleTester.assertTuple(.{ u32, f16 }, ArgsTuple(fn (a: u32, b: f16) noreturn));
|
||||||
|
TupleTester.assertTuple(.{ u32, f16, []const u8 }, ArgsTuple(fn (a: u32, b: f16, c: []const u8) noreturn));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "Tuple" {
|
||||||
|
TupleTester.assertTuple(.{}, Tuple(&[_]type{}));
|
||||||
|
TupleTester.assertTuple(.{u32}, Tuple(&[_]type{u32}));
|
||||||
|
TupleTester.assertTuple(.{ u32, f16 }, Tuple(&[_]type{ u32, f16 }));
|
||||||
|
TupleTester.assertTuple(.{ u32, f16, []const u8 }, Tuple(&[_]type{ u32, f16, []const u8 }));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user