mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
make Str.fromUtf8 in-place
This commit is contained in:
parent
9e97a09a87
commit
018348bd83
6 changed files with 49 additions and 14 deletions
|
@ -1,6 +1,7 @@
|
|||
const std = @import("std");
|
||||
const utils = @import("utils.zig");
|
||||
const RocResult = utils.RocResult;
|
||||
const UpdateMode = utils.UpdateMode;
|
||||
const mem = std.mem;
|
||||
|
||||
const EqFn = fn (?[*]u8, ?[*]u8) callconv(.C) bool;
|
||||
|
@ -52,6 +53,14 @@ pub const RocList = extern struct {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn makeUniqueExtra(self: RocList, alignment: u32, element_width: usize, update_mode: UpdateMode) RocList {
|
||||
if (update_mode == .InPlace) {
|
||||
return self;
|
||||
} else {
|
||||
return self.makeUnique(alignment, element_width);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn makeUnique(self: RocList, alignment: u32, element_width: usize) RocList {
|
||||
if (self.isEmpty()) {
|
||||
return self;
|
||||
|
@ -763,7 +772,7 @@ pub fn listSwap(
|
|||
element_width: usize,
|
||||
index_1: usize,
|
||||
index_2: usize,
|
||||
can_update_in_place: bool,
|
||||
update_mode: update_mode,
|
||||
) callconv(.C) RocList {
|
||||
const size = list.len();
|
||||
if (index_1 == index_2 or index_1 >= size or index_2 >= size) {
|
||||
|
@ -772,7 +781,7 @@ pub fn listSwap(
|
|||
}
|
||||
|
||||
const newList = blk: {
|
||||
if (can_update_in_place) {
|
||||
if (update_mode == .InPlace) {
|
||||
break :blk list;
|
||||
} else {
|
||||
break :blk list.makeUnique(alignment, element_width);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const utils = @import("utils.zig");
|
||||
const RocList = @import("list.zig").RocList;
|
||||
const UpdateMode = utils.UpdateMode;
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const always_inline = std.builtin.CallOptions.Modifier.always_inline;
|
||||
|
@ -1177,11 +1178,11 @@ const CountAndStart = extern struct {
|
|||
start: usize,
|
||||
};
|
||||
|
||||
pub fn fromUtf8C(arg: RocList, output: *FromUtf8Result) callconv(.C) void {
|
||||
output.* = @call(.{ .modifier = always_inline }, fromUtf8, .{arg});
|
||||
pub fn fromUtf8C(arg: RocList, update_mode: UpdateMode, output: *FromUtf8Result) callconv(.C) void {
|
||||
output.* = fromUtf8(arg, update_mode);
|
||||
}
|
||||
|
||||
fn fromUtf8(arg: RocList) FromUtf8Result {
|
||||
inline fn fromUtf8(arg: RocList, update_mode: UpdateMode) FromUtf8Result {
|
||||
const bytes = @ptrCast([*]const u8, arg.bytes)[0..arg.length];
|
||||
|
||||
if (unicode.utf8ValidateSlice(bytes)) {
|
||||
|
@ -1194,13 +1195,23 @@ fn fromUtf8(arg: RocList) FromUtf8Result {
|
|||
const data_bytes = arg.len();
|
||||
utils.decref(arg.bytes, data_bytes, RocStr.alignment);
|
||||
|
||||
return FromUtf8Result{ .is_ok = true, .string = string, .byte_index = 0, .problem_code = Utf8ByteProblem.InvalidStartByte };
|
||||
return FromUtf8Result{
|
||||
.is_ok = true,
|
||||
.string = string,
|
||||
.byte_index = 0,
|
||||
.problem_code = Utf8ByteProblem.InvalidStartByte,
|
||||
};
|
||||
} else {
|
||||
const byte_list = arg.makeUnique(RocStr.alignment, @sizeOf(u8));
|
||||
const byte_list = arg.makeUniqueExtra(RocStr.alignment, @sizeOf(u8), update_mode);
|
||||
|
||||
const string = RocStr{ .str_bytes = byte_list.bytes, .str_len = byte_list.length };
|
||||
|
||||
return FromUtf8Result{ .is_ok = true, .string = string, .byte_index = 0, .problem_code = Utf8ByteProblem.InvalidStartByte };
|
||||
return FromUtf8Result{
|
||||
.is_ok = true,
|
||||
.string = string,
|
||||
.byte_index = 0,
|
||||
.problem_code = Utf8ByteProblem.InvalidStartByte,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const temp = errorToProblem(@ptrCast([*]u8, arg.bytes), arg.length);
|
||||
|
@ -1209,7 +1220,12 @@ fn fromUtf8(arg: RocList) FromUtf8Result {
|
|||
const data_bytes = arg.len();
|
||||
utils.decref(arg.bytes, data_bytes, RocStr.alignment);
|
||||
|
||||
return FromUtf8Result{ .is_ok = false, .string = RocStr.empty(), .byte_index = temp.index, .problem_code = temp.problem };
|
||||
return FromUtf8Result{
|
||||
.is_ok = false,
|
||||
.string = RocStr.empty(),
|
||||
.byte_index = temp.index,
|
||||
.problem_code = temp.problem,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -256,3 +256,8 @@ pub const Ordering = enum(u8) {
|
|||
GT = 1,
|
||||
LT = 2,
|
||||
};
|
||||
|
||||
pub const UpdateMode = extern enum(u8) {
|
||||
Immutable = 0,
|
||||
InPlace = 1,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue