mirror of
https://github.com/roc-lang/roc.git
synced 2025-11-11 17:13:53 +00:00
Fixes #7065 in List.dropAt, author: @bhansconnect
This commit is contained in:
parent
14bfa91ff3
commit
c10b25cf6e
1 changed files with 18 additions and 17 deletions
|
|
@ -618,6 +618,16 @@ pub fn listDropAt(
|
||||||
) callconv(.C) RocList {
|
) callconv(.C) RocList {
|
||||||
const size = list.len();
|
const size = list.len();
|
||||||
const size_u64 = @as(u64, @intCast(size));
|
const size_u64 = @as(u64, @intCast(size));
|
||||||
|
|
||||||
|
// NOTE
|
||||||
|
// we need to return an empty list explicitly,
|
||||||
|
// because we rely on the pointer field being null if the list is empty
|
||||||
|
// which also requires duplicating the utils.decref call to spend the RC token
|
||||||
|
if (size <= 1) {
|
||||||
|
list.decref(alignment, element_width, elements_refcounted, dec);
|
||||||
|
return RocList.empty();
|
||||||
|
}
|
||||||
|
|
||||||
// If droping the first or last element, return a seamless slice.
|
// If droping the first or last element, return a seamless slice.
|
||||||
// For simplicity, do this by calling listSublist.
|
// For simplicity, do this by calling listSublist.
|
||||||
// In the future, we can test if it is faster to manually inline the important parts here.
|
// In the future, we can test if it is faster to manually inline the important parts here.
|
||||||
|
|
@ -638,25 +648,16 @@ pub fn listDropAt(
|
||||||
// were >= than `size`, and we know `size` fits in usize.
|
// were >= than `size`, and we know `size` fits in usize.
|
||||||
const drop_index: usize = @intCast(drop_index_u64);
|
const drop_index: usize = @intCast(drop_index_u64);
|
||||||
|
|
||||||
|
if (list.isUnique()) {
|
||||||
if (elements_refcounted) {
|
if (elements_refcounted) {
|
||||||
const element = source_ptr + drop_index * element_width;
|
const element = source_ptr + drop_index * element_width;
|
||||||
dec(element);
|
dec(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE
|
const copy_target = source_ptr + (drop_index * element_width);
|
||||||
// we need to return an empty list explicitly,
|
|
||||||
// because we rely on the pointer field being null if the list is empty
|
|
||||||
// which also requires duplicating the utils.decref call to spend the RC token
|
|
||||||
if (size < 2) {
|
|
||||||
list.decref(alignment, element_width, elements_refcounted, dec);
|
|
||||||
return RocList.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list.isUnique()) {
|
|
||||||
var i = drop_index;
|
|
||||||
const copy_target = source_ptr;
|
|
||||||
const copy_source = copy_target + element_width;
|
const copy_source = copy_target + element_width;
|
||||||
std.mem.copyForwards(u8, copy_target[i..size], copy_source[i..size]);
|
const copy_size = (size - drop_index - 1) * element_width;
|
||||||
|
std.mem.copyForwards(u8, copy_target[0..copy_size], copy_source[0..copy_size]);
|
||||||
|
|
||||||
var new_list = list;
|
var new_list = list;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue