| ... | @@ -182,6 +182,45 @@ pub const Parser = struct { | ... | @@ -182,6 +182,45 @@ pub const Parser = struct { |
| 182 | return std.mem.eql(u8, a, b); | 182 | return std.mem.eql(u8, a, b); |
| 183 | } | 183 | } |
| 184 | }; | 184 | }; |
| | 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 | } |
| 185 | }; | 224 | }; |
| 186 | | 225 | |
| 187 | pub fn Mixin(comptime T: type) type { | 226 | pub fn Mixin(comptime T: type) type { |