aboutsummaryrefslogtreecommitdiff
path: root/lib/std/array_hash_map.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-08-04 00:29:39 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-08-04 09:47:42 +0200
commitee6f7fee2900ea18bfd056e57952aba606158d7b (patch)
tree5360b0d6127090290171fe8711e675da31d4c99a /lib/std/array_hash_map.zig
parentaad4598367b136a06e3569373be7da8febea7f31 (diff)
downloadzig-ee6f7fee2900ea18bfd056e57952aba606158d7b.tar.gz
zig-ee6f7fee2900ea18bfd056e57952aba606158d7b.zip
libstd: add ArrayHashMap.popOrNull function
which internally calls `ArrayHashMap.pop`, however, returns `?KV` instead and performs the bounds checking automatically. This function correponds to `ArrayList.popOrNull` and is meant to fill the gap for situations where we want the quick lookup offered by the hash map with elegant ability to iterate and pop of the container with automatic bound checking that plugs in well with a `while`-loop such as ```zig var map = std.ArrayHashMap(K, V).init(allocator); map.deinit(); while (map.popOrNull()) |entry| { // ... do something } assert(map.count() == 0); ```
Diffstat (limited to 'lib/std/array_hash_map.zig')
-rw-r--r--lib/std/array_hash_map.zig37
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/std/array_hash_map.zig b/lib/std/array_hash_map.zig
index 9bcecab47e..4ca603d2e8 100644
--- a/lib/std/array_hash_map.zig
+++ b/lib/std/array_hash_map.zig
@@ -414,6 +414,12 @@ pub fn ArrayHashMap(
pub fn pop(self: *Self) KV {
return self.unmanaged.popContext(self.ctx);
}
+
+ /// Removes the last inserted `Entry` in the hash map and returns it if count is nonzero.
+ /// Otherwise returns null.
+ pub fn popOrNull(self: *Self) ?KV {
+ return self.unmanaged.popOrNullContext(self.ctx);
+ }
};
}
@@ -1181,6 +1187,17 @@ pub fn ArrayHashMapUnmanaged(
};
}
+ /// Removes the last inserted `Entry` in the hash map and returns it if count is nonzero.
+ /// Otherwise returns null.
+ pub fn popOrNull(self: *Self) ?KV {
+ if (@sizeOf(ByIndexContext) != 0)
+ @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call popContext instead.");
+ return self.popOrNullContext(undefined);
+ }
+ pub fn popOrNullContext(self: *Self, ctx: Context) ?KV {
+ return if (self.entries.len == 0) null else self.popContext(ctx);
+ }
+
// ------------------ No pub fns below this point ------------------
fn fetchRemoveByKey(self: *Self, key: anytype, key_ctx: anytype, ctx: ByIndexContext, comptime removal_type: RemovalType) ?KV {
@@ -2094,6 +2111,26 @@ test "pop" {
}
}
+test "popOrNull" {
+ var map = AutoArrayHashMap(i32, i32).init(std.testing.allocator);
+ defer map.deinit();
+
+ // Insert just enough entries so that the map expands. Afterwards,
+ // pop all entries out of the map.
+
+ var i: i32 = 0;
+ while (i < 9) : (i += 1) {
+ try testing.expect((try map.fetchPut(i, i)) == null);
+ }
+
+ while (map.popOrNull()) |pop| {
+ try testing.expect(pop.key == i - 1 and pop.value == i - 1);
+ i -= 1;
+ }
+
+ try testing.expect(map.count() == 0);
+}
+
test "reIndex" {
var map = ArrayHashMap(i32, i32, AutoContext(i32), true).init(std.testing.allocator);
defer map.deinit();