add List.releaseExcessCapacity builtin

This commit is contained in:
Brendan Hansknecht 2023-03-13 17:34:18 -07:00
parent 40b50b0091
commit 1319ba4844
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
13 changed files with 177 additions and 3 deletions

View file

@ -188,6 +188,23 @@ pub const RocList = extern struct {
};
}
pub fn allocateExact(
alignment: u32,
length: usize,
element_width: usize,
) RocList {
if (length == 0) {
return empty();
}
const data_bytes = length * element_width;
return RocList{
.bytes = utils.allocateWithRefcount(data_bytes, alignment),
.length = length,
.capacity_or_ref_ptr = length,
};
}
pub fn reallocate(
self: RocList,
alignment: u32,
@ -474,6 +491,30 @@ pub fn listReserve(
}
}
pub fn listReleaseExcessCapacity(
list: RocList,
alignment: u32,
element_width: usize,
update_mode: UpdateMode,
) callconv(.C) RocList {
const old_length = list.len();
// We use the direct list.capacity_or_ref_ptr to make sure both that there is no extra capacity and that it isn't a seamless slice.
if ((update_mode == .InPlace or list.isUnique()) and list.capacity_or_ref_ptr == old_length) {
return list;
} else if (old_length == 0) {
list.decref(alignment);
return RocList.empty();
} else {
var output = RocList.allocateExact(alignment, old_length, element_width);
if (list.bytes) |source_ptr| {
const dest_ptr = output.bytes orelse unreachable;
@memcpy(dest_ptr, source_ptr, old_length * element_width);
}
return output;
}
}
pub fn listAppendUnsafe(
list: RocList,
element: Opaque,

View file

@ -56,6 +56,7 @@ comptime {
exportListFn(list.listIsUnique, "is_unique");
exportListFn(list.listCapacity, "capacity");
exportListFn(list.listRefcountPtr, "refcount_ptr");
exportListFn(list.listReleaseExcessCapacity, "release_excess_capacity");
}
// Num Module