| ... | ... | @@ -126,7 +126,8 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 126 | 126 | |
| 127 | 127 | /// The caller owns the returned memory. Empties this ArrayList. |
| 128 | 128 | pub fn toOwnedSliceSentinel(self: *Self, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { |
| 129 | | try self.ensureTotalCapacityPrecise(try addOrOom(self.items.len, 1)); |
| 129 | // This addition can never overflow because `self.items` can never occupy the whole address space |
| 130 | try self.ensureTotalCapacityPrecise(self.items.len + 1); |
| 130 | 131 | self.appendAssumeCapacity(sentinel); |
| 131 | 132 | const result = try self.toOwnedSlice(); |
| 132 | 133 | return result[0 .. result.len - 1 :sentinel]; |
| ... | ... | @@ -241,9 +242,9 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 241 | 242 | /// Grows list if `len < new_items.len`. |
| 242 | 243 | /// Shrinks list if `len > new_items.len`. |
| 243 | 244 | /// Invalidates element pointers if this ArrayList is resized. |
| 244 | | /// Asserts that the start index is in bounds or equal to the length. |
| 245 | /// Asserts that the range is in bounds. |
| 245 | 246 | pub fn replaceRange(self: *Self, start: usize, len: usize, new_items: []const T) Allocator.Error!void { |
| 246 | | const after_range = try addOrOom(start, len); |
| 247 | const after_range = start + len; |
| 247 | 248 | const range = self.items[start..after_range]; |
| 248 | 249 | |
| 249 | 250 | if (range.len == new_items.len) |
| ... | ... | @@ -256,7 +257,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 256 | 257 | try self.insertSlice(after_range, rest); |
| 257 | 258 | } else { |
| 258 | 259 | @memcpy(range[0..new_items.len], new_items); |
| 259 | | const after_subrange = try addOrOom(start, new_items.len); |
| 260 | const after_subrange = start + new_items.len; |
| 260 | 261 | |
| 261 | 262 | for (self.items[after_range..], 0..) |item, i| { |
| 262 | 263 | self.items[after_subrange..][i] = item; |
| ... | ... | @@ -493,7 +494,9 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 493 | 494 | /// Increase length by 1, returning pointer to the new item. |
| 494 | 495 | /// The returned pointer becomes invalid when the list resized. |
| 495 | 496 | pub fn addOne(self: *Self) Allocator.Error!*T { |
| 496 | | try self.ensureUnusedCapacity(1); |
| 497 | // This can never overflow because `self.items` can never occupy the whole address space |
| 498 | const newlen = self.items.len + 1; |
| 499 | try self.ensureTotalCapacity(newlen); |
| 497 | 500 | return self.addOneAssumeCapacity(); |
| 498 | 501 | } |
| 499 | 502 | |
| ... | ... | @@ -710,7 +713,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 710 | 713 | |
| 711 | 714 | /// The caller owns the returned memory. ArrayList becomes empty. |
| 712 | 715 | pub fn toOwnedSliceSentinel(self: *Self, allocator: Allocator, comptime sentinel: T) Allocator.Error!SentinelSlice(sentinel) { |
| 713 | | try self.ensureTotalCapacityPrecise(allocator, try addOrOom(self.items.len, 1)); |
| 716 | // This addition can never overflow because `self.items` can never occupy the whole address space |
| 717 | try self.ensureTotalCapacityPrecise(allocator, self.items.len + 1); |
| 714 | 718 | self.appendAssumeCapacity(sentinel); |
| 715 | 719 | const result = try self.toOwnedSlice(allocator); |
| 716 | 720 | return result[0 .. result.len - 1 :sentinel]; |
| ... | ... | @@ -1071,7 +1075,8 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 1071 | 1075 | /// Increase length by 1, returning pointer to the new item. |
| 1072 | 1076 | /// The returned element pointer becomes invalid when the list is resized. |
| 1073 | 1077 | pub fn addOne(self: *Self, allocator: Allocator) Allocator.Error!*T { |
| 1074 | | const newlen = try addOrOom(self.items.len, 1); |
| 1078 | // This can never overflow because `self.items` can never occupy the whole address space |
| 1079 | const newlen = self.items.len + 1; |
| 1075 | 1080 | try self.ensureTotalCapacity(allocator, newlen); |
| 1076 | 1081 | return self.addOneAssumeCapacity(); |
| 1077 | 1082 | } |
| ... | ... | @@ -1991,47 +1996,40 @@ test "std.ArrayList(u32).getLastOrNull()" { |
| 1991 | 1996 | test "return OutOfMemory when capacity would exceed maximum usize integer value" { |
| 1992 | 1997 | const a = testing.allocator; |
| 1993 | 1998 | const new_item: u32 = 42; |
| 1999 | const items = &.{ 42, 43 }; |
| 1994 | 2000 | |
| 1995 | 2001 | { |
| 1996 | 2002 | var list: ArrayListUnmanaged(u32) = .{ |
| 1997 | 2003 | .items = undefined, |
| 1998 | | .capacity = math.maxInt(usize), |
| 2004 | .capacity = math.maxInt(usize) - 1, |
| 1999 | 2005 | }; |
| 2000 | | list.items.len = math.maxInt(usize); |
| 2001 | | |
| 2002 | | try testing.expectError(error.OutOfMemory, list.append(a, new_item)); |
| 2003 | | try testing.expectError(error.OutOfMemory, list.appendSlice(a, &.{new_item})); |
| 2004 | | try testing.expectError(error.OutOfMemory, list.appendNTimes(a, new_item, 1)); |
| 2005 | | try testing.expectError(error.OutOfMemory, list.appendUnalignedSlice(a, &.{new_item})); |
| 2006 | | try testing.expectError(error.OutOfMemory, list.addOne(a)); |
| 2007 | | try testing.expectError(error.OutOfMemory, list.addManyAt(a, 0, 1)); |
| 2008 | | try testing.expectError(error.OutOfMemory, list.addManyAsArray(a, 1)); |
| 2009 | | try testing.expectError(error.OutOfMemory, list.addManyAsSlice(a, 1)); |
| 2010 | | try testing.expectError(error.OutOfMemory, list.insert(a, 0, new_item)); |
| 2011 | | try testing.expectError(error.OutOfMemory, list.insertSlice(a, 0, &.{new_item})); |
| 2012 | | try testing.expectError(error.OutOfMemory, list.toOwnedSliceSentinel(a, 0)); |
| 2013 | | try testing.expectError(error.OutOfMemory, list.ensureUnusedCapacity(a, 1)); |
| 2006 | list.items.len = math.maxInt(usize) - 1; |
| 2007 | |
| 2008 | try testing.expectError(error.OutOfMemory, list.appendSlice(a, items)); |
| 2009 | try testing.expectError(error.OutOfMemory, list.appendNTimes(a, new_item, 2)); |
| 2010 | try testing.expectError(error.OutOfMemory, list.appendUnalignedSlice(a, &.{ new_item, new_item })); |
| 2011 | try testing.expectError(error.OutOfMemory, list.addManyAt(a, 0, 2)); |
| 2012 | try testing.expectError(error.OutOfMemory, list.addManyAsArray(a, 2)); |
| 2013 | try testing.expectError(error.OutOfMemory, list.addManyAsSlice(a, 2)); |
| 2014 | try testing.expectError(error.OutOfMemory, list.insertSlice(a, 0, items)); |
| 2015 | try testing.expectError(error.OutOfMemory, list.ensureUnusedCapacity(a, 2)); |
| 2014 | 2016 | } |
| 2015 | 2017 | |
| 2016 | 2018 | { |
| 2017 | 2019 | var list: ArrayList(u32) = .{ |
| 2018 | 2020 | .items = undefined, |
| 2019 | | .capacity = math.maxInt(usize), |
| 2021 | .capacity = math.maxInt(usize) - 1, |
| 2020 | 2022 | .allocator = a, |
| 2021 | 2023 | }; |
| 2022 | | list.items.len = math.maxInt(usize); |
| 2023 | | |
| 2024 | | try testing.expectError(error.OutOfMemory, list.append(new_item)); |
| 2025 | | try testing.expectError(error.OutOfMemory, list.appendSlice(&.{new_item})); |
| 2026 | | try testing.expectError(error.OutOfMemory, list.appendNTimes(new_item, 1)); |
| 2027 | | try testing.expectError(error.OutOfMemory, list.appendUnalignedSlice(&.{new_item})); |
| 2028 | | try testing.expectError(error.OutOfMemory, list.addOne()); |
| 2029 | | try testing.expectError(error.OutOfMemory, list.addManyAt(0, 1)); |
| 2030 | | try testing.expectError(error.OutOfMemory, list.addManyAsArray(1)); |
| 2031 | | try testing.expectError(error.OutOfMemory, list.addManyAsSlice(1)); |
| 2032 | | try testing.expectError(error.OutOfMemory, list.insert(0, new_item)); |
| 2033 | | try testing.expectError(error.OutOfMemory, list.insertSlice(0, &.{new_item})); |
| 2034 | | try testing.expectError(error.OutOfMemory, list.toOwnedSliceSentinel(0)); |
| 2035 | | try testing.expectError(error.OutOfMemory, list.ensureUnusedCapacity(1)); |
| 2024 | list.items.len = math.maxInt(usize) - 1; |
| 2025 | |
| 2026 | try testing.expectError(error.OutOfMemory, list.appendSlice(items)); |
| 2027 | try testing.expectError(error.OutOfMemory, list.appendNTimes(new_item, 2)); |
| 2028 | try testing.expectError(error.OutOfMemory, list.appendUnalignedSlice(&.{ new_item, new_item })); |
| 2029 | try testing.expectError(error.OutOfMemory, list.addManyAt(0, 2)); |
| 2030 | try testing.expectError(error.OutOfMemory, list.addManyAsArray(2)); |
| 2031 | try testing.expectError(error.OutOfMemory, list.addManyAsSlice(2)); |
| 2032 | try testing.expectError(error.OutOfMemory, list.insertSlice(0, items)); |
| 2033 | try testing.expectError(error.OutOfMemory, list.ensureUnusedCapacity(2)); |
| 2036 | 2034 | } |
| 2037 | 2035 | } |