authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-08 02:23:17-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-12-08 02:23:17-08:00
log225ed65ed2cc88fce54660250feaeb44e45943fa
tree53912cecb13cf5ddfa10ae19db1917b1f28644a3
parentd5ecb318c4550351eb1973d73cac61bc8af2a70f

Revert "std.ComptimeStringMap: use tuple types"

This reverts commit 096d3efae5fcaa5640f4acb2f9be2d7f93f7fdb2. This commit is not passing a very important CI test that was recently added.

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

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