DoxigAlpha

shrinkAndFree

Attempt to reduce allocated capacity to new_len. 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.

Function parameters

Parameters

#
self:*Self
new_len:usize

A MultiArrayList stores a list of a struct or tagged union type.

Functions

#
MultiArrayList
A MultiArrayList stores a list of a struct or tagged union type.

Source

Implementation

#
pub fn shrinkAndFree(self: *Self, gpa: Allocator, new_len: usize) void {
    if (new_len == 0) return clearAndFree(self, gpa);

    assert(new_len <= self.capacity);
    assert(new_len <= self.len);

    const other_bytes = gpa.alignedAlloc(u8, .of(Elem), capacityInBytes(new_len)) catch {
        const self_slice = self.slice();
        inline for (fields, 0..) |field_info, i| {
            if (@sizeOf(field_info.type) != 0) {
                const field = @as(Field, @enumFromInt(i));
                const dest_slice = self_slice.items(field)[new_len..];
                // We use memset here for more efficient codegen in safety-checked,
                // valgrind-enabled builds. Otherwise the valgrind client request
                // will be repeated for every element.
                @memset(dest_slice, undefined);
            }
        }
        self.len = new_len;
        return;
    };
    var other = Self{
        .bytes = other_bytes.ptr,
        .capacity = new_len,
        .len = new_len,
    };
    self.len = new_len;
    const self_slice = self.slice();
    const other_slice = other.slice();
    inline for (fields, 0..) |field_info, i| {
        if (@sizeOf(field_info.type) != 0) {
            const field = @as(Field, @enumFromInt(i));
            @memcpy(other_slice.items(field), self_slice.items(field));
        }
    }
    gpa.free(self.allocatedBytes());
    self.* = other;
}