Skip to content

refactor: use view primitives #2419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 31 additions & 19 deletions builtin/arrayview.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,23 @@
/// ```
#deprecated("use @array.View instead")
#builtin.valtype
struct ArrayView[T] {
buf : UninitializedArray[T]
start : Int
type ArrayView[T]

///|
fn[T] ArrayView::buf(self : ArrayView[T]) -> UninitializedArray[T] = "%arrayview.buf"

///|
fn[T] ArrayView::start(self : ArrayView[T]) -> Int = "%arrayview.start"

///|
fn[T] ArrayView::len(self : ArrayView[T]) -> Int = "%arrayview.len"

///|
fn[T] ArrayView::make(
buf : UninitializedArray[T],
start : Int,
len : Int
}
) -> ArrayView[T] = "%arrayview.make"

///|
/// Returns the length (number of elements) of an array view.
Expand All @@ -48,7 +60,7 @@ struct ArrayView[T] {
/// inspect(view.length(), content="2")
/// ```
pub fn[T] ArrayView::length(self : ArrayView[T]) -> Int {
self.len
self.len()
}

///|
Expand All @@ -74,12 +86,12 @@ pub fn[T] ArrayView::length(self : ArrayView[T]) -> Int {
/// inspect(view[1], content="4")
/// ```
pub fn[T] ArrayView::op_get(self : ArrayView[T], index : Int) -> T {
guard index >= 0 && index < self.len else {
guard index >= 0 && index < self.len() else {
abort(
"index out of bounds: the len is from 0 to \{self.len} but the index is \{index}",
"index out of bounds: the len is from 0 to \{self.len()} but the index is \{index}",
)
}
self.buf[self.start + index]
self.buf()[self.start() + index]
}

///|
Expand All @@ -104,7 +116,7 @@ pub fn[T] ArrayView::op_get(self : ArrayView[T], index : Int) -> T {
#intrinsic("%arrayview.unsafe_get")
#internal(unsafe, "Panic if index is out of bounds")
pub fn[T] ArrayView::unsafe_get(self : ArrayView[T], index : Int) -> T {
self.buf[self.start + index]
self.buf()[self.start() + index]
}

///|
Expand Down Expand Up @@ -133,12 +145,12 @@ pub fn[T] ArrayView::op_set(
index : Int,
value : T
) -> Unit {
guard index >= 0 && index < self.len else {
guard index >= 0 && index < self.len() else {
abort(
"index out of bounds: the len is from 0 to \{self.len} but the index is \{index}",
"index out of bounds: the len is from 0 to \{self.len()} but the index is \{index}",
)
}
self.buf[self.start + index] = value
self.buf()[self.start() + index] = value
}

///|
Expand All @@ -163,14 +175,14 @@ pub fn[T] ArrayView::op_set(
/// ```
///
pub fn[T] ArrayView::swap(self : ArrayView[T], i : Int, j : Int) -> Unit {
guard i >= 0 && i < self.len && j >= 0 && j < self.len else {
guard i >= 0 && i < self.len() && j >= 0 && j < self.len() else {
abort(
"index out of bounds: the len is from 0 to \{self.len} but the index is (\{i}, \{j})",
"index out of bounds: the len is from 0 to \{self.len()} but the index is (\{i}, \{j})",
)
}
let temp = self.buf[self.start + i]
self.buf[self.start + i] = self.buf[self.start + j]
self.buf[self.start + j] = temp
let temp = self.buf()[self.start() + i]
self.buf()[self.start() + i] = self.buf()[self.start() + j]
self.buf()[self.start() + j] = temp
}

///|
Expand Down Expand Up @@ -212,7 +224,7 @@ pub fn[T] Array::op_as_view(
guard start >= 0 && start <= end && end <= len else {
abort("View index out of bounds")
}
ArrayView::{ buf: self.buffer(), start, len: end - start }
ArrayView::make(self.buffer(), start, end - start)
}

///|
Expand Down Expand Up @@ -258,5 +270,5 @@ pub fn[T] ArrayView::op_as_view(
guard start >= 0 && start <= end && end <= len else {
abort("View index out of bounds")
}
ArrayView::{ buf: self.buf, start: self.start + start, len: end - start }
ArrayView::make(self.buf(), self.start() + start, end - start)
}
6 changes: 3 additions & 3 deletions builtin/uninitialized_array.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub fn[T] UninitializedArray::op_as_view(
guard start >= 0 && start <= end && end <= len else {
abort("View start index out of bounds")
}
{ buf: self, start, len: end - start }
ArrayView::make(self, start, end - start)
}

///|
Expand Down Expand Up @@ -113,8 +113,8 @@ pub fn[T] UninitializedArray::unsafe_blit(
test "op_as_view with valid_range" {
let arr : UninitializedArray[Int] = UninitializedArray::make(5)
let view = arr[1:4]
inspect(view.start, content="1")
inspect(view.len, content="3")
inspect(view.start(), content="1")
inspect(view.len(), content="3")
}

///|
Expand Down
1 change: 1 addition & 0 deletions bytes/view.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
/// assert_eq(bv[1], b'\x02')
/// assert_eq(bv[2], b'\x03')
/// ```
#builtin.valtype
type View

///|
Expand Down
36 changes: 12 additions & 24 deletions string/deprecated.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -108,35 +108,35 @@ pub fn String::op_as_view(self : String, start~ : Int = 0, end? : Int) -> View {
guard start >= 0 && start <= end && end <= str_len else {
abort("Invalid index for View")
}
{ str: self, start, end }
View::make_view(self, start, end)
}

///|
#deprecated("use view.charcodes(start = view.offset_of_nth_char(i).unwrap(), end = view.offset_of_nth_char(j).unwrap()) to replace view[i:j]")
#coverage.skip
pub fn View::op_as_view(self : View, start~ : Int = 0, end? : Int) -> View {
let start = if start >= 0 {
self.str.index_at_(start, start=self.start).unwrap().inner()
self.str().index_at_(start, start=self.start()).unwrap().inner()
} else {
self.str.index_at_rev_(-start, end=self.end).unwrap().inner()
self.str().index_at_rev_(-start, end=self.end()).unwrap().inner()
}
let end = match end {
Some(end) =>
if end >= 0 {
self.str.index_at_(end, start=self.start).unwrap().inner()
self.str().index_at_(end, start=self.start()).unwrap().inner()
} else {
self.str.index_at_rev_(-end, end=self.end).unwrap().inner()
self.str().index_at_rev_(-end, end=self.end()).unwrap().inner()
}
None => self.end
None => self.end()
}
guard start >= self.start &&
start <= self.end &&
end >= self.start &&
end <= self.end &&
guard start >= self.start() &&
start <= self.end() &&
end >= self.start() &&
end <= self.end() &&
start <= end else {
abort("Invalid index for View")
}
{ str: self.str, start, end }
View::make_view(self.str(), start, end)
}

///|
Expand Down Expand Up @@ -233,16 +233,4 @@ pub fn ends_with(self : String, str : String) -> Bool {
/// multi-byte characters correctly.
#deprecated("use @string.View instead")
#builtin.valtype
struct StringView {
// # Fields
//
// - `str`: The source String being viewed
// - `start`: Starting UTF-16 code unit index into the string
// - `end`: Ending UTF-16 code unit index into the string (not included)
//
// `len` is not included because it will make the operation of `op_as_view`
// has complexity O(n) where n is the length of the code points in the view.
str : String
start : Int
end : Int
}
type StringView
Loading
Loading