Re-apply: "std.ComptimeStringMap: use tuple types"

096d3efae5fcaa5640f4acb2f9be2d7f93f7fdb2 was not the cause of the
CI failure.
This commit is contained in:
r00ster91 2022-12-08 22:05:30 +02:00 committed by Veikka Tuominen
parent 225ed65ed2
commit 7826e28bd3
2 changed files with 22 additions and 37 deletions

View File

@ -5,9 +5,8 @@ const mem = std.mem;
/// Works by separating the keys by length at comptime and only checking strings of /// Works by separating the keys by length at comptime and only checking strings of
/// equal length at runtime. /// equal length at runtime.
/// ///
/// `kvs` expects a list literal containing list literals or an array/slice of structs /// `kvs_list` expects a list of `struct { []const u8, V }` (key-value pair) tuples.
/// where `.@"0"` is the `[]const u8` key and `.@"1"` is the associated value of type `V`. /// You can pass `struct { []const u8 }` (only keys) tuples if `V` is `void`.
/// TODO: https://github.com/ziglang/zig/issues/4335
pub fn ComptimeStringMap(comptime V: type, comptime kvs_list: anytype) type { pub fn ComptimeStringMap(comptime V: type, comptime kvs_list: anytype) type {
const precomputed = comptime blk: { const precomputed = comptime blk: {
@setEvalBranchQuota(2000); @setEvalBranchQuota(2000);
@ -97,32 +96,26 @@ test "ComptimeStringMap list literal of list literals" {
} }
test "ComptimeStringMap array of structs" { test "ComptimeStringMap array of structs" {
const KV = struct { const KV = struct { []const u8, TestEnum };
@"0": []const u8,
@"1": TestEnum,
};
const map = ComptimeStringMap(TestEnum, [_]KV{ const map = ComptimeStringMap(TestEnum, [_]KV{
.{ .@"0" = "these", .@"1" = .D }, .{ "these", .D },
.{ .@"0" = "have", .@"1" = .A }, .{ "have", .A },
.{ .@"0" = "nothing", .@"1" = .B }, .{ "nothing", .B },
.{ .@"0" = "incommon", .@"1" = .C }, .{ "incommon", .C },
.{ .@"0" = "samelen", .@"1" = .E }, .{ "samelen", .E },
}); });
try testMap(map); try testMap(map);
} }
test "ComptimeStringMap slice of structs" { test "ComptimeStringMap slice of structs" {
const KV = struct { const KV = struct { []const u8, TestEnum };
@"0": []const u8,
@"1": TestEnum,
};
const slice: []const KV = &[_]KV{ const slice: []const KV = &[_]KV{
.{ .@"0" = "these", .@"1" = .D }, .{ "these", .D },
.{ .@"0" = "have", .@"1" = .A }, .{ "have", .A },
.{ .@"0" = "nothing", .@"1" = .B }, .{ "nothing", .B },
.{ .@"0" = "incommon", .@"1" = .C }, .{ "incommon", .C },
.{ .@"0" = "samelen", .@"1" = .E }, .{ "samelen", .E },
}; };
const map = ComptimeStringMap(TestEnum, slice); const map = ComptimeStringMap(TestEnum, slice);
@ -141,15 +134,13 @@ fn testMap(comptime map: anytype) !void {
} }
test "ComptimeStringMap void value type, slice of structs" { test "ComptimeStringMap void value type, slice of structs" {
const KV = struct { const KV = struct { []const u8 };
@"0": []const u8,
};
const slice: []const KV = &[_]KV{ const slice: []const KV = &[_]KV{
.{ .@"0" = "these" }, .{"these"},
.{ .@"0" = "have" }, .{"have"},
.{ .@"0" = "nothing" }, .{"nothing"},
.{ .@"0" = "incommon" }, .{"incommon"},
.{ .@"0" = "samelen" }, .{"samelen"},
}; };
const map = ComptimeStringMap(void, slice); const map = ComptimeStringMap(void, slice);

View File

@ -115,16 +115,10 @@ pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
// - https://github.com/ziglang/zig/issues/3863 // - https://github.com/ziglang/zig/issues/3863
if (@typeInfo(T).Enum.fields.len <= 100) { if (@typeInfo(T).Enum.fields.len <= 100) {
const kvs = comptime build_kvs: { const kvs = comptime build_kvs: {
// In order to generate an array of structs that play nice with anonymous const EnumKV = struct { []const u8, T };
// list literals, we need to give them "0" and "1" field names.
// TODO https://github.com/ziglang/zig/issues/4335
const EnumKV = struct {
@"0": []const u8,
@"1": T,
};
var kvs_array: [@typeInfo(T).Enum.fields.len]EnumKV = undefined; var kvs_array: [@typeInfo(T).Enum.fields.len]EnumKV = undefined;
inline for (@typeInfo(T).Enum.fields) |enumField, i| { inline for (@typeInfo(T).Enum.fields) |enumField, i| {
kvs_array[i] = .{ .@"0" = enumField.name, .@"1" = @field(T, enumField.name) }; kvs_array[i] = .{ enumField.name, @field(T, enumField.name) };
} }
break :build_kvs kvs_array[0..]; break :build_kvs kvs_array[0..];
}; };