Skip to content

Instantly share code, notes, and snippets.

@kooparse
Last active March 4, 2021 22:27
Show Gist options
  • Save kooparse/4f58b886a2d7158a7e5c7a8246bbe196 to your computer and use it in GitHub Desktop.
Save kooparse/4f58b886a2d7158a7e5c7a8246bbe196 to your computer and use it in GitHub Desktop.
StringHashMap which own keys
// SPDX-License-Identifier: MIT
// Copyright (c) 2015-2021 Zig Contributors
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const std = @import("std.zig");
const StringHashMap = std.StringHashMap;
const mem = @import("mem.zig");
const Allocator = mem.Allocator;
const testing = std.testing;
pub fn StringBufMap(comptime T: anytype) type {
return struct {
hash_map: BufSetHashMap,
const StringBuf = StringHashMap(T);
const Self = @This();
pub fn init(a: *Allocator) Self {
return .{ .hash_map = StringBuf.init(a) };
}
/// Given `key` will be copied into the BufSet.
pub fn put(self: *Self, key: []const u8, value: T) !void {
if (self.hash_map.get(key) == null) {
const key_copy = try self.copy(key);
errdefer self.free(key_copy);
try self.hash_map.put(key_copy, value);
}
}
pub fn exists(self: Self, key: []const u8) bool {
return self.hash_map.get(key) != null;
}
pub fn delete(self: *Self, key: []const u8) void {
const entry = self.hash_map.remove(key) orelse return;
self.free(entry.key);
}
pub fn count(self: *const Self) usize {
return self.hash_map.count();
}
pub fn iterator(self: *const Self) StringBuf.Iterator {
return self.hash_map.iterator();
}
pub fn allocator(self: *const Self) *Allocator {
return self.hash_map.allocator;
}
pub fn deinit(self: *Self) void {
var it = self.hash_map.iterator();
while (it.next()) |entry| self.free(entry.key);
self.hash_map.deinit();
self.* = undefined;
}
/// Return a pointer to the copied given `key`.
fn copy(self: Self, key: []const u8) ![]u8 {
return self.hash_map.allocator.dupe(u8, key);
}
/// Used to free the copied `key`.
fn free(self: *const Self, value: []const u8) void {
self.hash_map.allocator.free(value);
}
};
}
test "StringBuf" {
var bufset = BufSet(void).init(std.testing.allocator);
defer bufset.deinit();
try bufset.put("x", {});
testing.expect(bufset.count() == 1);
bufset.delete("x");
testing.expect(bufset.count() == 0);
try bufset.put("x", {});
try bufset.put("y", {});
try bufset.put("z", {});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment