diff options
| author | Erik Arvstedt <erik.arvstedt@gmail.com> | 2024-01-19 00:25:43 +0100 |
|---|---|---|
| committer | Erik Arvstedt <erik.arvstedt@gmail.com> | 2024-01-19 00:55:17 +0100 |
| commit | 0bb6967d1464d95e50ef620ea5b3ebd9f9c0bc97 (patch) | |
| tree | 9e12c6195d5224a53537962408bffecc310d9b81 /lib/std/array_list.zig | |
| parent | 14efbbfd89c7e034436faa87a201a35324b9dff3 (diff) | |
| download | zig-0bb6967d1464d95e50ef620ea5b3ebd9f9c0bc97.tar.gz zig-0bb6967d1464d95e50ef620ea5b3ebd9f9c0bc97.zip | |
std.ArrayList: remove `+ 1` overflow checks
Diffstat (limited to 'lib/std/array_list.zig')
| -rw-r--r-- | lib/std/array_list.zig | 66 |
1 files changed, 32 insertions, 34 deletions
diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index b49763df3c..18b741f1c3 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -126,7 +126,8 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { /// The caller owns the returned memory. Empties this ArrayList. pub fn toOwnedSliceSentinel(self: *Self, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { - try self.ensureTotalCapacityPrecise(try addOrOom(self.items.len, 1)); + // This addition can never overflow because `self.items` can never occupy the whole address space + try self.ensureTotalCapacityPrecise(self.items.len + 1); self.appendAssumeCapacity(sentinel); const result = try self.toOwnedSlice(); return result[0 .. result.len - 1 :sentinel]; @@ -493,7 +494,9 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { /// Increase length by 1, returning pointer to the new item. /// The returned pointer becomes invalid when the list resized. pub fn addOne(self: *Self) Allocator.Error!*T { - try self.ensureUnusedCapacity(1); + // This can never overflow because `self.items` can never occupy the whole address space + const newlen = self.items.len + 1; + try self.ensureTotalCapacity(newlen); return self.addOneAssumeCapacity(); } @@ -710,7 +713,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// The caller owns the returned memory. ArrayList becomes empty. pub fn toOwnedSliceSentinel(self: *Self, allocator: Allocator, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { - try self.ensureTotalCapacityPrecise(allocator, try addOrOom(self.items.len, 1)); + // This addition can never overflow because `self.items` can never occupy the whole address space + try self.ensureTotalCapacityPrecise(allocator, self.items.len + 1); self.appendAssumeCapacity(sentinel); const result = try self.toOwnedSlice(allocator); return result[0 .. result.len - 1 :sentinel]; @@ -1071,7 +1075,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Increase length by 1, returning pointer to the new item. /// The returned element pointer becomes invalid when the list is resized. pub fn addOne(self: *Self, allocator: Allocator) Allocator.Error!*T { - const newlen = try addOrOom(self.items.len, 1); + // This can never overflow because `self.items` can never occupy the whole address space + const newlen = self.items.len + 1; try self.ensureTotalCapacity(allocator, newlen); return self.addOneAssumeCapacity(); } @@ -1991,47 +1996,40 @@ test "std.ArrayList(u32).getLastOrNull()" { test "return OutOfMemory when capacity would exceed maximum usize integer value" { const a = testing.allocator; const new_item: u32 = 42; + const items = &.{ 42, 43 }; { var list: ArrayListUnmanaged(u32) = .{ .items = undefined, - .capacity = math.maxInt(usize), + .capacity = math.maxInt(usize) - 1, }; - list.items.len = math.maxInt(usize); - - try testing.expectError(error.OutOfMemory, list.append(a, new_item)); - try testing.expectError(error.OutOfMemory, list.appendSlice(a, &.{new_item})); - try testing.expectError(error.OutOfMemory, list.appendNTimes(a, new_item, 1)); - try testing.expectError(error.OutOfMemory, list.appendUnalignedSlice(a, &.{new_item})); - try testing.expectError(error.OutOfMemory, list.addOne(a)); - try testing.expectError(error.OutOfMemory, list.addManyAt(a, 0, 1)); - try testing.expectError(error.OutOfMemory, list.addManyAsArray(a, 1)); - try testing.expectError(error.OutOfMemory, list.addManyAsSlice(a, 1)); - try testing.expectError(error.OutOfMemory, list.insert(a, 0, new_item)); - try testing.expectError(error.OutOfMemory, list.insertSlice(a, 0, &.{new_item})); - try testing.expectError(error.OutOfMemory, list.toOwnedSliceSentinel(a, 0)); - try testing.expectError(error.OutOfMemory, list.ensureUnusedCapacity(a, 1)); + list.items.len = math.maxInt(usize) - 1; + + try testing.expectError(error.OutOfMemory, list.appendSlice(a, items)); + try testing.expectError(error.OutOfMemory, list.appendNTimes(a, new_item, 2)); + try testing.expectError(error.OutOfMemory, list.appendUnalignedSlice(a, &.{ new_item, new_item })); + try testing.expectError(error.OutOfMemory, list.addManyAt(a, 0, 2)); + try testing.expectError(error.OutOfMemory, list.addManyAsArray(a, 2)); + try testing.expectError(error.OutOfMemory, list.addManyAsSlice(a, 2)); + try testing.expectError(error.OutOfMemory, list.insertSlice(a, 0, items)); + try testing.expectError(error.OutOfMemory, list.ensureUnusedCapacity(a, 2)); } { var list: ArrayList(u32) = .{ .items = undefined, - .capacity = math.maxInt(usize), + .capacity = math.maxInt(usize) - 1, .allocator = a, }; - list.items.len = math.maxInt(usize); - - try testing.expectError(error.OutOfMemory, list.append(new_item)); - try testing.expectError(error.OutOfMemory, list.appendSlice(&.{new_item})); - try testing.expectError(error.OutOfMemory, list.appendNTimes(new_item, 1)); - try testing.expectError(error.OutOfMemory, list.appendUnalignedSlice(&.{new_item})); - try testing.expectError(error.OutOfMemory, list.addOne()); - try testing.expectError(error.OutOfMemory, list.addManyAt(0, 1)); - try testing.expectError(error.OutOfMemory, list.addManyAsArray(1)); - try testing.expectError(error.OutOfMemory, list.addManyAsSlice(1)); - try testing.expectError(error.OutOfMemory, list.insert(0, new_item)); - try testing.expectError(error.OutOfMemory, list.insertSlice(0, &.{new_item})); - try testing.expectError(error.OutOfMemory, list.toOwnedSliceSentinel(0)); - try testing.expectError(error.OutOfMemory, list.ensureUnusedCapacity(1)); + list.items.len = math.maxInt(usize) - 1; + + try testing.expectError(error.OutOfMemory, list.appendSlice(items)); + try testing.expectError(error.OutOfMemory, list.appendNTimes(new_item, 2)); + try testing.expectError(error.OutOfMemory, list.appendUnalignedSlice(&.{ new_item, new_item })); + try testing.expectError(error.OutOfMemory, list.addManyAt(0, 2)); + try testing.expectError(error.OutOfMemory, list.addManyAsArray(2)); + try testing.expectError(error.OutOfMemory, list.addManyAsSlice(2)); + try testing.expectError(error.OutOfMemory, list.insertSlice(0, items)); + try testing.expectError(error.OutOfMemory, list.ensureUnusedCapacity(2)); } } |
