| ... | @@ -18,16 +18,14 @@ pub fn TrailerFlags(comptime Fields: type) type { | ... | @@ -18,16 +18,14 @@ pub fn TrailerFlags(comptime Fields: type) type { |
| 18 | | 18 | |
| 19 | pub const FieldEnum = std.meta.FieldEnum(Fields); | 19 | pub const FieldEnum = std.meta.FieldEnum(Fields); |
| 20 | | 20 | |
| 21 | pub const InitStruct = blk: { | 21 | pub const ActiveFields = std.enums.EnumFieldStruct(FieldEnum, bool, false); |
| | 22 | pub const FieldValues = blk: { |
| 22 | comptime var fields: [bit_count]Type.StructField = undefined; | 23 | comptime var fields: [bit_count]Type.StructField = undefined; |
| 23 | inline for (@typeInfo(Fields).Struct.fields) |struct_field, i| { | 24 | inline for (@typeInfo(Fields).Struct.fields) |struct_field, i| { |
| 24 | fields[i] = Type.StructField{ | 25 | fields[i] = Type.StructField{ |
| 25 | .name = struct_field.name, | 26 | .name = struct_field.name, |
| 26 | .field_type = ?struct_field.field_type, | 27 | .field_type = ?struct_field.field_type, |
| 27 | .default_value = @as( | 28 | .default_value = &@as(?struct_field.field_type, null), |
| 28 | ??struct_field.field_type, | | |
| 29 | @as(?struct_field.field_type, null), | | |
| 30 | ), | | |
| 31 | .is_comptime = false, | 29 | .is_comptime = false, |
| 32 | .alignment = @alignOf(?struct_field.field_type), | 30 | .alignment = @alignOf(?struct_field.field_type), |
| 33 | }; | 31 | }; |
| ... | @@ -60,19 +58,18 @@ pub fn TrailerFlags(comptime Fields: type) type { | ... | @@ -60,19 +58,18 @@ pub fn TrailerFlags(comptime Fields: type) type { |
| 60 | self.bits |= 1 << field_index; | 58 | self.bits |= 1 << field_index; |
| 61 | } | 59 | } |
| 62 | | 60 | |
| 63 | /// `fields` is a struct with each field set to an optional value. | 61 | /// `fields` is a boolean struct where each active field is set to `true` |
| 64 | /// Only the non-null bits are observed and are used to set the flag bits. | 62 | pub fn init(fields: ActiveFields) Self { |
| 65 | pub fn init(fields: InitStruct) Self { | | |
| 66 | var self: Self = .{ .bits = 0 }; | 63 | var self: Self = .{ .bits = 0 }; |
| 67 | inline for (@typeInfo(Fields).Struct.fields) |field, i| { | 64 | inline for (@typeInfo(Fields).Struct.fields) |field, i| { |
| 68 | if (@field(fields, field.name)) |_| | 65 | if (@field(fields, field.name)) |
| 69 | self.bits |= 1 << i; | 66 | self.bits |= 1 << i; |
| 70 | } | 67 | } |
| 71 | return self; | 68 | return self; |
| 72 | } | 69 | } |
| 73 | | 70 | |
| 74 | /// `fields` is a struct with each field set to an optional value (same as `init`). | 71 | /// `fields` is a struct with each field set to an optional value |
| 75 | pub fn setMany(self: Self, p: [*]align(@alignOf(Fields)) u8, fields: InitStruct) void { | 72 | pub fn setMany(self: Self, p: [*]align(@alignOf(Fields)) u8, fields: FieldValues) void { |
| 76 | inline for (@typeInfo(Fields).Struct.fields) |field, i| { | 73 | inline for (@typeInfo(Fields).Struct.fields) |field, i| { |
| 77 | if (@field(fields, field.name)) |value| | 74 | if (@field(fields, field.name)) |value| |
| 78 | self.set(p, @intToEnum(FieldEnum, i), value); | 75 | self.set(p, @intToEnum(FieldEnum, i), value); |
| ... | @@ -145,7 +142,7 @@ test "TrailerFlags" { | ... | @@ -145,7 +142,7 @@ test "TrailerFlags" { |
| 145 | | 142 | |
| 146 | var flags = Flags.init(.{ | 143 | var flags = Flags.init(.{ |
| 147 | .b = true, | 144 | .b = true, |
| 148 | .c = 1234, | 145 | .c = true, |
| 149 | }); | 146 | }); |
| 150 | const slice = try testing.allocator.allocAdvanced(u8, 8, flags.sizeInBytes(), .exact); | 147 | const slice = try testing.allocator.allocAdvanced(u8, 8, flags.sizeInBytes(), .exact); |
| 151 | defer testing.allocator.free(slice); | 148 | defer testing.allocator.free(slice); |