| ... | @@ -606,6 +606,18 @@ test "std.meta.tags" { | ... | @@ -606,6 +606,18 @@ test "std.meta.tags" { |
| 606 | | 606 | |
| 607 | pub fn FieldEnum(comptime T: type) type { | 607 | pub fn FieldEnum(comptime T: type) type { |
| 608 | const field_infos = fields(T); | 608 | const field_infos = fields(T); |
| | 609 | |
| | 610 | if (@typeInfo(T) == .Union) { |
| | 611 | if (@typeInfo(T).Union.tag_type) |tag_type| { |
| | 612 | for (std.enums.values(tag_type)) |v, i| { |
| | 613 | if (@enumToInt(v) != i) break; // enum values not consecutive |
| | 614 | if (!std.mem.eql(u8, @tagName(v), field_infos[i].name)) break; // fields out of order |
| | 615 | } else { |
| | 616 | return tag_type; |
| | 617 | } |
| | 618 | } |
| | 619 | } |
| | 620 | |
| 609 | var enumFields: [field_infos.len]std.builtin.Type.EnumField = undefined; | 621 | var enumFields: [field_infos.len]std.builtin.Type.EnumField = undefined; |
| 610 | var decls = [_]std.builtin.Type.Declaration{}; | 622 | var decls = [_]std.builtin.Type.Declaration{}; |
| 611 | inline for (field_infos) |field, i| { | 623 | inline for (field_infos) |field, i| { |
| ... | @@ -669,6 +681,17 @@ test "std.meta.FieldEnum" { | ... | @@ -669,6 +681,17 @@ test "std.meta.FieldEnum" { |
| 669 | try expectEqualEnum(enum { a }, FieldEnum(struct { a: u8 })); | 681 | try expectEqualEnum(enum { a }, FieldEnum(struct { a: u8 })); |
| 670 | try expectEqualEnum(enum { a, b, c }, FieldEnum(struct { a: u8, b: void, c: f32 })); | 682 | try expectEqualEnum(enum { a, b, c }, FieldEnum(struct { a: u8, b: void, c: f32 })); |
| 671 | try expectEqualEnum(enum { a, b, c }, FieldEnum(union { a: u8, b: void, c: f32 })); | 683 | try expectEqualEnum(enum { a, b, c }, FieldEnum(union { a: u8, b: void, c: f32 })); |
| | 684 | |
| | 685 | const Tagged = union(enum) { a: u8, b: void, c: f32 }; |
| | 686 | try testing.expectEqual(Tag(Tagged), FieldEnum(Tagged)); |
| | 687 | |
| | 688 | const Tag2 = enum { b, c, a }; |
| | 689 | const Tagged2 = union(Tag2) { a: u8, b: void, c: f32 }; |
| | 690 | try testing.expect(Tag(Tagged2) != FieldEnum(Tagged2)); |
| | 691 | |
| | 692 | const Tag3 = enum(u8) { a, b, c = 7 }; |
| | 693 | const Tagged3 = union(Tag3) { a: u8, b: void, c: f32 }; |
| | 694 | try testing.expect(Tag(Tagged3) != FieldEnum(Tagged3)); |
| 672 | } | 695 | } |
| 673 | | 696 | |
| 674 | pub fn DeclEnum(comptime T: type) type { | 697 | pub fn DeclEnum(comptime T: type) type { |