mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
improvements to str.zig
This commit is contained in:
parent
3ec8832e62
commit
20c041dc60
1 changed files with 13 additions and 16 deletions
|
@ -12,7 +12,7 @@ const InPlace = packed enum(u8) {
|
||||||
Clone,
|
Clone,
|
||||||
};
|
};
|
||||||
|
|
||||||
const RocStr = extern struct {
|
pub const RocStr = extern struct {
|
||||||
str_bytes: ?[*]u8,
|
str_bytes: ?[*]u8,
|
||||||
str_len: usize,
|
str_len: usize,
|
||||||
|
|
||||||
|
@ -181,10 +181,16 @@ const RocStr = extern struct {
|
||||||
return self.len() == 0;
|
return self.len() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn asSlice(self: RocStr) []u8 {
|
||||||
|
// Since this conditional would be prone to branch misprediction,
|
||||||
|
// make sure it will compile to a cmov.
|
||||||
|
return self.asU8ptr()[0..self.len()];
|
||||||
|
}
|
||||||
|
|
||||||
pub fn asU8ptr(self: RocStr) [*]u8 {
|
pub fn asU8ptr(self: RocStr) [*]u8 {
|
||||||
const if_small = &@bitCast([16]u8, self);
|
// Since this conditional would be prone to branch misprediction,
|
||||||
const if_big = @ptrCast([*]u8, self.str_bytes);
|
// make sure it will compile to a cmov.
|
||||||
return if (self.isSmallStr() or self.isEmpty()) if_small else if_big;
|
return if (self.isSmallStr() or self.isEmpty()) (&@bitCast([16]u8, self)) else (@ptrCast([*]u8, self.str_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a pointer to some bytes, write the first (len) bytes of this
|
// Given a pointer to some bytes, write the first (len) bytes of this
|
||||||
|
@ -193,18 +199,9 @@ const RocStr = extern struct {
|
||||||
// One use for this function is writing into an `alloca` for a C string that
|
// One use for this function is writing into an `alloca` for a C string that
|
||||||
// only needs to live long enough to be passed as an argument to
|
// only needs to live long enough to be passed as an argument to
|
||||||
// a C function - like the file path argument to `fopen`.
|
// a C function - like the file path argument to `fopen`.
|
||||||
pub fn memcpy(self: RocStr, dest: [*]u8, len: usize) void {
|
pub fn memcpy(self: RocStr, dest: [*]u8, length: usize) void {
|
||||||
const small_src = @ptrCast(*u8, self);
|
const src = self.asU8ptr();
|
||||||
const big_src = self.str_bytes_ptr;
|
@memcpy(dest, src, length);
|
||||||
|
|
||||||
// For a small string, copy the bytes directly from `self`.
|
|
||||||
// For a large string, copy from the pointed-to bytes.
|
|
||||||
|
|
||||||
// Since this conditional would be prone to branch misprediction,
|
|
||||||
// make sure it will compile to a cmov.
|
|
||||||
const src: [*]u8 = if (self.isSmallStr()) small_src else big_src;
|
|
||||||
|
|
||||||
@memcpy(dest, src, len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test "RocStr.eq: equal" {
|
test "RocStr.eq: equal" {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue