create seamless slices when getting a substring

This commit is contained in:
Brendan Hansknecht 2023-12-05 22:46:43 -08:00
parent 9889984dd4
commit 087ca115c9
No known key found for this signature in database
GPG key ID: A199D0660F95F948
3 changed files with 29 additions and 4 deletions

View file

@ -1498,8 +1498,33 @@ pub fn getCapacity(string: RocStr) callconv(.C) usize {
}
pub fn substringUnsafe(string: RocStr, start: usize, length: usize) callconv(.C) RocStr {
const slice = string.asSlice()[start .. start + length];
return RocStr.fromSlice(slice);
if (string.isSmallStr()) {
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 {