| author | |
| committer | |
| log | bb956f2cf60cf5983309a22f1f88facda0a04a16 |
| tree | 2df82220662c44bac353d120f30feae25296efb8 |
| parent | 2cb1b3d619b10f4ad2c870f0359adb0c6129ca67 |
| signature |
13 files changed, 67 insertions(+), 95 deletions(-)
README.md+1-1| ... | ... | @@ -3,7 +3,7 @@ |
| 3 | 3 |  |
| 4 | 4 | [](https://github.com/nektro/zig-extras/blob/master/LICENSE) |
| 5 | 5 | [](https://github.com/sponsors/nektro) |
| 6 | [](https://ziglang.org/) | |
| 6 | [](https://ziglang.org/) | |
| 7 | 7 | [](https://github.com/nektro/zigmod) |
| 8 | 8 | |
| 9 | 9 | An assortment of random utility functions that aren't in std and don't deserve their own package. |
src/FieldUnion.zig+9-14| ... | ... | @@ -4,22 +4,17 @@ const extras = @import("./lib.zig"); |
| 4 | 4 | const expectSimilarType = extras.expectSimilarType; |
| 5 | 5 | |
| 6 | 6 | pub fn FieldUnion(comptime T: type) type { |
| 7 | const infos = std.meta.fields(T); | |
| 7 | const fields = std.meta.fields(T); | |
| 8 | var names: [fields.fields.len][]const u8 = undefined; | |
| 9 | var types: [fields.fields.len]type = undefined; | |
| 10 | var attrs: [fields.fields.len]std.builtin.Type.UnionField.Attributes = undefined; | |
| 8 | 11 | |
| 9 | var fields: [infos.len]std.builtin.Type.UnionField = undefined; | |
| 10 | inline for (infos, 0..) |field, i| { | |
| 11 | fields[i] = .{ | |
| 12 | .name = field.name, | |
| 13 | .type = field.type, | |
| 14 | .alignment = field.alignment, | |
| 15 | }; | |
| 12 | inline for (fields, 0..) |field, i| { | |
| 13 | names[i] = field.name; | |
| 14 | types[i] = field.type; | |
| 15 | attrs[i] = .{ .@"align" = field.alignment }; | |
| 16 | 16 | } |
| 17 | return @Type(std.builtin.Type{ .@"union" = .{ | |
| 18 | .layout = .auto, | |
| 19 | .tag_type = std.meta.FieldEnum(T), | |
| 20 | .fields = &fields, | |
| 21 | .decls = &.{}, | |
| 22 | } }); | |
| 17 | return @Union(.auto, std.meta.FieldEnum(T), &names, &types, &attrs); | |
| 23 | 18 | } |
| 24 | 19 | |
| 25 | 20 | test { |
src/FlippedInt.zig+8-6| ... | ... | @@ -3,12 +3,14 @@ const string = []const u8; |
| 3 | 3 | const extras = @import("./lib.zig"); |
| 4 | 4 | |
| 5 | 5 | pub fn FlippedInt(comptime T: type) type { |
| 6 | var info = @typeInfo(T); | |
| 7 | info.int.signedness = switch (info.int.signedness) { | |
| 8 | .signed => .unsigned, | |
| 9 | .unsigned => .signed, | |
| 10 | }; | |
| 11 | return @Type(info); | |
| 6 | const info = @typeInfo(T).int; | |
| 7 | return @Int( | |
| 8 | switch (info.signedness) { | |
| 9 | .signed => .unsigned, | |
| 10 | .unsigned => .signed, | |
| 11 | }, | |
| 12 | info.signedness, | |
| 13 | ); | |
| 12 | 14 | } |
| 13 | 15 | |
| 14 | 16 | test { |
src/LoggingReader.zig+1-1| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const string = []const u8; |
| 3 | 3 | const extras = @import("./lib.zig"); |
| 4 | 4 | |
| 5 | pub fn LoggingReader(comptime T: type, comptime scope: @Type(.EnumLiteral)) type { | |
| 5 | pub fn LoggingReader(comptime T: type, comptime scope: @EnumLiteral()) type { | |
| 6 | 6 | return struct { |
| 7 | 7 | child_stream: T, |
| 8 | 8 |
src/LoggingWriter.zig+1-1| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); |
| 2 | 2 | const string = []const u8; |
| 3 | 3 | const extras = @import("./lib.zig"); |
| 4 | 4 | |
| 5 | pub fn LoggingWriter(comptime T: type, comptime scope: @Type(.EnumLiteral)) type { | |
| 5 | pub fn LoggingWriter(comptime T: type, comptime scope: @EnumLiteral()) type { | |
| 6 | 6 | return struct { |
| 7 | 7 | child_stream: T, |
| 8 | 8 |
src/OneBiggerInt.zig+2-3| ... | ... | @@ -3,9 +3,8 @@ const string = []const u8; |
| 3 | 3 | const extras = @import("./lib.zig"); |
| 4 | 4 | |
| 5 | 5 | pub fn OneBiggerInt(comptime T: type) type { |
| 6 | var info = @typeInfo(T); | |
| 7 | info.int.bits += 1; | |
| 8 | return @Type(info); | |
| 6 | const info = @typeInfo(T).int; | |
| 7 | return @Int(info.signedness, info.bits + 1); | |
| 9 | 8 | } |
| 10 | 9 | |
| 11 | 10 | test { |
src/OneSmallerInt.zig+2-3| ... | ... | @@ -3,9 +3,8 @@ const string = []const u8; |
| 3 | 3 | const extras = @import("./lib.zig"); |
| 4 | 4 | |
| 5 | 5 | pub fn OneSmallerInt(comptime T: type) type { |
| 6 | var info = @typeInfo(T); | |
| 7 | info.int.bits -= 1; | |
| 8 | return @Type(info); | |
| 6 | const info = @typeInfo(T).int; | |
| 7 | return @Int(info.signedness, info.bits - 1); | |
| 9 | 8 | } |
| 10 | 9 | |
| 11 | 10 | test { |
src/Partial.zig+9-17| ... | ... | @@ -6,24 +6,16 @@ const expectSimilarType = extras.expectSimilarType; |
| 6 | 6 | /// Creates a new version of struct T where all fields are optional. |
| 7 | 7 | /// Name inspried by https://www.typescriptlang.org/docs/handbook/utility-types.html#partialtype. |
| 8 | 8 | pub fn Partial(comptime T: type) type { |
| 9 | const fields_before = std.meta.fields(T); | |
| 10 | var fields_after: [fields_before.len]std.builtin.Type.StructField = undefined; | |
| 11 | inline for (fields_before, 0..) |item, i| { | |
| 12 | fields_after[i] = std.builtin.Type.StructField{ | |
| 13 | .name = item.name, | |
| 14 | .type = ?item.type, | |
| 15 | .default_value_ptr = &@as(?item.type, null), | |
| 16 | .is_comptime = false, | |
| 17 | .alignment = @alignOf(?item.type), | |
| 18 | }; | |
| 9 | const fields = std.meta.fields(T); | |
| 10 | var names: [fields.len][]const u8 = undefined; | |
| 11 | var types: [fields.len]type = undefined; | |
| 12 | var attrs: [fields.len]std.builtin.Type.StructField.Attributes = undefined; | |
| 13 | for (fields, 0..) |item, i| { | |
| 14 | names[i] = item.name; | |
| 15 | types[i] = ?item.type; | |
| 16 | attrs[i] = .{ .default_value_ptr = &@as(?item.type, null) }; | |
| 19 | 17 | } |
| 20 | return @Type(@unionInit(std.builtin.Type, "struct", .{ | |
| 21 | .layout = .auto, | |
| 22 | .backing_integer = null, | |
| 23 | .fields = &fields_after, | |
| 24 | .decls = &.{}, | |
| 25 | .is_tuple = false, | |
| 26 | })); | |
| 18 | return @Struct(.auto, null, &names, &types, &attrs); | |
| 27 | 19 | } |
| 28 | 20 | |
| 29 | 21 | test { |
src/ReverseFields.zig+6-5| ... | ... | @@ -4,14 +4,15 @@ const extras = @import("./lib.zig"); |
| 4 | 4 | const expectSimilarType = extras.expectSimilarType; |
| 5 | 5 | |
| 6 | 6 | pub fn ReverseFields(comptime T: type) type { |
| 7 | var info = @typeInfo(T).@"struct"; | |
| 7 | const info = @typeInfo(T).@"struct"; | |
| 8 | 8 | const len = info.fields.len; |
| 9 | var fields: [len]std.builtin.Type.StructField = undefined; | |
| 9 | var names: [len][]const u8 = undefined; | |
| 10 | var types: [len]type = undefined; | |
| 10 | 11 | for (0..len) |i| { |
| 11 | fields[i] = info.fields[len - 1 - i]; | |
| 12 | names[i] = info.fields[len - 1 - i].name; | |
| 13 | types[i] = info.fields[len - 1 - i].type; | |
| 12 | 14 | } |
| 13 | info.fields = &fields; | |
| 14 | return @Type(.{ .@"struct" = info }); | |
| 15 | return @Struct(.auto, null, &names, &types, &@splat(.{})); | |
| 15 | 16 | } |
| 16 | 17 | |
| 17 | 18 | test { |
src/StructOfArrays.zig+5-16| ... | ... | @@ -6,24 +6,13 @@ const expectSimilarType = extras.expectSimilarType; |
| 6 | 6 | pub fn StructOfArrays(len: usize, T: type) type { |
| 7 | 7 | const info = @typeInfo(T).@"struct"; |
| 8 | 8 | const fields = info.fields; |
| 9 | var new_fields: [fields.len]std.builtin.Type.StructField = undefined; | |
| 9 | var names: [fields.len][]const u8 = undefined; | |
| 10 | var types: [fields.len]type = undefined; | |
| 10 | 11 | for (fields, 0..) |item, i| { |
| 11 | new_fields[i] = .{ | |
| 12 | .name = item.name, | |
| 13 | .type = [len]item.type, | |
| 14 | .default_value_ptr = null, | |
| 15 | .is_comptime = false, | |
| 16 | .alignment = @alignOf([len]item.type), | |
| 17 | }; | |
| 12 | names[i] = item.name; | |
| 13 | types[i] = [len]item.type; | |
| 18 | 14 | } |
| 19 | const result = new_fields[0..fields.len]; | |
| 20 | return @Type(@unionInit(std.builtin.Type, "struct", .{ | |
| 21 | .layout = .auto, | |
| 22 | .backing_integer = null, | |
| 23 | .fields = result, | |
| 24 | .decls = &.{}, | |
| 25 | .is_tuple = info.is_tuple, | |
| 26 | })); | |
| 15 | return @Struct(.auto, null, &names, &types, &@splat(.{})); | |
| 27 | 16 | } |
| 28 | 17 | |
| 29 | 18 | test { |
src/StructOfSlices.zig+5-16| ... | ... | @@ -6,24 +6,13 @@ const expectSimilarType = extras.expectSimilarType; |
| 6 | 6 | pub fn StructOfSlices(T: type) type { |
| 7 | 7 | const info = @typeInfo(T).@"struct"; |
| 8 | 8 | const fields = info.fields; |
| 9 | var new_fields: [fields.len]std.builtin.Type.StructField = undefined; | |
| 9 | var names: [fields.len][]const u8 = undefined; | |
| 10 | var types: [fields.len]type = undefined; | |
| 10 | 11 | for (fields, 0..) |item, i| { |
| 11 | new_fields[i] = .{ | |
| 12 | .name = item.name, | |
| 13 | .type = []const item.type, | |
| 14 | .default_value_ptr = null, | |
| 15 | .is_comptime = false, | |
| 16 | .alignment = @alignOf([]const item.type), | |
| 17 | }; | |
| 12 | names[i] = item.name; | |
| 13 | types[i] = []const item.type; | |
| 18 | 14 | } |
| 19 | const result = new_fields[0..fields.len]; | |
| 20 | return @Type(@unionInit(std.builtin.Type, "struct", .{ | |
| 21 | .layout = .auto, | |
| 22 | .backing_integer = null, | |
| 23 | .fields = result, | |
| 24 | .decls = &.{}, | |
| 25 | .is_tuple = info.is_tuple, | |
| 26 | })); | |
| 15 | return @Struct(.auto, null, &names, &types, &@splat(.{})); | |
| 27 | 16 | } |
| 28 | 17 | |
| 29 | 18 | test { |
src/join.zig+5-9| ... | ... | @@ -14,17 +14,13 @@ pub fn join(input: anytype) Join(@TypeOf(input)) { |
| 14 | 14 | } |
| 15 | 15 | |
| 16 | 16 | pub fn Join(comptime T: type) type { |
| 17 | var fields: []const std.builtin.Type.StructField = &.{}; | |
| 17 | var names: [][]const u8 = &.{}; | |
| 18 | var types: []type = &.{}; | |
| 18 | 19 | inline for (std.meta.fields(T)) |item| { |
| 19 | 20 | inline for (std.meta.fields(item.type)) |f| { |
| 20 | fields = fields ++ &[_]std.builtin.Type.StructField{.{ | |
| 21 | .name = f.name, | |
| 22 | .type = f.type, | |
| 23 | .default_value_ptr = null, | |
| 24 | .is_comptime = false, | |
| 25 | .alignment = @alignOf(f.type), | |
| 26 | }}; | |
| 21 | names = names ++ &[_][]const u8{f.name}; | |
| 22 | types = types ++ &[_]type{f.type}; | |
| 27 | 23 | } |
| 28 | 24 | } |
| 29 | return @Type(.{ .@"struct" = .{ .layout = .auto, .fields = fields, .decls = &.{}, .is_tuple = false } }); | |
| 25 | return @Struct(.auto, null, &names, &types, &@splat(.{})); | |
| 30 | 26 | } |
src/omit.zig+13-3| ... | ... | @@ -14,12 +14,22 @@ pub fn omit(value: anytype, comptime field_name: []const u8) Omit(@TypeOf(value) |
| 14 | 14 | |
| 15 | 15 | pub fn Omit(T: type, field_name: []const u8) type { |
| 16 | 16 | const fields_original = std.meta.fields(T); |
| 17 | var fields: [fields_original.len - 1]std.builtin.Type.StructField = undefined; | |
| 17 | const len = fields_original.len - 1; | |
| 18 | var names: [len][]const u8 = undefined; | |
| 19 | var types: [len]type = undefined; | |
| 20 | var attrs: [len]std.builtin.Type.StructField.Attributes = undefined; | |
| 18 | 21 | var i: usize = 0; |
| 19 | 22 | for (fields_original) |f| { |
| 20 | 23 | if (std.mem.eql(u8, f.name, field_name)) continue; |
| 21 | fields[i] = f; | |
| 24 | names[i] = f.name; | |
| 25 | types[i] = f.type; | |
| 26 | attrs[i] = .{ | |
| 27 | .@"comptime" = f.is_comptime, | |
| 28 | .@"align" = f.alignment, | |
| 29 | .default_value_ptr = f.default_value_ptr, | |
| 30 | }; | |
| 22 | 31 | i += 1; |
| 23 | 32 | } |
| 24 | return @Type(.{ .@"struct" = .{ .layout = .auto, .fields = &fields, .decls = &.{}, .is_tuple = false } }); | |
| 33 | return @Struct(.auto, null, &names, &types, &attrs); | |
| 34 | // return @Type(.{ .@"struct" = .{ .layout = .auto, .fields = &fields, .decls = &.{}, .is_tuple = false } }); | |
| 25 | 35 | } |