mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-02 11:22:19 +00:00
create seamless slices when getting a substring
This commit is contained in:
parent
9889984dd4
commit
087ca115c9
3 changed files with 29 additions and 4 deletions
|
@ -1498,8 +1498,33 @@ pub fn getCapacity(string: RocStr) callconv(.C) usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn substringUnsafe(string: RocStr, start: usize, length: usize) callconv(.C) RocStr {
|
pub fn substringUnsafe(string: RocStr, start: usize, length: usize) callconv(.C) RocStr {
|
||||||
const slice = string.asSlice()[start .. start + length];
|
if (string.isSmallStr()) {
|
||||||
return RocStr.fromSlice(slice);
|
if (start == 0) {
|
||||||
|
var output = string;
|
||||||
|
output.setLen(length);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
const slice = string.asSlice()[start .. start + length];
|
||||||
|
return RocStr.fromSlice(slice);
|
||||||
|
}
|
||||||
|
if (string.str_bytes) |source_ptr| {
|
||||||
|
if (start == 0 and string.isUnique()) {
|
||||||
|
var output = string;
|
||||||
|
output.setLen(length);
|
||||||
|
return output;
|
||||||
|
} else {
|
||||||
|
const str_ref_ptr = (@intFromPtr(source_ptr) >> 1);
|
||||||
|
const slice_ref_ptr = string.str_capacity;
|
||||||
|
const slice_mask = string.seamlessSliceMask();
|
||||||
|
const ref_ptr = (str_ref_ptr & ~slice_mask) | (slice_ref_ptr & slice_mask);
|
||||||
|
return RocStr{
|
||||||
|
.str_bytes = source_ptr + start,
|
||||||
|
.str_len = length | SEAMLESS_SLICE_BIT,
|
||||||
|
.str_capacity = ref_ptr,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RocStr.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getUnsafe(string: RocStr, index: usize) callconv(.C) u8 {
|
pub fn getUnsafe(string: RocStr, index: usize) callconv(.C) u8 {
|
||||||
|
|
|
@ -1540,7 +1540,7 @@ fn low_level_no_rc(lowlevel: &LowLevel) -> RC {
|
||||||
StrGetUnsafe | ListGetUnsafe => RC::NoRc,
|
StrGetUnsafe | ListGetUnsafe => RC::NoRc,
|
||||||
ListConcat => RC::Rc,
|
ListConcat => RC::Rc,
|
||||||
StrConcat => RC::Rc,
|
StrConcat => RC::Rc,
|
||||||
StrSubstringUnsafe => RC::NoRc,
|
StrSubstringUnsafe => RC::Rc,
|
||||||
StrReserve => RC::Rc,
|
StrReserve => RC::Rc,
|
||||||
StrAppendScalar => RC::Rc,
|
StrAppendScalar => RC::Rc,
|
||||||
StrGetScalarUnsafe => RC::NoRc,
|
StrGetScalarUnsafe => RC::NoRc,
|
||||||
|
|
|
@ -1292,7 +1292,7 @@ fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[Ownership] {
|
||||||
StrGetUnsafe | ListGetUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
StrGetUnsafe | ListGetUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||||
ListConcat => arena.alloc_slice_copy(&[owned, owned]),
|
ListConcat => arena.alloc_slice_copy(&[owned, owned]),
|
||||||
StrConcat => arena.alloc_slice_copy(&[owned, borrowed]),
|
StrConcat => arena.alloc_slice_copy(&[owned, borrowed]),
|
||||||
StrSubstringUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant, irrelevant]),
|
StrSubstringUnsafe => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]),
|
||||||
StrReserve => arena.alloc_slice_copy(&[owned, irrelevant]),
|
StrReserve => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
StrAppendScalar => arena.alloc_slice_copy(&[owned, irrelevant]),
|
StrAppendScalar => arena.alloc_slice_copy(&[owned, irrelevant]),
|
||||||
StrGetScalarUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
StrGetScalarUnsafe => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue