std: deprecate ensureCapacity, add two other capacity functions

I've run into this footgun enough times, nearly every time I want
`ensureUnusedCapacity`, not `ensureCapacity`. This commit deprecates
`ensureCapacity` in favor of `ensureTotalCapacity` and introduces
`ensureUnusedCapacity`.
This commit is contained in:
Andrew Kelley 2021-04-16 17:56:30 -07:00
parent 5ff45b3f44
commit c8ae581fef

View File

@ -132,7 +132,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
/// Insert `item` at index `n` by moving `list[n .. list.len]` to make room.
/// This operation is O(N).
pub fn insert(self: *Self, n: usize, item: T) !void {
try self.ensureCapacity(self.items.len + 1);
try self.ensureUnusedCapacity(1);
self.items.len += 1;
mem.copyBackwards(T, self.items[n + 1 .. self.items.len], self.items[n .. self.items.len - 1]);
@ -142,7 +142,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
/// Insert slice `items` at index `i` by moving `list[i .. list.len]` to make room.
/// This operation is O(N).
pub fn insertSlice(self: *Self, i: usize, items: SliceConst) !void {
try self.ensureCapacity(self.items.len + items.len);
try self.ensureUnusedCapacity(items.len);
self.items.len += items.len;
mem.copyBackwards(T, self.items[i + items.len .. self.items.len], self.items[i .. self.items.len - items.len]);
@ -221,7 +221,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
/// Append the slice of items to the list. Allocates more
/// memory as necessary.
pub fn appendSlice(self: *Self, items: SliceConst) !void {
try self.ensureCapacity(self.items.len + items.len);
try self.ensureUnusedCapacity(items.len);
self.appendSliceAssumeCapacity(items);
}
@ -270,7 +270,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
/// Adjust the list's length to `new_len`.
/// Does not initialize added items if any.
pub fn resize(self: *Self, new_len: usize) !void {
try self.ensureCapacity(new_len);
try self.ensureTotalCapacity(new_len);
self.items.len = new_len;
}
@ -295,9 +295,12 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
self.items.len = new_len;
}
/// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
pub const ensureCapacity = ensureTotalCapacity;
/// Modify the array so that it can hold at least `new_capacity` items.
/// Invalidates pointers if additional memory is needed.
pub fn ensureCapacity(self: *Self, new_capacity: usize) !void {
pub fn ensureTotalCapacity(self: *Self, new_capacity: usize) !void {
var better_capacity = self.capacity;
if (better_capacity >= new_capacity) return;
@ -312,6 +315,12 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
self.capacity = new_memory.len;
}
/// Modify the array so that it can hold at least `additional_count` **more** items.
/// Invalidates pointers if additional memory is needed.
pub fn ensureUnusedCapacity(self: *Self, additional_count: usize) !void {
return self.ensureTotalCapacity(self.items.len + additional_count);
}
/// Increases the array's length to match the full capacity that is already allocated.
/// The new elements have `undefined` values. **Does not** invalidate pointers.
pub fn expandToCapacity(self: *Self) void {
@ -322,7 +331,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type {
/// The returned pointer becomes invalid when the list resized.
pub fn addOne(self: *Self) !*T {
const newlen = self.items.len + 1;
try self.ensureCapacity(newlen);
try self.ensureTotalCapacity(newlen);
return self.addOneAssumeCapacity();
}
@ -473,7 +482,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
/// to higher indices to make room.
/// This operation is O(N).
pub fn insert(self: *Self, allocator: *Allocator, n: usize, item: T) !void {
try self.ensureCapacity(allocator, self.items.len + 1);
try self.ensureUnusedCapacity(allocator, 1);
self.items.len += 1;
mem.copyBackwards(T, self.items[n + 1 .. self.items.len], self.items[n .. self.items.len - 1]);
@ -484,7 +493,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
/// higher indicices make room.
/// This operation is O(N).
pub fn insertSlice(self: *Self, allocator: *Allocator, i: usize, items: SliceConst) !void {
try self.ensureCapacity(allocator, self.items.len + items.len);
try self.ensureUnusedCapacity(allocator, items.len);
self.items.len += items.len;
mem.copyBackwards(T, self.items[i + items.len .. self.items.len], self.items[i .. self.items.len - items.len]);
@ -544,7 +553,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
/// Append the slice of items to the list. Allocates more
/// memory as necessary.
pub fn appendSlice(self: *Self, allocator: *Allocator, items: SliceConst) !void {
try self.ensureCapacity(allocator, self.items.len + items.len);
try self.ensureUnusedCapacity(allocator, items.len);
self.appendSliceAssumeCapacity(items);
}
@ -579,7 +588,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
/// Adjust the list's length to `new_len`.
/// Does not initialize added items, if any.
pub fn resize(self: *Self, allocator: *Allocator, new_len: usize) !void {
try self.ensureCapacity(allocator, new_len);
try self.ensureTotalCapacity(allocator, new_len);
self.items.len = new_len;
}
@ -604,9 +613,12 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
self.items.len = new_len;
}
/// Deprecated: call `ensureUnusedCapacity` or `ensureTotalCapacity`.
pub const ensureCapacity = ensureTotalCapacity;
/// Modify the array so that it can hold at least `new_capacity` items.
/// Invalidates pointers if additional memory is needed.
pub fn ensureCapacity(self: *Self, allocator: *Allocator, new_capacity: usize) !void {
pub fn ensureTotalCapacity(self: *Self, allocator: *Allocator, new_capacity: usize) !void {
var better_capacity = self.capacity;
if (better_capacity >= new_capacity) return;
@ -620,6 +632,16 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
self.capacity = new_memory.len;
}
/// Modify the array so that it can hold at least `additional_count` **more** items.
/// Invalidates pointers if additional memory is needed.
pub fn ensureUnusedCapacity(
self: *Self,
allocator: *Allocator,
additional_count: usize,
) !void {
return self.ensureTotalCapacity(allocator, self.items.len + additional_count);
}
/// Increases the array's length to match the full capacity that is already allocated.
/// The new elements have `undefined` values.
/// **Does not** invalidate pointers.
@ -631,7 +653,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ
/// The returned pointer becomes invalid when the list resized.
pub fn addOne(self: *Self, allocator: *Allocator) !*T {
const newlen = self.items.len + 1;
try self.ensureCapacity(allocator, newlen);
try self.ensureTotalCapacity(allocator, newlen);
return self.addOneAssumeCapacity();
}
@ -1186,7 +1208,7 @@ test "std.ArrayList/ArrayListUnmanaged.addManyAsArray" {
defer list.deinit();
(try list.addManyAsArray(4)).* = "aoeu".*;
try list.ensureCapacity(8);
try list.ensureTotalCapacity(8);
list.addManyAsArrayAssumeCapacity(4).* = "asdf".*;
testing.expectEqualSlices(u8, list.items, "aoeuasdf");
@ -1196,7 +1218,7 @@ test "std.ArrayList/ArrayListUnmanaged.addManyAsArray" {
defer list.deinit(a);
(try list.addManyAsArray(a, 4)).* = "aoeu".*;
try list.ensureCapacity(a, 8);
try list.ensureTotalCapacity(a, 8);
list.addManyAsArrayAssumeCapacity(4).* = "asdf".*;
testing.expectEqualSlices(u8, list.items, "aoeuasdf");