authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-07-02 11:57:41 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2024-07-02 11:57:41 -07:00
log2336d8b767eb7378762e1ba63635ca44accbd2ca
treeadd574d4933fc070d75774159bc7aa4ce7526f09
parentc756fb84ba7de002dd93709730c663ab39841ab4

add AddStrGeneric


1 files changed, 39 insertions(+), 0 deletions(-)

intrusive_parser.zig+39
......@@ -182,6 +182,45 @@ pub const Parser = struct {
182182 return std.mem.eql(u8, a, b);
183183 }
184184 };
185
186 /// Similar to addStr but lets you change the tag so that new index types can be aliases and use the same intern storage
187 pub fn AddStrGeneric(comptime tag: u8) type {
188 return struct {
189 pub fn add(p: *Parser, alloc: std.mem.Allocator, str: string) !usize {
190 const adapter: Adapter = .{ .p = p };
191 const res = try p.strings_map.getOrPutAdapted(alloc, str, adapter);
192 if (res.found_existing) return res.value_ptr.*;
193 errdefer p.strings_map.orderedRemoveAt(res.index);
194 const r = p.data.items.len;
195 const l = str.len;
196 try p.data.ensureUnusedCapacity(alloc, 1 + 4 + l);
197 p.data.appendAssumeCapacity(tag);
198 p.data.appendSliceAssumeCapacity(&std.mem.toBytes(@as(u32, @intCast(l))));
199 p.data.appendSliceAssumeCapacity(str);
200 res.value_ptr.* = r;
201 return r;
202 }
203
204 const Adapter = struct {
205 p: *const Parser,
206
207 pub fn hash(ctx: @This(), a: string) u32 {
208 _ = ctx;
209 var hasher = std.hash.Wyhash.init(0);
210 hasher.update(a);
211 return @truncate(hasher.final());
212 }
213
214 pub fn eql(ctx: @This(), a: string, _: string, b_index: usize) bool {
215 const i = ctx.p.strings_map.values()[b_index];
216 std.debug.assert(ctx.p.data.items[i] == tag);
217 const l: u32 = @bitCast(ctx.p.data.items[i..][1..][0..4].*);
218 const b = ctx.p.data.items[i..][1..][4..][0..l];
219 return std.mem.eql(u8, a, b);
220 }
221 };
222 };
223 }
185224};
186225
187226pub fn Mixin(comptime T: type) type {