| ... | ... | @@ -314,32 +314,9 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 314 | 314 | /// Reduce allocated capacity to `new_len`. |
| 315 | 315 | /// May invalidate element pointers. |
| 316 | 316 | pub fn shrinkAndFree(self: *Self, new_len: usize) void { |
| 317 | | assert(new_len <= self.items.len); |
| 318 | | |
| 319 | | if (@sizeOf(T) == 0) { |
| 320 | | self.items.len = new_len; |
| 321 | | return; |
| 322 | | } |
| 323 | | |
| 324 | | const old_memory = self.allocatedSlice(); |
| 325 | | if (self.allocator.resize(old_memory, new_len)) { |
| 326 | | self.capacity = new_len; |
| 327 | | self.items.len = new_len; |
| 328 | | return; |
| 329 | | } |
| 330 | | |
| 331 | | const new_memory = self.allocator.alignedAlloc(T, alignment, new_len) catch |e| switch (e) { |
| 332 | | error.OutOfMemory => { |
| 333 | | // No problem, capacity is still correct then. |
| 334 | | self.items.len = new_len; |
| 335 | | return; |
| 336 | | }, |
| 337 | | }; |
| 338 | | |
| 339 | | mem.copy(T, new_memory, self.items); |
| 340 | | self.allocator.free(old_memory); |
| 341 | | self.items = new_memory; |
| 342 | | self.capacity = new_memory.len; |
| 317 | var unmanaged = self.moveToUnmanaged(); |
| 318 | unmanaged.shrinkAndFree(self.allocator, new_len); |
| 319 | self.* = unmanaged.toManaged(self.allocator); |
| 343 | 320 | } |
| 344 | 321 | |
| 345 | 322 | /// Reduce length to `new_len`. |
| ... | ... | @@ -782,7 +759,7 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ |
| 782 | 759 | }, |
| 783 | 760 | }; |
| 784 | 761 | |
| 785 | | mem.copy(T, new_memory, self.items); |
| 762 | mem.copy(T, new_memory, self.items[0..new_len]); |
| 786 | 763 | allocator.free(old_memory); |
| 787 | 764 | self.items = new_memory; |
| 788 | 765 | self.capacity = new_memory.len; |
| ... | ... | @@ -1488,14 +1465,18 @@ test "std.ArrayListUnmanaged(u8) implements writer" { |
| 1488 | 1465 | } |
| 1489 | 1466 | } |
| 1490 | 1467 | |
| 1491 | | test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMemory" { |
| 1492 | | // use an arena allocator to make sure realloc returns error.OutOfMemory |
| 1493 | | var arena = std.heap.ArenaAllocator.init(testing.allocator); |
| 1494 | | defer arena.deinit(); |
| 1495 | | const a = arena.allocator(); |
| 1468 | test "shrink still sets length when resizing is disabled" { |
| 1469 | // Use the testing allocator but with resize disabled. |
| 1470 | var a = testing.allocator; |
| 1471 | a.vtable = &.{ |
| 1472 | .alloc = a.vtable.alloc, |
| 1473 | .resize = Allocator.noResize, |
| 1474 | .free = a.vtable.free, |
| 1475 | }; |
| 1496 | 1476 | |
| 1497 | 1477 | { |
| 1498 | 1478 | var list = ArrayList(i32).init(a); |
| 1479 | defer list.deinit(); |
| 1499 | 1480 | |
| 1500 | 1481 | try list.append(1); |
| 1501 | 1482 | try list.append(2); |
| ... | ... | @@ -1506,6 +1487,7 @@ test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMe |
| 1506 | 1487 | } |
| 1507 | 1488 | { |
| 1508 | 1489 | var list = ArrayListUnmanaged(i32){}; |
| 1490 | defer list.deinit(a); |
| 1509 | 1491 | |
| 1510 | 1492 | try list.append(a, 1); |
| 1511 | 1493 | try list.append(a, 2); |
| ... | ... | @@ -1516,6 +1498,22 @@ test "std.ArrayList/ArrayListUnmanaged.shrink still sets length on error.OutOfMe |
| 1516 | 1498 | } |
| 1517 | 1499 | } |
| 1518 | 1500 | |
| 1501 | test "shrinkAndFree with a copy" { |
| 1502 | // Use the testing allocator but with resize disabled. |
| 1503 | var a = testing.allocator; |
| 1504 | a.vtable = &.{ |
| 1505 | .alloc = a.vtable.alloc, |
| 1506 | .resize = Allocator.noResize, |
| 1507 | .free = a.vtable.free, |
| 1508 | }; |
| 1509 | var list = ArrayList(i32).init(a); |
| 1510 | defer list.deinit(); |
| 1511 | |
| 1512 | try list.appendNTimes(3, 16); |
| 1513 | list.shrinkAndFree(4); |
| 1514 | try testing.expect(mem.eql(i32, list.items, &.{ 3, 3, 3, 3 })); |
| 1515 | } |
| 1516 | |
| 1519 | 1517 | test "std.ArrayList/ArrayListUnmanaged.addManyAsArray" { |
| 1520 | 1518 | const a = std.testing.allocator; |
| 1521 | 1519 | { |