diff --git a/builtin/pkg.generated.mbti b/builtin/pkg.generated.mbti index b66e55805..7cd0472c3 100644 --- a/builtin/pkg.generated.mbti +++ b/builtin/pkg.generated.mbti @@ -440,6 +440,7 @@ type UninitializedArray[T] pub fn[T] UninitializedArray::at(Self[T], Int) -> T pub fn[A] UninitializedArray::length(Self[A]) -> Int pub fn[T] UninitializedArray::make(Int) -> Self[T] +pub fn[T] UninitializedArray::mut_view(Self[T], start? : Int, end? : Int) -> MutArrayView[T] #alias("_[_]=_") pub fn[T] UninitializedArray::set(Self[T], Int, T) -> Unit #alias("_[_:_]") diff --git a/builtin/uninitialized_array.mbt b/builtin/uninitialized_array.mbt index 1a37a11f4..5ad97e4b4 100644 --- a/builtin/uninitialized_array.mbt +++ b/builtin/uninitialized_array.mbt @@ -68,7 +68,7 @@ pub fn[T] UninitializedArray::set( /// Returns an `ArrayView` that provides a window into the specified portion of /// the array. /// -/// Throws an error if the indices are out of bounds or if `start` is greater +/// Panics if the indices are out of bounds or if `start` is greater /// than `end`. #alias("_[_:_]") pub fn[T] UninitializedArray::sub( @@ -87,6 +87,37 @@ pub fn[T] UninitializedArray::sub( ArrayView::make(self, start, end - start) } +///| +/// Creates a mutable view into a portion of the uninitialized array. +/// +/// Parameters: +/// +/// * `array` : The uninitialized array to create a mutable view from. +/// * `start` : The starting index of the view (inclusive). Defaults to 0 +/// * `end` : The ending index of the view (exclusive). If not provided, defaults +/// to the length of the array. +/// +/// Returns a `MutArrayView` that provides a mutable window into the specified +/// portion of the array. +/// +/// Panics if the indices are out of bounds or if `start` is greater +/// than `end`. +pub fn[T] UninitializedArray::mut_view( + self : UninitializedArray[T], + start? : Int = 0, + end? : Int, +) -> MutArrayView[T] { + let len = self.length() + let end = match end { + None => len + Some(end) => end + } + guard start >= 0 && start <= end && end <= len else { + abort("View start index out of bounds") + } + MutArrayView::make(self, start, end - start) +} + ///| /// Returns the length of an uninitialized array. /// diff --git a/deque/deque.mbt b/deque/deque.mbt index d99dd188a..86f81d29a 100644 --- a/deque/deque.mbt +++ b/deque/deque.mbt @@ -861,6 +861,24 @@ pub fn[A] Deque::as_views(self : Deque[A]) -> (ArrayView[A], ArrayView[A]) { } } +///| +pub fn[A] Deque::as_mut_views( + self : Deque[A], +) -> (MutArrayView[A], MutArrayView[A]) { + guard self.len != 0 else { ([].mut_view(), [].mut_view()) } + let { buf, head, len, .. } = self + let cap = buf.length() + let head_len = cap - head + if head_len >= len { + (buf.mut_view(start=head, end=head + len), [].mut_view()) + } else { + ( + buf.mut_view(start=head, end=cap), + buf.mut_view(start=0, end=len - head_len), + ) + } +} + ///| /// Compares two deques for equality. Returns `true` if both deques contain the /// same elements in the same order. @@ -2361,3 +2379,29 @@ pub fn[A] Deque::shuffle(self : Deque[A], rand~ : (Int) -> Int) -> Deque[A] { // Return the shuffled copy new_deque } + +///| +pub fn[A] Deque::make_contiguous(self : Deque[A]) -> MutArrayView[A] { + let view = self.as_views() + if view.0 is [] { + return self.buf.mut_view( + start=view.1.start_offset(), + end=view.1.start_offset() + view.1.length(), + ) + } else if view.1 is [] { + return self.buf.mut_view( + start=view.0.start_offset(), + end=view.0.start_offset() + view.0.length(), + ) + } + let new_buf = UninitializedArray::make(self.len) + new_buf.unsafe_blit(0, self.buf, view.0.start_offset(), view.0.length()) + new_buf.unsafe_blit( + view.0.length(), + self.buf, + view.1.start_offset(), + view.1.length(), + ) + self.buf = new_buf + new_buf.mut_view(end=self.len) +} diff --git a/deque/pkg.generated.mbti b/deque/pkg.generated.mbti index 08a59698d..95ac7f257 100644 --- a/deque/pkg.generated.mbti +++ b/deque/pkg.generated.mbti @@ -13,6 +13,7 @@ import { #alias(T, deprecated) type Deque[A] pub fn[A] Deque::append(Self[A], Self[A]) -> Unit +pub fn[A] Deque::as_mut_views(Self[A]) -> (MutArrayView[A], MutArrayView[A]) pub fn[A] Deque::as_views(Self[A]) -> (ArrayView[A], ArrayView[A]) #alias("_[_]") pub fn[A] Deque::at(Self[A], Int) -> A @@ -50,6 +51,7 @@ pub fn[A] Deque::iter(Self[A]) -> Iter[A] pub fn[A] Deque::iter2(Self[A]) -> Iter2[Int, A] pub fn Deque::join(Self[String], StringView) -> String pub fn[A] Deque::length(Self[A]) -> Int +pub fn[A] Deque::make_contiguous(Self[A]) -> MutArrayView[A] pub fn[A, U] Deque::map(Self[A], (A) -> U) -> Self[U] pub fn[A, U] Deque::mapi(Self[A], (Int, A) -> U) -> Self[U] #as_free_fn