const std = @import("std"); pub fn Dynamic(comptime Key: type, comptime Value: type, comptime key_context: KeyContext(Key)) type { return struct { buckets_used: usize, bucket_map: []?Bucket, /// /// /// const Bucket = struct { key: Key, value: Value, next: ?usize, }; /// /// /// pub const InsertError = error { }; /// /// /// const Self = @This(); /// /// /// pub fn insert(self: Self, key: Key, value: Value) InsertError!void { _ = value; _ = key; _ = self; } /// /// /// pub fn lookup(self: Self, key: Key) ?*Value { var bucket = &(self.bucket_map[@mod(key_context.hash( key), self.bucket_map.len)] orelse return null); while (bucket) { if (key_context.equals(bucket.key, key)) return &bucket.value; bucket = bucket.next; } return null; } }; } pub fn KeyContext(comptime Key: type) type { return struct { hash: fn (Key) usize, equals: fn (Key, Key) bool, }; } fn equalsString(this_string: []const u8, that_string: []const u8) bool { return std.mem.eql(u8, this_string, that_string); } fn hashString(string: []const u8) usize { var hash = @as(usize, 5381); for (string) |byte| hash = ((hash << 5) + hash) + byte; return hash; } pub const string_context = KeyContext([]const u8){ .hash = hashString, .equals = equalsString, };