| ... | @@ -346,11 +346,8 @@ pub fn MultiArrayList(comptime T: type) type { | ... | @@ -346,11 +346,8 @@ pub fn MultiArrayList(comptime T: type) type { |
| 346 | /// If `new_len` is greater than zero, this may fail to reduce the capacity, | 346 | /// If `new_len` is greater than zero, this may fail to reduce the capacity, |
| 347 | /// but the data remains intact and the length is updated to new_len. | 347 | /// but the data remains intact and the length is updated to new_len. |
| 348 | pub fn shrinkAndFree(self: *Self, gpa: Allocator, new_len: usize) void { | 348 | pub fn shrinkAndFree(self: *Self, gpa: Allocator, new_len: usize) void { |
| 349 | if (new_len == 0) { | 349 | if (new_len == 0) return clearAndFree(self, gpa); |
| 350 | gpa.free(self.allocatedBytes()); | 350 | |
| 351 | self.* = .{}; | | |
| 352 | return; | | |
| 353 | } | | |
| 354 | assert(new_len <= self.capacity); | 351 | assert(new_len <= self.capacity); |
| 355 | assert(new_len <= self.len); | 352 | assert(new_len <= self.len); |
| 356 | | 353 | |
| ... | @@ -391,6 +388,11 @@ pub fn MultiArrayList(comptime T: type) type { | ... | @@ -391,6 +388,11 @@ pub fn MultiArrayList(comptime T: type) type { |
| 391 | self.* = other; | 388 | self.* = other; |
| 392 | } | 389 | } |
| 393 | | 390 | |
| | 391 | pub fn clearAndFree(self: *Self, gpa: Allocator) void { |
| | 392 | gpa.free(self.allocatedBytes()); |
| | 393 | self.* = .{}; |
| | 394 | } |
| | 395 | |
| 394 | /// Reduce length to `new_len`. | 396 | /// Reduce length to `new_len`. |
| 395 | /// Invalidates pointers to elements `items[new_len..]`. | 397 | /// Invalidates pointers to elements `items[new_len..]`. |
| 396 | /// Keeps capacity the same. | 398 | /// Keeps capacity the same. |
| ... | @@ -398,6 +400,11 @@ pub fn MultiArrayList(comptime T: type) type { | ... | @@ -398,6 +400,11 @@ pub fn MultiArrayList(comptime T: type) type { |
| 398 | self.len = new_len; | 400 | self.len = new_len; |
| 399 | } | 401 | } |
| 400 | | 402 | |
| | 403 | /// Invalidates all element pointers. |
| | 404 | pub fn clearRetainingCapacity(self: *Self) void { |
| | 405 | self.len = 0; |
| | 406 | } |
| | 407 | |
| 401 | /// Modify the array so that it can hold at least `new_capacity` items. | 408 | /// Modify the array so that it can hold at least `new_capacity` items. |
| 402 | /// Implements super-linear growth to achieve amortized O(1) append operations. | 409 | /// Implements super-linear growth to achieve amortized O(1) append operations. |
| 403 | /// Invalidates pointers if additional memory is needed. | 410 | /// Invalidates pointers if additional memory is needed. |
| ... | @@ -677,6 +684,14 @@ test "basic usage" { | ... | @@ -677,6 +684,14 @@ test "basic usage" { |
| 677 | try testing.expectEqual(@as(u32, 2), list.pop().a); | 684 | try testing.expectEqual(@as(u32, 2), list.pop().a); |
| 678 | try testing.expectEqual(@as(u8, 'a'), list.pop().c); | 685 | try testing.expectEqual(@as(u8, 'a'), list.pop().c); |
| 679 | try testing.expectEqual(@as(?Foo, null), list.popOrNull()); | 686 | try testing.expectEqual(@as(?Foo, null), list.popOrNull()); |
| | 687 | |
| | 688 | list.clearRetainingCapacity(); |
| | 689 | try testing.expectEqual(0, list.len); |
| | 690 | try testing.expect(list.capacity > 0); |
| | 691 | |
| | 692 | list.clearAndFree(ally); |
| | 693 | try testing.expectEqual(0, list.len); |
| | 694 | try testing.expectEqual(0, list.capacity); |
| 680 | } | 695 | } |
| 681 | | 696 | |
| 682 | // This was observed to fail on aarch64 with LLVM 11, when the capacityInBytes | 697 | // This was observed to fail on aarch64 with LLVM 11, when the capacityInBytes |