diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig index 681fbc3e7e5c..71ccb68b992e 100644 --- a/lib/std/multi_array_list.zig +++ b/lib/std/multi_array_list.zig @@ -346,11 +346,8 @@ pub fn MultiArrayList(comptime T: type) type { /// If `new_len` is greater than zero, this may fail to reduce the capacity, /// but the data remains intact and the length is updated to new_len. pub fn shrinkAndFree(self: *Self, gpa: Allocator, new_len: usize) void { - if (new_len == 0) { - gpa.free(self.allocatedBytes()); - self.* = .{}; - return; - } + if (new_len == 0) return clearAndFree(self, gpa); + assert(new_len <= self.capacity); assert(new_len <= self.len); @@ -391,6 +388,11 @@ pub fn MultiArrayList(comptime T: type) type { self.* = other; } + pub fn clearAndFree(self: *Self, gpa: Allocator) void { + gpa.free(self.allocatedBytes()); + self.* = .{}; + } + /// Reduce length to `new_len`. /// Invalidates pointers to elements `items[new_len..]`. /// Keeps capacity the same. @@ -398,6 +400,11 @@ pub fn MultiArrayList(comptime T: type) type { self.len = new_len; } + /// Invalidates all element pointers. + pub fn clearRetainingCapacity(self: *Self) void { + self.len = 0; + } + /// Modify the array so that it can hold at least `new_capacity` items. /// Implements super-linear growth to achieve amortized O(1) append operations. /// Invalidates pointers if additional memory is needed. @@ -677,6 +684,14 @@ test "basic usage" { try testing.expectEqual(@as(u32, 2), list.pop().a); try testing.expectEqual(@as(u8, 'a'), list.pop().c); try testing.expectEqual(@as(?Foo, null), list.popOrNull()); + + list.clearRetainingCapacity(); + try testing.expectEqual(0, list.len); + try testing.expect(list.capacity > 0); + + list.clearAndFree(ally); + try testing.expectEqual(0, list.len); + try testing.expectEqual(0, list.capacity); } // This was observed to fail on aarch64 with LLVM 11, when the capacityInBytes