aboutsummaryrefslogtreecommitdiff
path: root/lib/std/buf_set.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-06-04 01:12:38 -0400
committerGitHub <noreply@github.com>2021-06-04 01:12:38 -0400
commit7d15a3ac71c5d8dc8c08dfd8ea8ad43d4eae188a (patch)
treeae007106526e300bb7143be003fe8d847ba7230c /lib/std/buf_set.zig
parent87dae0ce98fde1957a9290c22866b3101ce419d8 (diff)
parent6953c8544b68c788dca4ed065e4a15eccbd4446b (diff)
downloadzig-7d15a3ac71c5d8dc8c08dfd8ea8ad43d4eae188a.tar.gz
zig-7d15a3ac71c5d8dc8c08dfd8ea8ad43d4eae188a.zip
Merge pull request #8975 from SpexGuy/hash-map-updates
Breaking hash map changes for 0.8.0
Diffstat (limited to 'lib/std/buf_set.zig')
-rw-r--r--lib/std/buf_set.zig59
1 files changed, 39 insertions, 20 deletions
diff --git a/lib/std/buf_set.zig b/lib/std/buf_set.zig
index 5e09aa6bcb..c2a1f9bcb9 100644
--- a/lib/std/buf_set.zig
+++ b/lib/std/buf_set.zig
@@ -9,50 +9,69 @@ const mem = @import("mem.zig");
const Allocator = mem.Allocator;
const testing = std.testing;
+/// A BufSet is a set of strings. The BufSet duplicates
+/// strings internally, and never takes ownership of strings
+/// which are passed to it.
pub const BufSet = struct {
hash_map: BufSetHashMap,
const BufSetHashMap = StringHashMap(void);
+ pub const Iterator = BufSetHashMap.KeyIterator;
+ /// Create a BufSet using an allocator. The allocator will
+ /// be used internally for both backing allocations and
+ /// string duplication.
pub fn init(a: *Allocator) BufSet {
var self = BufSet{ .hash_map = BufSetHashMap.init(a) };
return self;
}
+ /// Free a BufSet along with all stored keys.
pub fn deinit(self: *BufSet) void {
- var it = self.hash_map.iterator();
- while (it.next()) |entry| {
- self.free(entry.key);
+ var it = self.hash_map.keyIterator();
+ while (it.next()) |key_ptr| {
+ self.free(key_ptr.*);
}
self.hash_map.deinit();
self.* = undefined;
}
- pub fn put(self: *BufSet, key: []const u8) !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, {});
+ /// Insert an item into the BufSet. The item will be
+ /// copied, so the caller may delete or reuse the
+ /// passed string immediately.
+ pub fn insert(self: *BufSet, value: []const u8) !void {
+ const gop = try self.hash_map.getOrPut(value);
+ if (!gop.found_existing) {
+ gop.key_ptr.* = self.copy(value) catch |err| {
+ _ = self.hash_map.remove(value);
+ return err;
+ };
}
}
- pub fn exists(self: BufSet, key: []const u8) bool {
- return self.hash_map.get(key) != null;
+ /// Check if the set contains an item matching the passed string
+ pub fn contains(self: BufSet, value: []const u8) bool {
+ return self.hash_map.contains(value);
}
- pub fn delete(self: *BufSet, key: []const u8) void {
- const entry = self.hash_map.remove(key) orelse return;
- self.free(entry.key);
+ /// Remove an item from the set.
+ pub fn remove(self: *BufSet, value: []const u8) void {
+ const kv = self.hash_map.fetchRemove(value) orelse return;
+ self.free(kv.key);
}
+ /// Returns the number of items stored in the set
pub fn count(self: *const BufSet) usize {
return self.hash_map.count();
}
- pub fn iterator(self: *const BufSet) BufSetHashMap.Iterator {
- return self.hash_map.iterator();
+ /// Returns an iterator over the items stored in the set.
+ /// Iteration order is arbitrary.
+ pub fn iterator(self: *const BufSet) Iterator {
+ return self.hash_map.keyIterator();
}
+ /// Get the allocator used by this set
pub fn allocator(self: *const BufSet) *Allocator {
return self.hash_map.allocator;
}
@@ -72,12 +91,12 @@ test "BufSet" {
var bufset = BufSet.init(std.testing.allocator);
defer bufset.deinit();
- try bufset.put("x");
+ try bufset.insert("x");
try testing.expect(bufset.count() == 1);
- bufset.delete("x");
+ bufset.remove("x");
try testing.expect(bufset.count() == 0);
- try bufset.put("x");
- try bufset.put("y");
- try bufset.put("z");
+ try bufset.insert("x");
+ try bufset.insert("y");
+ try bufset.insert("z");
}