authorgravatar for r00ster91@proton.meWooster <r00ster91@proton.me> 2022-11-26 01:16:26+01:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-07 14:56:55+02:00
log096d3efae5fcaa5640f4acb2f9be2d7f93f7fdb2
treec3e576cec471b9a38cab5424a0e090b86fb84e5e
parent1310ef75777209f061bfd61473db75911538b5ff

std.ComptimeStringMap: use tuple types

This is now possible due to #13627.

2 files changed, 22 insertions(+), 37 deletions(-)

lib/std/comptime_string_map.zig+20-29
...@@ -5,9 +5,8 @@ const mem = std.mem;...@@ -5,9 +5,8 @@ const mem = std.mem;
5/// Works by separating the keys by length at comptime and only checking strings of5/// Works by separating the keys by length at comptime and only checking strings of
6/// equal length at runtime.6/// equal length at runtime.
7///7///
8/// `kvs` expects a list literal containing list literals or an array/slice of structs8/// `kvs_list` expects a list of `struct { []const u8, V }` (key-value pair) tuples.
9/// where `.@"0"` is the `[]const u8` key and `.@"1"` is the associated value of type `V`.9/// You can pass `struct { []const u8 }` (only keys) tuples if `V` is `void`.
10/// TODO: https://github.com/ziglang/zig/issues/4335
11pub fn ComptimeStringMap(comptime V: type, comptime kvs_list: anytype) type {10pub fn ComptimeStringMap(comptime V: type, comptime kvs_list: anytype) type {
12 const precomputed = comptime blk: {11 const precomputed = comptime blk: {
13 @setEvalBranchQuota(2000);12 @setEvalBranchQuota(2000);
...@@ -97,32 +96,26 @@ test "ComptimeStringMap list literal of list literals" {...@@ -97,32 +96,26 @@ test "ComptimeStringMap list literal of list literals" {
97}96}
9897
99test "ComptimeStringMap array of structs" {98test "ComptimeStringMap array of structs" {
100 const KV = struct {99 const KV = struct { []const u8, TestEnum };
101 @"0": []const u8,
102 @"1": TestEnum,
103 };
104 const map = ComptimeStringMap(TestEnum, [_]KV{100 const map = ComptimeStringMap(TestEnum, [_]KV{
105 .{ .@"0" = "these", .@"1" = .D },101 .{ "these", .D },
106 .{ .@"0" = "have", .@"1" = .A },102 .{ "have", .A },
107 .{ .@"0" = "nothing", .@"1" = .B },103 .{ "nothing", .B },
108 .{ .@"0" = "incommon", .@"1" = .C },104 .{ "incommon", .C },
109 .{ .@"0" = "samelen", .@"1" = .E },105 .{ "samelen", .E },
110 });106 });
111107
112 try testMap(map);108 try testMap(map);
113}109}
114110
115test "ComptimeStringMap slice of structs" {111test "ComptimeStringMap slice of structs" {
116 const KV = struct {112 const KV = struct { []const u8, TestEnum };
117 @"0": []const u8,
118 @"1": TestEnum,
119 };
120 const slice: []const KV = &[_]KV{113 const slice: []const KV = &[_]KV{
121 .{ .@"0" = "these", .@"1" = .D },114 .{ "these", .D },
122 .{ .@"0" = "have", .@"1" = .A },115 .{ "have", .A },
123 .{ .@"0" = "nothing", .@"1" = .B },116 .{ "nothing", .B },
124 .{ .@"0" = "incommon", .@"1" = .C },117 .{ "incommon", .C },
125 .{ .@"0" = "samelen", .@"1" = .E },118 .{ "samelen", .E },
126 };119 };
127 const map = ComptimeStringMap(TestEnum, slice);120 const map = ComptimeStringMap(TestEnum, slice);
128121
...@@ -141,15 +134,13 @@ fn testMap(comptime map: anytype) !void {...@@ -141,15 +134,13 @@ fn testMap(comptime map: anytype) !void {
141}134}
142135
143test "ComptimeStringMap void value type, slice of structs" {136test "ComptimeStringMap void value type, slice of structs" {
144 const KV = struct {137 const KV = struct { []const u8 };
145 @"0": []const u8,
146 };
147 const slice: []const KV = &[_]KV{138 const slice: []const KV = &[_]KV{
148 .{ .@"0" = "these" },139 .{"these"},
149 .{ .@"0" = "have" },140 .{"have"},
150 .{ .@"0" = "nothing" },141 .{"nothing"},
151 .{ .@"0" = "incommon" },142 .{"incommon"},
152 .{ .@"0" = "samelen" },143 .{"samelen"},
153 };144 };
154 const map = ComptimeStringMap(void, slice);145 const map = ComptimeStringMap(void, slice);
155146
lib/std/meta.zig+2-8
...@@ -115,16 +115,10 @@ pub fn stringToEnum(comptime T: type, str: []const u8) ?T {...@@ -115,16 +115,10 @@ pub fn stringToEnum(comptime T: type, str: []const u8) ?T {
115 // - https://github.com/ziglang/zig/issues/3863115 // - https://github.com/ziglang/zig/issues/3863
116 if (@typeInfo(T).Enum.fields.len <= 100) {116 if (@typeInfo(T).Enum.fields.len <= 100) {
117 const kvs = comptime build_kvs: {117 const kvs = comptime build_kvs: {
118 // In order to generate an array of structs that play nice with anonymous118 const EnumKV = struct { []const u8, T };
119 // list literals, we need to give them "0" and "1" field names.
120 // TODO https://github.com/ziglang/zig/issues/4335
121 const EnumKV = struct {
122 @"0": []const u8,
123 @"1": T,
124 };
125 var kvs_array: [@typeInfo(T).Enum.fields.len]EnumKV = undefined;119 var kvs_array: [@typeInfo(T).Enum.fields.len]EnumKV = undefined;
126 inline for (@typeInfo(T).Enum.fields) |enumField, i| {120 inline for (@typeInfo(T).Enum.fields) |enumField, i| {
127 kvs_array[i] = .{ .@"0" = enumField.name, .@"1" = @field(T, enumField.name) };121 kvs_array[i] = .{ enumField.name, @field(T, enumField.name) };
128 }122 }
129 break :build_kvs kvs_array[0..];123 break :build_kvs kvs_array[0..];
130 };124 };