diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-02-03 19:55:09 -0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-02-06 14:23:23 -0800 |
| commit | 7eeef5fb2b9dc78679f4091e2a8173d07968b3e5 (patch) | |
| tree | a5edee99fe9ea1e5c241ec0e7b21268d65a8ff8b /lib/std/array_list.zig | |
| parent | dd2fa4f75d3d2b1214fde22081f0b88850d1b55d (diff) | |
| download | zig-7eeef5fb2b9dc78679f4091e2a8173d07968b3e5.tar.gz zig-7eeef5fb2b9dc78679f4091e2a8173d07968b3e5.zip | |
std.mem.Allocator: introduce `remap` function to the interface
This one changes the size of an allocation, allowing it to be relocated.
However, the implementation will still return `null` if it would be
equivalent to
new = alloc
memcpy(new, old)
free(old)
Mainly this prepares for taking advantage of `mremap` which I thought
would be a bigger deal but apparently is only available on Linux. Still,
we should use it on Linux.
Diffstat (limited to 'lib/std/array_list.zig')
| -rw-r--r-- | lib/std/array_list.zig | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/lib/std/array_list.zig b/lib/std/array_list.zig index 5eb527e742..55b6e3cc40 100644 --- a/lib/std/array_list.zig +++ b/lib/std/array_list.zig @@ -105,21 +105,19 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { return result; } - /// The caller owns the returned memory. Empties this ArrayList, - /// Its capacity is cleared, making deinit() safe but unnecessary to call. + /// The caller owns the returned memory. Empties this ArrayList. + /// Its capacity is cleared, making `deinit` safe but unnecessary to call. pub fn toOwnedSlice(self: *Self) Allocator.Error!Slice { const allocator = self.allocator; const old_memory = self.allocatedSlice(); - if (allocator.resize(old_memory, self.items.len)) { - const result = self.items; + if (allocator.remap(old_memory, self.items.len)) |new_items| { self.* = init(allocator); - return result; + return new_items; } const new_memory = try allocator.alignedAlloc(T, alignment, self.items.len); @memcpy(new_memory, self.items); - @memset(self.items, undefined); self.clearAndFree(); return new_memory; } @@ -185,8 +183,9 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { // extra capacity. const new_capacity = growCapacity(self.capacity, new_len); const old_memory = self.allocatedSlice(); - if (self.allocator.resize(old_memory, new_capacity)) { - self.capacity = new_capacity; + if (self.allocator.remap(old_memory, new_capacity)) |new_memory| { + self.items.ptr = new_memory.ptr; + self.capacity = new_memory.len; return addManyAtAssumeCapacity(self, index, count); } @@ -468,8 +467,9 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { // the allocator implementation would pointlessly copy our // extra capacity. const old_memory = self.allocatedSlice(); - if (self.allocator.resize(old_memory, new_capacity)) { - self.capacity = new_capacity; + if (self.allocator.remap(old_memory, new_capacity)) |new_memory| { + self.items.ptr = new_memory.ptr; + self.capacity = new_memory.len; } else { const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity); @memcpy(new_memory[0..self.items.len], self.items); @@ -707,15 +707,13 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ /// Its capacity is cleared, making deinit() safe but unnecessary to call. pub fn toOwnedSlice(self: *Self, allocator: Allocator) Allocator.Error!Slice { const old_memory = self.allocatedSlice(); - if (allocator.resize(old_memory, self.items.len)) { - const result = self.items; + if (allocator.remap(old_memory, self.items.len)) |new_items| { self.* = .empty; - return result; + return new_items; } const new_memory = try allocator.alignedAlloc(T, alignment, self.items.len); @memcpy(new_memory, self.items); - @memset(self.items, undefined); self.clearAndFree(allocator); return new_memory; } @@ -1031,9 +1029,9 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ } const old_memory = self.allocatedSlice(); - if (allocator.resize(old_memory, new_len)) { - self.capacity = new_len; - self.items.len = new_len; + if (allocator.remap(old_memory, new_len)) |new_items| { + self.capacity = new_items.len; + self.items = new_items; return; } @@ -1099,8 +1097,9 @@ pub fn ArrayListAlignedUnmanaged(comptime T: type, comptime alignment: ?u29) typ // the allocator implementation would pointlessly copy our // extra capacity. const old_memory = self.allocatedSlice(); - if (allocator.resize(old_memory, new_capacity)) { - self.capacity = new_capacity; + if (allocator.remap(old_memory, new_capacity)) |new_memory| { + self.items.ptr = new_memory.ptr; + self.capacity = new_memory.len; } else { const new_memory = try allocator.alignedAlloc(T, alignment, new_capacity); @memcpy(new_memory[0..self.items.len], self.items); |
