authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2020-05-26 22:31:36-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2020-05-26 23:10:13-07:00
logb683498ae8065ba820700944b4417e8d2174d068
treef9396915c27bee46277041c77babb76adb2e3c54
parentdfafafac7b701feb154e28981e77aa6f66624e8f

Use ComptimeStringMap in std.meta.stringToEnum when feasible


1 files changed, 29 insertions(+), 4 deletions(-)

lib/std/meta.zig+29-4
......@@ -53,12 +53,37 @@ test "std.meta.tagName" {
5353}
5454
5555pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
56 inline for (@typeInfo(T).Enum.fields) |enumField| {
57 if (mem.eql(u8, str, enumField.name)) {
58 return @field(T, enumField.name);
56 // Using ComptimeStringMap here is more performant, but it will start to take too
57 // long to compile if the enum is large enough, due to the current limits of comptime
58 // performance when doing things like constructing lookup maps at comptime.
59 // TODO The '100' here is arbitrary and should be increased when possible:
60 // - https://github.com/ziglang/zig/issues/4055
61 // - https://github.com/ziglang/zig/issues/3863
62 if (@typeInfo(T).Enum.fields.len <= 100) {
63 const kvs = comptime build_kvs: {
64 // In order to generate an array of structs that play nice with anonymous
65 // list literals, we need to give them "0" and "1" field names.
66 // TODO https://github.com/ziglang/zig/issues/4335
67 const EnumKV = struct {
68 @"0": []const u8,
69 @"1": T,
70 };
71 var kvs_array: [@typeInfo(T).Enum.fields.len]EnumKV = undefined;
72 inline for (@typeInfo(T).Enum.fields) |enumField, i| {
73 kvs_array[i] = .{.@"0" = enumField.name, .@"1" = @field(T, enumField.name)};
74 }
75 break :build_kvs kvs_array[0..];
76 };
77 const map = std.ComptimeStringMap(T, kvs);
78 return map.get(str);
79 } else {
80 inline for (@typeInfo(T).Enum.fields) |enumField| {
81 if (mem.eql(u8, str, enumField.name)) {
82 return @field(T, enumField.name);
83 }
5984 }
85 return null;
6086 }
61 return null;
6287}
6388
6489test "std.meta.stringToEnum" {