authorgravatar for motiejus@jakstys.ltMotiejus Jakštys <motiejus@jakstys.lt> 2022-02-27 22:24:00+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-02-27 15:24:00-05:00
logc03b733f0999418b234067cac51eac0e4412dfe1
treebabffc6d7495f74b75d06be22dd39503df07c7ad
parent4d658f83ed3893cf950615e9f58c2b533525b71d
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

std.HashMap: return explicit errors (#11000)

All errors from std.HashMap are allocation errors. Mark them as such. This is helpful when one wants to return explicit errors where HashMap is used.

1 files changed, 33 insertions(+), 33 deletions(-)

lib/std/hash_map.zig+33-33
...@@ -473,7 +473,7 @@ pub fn HashMap(...@@ -473,7 +473,7 @@ pub fn HashMap(
473 /// Otherwise, puts a new item with undefined value, and473 /// Otherwise, puts a new item with undefined value, and
474 /// the `Entry` pointers point to it. Caller should then initialize474 /// the `Entry` pointers point to it. Caller should then initialize
475 /// the value (but not the key).475 /// the value (but not the key).
476 pub fn getOrPut(self: *Self, key: K) !GetOrPutResult {476 pub fn getOrPut(self: *Self, key: K) Allocator.Error!GetOrPutResult {
477 return self.unmanaged.getOrPutContext(self.allocator, key, self.ctx);477 return self.unmanaged.getOrPutContext(self.allocator, key, self.ctx);
478 }478 }
479479
...@@ -483,7 +483,7 @@ pub fn HashMap(...@@ -483,7 +483,7 @@ pub fn HashMap(
483 /// Otherwise, puts a new item with undefined key and value, and483 /// Otherwise, puts a new item with undefined key and value, and
484 /// the `Entry` pointers point to it. Caller must then initialize484 /// the `Entry` pointers point to it. Caller must then initialize
485 /// the key and value.485 /// the key and value.
486 pub fn getOrPutAdapted(self: *Self, key: anytype, ctx: anytype) !GetOrPutResult {486 pub fn getOrPutAdapted(self: *Self, key: anytype, ctx: anytype) Allocator.Error!GetOrPutResult {
487 return self.unmanaged.getOrPutContextAdapted(self.allocator, key, ctx, self.ctx);487 return self.unmanaged.getOrPutContextAdapted(self.allocator, key, ctx, self.ctx);
488 }488 }
489489
...@@ -509,7 +509,7 @@ pub fn HashMap(...@@ -509,7 +509,7 @@ pub fn HashMap(
509 return self.unmanaged.getOrPutAssumeCapacityAdapted(self.allocator, key, ctx);509 return self.unmanaged.getOrPutAssumeCapacityAdapted(self.allocator, key, ctx);
510 }510 }
511511
512 pub fn getOrPutValue(self: *Self, key: K, value: V) !Entry {512 pub fn getOrPutValue(self: *Self, key: K, value: V) Allocator.Error!Entry {
513 return self.unmanaged.getOrPutValueContext(self.allocator, key, value, self.ctx);513 return self.unmanaged.getOrPutValueContext(self.allocator, key, value, self.ctx);
514 }514 }
515515
...@@ -517,14 +517,14 @@ pub fn HashMap(...@@ -517,14 +517,14 @@ pub fn HashMap(
517517
518 /// Increases capacity, guaranteeing that insertions up until the518 /// Increases capacity, guaranteeing that insertions up until the
519 /// `expected_count` will not cause an allocation, and therefore cannot fail.519 /// `expected_count` will not cause an allocation, and therefore cannot fail.
520 pub fn ensureTotalCapacity(self: *Self, expected_count: Size) !void {520 pub fn ensureTotalCapacity(self: *Self, expected_count: Size) Allocator.Error!void {
521 return self.unmanaged.ensureTotalCapacityContext(self.allocator, expected_count, self.ctx);521 return self.unmanaged.ensureTotalCapacityContext(self.allocator, expected_count, self.ctx);
522 }522 }
523523
524 /// Increases capacity, guaranteeing that insertions up until524 /// Increases capacity, guaranteeing that insertions up until
525 /// `additional_count` **more** items will not cause an allocation, and525 /// `additional_count` **more** items will not cause an allocation, and
526 /// therefore cannot fail.526 /// therefore cannot fail.
527 pub fn ensureUnusedCapacity(self: *Self, additional_count: Size) !void {527 pub fn ensureUnusedCapacity(self: *Self, additional_count: Size) Allocator.Error!void {
528 return self.unmanaged.ensureUnusedCapacityContext(self.allocator, additional_count, self.ctx);528 return self.unmanaged.ensureUnusedCapacityContext(self.allocator, additional_count, self.ctx);
529 }529 }
530530
...@@ -536,13 +536,13 @@ pub fn HashMap(...@@ -536,13 +536,13 @@ pub fn HashMap(
536536
537 /// Clobbers any existing data. To detect if a put would clobber537 /// Clobbers any existing data. To detect if a put would clobber
538 /// existing data, see `getOrPut`.538 /// existing data, see `getOrPut`.
539 pub fn put(self: *Self, key: K, value: V) !void {539 pub fn put(self: *Self, key: K, value: V) Allocator.Error!void {
540 return self.unmanaged.putContext(self.allocator, key, value, self.ctx);540 return self.unmanaged.putContext(self.allocator, key, value, self.ctx);
541 }541 }
542542
543 /// Inserts a key-value pair into the hash map, asserting that no previous543 /// Inserts a key-value pair into the hash map, asserting that no previous
544 /// entry with the same key is already present544 /// entry with the same key is already present
545 pub fn putNoClobber(self: *Self, key: K, value: V) !void {545 pub fn putNoClobber(self: *Self, key: K, value: V) Allocator.Error!void {
546 return self.unmanaged.putNoClobberContext(self.allocator, key, value, self.ctx);546 return self.unmanaged.putNoClobberContext(self.allocator, key, value, self.ctx);
547 }547 }
548548
...@@ -561,7 +561,7 @@ pub fn HashMap(...@@ -561,7 +561,7 @@ pub fn HashMap(
561 }561 }
562562
563 /// Inserts a new `Entry` into the hash map, returning the previous one, if any.563 /// Inserts a new `Entry` into the hash map, returning the previous one, if any.
564 pub fn fetchPut(self: *Self, key: K, value: V) !?KV {564 pub fn fetchPut(self: *Self, key: K, value: V) Allocator.Error!?KV {
565 return self.unmanaged.fetchPutContext(self.allocator, key, value, self.ctx);565 return self.unmanaged.fetchPutContext(self.allocator, key, value, self.ctx);
566 }566 }
567567
...@@ -647,19 +647,19 @@ pub fn HashMap(...@@ -647,19 +647,19 @@ pub fn HashMap(
647 }647 }
648648
649 /// Creates a copy of this map, using the same allocator649 /// Creates a copy of this map, using the same allocator
650 pub fn clone(self: Self) !Self {650 pub fn clone(self: Self) Allocator.Error!Self {
651 var other = try self.unmanaged.cloneContext(self.allocator, self.ctx);651 var other = try self.unmanaged.cloneContext(self.allocator, self.ctx);
652 return other.promoteContext(self.allocator, self.ctx);652 return other.promoteContext(self.allocator, self.ctx);
653 }653 }
654654
655 /// Creates a copy of this map, using a specified allocator655 /// Creates a copy of this map, using a specified allocator
656 pub fn cloneWithAllocator(self: Self, new_allocator: Allocator) !Self {656 pub fn cloneWithAllocator(self: Self, new_allocator: Allocator) Allocator.Error!Self {
657 var other = try self.unmanaged.cloneContext(new_allocator, self.ctx);657 var other = try self.unmanaged.cloneContext(new_allocator, self.ctx);
658 return other.promoteContext(new_allocator, self.ctx);658 return other.promoteContext(new_allocator, self.ctx);
659 }659 }
660660
661 /// Creates a copy of this map, using a specified context661 /// Creates a copy of this map, using a specified context
662 pub fn cloneWithContext(self: Self, new_ctx: anytype) !HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {662 pub fn cloneWithContext(self: Self, new_ctx: anytype) Allocator.Error!HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {
663 var other = try self.unmanaged.cloneContext(self.allocator, new_ctx);663 var other = try self.unmanaged.cloneContext(self.allocator, new_ctx);
664 return other.promoteContext(self.allocator, new_ctx);664 return other.promoteContext(self.allocator, new_ctx);
665 }665 }
...@@ -669,7 +669,7 @@ pub fn HashMap(...@@ -669,7 +669,7 @@ pub fn HashMap(
669 self: Self,669 self: Self,
670 new_allocator: Allocator,670 new_allocator: Allocator,
671 new_ctx: anytype,671 new_ctx: anytype,
672 ) !HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {672 ) Allocator.Error!HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {
673 var other = try self.unmanaged.cloneContext(new_allocator, new_ctx);673 var other = try self.unmanaged.cloneContext(new_allocator, new_ctx);
674 return other.promoteContext(new_allocator, new_ctx);674 return other.promoteContext(new_allocator, new_ctx);
675 }675 }
...@@ -896,20 +896,20 @@ pub fn HashMapUnmanaged(...@@ -896,20 +896,20 @@ pub fn HashMapUnmanaged(
896896
897 pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");897 pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
898898
899 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_size: Size) !void {899 pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_size: Size) Allocator.Error!void {
900 if (@sizeOf(Context) != 0)900 if (@sizeOf(Context) != 0)
901 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");901 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");
902 return ensureTotalCapacityContext(self, allocator, new_size, undefined);902 return ensureTotalCapacityContext(self, allocator, new_size, undefined);
903 }903 }
904 pub fn ensureTotalCapacityContext(self: *Self, allocator: Allocator, new_size: Size, ctx: Context) !void {904 pub fn ensureTotalCapacityContext(self: *Self, allocator: Allocator, new_size: Size, ctx: Context) Allocator.Error!void {
905 if (new_size > self.size)905 if (new_size > self.size)
906 try self.growIfNeeded(allocator, new_size - self.size, ctx);906 try self.growIfNeeded(allocator, new_size - self.size, ctx);
907 }907 }
908908
909 pub fn ensureUnusedCapacity(self: *Self, allocator: Allocator, additional_size: Size) !void {909 pub fn ensureUnusedCapacity(self: *Self, allocator: Allocator, additional_size: Size) Allocator.Error!void {
910 return ensureUnusedCapacityContext(self, allocator, additional_size, undefined);910 return ensureUnusedCapacityContext(self, allocator, additional_size, undefined);
911 }911 }
912 pub fn ensureUnusedCapacityContext(self: *Self, allocator: Allocator, additional_size: Size, ctx: Context) !void {912 pub fn ensureUnusedCapacityContext(self: *Self, allocator: Allocator, additional_size: Size, ctx: Context) Allocator.Error!void {
913 return ensureTotalCapacityContext(self, allocator, self.count() + additional_size, ctx);913 return ensureTotalCapacityContext(self, allocator, self.count() + additional_size, ctx);
914 }914 }
915915
...@@ -986,12 +986,12 @@ pub fn HashMapUnmanaged(...@@ -986,12 +986,12 @@ pub fn HashMapUnmanaged(
986 }986 }
987987
988 /// Insert an entry in the map. Assumes it is not already present.988 /// Insert an entry in the map. Assumes it is not already present.
989 pub fn putNoClobber(self: *Self, allocator: Allocator, key: K, value: V) !void {989 pub fn putNoClobber(self: *Self, allocator: Allocator, key: K, value: V) Allocator.Error!void {
990 if (@sizeOf(Context) != 0)990 if (@sizeOf(Context) != 0)
991 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");991 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");
992 return self.putNoClobberContext(allocator, key, value, undefined);992 return self.putNoClobberContext(allocator, key, value, undefined);
993 }993 }
994 pub fn putNoClobberContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void {994 pub fn putNoClobberContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Allocator.Error!void {
995 assert(!self.containsContext(key, ctx));995 assert(!self.containsContext(key, ctx));
996 try self.growIfNeeded(allocator, 1, ctx);996 try self.growIfNeeded(allocator, 1, ctx);
997997
...@@ -1043,12 +1043,12 @@ pub fn HashMapUnmanaged(...@@ -1043,12 +1043,12 @@ pub fn HashMapUnmanaged(
1043 }1043 }
10441044
1045 /// Inserts a new `Entry` into the hash map, returning the previous one, if any.1045 /// Inserts a new `Entry` into the hash map, returning the previous one, if any.
1046 pub fn fetchPut(self: *Self, allocator: Allocator, key: K, value: V) !?KV {1046 pub fn fetchPut(self: *Self, allocator: Allocator, key: K, value: V) Allocator.Error!?KV {
1047 if (@sizeOf(Context) != 0)1047 if (@sizeOf(Context) != 0)
1048 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");1048 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");
1049 return self.fetchPutContext(allocator, key, value, undefined);1049 return self.fetchPutContext(allocator, key, value, undefined);
1050 }1050 }
1051 pub fn fetchPutContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !?KV {1051 pub fn fetchPutContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Allocator.Error!?KV {
1052 const gop = try self.getOrPutContext(allocator, key, ctx);1052 const gop = try self.getOrPutContext(allocator, key, ctx);
1053 var result: ?KV = null;1053 var result: ?KV = null;
1054 if (gop.found_existing) {1054 if (gop.found_existing) {
...@@ -1182,12 +1182,12 @@ pub fn HashMapUnmanaged(...@@ -1182,12 +1182,12 @@ pub fn HashMapUnmanaged(
1182 }1182 }
11831183
1184 /// Insert an entry if the associated key is not already present, otherwise update preexisting value.1184 /// Insert an entry if the associated key is not already present, otherwise update preexisting value.
1185 pub fn put(self: *Self, allocator: Allocator, key: K, value: V) !void {1185 pub fn put(self: *Self, allocator: Allocator, key: K, value: V) Allocator.Error!void {
1186 if (@sizeOf(Context) != 0)1186 if (@sizeOf(Context) != 0)
1187 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");1187 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");
1188 return self.putContext(allocator, key, value, undefined);1188 return self.putContext(allocator, key, value, undefined);
1189 }1189 }
1190 pub fn putContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void {1190 pub fn putContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Allocator.Error!void {
1191 const result = try self.getOrPutContext(allocator, key, ctx);1191 const result = try self.getOrPutContext(allocator, key, ctx);
1192 result.value_ptr.* = value;1192 result.value_ptr.* = value;
1193 }1193 }
...@@ -1256,24 +1256,24 @@ pub fn HashMapUnmanaged(...@@ -1256,24 +1256,24 @@ pub fn HashMapUnmanaged(
1256 return null;1256 return null;
1257 }1257 }
12581258
1259 pub fn getOrPut(self: *Self, allocator: Allocator, key: K) !GetOrPutResult {1259 pub fn getOrPut(self: *Self, allocator: Allocator, key: K) Allocator.Error!GetOrPutResult {
1260 if (@sizeOf(Context) != 0)1260 if (@sizeOf(Context) != 0)
1261 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");1261 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");
1262 return self.getOrPutContext(allocator, key, undefined);1262 return self.getOrPutContext(allocator, key, undefined);
1263 }1263 }
1264 pub fn getOrPutContext(self: *Self, allocator: Allocator, key: K, ctx: Context) !GetOrPutResult {1264 pub fn getOrPutContext(self: *Self, allocator: Allocator, key: K, ctx: Context) Allocator.Error!GetOrPutResult {
1265 const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);1265 const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);
1266 if (!gop.found_existing) {1266 if (!gop.found_existing) {
1267 gop.key_ptr.* = key;1267 gop.key_ptr.* = key;
1268 }1268 }
1269 return gop;1269 return gop;
1270 }1270 }
1271 pub fn getOrPutAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult {1271 pub fn getOrPutAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype) Allocator.Error!GetOrPutResult {
1272 if (@sizeOf(Context) != 0)1272 if (@sizeOf(Context) != 0)
1273 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");1273 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");
1274 return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);1274 return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);
1275 }1275 }
1276 pub fn getOrPutContextAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult {1276 pub fn getOrPutContextAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype, ctx: Context) Allocator.Error!GetOrPutResult {
1277 self.growIfNeeded(allocator, 1, ctx) catch |err| {1277 self.growIfNeeded(allocator, 1, ctx) catch |err| {
1278 // If allocation fails, try to do the lookup anyway.1278 // If allocation fails, try to do the lookup anyway.
1279 // If we find an existing item, we can return it.1279 // If we find an existing item, we can return it.
...@@ -1367,12 +1367,12 @@ pub fn HashMapUnmanaged(...@@ -1367,12 +1367,12 @@ pub fn HashMapUnmanaged(
1367 };1367 };
1368 }1368 }
13691369
1370 pub fn getOrPutValue(self: *Self, allocator: Allocator, key: K, value: V) !Entry {1370 pub fn getOrPutValue(self: *Self, allocator: Allocator, key: K, value: V) Allocator.Error!Entry {
1371 if (@sizeOf(Context) != 0)1371 if (@sizeOf(Context) != 0)
1372 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");1372 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");
1373 return self.getOrPutValueContext(allocator, key, value, undefined);1373 return self.getOrPutValueContext(allocator, key, value, undefined);
1374 }1374 }
1375 pub fn getOrPutValueContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !Entry {1375 pub fn getOrPutValueContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Allocator.Error!Entry {
1376 const res = try self.getOrPutAdapted(allocator, key, ctx);1376 const res = try self.getOrPutAdapted(allocator, key, ctx);
1377 if (!res.found_existing) {1377 if (!res.found_existing) {
1378 res.key_ptr.* = key;1378 res.key_ptr.* = key;
...@@ -1450,18 +1450,18 @@ pub fn HashMapUnmanaged(...@@ -1450,18 +1450,18 @@ pub fn HashMapUnmanaged(
1450 return @truncate(Size, max_load - self.available);1450 return @truncate(Size, max_load - self.available);
1451 }1451 }
14521452
1453 fn growIfNeeded(self: *Self, allocator: Allocator, new_count: Size, ctx: Context) !void {1453 fn growIfNeeded(self: *Self, allocator: Allocator, new_count: Size, ctx: Context) Allocator.Error!void {
1454 if (new_count > self.available) {1454 if (new_count > self.available) {
1455 try self.grow(allocator, capacityForSize(self.load() + new_count), ctx);1455 try self.grow(allocator, capacityForSize(self.load() + new_count), ctx);
1456 }1456 }
1457 }1457 }
14581458
1459 pub fn clone(self: Self, allocator: Allocator) !Self {1459 pub fn clone(self: Self, allocator: Allocator) Allocator.Error!Self {
1460 if (@sizeOf(Context) != 0)1460 if (@sizeOf(Context) != 0)
1461 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");1461 @compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");
1462 return self.cloneContext(allocator, @as(Context, undefined));1462 return self.cloneContext(allocator, @as(Context, undefined));
1463 }1463 }
1464 pub fn cloneContext(self: Self, allocator: Allocator, new_ctx: anytype) !HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage) {1464 pub fn cloneContext(self: Self, allocator: Allocator, new_ctx: anytype) Allocator.Error!HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage) {
1465 var other = HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage){};1465 var other = HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage){};
1466 if (self.size == 0)1466 if (self.size == 0)
1467 return other;1467 return other;
...@@ -1486,7 +1486,7 @@ pub fn HashMapUnmanaged(...@@ -1486,7 +1486,7 @@ pub fn HashMapUnmanaged(
1486 return other;1486 return other;
1487 }1487 }
14881488
1489 fn grow(self: *Self, allocator: Allocator, new_capacity: Size, ctx: Context) !void {1489 fn grow(self: *Self, allocator: Allocator, new_capacity: Size, ctx: Context) Allocator.Error!void {
1490 @setCold(true);1490 @setCold(true);
1491 const new_cap = std.math.max(new_capacity, minimal_capacity);1491 const new_cap = std.math.max(new_capacity, minimal_capacity);
1492 assert(new_cap > self.capacity());1492 assert(new_cap > self.capacity());
...@@ -1517,7 +1517,7 @@ pub fn HashMapUnmanaged(...@@ -1517,7 +1517,7 @@ pub fn HashMapUnmanaged(
1517 std.mem.swap(Self, self, &map);1517 std.mem.swap(Self, self, &map);
1518 }1518 }
15191519
1520 fn allocate(self: *Self, allocator: Allocator, new_capacity: Size) !void {1520 fn allocate(self: *Self, allocator: Allocator, new_capacity: Size) Allocator.Error!void {
1521 const header_align = @alignOf(Header);1521 const header_align = @alignOf(Header);
1522 const key_align = if (@sizeOf(K) == 0) 1 else @alignOf(K);1522 const key_align = if (@sizeOf(K) == 0) 1 else @alignOf(K);
1523 const val_align = if (@sizeOf(V) == 0) 1 else @alignOf(V);1523 const val_align = if (@sizeOf(V) == 0) 1 else @alignOf(V);