diff --git a/array/mutview.mbt b/array/mutview.mbt new file mode 100644 index 000000000..e96343346 --- /dev/null +++ b/array/mutview.mbt @@ -0,0 +1,65 @@ +// Copyright 2025 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +///| +pub fn[X] MutArrayView::iterator(self : MutArrayView[X]) -> Iterator[X] { + let mut i = 0 + Iterator::new(fn() { + guard i < self.length() else { None } + let elem = self.unsafe_get(i) + i += 1 + Some(elem) + }) +} + +///| +pub fn[X] MutArrayView::rev_iterator(self : MutArrayView[X]) -> Iterator[X] { + let mut i = self.length() + Iterator::new(fn() { + guard i > 0 else { None } + i -= 1 + Some(self.unsafe_get(i)) + }) +} + +///| +pub fn[X] MutArrayView::iterator2(self : MutArrayView[X]) -> Iterator2[Int, X] { + let mut i = 0 + Iterator2::new(fn() { + guard i < self.length() else { None } + let result = Some((i, self.unsafe_get(i))) + i += 1 + result + }) +} + +///| +pub impl[X : Show] Show for MutArrayView[X] with output(self, logger) { + self[:].output(logger) +} + +///| +pub impl[T : Eq] Eq for MutArrayView[T] with equal(self, other) -> Bool { + self[:] == other[:] +} + +///| +pub impl[T : Compare] Compare for MutArrayView[T] with compare(self, other) -> Int { + self[:].compare(other[:]) +} + +///| +pub impl[A : Hash] Hash for MutArrayView[A] with hash_combine(self, hasher) { + self[:].hash_combine(hasher) +} diff --git a/array/mutview_test.mbt b/array/mutview_test.mbt new file mode 100644 index 000000000..a8b3f0ac8 --- /dev/null +++ b/array/mutview_test.mbt @@ -0,0 +1,34 @@ +// Copyright 2025 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +///| +test "iterator" { + let arr = [1, 2, 3, 4, 5] + let iter = arr.iterator().map(x => x * 2) + inspect(iter.to_array(), content="[2, 4, 6, 8, 10]") +} + +///| +test "rev_iterator" { + let arr = [1, 2, 3, 4, 5] + let iter = arr.rev_iterator().map(x => x * 2) + inspect(iter.to_array(), content="[10, 8, 6, 4, 2]") +} + +///| +test "iterator2" { + let arr = [1, 2, 3, 4, 5] + let iter = arr.iterator2() + inspect(iter.to_string(), content="[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]") +} diff --git a/array/pkg.generated.mbti b/array/pkg.generated.mbti index e7b13926b..6d83da4cd 100644 --- a/array/pkg.generated.mbti +++ b/array/pkg.generated.mbti @@ -165,6 +165,14 @@ impl[A : Hash] Hash for ArrayView[A] impl[X : Show] Show for ArrayView[X] impl[A : @quickcheck.Arbitrary] @quickcheck.Arbitrary for ArrayView[A] +fn[X] MutArrayView::iterator(Self[X]) -> Iterator[X] +fn[X] MutArrayView::iterator2(Self[X]) -> Iterator2[Int, X] +fn[X] MutArrayView::rev_iterator(Self[X]) -> Iterator[X] +impl[T : Compare] Compare for MutArrayView[T] +impl[T : Eq] Eq for MutArrayView[T] +impl[A : Hash] Hash for MutArrayView[A] +impl[X : Show] Show for MutArrayView[X] + // Type aliases pub using @builtin {type ArrayView as View} diff --git a/builtin/mutarrayview.mbt b/builtin/mutarrayview.mbt new file mode 100644 index 000000000..ed3ab9f9f --- /dev/null +++ b/builtin/mutarrayview.mbt @@ -0,0 +1,346 @@ +// Copyright 2025 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +///| +/// A `MutArrayView` represents a view into a section of an array without copying the data. +/// The view provides read-write access to elements of the underlying array. +/// +/// # Example +/// +/// ```moonbit +/// let arr = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=1, end=4) // Creates a view of elements at indices 1,2,3 +/// assert_eq(view[0], 2) +/// assert_eq(view.length(), 3) +/// ``` +#builtin.valtype +type MutArrayView[T] + +///| +fn[T] MutArrayView::buf(self : MutArrayView[T]) -> UninitializedArray[T] = "%arrayview.buf" + +///| +fn[T] MutArrayView::start(self : MutArrayView[T]) -> Int = "%arrayview.start" + +///| +fn[T] MutArrayView::len(self : MutArrayView[T]) -> Int = "%arrayview.len" + +///| +fn[T] MutArrayView::make( + buf : UninitializedArray[T], + start : Int, + len : Int, +) -> MutArrayView[T] = "%arrayview.make" + +///| +/// Returns the length (number of elements) of a mutable array view. +/// +/// Parameters: +/// +/// * `array_view` : The mutable array view whose length is to be determined. +/// +/// Returns an integer representing the number of elements in the mutable array view. +/// +/// Example: +/// +/// ```moonbit +/// let arr = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=2, end=4) +/// inspect(view.length(), content="2") +/// ``` +pub fn[T] MutArrayView::length(self : MutArrayView[T]) -> Int { + self.len() +} + +///| +/// Retrieves an element at the specified index from the mutable array view. +/// +/// Parameters: +/// +/// * `self` : The mutable array view to access. +/// * `index` : The position in the array view from which to retrieve the +/// element. +/// +/// Returns the element at the specified index. +/// +/// Throws a runtime error if the index is out of bounds (less than 0 or greater +/// than or equal to the length of the array view). +/// +/// Example: +/// +/// ```moonbit +/// let arr = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=2, end=4) +/// inspect(view[0], content="3") +/// inspect(view[1], content="4") +/// ``` +#alias("_[_]") +pub fn[T] MutArrayView::at(self : MutArrayView[T], index : Int) -> T { + 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}", + ) + } + self.buf()[self.start() + index] +} + +///| +/// Retrieves an element from the mutable array view at the specified index without +/// performing bounds checking. +/// +/// Parameters: +/// +/// * `array_view` : The mutable array view to retrieve the element from. +/// * `index` : The position in the array view from which to retrieve the +/// element. +/// +/// Returns the element at the specified index in the array view. +/// +/// Example: +/// +/// ```moonbit +/// let arr = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=1, end=4) +/// inspect(view.unsafe_get(1), content="3") +/// ``` +#intrinsic("%arrayview.unsafe_get") +#internal(unsafe, "Panic if index is out of bounds") +pub fn[T] MutArrayView::unsafe_get(self : MutArrayView[T], index : Int) -> T { + self.buf()[self.start() + index] +} + +///| +/// Sets an element at the specified index in the mutable array view. +/// +/// Parameters: +/// +/// * `self` : The mutable array view to modify. +/// * `index` : The position in the array view at which to set the element. +/// * `value` : The value to set at the specified index. +/// +/// Throws a runtime error if the index is out of bounds (less than 0 or greater +/// than or equal to the length of the array view). +/// +/// Example: +/// +/// ```moonbit +/// let arr = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=2, end=4) +/// view[0] = 10 +/// inspect(view[0], content="10") +/// inspect(arr[2], content="10") +/// ``` +#alias("_[_]=_") +pub fn[T] MutArrayView::set( + self : MutArrayView[T], + index : Int, + value : T, +) -> Unit { + 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}", + ) + } + self.buf()[self.start() + index] = value +} + +///| +/// Sets an element at the specified index in the mutable array view without +/// performing bounds checking. +/// +/// Parameters: +/// +/// * `self` : The mutable array view to modify. +/// * `index` : The position in the array view at which to set the element. +/// * `value` : The value to set at the specified index. +/// +/// Example: +/// +/// ```moonbit +/// let arr = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=1, end=4) +/// view.unsafe_set(1, 10) +/// inspect(view[1], content="10") +/// ``` +#intrinsic("%arrayview.unsafe_set") +#internal(unsafe, "Panic if index is out of bounds") +pub fn[T] MutArrayView::unsafe_set( + self : MutArrayView[T], + index : Int, + value : T, +) -> Unit { + self.buf()[self.start() + index] = value +} + +///| +/// Creates a mutable view of a portion of the array. The view provides read-write access +/// to the underlying array without copying the elements. +/// +/// Parameters: +/// +/// * `array` : The array to create a 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 window into the specified portion of +/// the array. +/// +/// Throws a panic if the indices are invalid (i.e., `start` is negative, `end` +/// is greater than the array length, or `start` is greater than `end`). +/// +/// Example: +/// +/// ```moonbit +/// let arr = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=1, end=4) // Create a view of elements at indices 1, 2, and 3 +/// inspect(view[0], content="2") // First element of view is arr[1] +/// inspect(view.length(), content="3") // View contains 3 elements +/// ``` +pub fn[T] Array::mut_sub( + self : Array[T], + start? : Int = 0, + end? : Int, +) -> MutArrayView[T] { + let len = self.length() + let end = match end { + None => len + Some(end) => if end < 0 { len + end } else { end } + } + let start = if start < 0 { len + start } else { start } + guard start >= 0 && start <= end && end <= len else { + abort("View index out of bounds") + } + MutArrayView::make(self.buffer(), start, end - start) +} + +///| +/// Creates a new mutable view into a portion of the mutable array view. +/// +/// Parameters: +/// +/// * `self` : The mutable array view to create a new view from. +/// * `start` : The starting index in the current view (inclusive). Defaults to +/// 0. +/// * `end` : The ending index in the current view (exclusive). Defaults to the +/// length of the current view. +/// +/// Returns a new `MutArrayView` that provides a window into the specified portion +/// of the original mutable array view. The indices are relative to the start of the +/// current view. +/// +/// Throws a panic if: +/// +/// * `start` is negative +/// * `end` is greater than the length of the current view +/// * `start` is greater than `end` +/// +/// Example: +/// +/// ```moonbit +/// let arr = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=1, end=4) // view = [2, 3, 4] +/// let subview = view.mut_sub(start=1, end=2) // subview = [3] +/// inspect(subview[0], content="3") +/// ``` +pub fn[T] MutArrayView::mut_sub( + self : MutArrayView[T], + start? : Int = 0, + end? : Int, +) -> MutArrayView[T] { + let len = self.length() + let end = match end { + None => len + Some(end) => if end < 0 { len + end } else { end } + } + let start = if start < 0 { len + start } else { start } + guard start >= 0 && start <= end && end <= len else { + abort("View index out of bounds") + } + MutArrayView::make(self.buf(), self.start() + start, end - start) +} + +///| +/// Creates a new mutable `ArrayView` from a `FixedArray`. +/// +/// Parameters: +/// +/// * `self` : The fixed array to create a new view from. +/// * `start` : The starting index in the array (inclusive). Defaults to 0. +/// * `end` : The ending index in the array (exclusive). Defaults to the +/// length of the array. +/// +/// Returns a new `MutArrayView` that provides a window into the specified portion +/// of the original fixed array. +/// +/// Throws a panic if: +/// +/// * `start` is negative +/// * `end` is greater than the length of the array +/// * `start` is greater than `end` +/// +/// Example: +/// +/// ```moonbit +/// let arr: FixedArray[Int] = [1, 2, 3, 4, 5] +/// let view = arr.mut_sub(start=1, end=4) // view = [2, 3, 4] +/// inspect(view[0], content="2") +/// ``` +pub fn[T] FixedArray::mut_sub( + self : FixedArray[T], + start? : Int = 0, + end? : Int, +) -> MutArrayView[T] { + let len = self.length() + let end = match end { + None => len + Some(end) => if end < 0 { len + end } else { end } + } + let start = if start < 0 { len + start } else { start } + guard start >= 0 && start <= end && end <= len else { + abort("View index out of bounds") + } + MutArrayView::make( + unsafe_cast_fixedarray_to_uninitializedarray(self), + start, + end - start, + ) +} + +///| +/// Creates a new `ArrayView` from a `MutArrayView`. +/// +/// Parameters: +/// +/// * `self` : The mutable array view to create a new view from. +/// * `start` : The starting index in the array (inclusive). Defaults to 0. +/// * `end` : The ending index in the array (exclusive). Defaults to the +/// length of the array. +#alias("_[_:_]") +pub fn[T] MutArrayView::sub( + self : MutArrayView[T], + start? : Int = 0, + end? : Int, +) -> ArrayView[T] { + let len = self.length() + let end = match end { + None => len + Some(end) => if end < 0 { len + end } else { end } + } + let start = if start < 0 { len + start } else { start } + guard start >= 0 && start <= end && end <= len else { + abort("View index out of bounds") + } + ArrayView::make(self.buf(), self.start() + start, end - start) +} diff --git a/builtin/mutarrayview_test.mbt b/builtin/mutarrayview_test.mbt new file mode 100644 index 000000000..ff9304a19 --- /dev/null +++ b/builtin/mutarrayview_test.mbt @@ -0,0 +1,231 @@ +// Copyright 2025 International Digital Economy Academy +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +///| +test "array_mut_sub" { + let arr = [1, 2, 3, 4, 5] + let view = arr.mut_sub() + inspect(view, content="[1, 2, 3, 4, 5]") + inspect(view.length(), content="5") + inspect(view[0], content="1") + inspect(view[4], content="5") + inspect(view[:], content="[1, 2, 3, 4, 5]") + inspect(view[1:], content="[2, 3, 4, 5]") + inspect(view[:-1], content="[1, 2, 3, 4]") + inspect(view[1:-1], content="[2, 3, 4]") + inspect(view[-1:], content="[5]") + inspect(view[-1:-1], content="[]") +} + +///| +test "mutarrayview_get" { + let arr = [1, 2, 3, 4, 5] + let view = arr.mut_sub(start=1, end=4) + inspect(view.length(), content="3") + inspect(view[0], content="2") + inspect(view[1], content="3") + inspect(view[2], content="4") +} + +///| +test "mutarrayview_set" { + let arr = [1, 2, 3, 4, 5] + let view = arr.mut_sub(start=1, end=4) + view[0] = 10 + view[1] = 20 + view[2] = 30 + inspect(view[0], content="10") + inspect(view[1], content="20") + inspect(view[2], content="30") + // Verify underlying array is modified + inspect(arr[1], content="10") + inspect(arr[2], content="20") + inspect(arr[3], content="30") +} + +///| +test "mutarrayview_as_mutarrayview" { + let arr = [1, 2, 3, 4, 5] + let view1 = arr.mut_sub(start=1, end=4) + let view2 = view1.mut_sub(start=1, end=2) + inspect(view2.length(), content="1") + inspect(view2[0], content="3") + view2[0] = 99 + inspect(arr[2], content="99") + inspect(view1[1], content="99") +} + +///| +test "negative index1" { + let arr = [1, 2, 3] + let view = arr.mut_sub(start=-1) + inspect(view, content="[3]") + let view = arr.mut_sub(start=-2) + inspect(view, content="[2, 3]") + let view = arr.mut_sub(start=-3) + inspect(view, content="[1, 2, 3]") + let view = arr.mut_sub(end=-1) + inspect(view, content="[1, 2]") + let view = arr.mut_sub(end=-2) + inspect(view, content="[1]") + let view = arr.mut_sub(end=-3) + inspect(view, content="[]") + let view = arr.mut_sub(start=-3, end=-3) + inspect(view, content="[]") + let view = arr.mut_sub(start=-3, end=-2) + inspect(view, content="[1]") + let view = arr.mut_sub(start=-3, end=-1) + inspect(view, content="[1, 2]") + let view = arr.mut_sub(start=-3, end=0) + inspect(view, content="[]") + let view = arr.mut_sub(start=-3, end=1) + inspect(view, content="[1]") + let view = arr.mut_sub(start=-3, end=2) + inspect(view, content="[1, 2]") + let view = arr.mut_sub(start=-3, end=3) + inspect(view, content="[1, 2, 3]") +} + +///| +test "negative index2" { + let arr = [0, 1, 2, 3, 4] + let view = arr.mut_sub(start=1, end=4) + let view2 = view.mut_sub(start=-1) + inspect(view2, content="[3]") + let view2 = view.mut_sub(start=-2) + inspect(view2, content="[2, 3]") + let view2 = view.mut_sub(start=-3) + inspect(view2, content="[1, 2, 3]") + let view2 = view.mut_sub(end=-1) + inspect(view2, content="[1, 2]") + let view2 = view.mut_sub(end=-2) + inspect(view2, content="[1]") + let view2 = view.mut_sub(end=-3) + inspect(view2, content="[]") + let view2 = view.mut_sub(start=-3, end=-3) + inspect(view2, content="[]") + let view2 = view.mut_sub(start=-3, end=-2) + inspect(view2, content="[1]") + let view2 = view.mut_sub(start=-3, end=-1) + inspect(view2, content="[1, 2]") + let view2 = view.mut_sub(start=-3, end=0) + inspect(view2, content="[]") + let view2 = view.mut_sub(start=-3, end=1) + inspect(view2, content="[1]") + let view2 = view.mut_sub(start=-3, end=2) + inspect(view2, content="[1, 2]") + let view2 = view.mut_sub(start=-3, end=3) + inspect(view2, content="[1, 2, 3]") +} + +///| +test "panic negative index1" { + let arr = [1, 2, 3] + let _ = arr.mut_sub(start=-4) + +} + +///| +test "panic negative index2" { + let arr = [1, 2, 3] + let _ = arr.mut_sub(end=-4) + +} + +///| +test "panic negative index3" { + let arr = [1, 2, 3] + let _ = arr.mut_sub(start=-1, end=-2) + +} + +///| +test "panic negative index4" { + let arr = [1, 2, 3] + let _ = arr.mut_sub(start=-1, end=-3) + +} + +///| +test "panic negative index5" { + let arr = [1, 2, 3] + let view = arr.mut_sub() + let _ = view.mut_sub(start=-4) + +} + +///| +test "panic negative index6" { + let arr = [1, 2, 3] + let view = arr.mut_sub() + let _ = view.mut_sub(end=-4) + +} + +///| +test "panic negative index7" { + let arr = [1, 2, 3] + let view = arr.mut_sub() + let _ = view.mut_sub(start=-1, end=-2) + +} + +///| +test "panic negative index8" { + let arr = [1, 2, 3] + let view = arr.mut_sub() + let _ = view.mut_sub(start=-1, end=-3) + +} + +///| +test "fixedarray_mut_sub" { + // scalar case + let arr = FixedArray::makei(10, i => i) + let view = arr.mut_sub() + inspect(view, content="[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]") + let view = arr.mut_sub(start=1) + inspect(view, content="[1, 2, 3, 4, 5, 6, 7, 8, 9]") + let view = arr.mut_sub(end=-2) + inspect(view, content="[0, 1, 2, 3, 4, 5, 6, 7]") + let view = arr.mut_sub(start=3, end=-4) + inspect(view, content="[3, 4, 5]") + let view = arr.mut_sub(start=-5) + inspect(view, content="[5, 6, 7, 8, 9]") + + // Test mutation through view + let view = arr.mut_sub(start=3, end=-4) + view[0] = 100 + inspect(arr[3], content="100") + inspect(view, content="[100, 4, 5]") + + // reference case + let arr = FixedArray::makei(10, i => (i, i)) + let view = arr.mut_sub() + inspect( + view, + content="[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]", + ) + let view = arr.mut_sub(start=1) + inspect( + view, + content="[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)]", + ) + + // Test mutation + let view = arr.mut_sub(start=3, end=-4) + view[0] = (100, 100) + inspect(arr[3], content="(100, 100)") + inspect(view, content="[(100, 100), (4, 4), (5, 5)]") +} diff --git a/builtin/pkg.generated.mbti b/builtin/pkg.generated.mbti index df407f8f2..a3eb5ca82 100644 --- a/builtin/pkg.generated.mbti +++ b/builtin/pkg.generated.mbti @@ -107,6 +107,7 @@ fn[T, U] Array::map(Self[T], (T) -> U raise?) -> Self[U] raise? fn[T] Array::map_inplace(Self[T], (T) -> T raise?) -> Unit raise? fn[T, U] Array::mapi(Self[T], (Int, T) -> U raise?) -> Self[U] raise? fn[T] Array::mapi_inplace(Self[T], (Int, T) -> T raise?) -> Unit raise? +fn[T] Array::mut_sub(Self[T], start? : Int, end? : Int) -> MutArrayView[T] fn[T] Array::new(capacity? : Int) -> Self[T] fn[T] Array::pop(Self[T]) -> T? fn[T] Array::push(Self[T], T) -> Unit @@ -369,6 +370,18 @@ impl[K : Hash + Eq, V : Eq] Eq for Map[K, V] impl[K : Show, V : Show] Show for Map[K, V] impl[K : Show, V : ToJson] ToJson for Map[K, V] +type MutArrayView[T] +#alias("_[_]") +fn[T] MutArrayView::at(Self[T], Int) -> T +fn[T] MutArrayView::length(Self[T]) -> Int +fn[T] MutArrayView::mut_sub(Self[T], start? : Int, end? : Int) -> Self[T] +#alias("_[_]=_") +fn[T] MutArrayView::set(Self[T], Int, T) -> Unit +#alias("_[_:_]") +fn[T] MutArrayView::sub(Self[T], start? : Int, end? : Int) -> ArrayView[T] +fn[T] MutArrayView::unsafe_get(Self[T], Int) -> T +fn[T] MutArrayView::unsafe_set(Self[T], Int, T) -> Unit + pub(all) type SourceLoc fn SourceLoc::to_string(Self) -> String impl Show for SourceLoc @@ -621,6 +634,7 @@ fn[T] FixedArray::iter(Self[T]) -> Iter[T] fn[T] FixedArray::iter2(Self[T]) -> Iter2[Int, T] fn[T] FixedArray::length(Self[T]) -> Int fn[T] FixedArray::make(Int, T) -> Self[T] +fn[T] FixedArray::mut_sub(Self[T], start? : Int, end? : Int) -> MutArrayView[T] #alias("_[_]=_") fn[T] FixedArray::set(Self[T], Int, T) -> Unit fn FixedArray::set_utf16be_char(Self[Byte], Int, Char) -> Int