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.
This commit is contained in:
@@ -473,7 +473,7 @@ pub fn HashMap(
|
||||
/// Otherwise, puts a new item with undefined value, and
|
||||
/// the `Entry` pointers point to it. Caller should then initialize
|
||||
/// the value (but not the key).
|
||||
pub fn getOrPut(self: *Self, key: K) !GetOrPutResult {
|
||||
pub fn getOrPut(self: *Self, key: K) Allocator.Error!GetOrPutResult {
|
||||
return self.unmanaged.getOrPutContext(self.allocator, key, self.ctx);
|
||||
}
|
||||
|
||||
@@ -483,7 +483,7 @@ pub fn HashMap(
|
||||
/// Otherwise, puts a new item with undefined key and value, and
|
||||
/// the `Entry` pointers point to it. Caller must then initialize
|
||||
/// the key and value.
|
||||
pub fn getOrPutAdapted(self: *Self, key: anytype, ctx: anytype) !GetOrPutResult {
|
||||
pub fn getOrPutAdapted(self: *Self, key: anytype, ctx: anytype) Allocator.Error!GetOrPutResult {
|
||||
return self.unmanaged.getOrPutContextAdapted(self.allocator, key, ctx, self.ctx);
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ pub fn HashMap(
|
||||
return self.unmanaged.getOrPutAssumeCapacityAdapted(self.allocator, key, ctx);
|
||||
}
|
||||
|
||||
pub fn getOrPutValue(self: *Self, key: K, value: V) !Entry {
|
||||
pub fn getOrPutValue(self: *Self, key: K, value: V) Allocator.Error!Entry {
|
||||
return self.unmanaged.getOrPutValueContext(self.allocator, key, value, self.ctx);
|
||||
}
|
||||
|
||||
@@ -517,14 +517,14 @@ pub fn HashMap(
|
||||
|
||||
/// Increases capacity, guaranteeing that insertions up until the
|
||||
/// `expected_count` will not cause an allocation, and therefore cannot fail.
|
||||
pub fn ensureTotalCapacity(self: *Self, expected_count: Size) !void {
|
||||
pub fn ensureTotalCapacity(self: *Self, expected_count: Size) Allocator.Error!void {
|
||||
return self.unmanaged.ensureTotalCapacityContext(self.allocator, expected_count, self.ctx);
|
||||
}
|
||||
|
||||
/// Increases capacity, guaranteeing that insertions up until
|
||||
/// `additional_count` **more** items will not cause an allocation, and
|
||||
/// therefore cannot fail.
|
||||
pub fn ensureUnusedCapacity(self: *Self, additional_count: Size) !void {
|
||||
pub fn ensureUnusedCapacity(self: *Self, additional_count: Size) Allocator.Error!void {
|
||||
return self.unmanaged.ensureUnusedCapacityContext(self.allocator, additional_count, self.ctx);
|
||||
}
|
||||
|
||||
@@ -536,13 +536,13 @@ pub fn HashMap(
|
||||
|
||||
/// Clobbers any existing data. To detect if a put would clobber
|
||||
/// existing data, see `getOrPut`.
|
||||
pub fn put(self: *Self, key: K, value: V) !void {
|
||||
pub fn put(self: *Self, key: K, value: V) Allocator.Error!void {
|
||||
return self.unmanaged.putContext(self.allocator, key, value, self.ctx);
|
||||
}
|
||||
|
||||
/// Inserts a key-value pair into the hash map, asserting that no previous
|
||||
/// entry with the same key is already present
|
||||
pub fn putNoClobber(self: *Self, key: K, value: V) !void {
|
||||
pub fn putNoClobber(self: *Self, key: K, value: V) Allocator.Error!void {
|
||||
return self.unmanaged.putNoClobberContext(self.allocator, key, value, self.ctx);
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ pub fn HashMap(
|
||||
}
|
||||
|
||||
/// Inserts a new `Entry` into the hash map, returning the previous one, if any.
|
||||
pub fn fetchPut(self: *Self, key: K, value: V) !?KV {
|
||||
pub fn fetchPut(self: *Self, key: K, value: V) Allocator.Error!?KV {
|
||||
return self.unmanaged.fetchPutContext(self.allocator, key, value, self.ctx);
|
||||
}
|
||||
|
||||
@@ -647,19 +647,19 @@ pub fn HashMap(
|
||||
}
|
||||
|
||||
/// Creates a copy of this map, using the same allocator
|
||||
pub fn clone(self: Self) !Self {
|
||||
pub fn clone(self: Self) Allocator.Error!Self {
|
||||
var other = try self.unmanaged.cloneContext(self.allocator, self.ctx);
|
||||
return other.promoteContext(self.allocator, self.ctx);
|
||||
}
|
||||
|
||||
/// Creates a copy of this map, using a specified allocator
|
||||
pub fn cloneWithAllocator(self: Self, new_allocator: Allocator) !Self {
|
||||
pub fn cloneWithAllocator(self: Self, new_allocator: Allocator) Allocator.Error!Self {
|
||||
var other = try self.unmanaged.cloneContext(new_allocator, self.ctx);
|
||||
return other.promoteContext(new_allocator, self.ctx);
|
||||
}
|
||||
|
||||
/// Creates a copy of this map, using a specified context
|
||||
pub fn cloneWithContext(self: Self, new_ctx: anytype) !HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {
|
||||
pub fn cloneWithContext(self: Self, new_ctx: anytype) Allocator.Error!HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {
|
||||
var other = try self.unmanaged.cloneContext(self.allocator, new_ctx);
|
||||
return other.promoteContext(self.allocator, new_ctx);
|
||||
}
|
||||
@@ -669,7 +669,7 @@ pub fn HashMap(
|
||||
self: Self,
|
||||
new_allocator: Allocator,
|
||||
new_ctx: anytype,
|
||||
) !HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {
|
||||
) Allocator.Error!HashMap(K, V, @TypeOf(new_ctx), max_load_percentage) {
|
||||
var other = try self.unmanaged.cloneContext(new_allocator, new_ctx);
|
||||
return other.promoteContext(new_allocator, new_ctx);
|
||||
}
|
||||
@@ -896,20 +896,20 @@ pub fn HashMapUnmanaged(
|
||||
|
||||
pub const ensureCapacity = @compileError("deprecated; call `ensureUnusedCapacity` or `ensureTotalCapacity`");
|
||||
|
||||
pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_size: Size) !void {
|
||||
pub fn ensureTotalCapacity(self: *Self, allocator: Allocator, new_size: Size) Allocator.Error!void {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call ensureTotalCapacityContext instead.");
|
||||
return ensureTotalCapacityContext(self, allocator, new_size, undefined);
|
||||
}
|
||||
pub fn ensureTotalCapacityContext(self: *Self, allocator: Allocator, new_size: Size, ctx: Context) !void {
|
||||
pub fn ensureTotalCapacityContext(self: *Self, allocator: Allocator, new_size: Size, ctx: Context) Allocator.Error!void {
|
||||
if (new_size > self.size)
|
||||
try self.growIfNeeded(allocator, new_size - self.size, ctx);
|
||||
}
|
||||
|
||||
pub fn ensureUnusedCapacity(self: *Self, allocator: Allocator, additional_size: Size) !void {
|
||||
pub fn ensureUnusedCapacity(self: *Self, allocator: Allocator, additional_size: Size) Allocator.Error!void {
|
||||
return ensureUnusedCapacityContext(self, allocator, additional_size, undefined);
|
||||
}
|
||||
pub fn ensureUnusedCapacityContext(self: *Self, allocator: Allocator, additional_size: Size, ctx: Context) !void {
|
||||
pub fn ensureUnusedCapacityContext(self: *Self, allocator: Allocator, additional_size: Size, ctx: Context) Allocator.Error!void {
|
||||
return ensureTotalCapacityContext(self, allocator, self.count() + additional_size, ctx);
|
||||
}
|
||||
|
||||
@@ -986,12 +986,12 @@ pub fn HashMapUnmanaged(
|
||||
}
|
||||
|
||||
/// Insert an entry in the map. Assumes it is not already present.
|
||||
pub fn putNoClobber(self: *Self, allocator: Allocator, key: K, value: V) !void {
|
||||
pub fn putNoClobber(self: *Self, allocator: Allocator, key: K, value: V) Allocator.Error!void {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putNoClobberContext instead.");
|
||||
return self.putNoClobberContext(allocator, key, value, undefined);
|
||||
}
|
||||
pub fn putNoClobberContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void {
|
||||
pub fn putNoClobberContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Allocator.Error!void {
|
||||
assert(!self.containsContext(key, ctx));
|
||||
try self.growIfNeeded(allocator, 1, ctx);
|
||||
|
||||
@@ -1043,12 +1043,12 @@ pub fn HashMapUnmanaged(
|
||||
}
|
||||
|
||||
/// Inserts a new `Entry` into the hash map, returning the previous one, if any.
|
||||
pub fn fetchPut(self: *Self, allocator: Allocator, key: K, value: V) !?KV {
|
||||
pub fn fetchPut(self: *Self, allocator: Allocator, key: K, value: V) Allocator.Error!?KV {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call fetchPutContext instead.");
|
||||
return self.fetchPutContext(allocator, key, value, undefined);
|
||||
}
|
||||
pub fn fetchPutContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !?KV {
|
||||
pub fn fetchPutContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Allocator.Error!?KV {
|
||||
const gop = try self.getOrPutContext(allocator, key, ctx);
|
||||
var result: ?KV = null;
|
||||
if (gop.found_existing) {
|
||||
@@ -1182,12 +1182,12 @@ pub fn HashMapUnmanaged(
|
||||
}
|
||||
|
||||
/// Insert an entry if the associated key is not already present, otherwise update preexisting value.
|
||||
pub fn put(self: *Self, allocator: Allocator, key: K, value: V) !void {
|
||||
pub fn put(self: *Self, allocator: Allocator, key: K, value: V) Allocator.Error!void {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call putContext instead.");
|
||||
return self.putContext(allocator, key, value, undefined);
|
||||
}
|
||||
pub fn putContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !void {
|
||||
pub fn putContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Allocator.Error!void {
|
||||
const result = try self.getOrPutContext(allocator, key, ctx);
|
||||
result.value_ptr.* = value;
|
||||
}
|
||||
@@ -1256,24 +1256,24 @@ pub fn HashMapUnmanaged(
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getOrPut(self: *Self, allocator: Allocator, key: K) !GetOrPutResult {
|
||||
pub fn getOrPut(self: *Self, allocator: Allocator, key: K) Allocator.Error!GetOrPutResult {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContext instead.");
|
||||
return self.getOrPutContext(allocator, key, undefined);
|
||||
}
|
||||
pub fn getOrPutContext(self: *Self, allocator: Allocator, key: K, ctx: Context) !GetOrPutResult {
|
||||
pub fn getOrPutContext(self: *Self, allocator: Allocator, key: K, ctx: Context) Allocator.Error!GetOrPutResult {
|
||||
const gop = try self.getOrPutContextAdapted(allocator, key, ctx, ctx);
|
||||
if (!gop.found_existing) {
|
||||
gop.key_ptr.* = key;
|
||||
}
|
||||
return gop;
|
||||
}
|
||||
pub fn getOrPutAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype) !GetOrPutResult {
|
||||
pub fn getOrPutAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype) Allocator.Error!GetOrPutResult {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutContextAdapted instead.");
|
||||
return self.getOrPutContextAdapted(allocator, key, key_ctx, undefined);
|
||||
}
|
||||
pub fn getOrPutContextAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype, ctx: Context) !GetOrPutResult {
|
||||
pub fn getOrPutContextAdapted(self: *Self, allocator: Allocator, key: anytype, key_ctx: anytype, ctx: Context) Allocator.Error!GetOrPutResult {
|
||||
self.growIfNeeded(allocator, 1, ctx) catch |err| {
|
||||
// If allocation fails, try to do the lookup anyway.
|
||||
// If we find an existing item, we can return it.
|
||||
@@ -1367,12 +1367,12 @@ pub fn HashMapUnmanaged(
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getOrPutValue(self: *Self, allocator: Allocator, key: K, value: V) !Entry {
|
||||
pub fn getOrPutValue(self: *Self, allocator: Allocator, key: K, value: V) Allocator.Error!Entry {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call getOrPutValueContext instead.");
|
||||
return self.getOrPutValueContext(allocator, key, value, undefined);
|
||||
}
|
||||
pub fn getOrPutValueContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) !Entry {
|
||||
pub fn getOrPutValueContext(self: *Self, allocator: Allocator, key: K, value: V, ctx: Context) Allocator.Error!Entry {
|
||||
const res = try self.getOrPutAdapted(allocator, key, ctx);
|
||||
if (!res.found_existing) {
|
||||
res.key_ptr.* = key;
|
||||
@@ -1450,18 +1450,18 @@ pub fn HashMapUnmanaged(
|
||||
return @truncate(Size, max_load - self.available);
|
||||
}
|
||||
|
||||
fn growIfNeeded(self: *Self, allocator: Allocator, new_count: Size, ctx: Context) !void {
|
||||
fn growIfNeeded(self: *Self, allocator: Allocator, new_count: Size, ctx: Context) Allocator.Error!void {
|
||||
if (new_count > self.available) {
|
||||
try self.grow(allocator, capacityForSize(self.load() + new_count), ctx);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone(self: Self, allocator: Allocator) !Self {
|
||||
pub fn clone(self: Self, allocator: Allocator) Allocator.Error!Self {
|
||||
if (@sizeOf(Context) != 0)
|
||||
@compileError("Cannot infer context " ++ @typeName(Context) ++ ", call cloneContext instead.");
|
||||
return self.cloneContext(allocator, @as(Context, undefined));
|
||||
}
|
||||
pub fn cloneContext(self: Self, allocator: Allocator, new_ctx: anytype) !HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage) {
|
||||
pub fn cloneContext(self: Self, allocator: Allocator, new_ctx: anytype) Allocator.Error!HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage) {
|
||||
var other = HashMapUnmanaged(K, V, @TypeOf(new_ctx), max_load_percentage){};
|
||||
if (self.size == 0)
|
||||
return other;
|
||||
@@ -1486,7 +1486,7 @@ pub fn HashMapUnmanaged(
|
||||
return other;
|
||||
}
|
||||
|
||||
fn grow(self: *Self, allocator: Allocator, new_capacity: Size, ctx: Context) !void {
|
||||
fn grow(self: *Self, allocator: Allocator, new_capacity: Size, ctx: Context) Allocator.Error!void {
|
||||
@setCold(true);
|
||||
const new_cap = std.math.max(new_capacity, minimal_capacity);
|
||||
assert(new_cap > self.capacity());
|
||||
@@ -1517,7 +1517,7 @@ pub fn HashMapUnmanaged(
|
||||
std.mem.swap(Self, self, &map);
|
||||
}
|
||||
|
||||
fn allocate(self: *Self, allocator: Allocator, new_capacity: Size) !void {
|
||||
fn allocate(self: *Self, allocator: Allocator, new_capacity: Size) Allocator.Error!void {
|
||||
const header_align = @alignOf(Header);
|
||||
const key_align = if (@sizeOf(K) == 0) 1 else @alignOf(K);
|
||||
const val_align = if (@sizeOf(V) == 0) 1 else @alignOf(V);
|
||||
|
||||
Reference in New Issue
Block a user