diff --git a/library/src/scala/IArray.scala b/library/src/scala/IArray.scala index 75fcb758a3dc..d0f45fb9f2bc 100644 --- a/library/src/scala/IArray.scala +++ b/library/src/scala/IArray.scala @@ -10,269 +10,266 @@ object opaques: private[scala] type Sub[A] >: Array[A] <: IArray[A] private[scala] type Sup[A] >: IArray[A] <: Array[_ <: A] - /** Defines extension methods for immutable arrays */ - given arrayOps: Object with { - - /** The selection operation on an immutable array. - * - * @param arr the immutable array - * @param n the index of the element to select - * @return the element of the array at the given index - */ - extension (arr: IArray[Byte]) def apply(n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n) - extension (arr: IArray[Short]) def apply(n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n) - extension (arr: IArray[Char]) def apply(n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n) - extension (arr: IArray[Int]) def apply(n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n) - extension (arr: IArray[Long]) def apply(n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n) - extension (arr: IArray[Float]) def apply(n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n) - extension (arr: IArray[Double]) def apply(n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n) - extension [T <: Object](arr: IArray[T]) def apply (n: Int): T = arr.asInstanceOf[Array[T]].apply(n) - extension [T](arr: IArray[T]) def apply (n: Int): T = arr.asInstanceOf[Array[T]].apply(n) - - /** The number of elements in an immutable array - * @param arr the immutable array - */ - extension (arr: IArray[Byte]) def length: Int = arr.asInstanceOf[Array[Byte]].length - extension (arr: IArray[Short]) def length: Int = arr.asInstanceOf[Array[Short]].length - extension (arr: IArray[Char]) def length: Int = arr.asInstanceOf[Array[Char]].length - extension (arr: IArray[Int]) def length: Int = arr.asInstanceOf[Array[Int]].length - extension (arr: IArray[Long]) def length: Int = arr.asInstanceOf[Array[Long]].length - extension (arr: IArray[Float]) def length: Int = arr.asInstanceOf[Array[Float]].length - extension (arr: IArray[Double]) def length: Int = arr.asInstanceOf[Array[Double]].length - extension (arr: IArray[Object]) def length: Int = arr.asInstanceOf[Array[Object]].length - extension [T](arr: IArray[T]) def length: Int = arr.asInstanceOf[Array[T]].length - - /** Returns this array concatenated with the given array. */ - extension [T](arr: IArray[T]) def ++ [U >: T: ClassTag](that: IArray[U]): IArray[U] = - genericArrayOps(arr) ++ that - - /** Tests whether this array contains a given value as an element. */ - extension [T](arr: IArray[T]) def contains(elem: T): Boolean = - // `genericArrayOps(arr).contains(elem)` does not work because `elem` does not have type `arr.T` - // but we can use `exists` instead, which is how `ArrayOps#contains` itself is implemented: - genericArrayOps(arr).exists(_ == elem) - - /** Copy elements of this array to another array. */ - extension [T](arr: IArray[T]) def copyToArray[U >: T](xs: Array[U]): Int = - genericArrayOps(arr).copyToArray(xs) - - /** Copy elements of this array to another array. */ - extension [T](arr: IArray[T]) def copyToArray[U >: T](xs: Array[U], start: Int): Int = - genericArrayOps(arr).copyToArray(xs, start) - - /** Copy elements of this array to another array. */ - extension [T](arr: IArray[T]) def copyToArray[U >: T](xs: Array[U], start: Int, len: Int): Int = - genericArrayOps(arr).copyToArray(xs, start, len) - - /** Counts the number of elements in this array which satisfy a predicate */ - extension [T](arr: IArray[T]) def count(p: T => Boolean): Int = - genericArrayOps(arr).count(p) - - /** The rest of the array without its `n` first elements. */ - extension [T](arr: IArray[T]) def drop(n: Int): IArray[T] = - genericArrayOps(arr).drop(n) - - /** The rest of the array without its `n` last elements. */ - extension [T](arr: IArray[T]) def dropRight(n: Int): IArray[T] = - genericArrayOps(arr).dropRight(n) - - /** Drops longest prefix of elements that satisfy a predicate. */ - extension [T](arr: IArray[T]) def dropWhile(p: T => Boolean): IArray[T] = - genericArrayOps(arr).dropWhile(p) - - /** Tests whether a predicate holds for at least one element of this array. */ - extension [T](arr: IArray[T]) def exists(p: T => Boolean): Boolean = - genericArrayOps(arr).exists(p) - - /** Selects all elements of this array which satisfy a predicate. */ - extension [T](arr: IArray[T]) def filter(p: T => Boolean): IArray[T] = - genericArrayOps(arr).filter(p) - - /** Selects all elements of this array which do not satisfy a predicate. */ - extension [T](arr: IArray[T]) def filterNot(p: T => Boolean): IArray[T] = - genericArrayOps(arr).filterNot(p) - - /** Finds the first element of the array satisfying a predicate, if any. */ - extension [T](arr: IArray[T]) def find(p: T => Boolean): Option[T] = - genericArrayOps(arr).find(p) - - /** Builds a new array by applying a function to all elements of this array - * and using the elements of the resulting collections. */ - extension [T](arr: IArray[T]) def flatMap[U: ClassTag](f: T => IterableOnce[U]): IArray[U] = - genericArrayOps(arr).flatMap(f) - - /** Flattens a two-dimensional array by concatenating all its rows - * into a single array. */ - extension [T](arr: IArray[T]) def flatten[U: ClassTag](using T => Iterable[U]): IArray[U] = - genericArrayOps(arr).flatten - - /** Folds the elements of this array using the specified associative binary operator. */ - extension [T](arr: IArray[T]) def fold[U >: T: ClassTag](z: U)(op: (U, U) => U): U = - genericArrayOps(arr).fold(z)(op) - - /** Applies a binary operator to a start value and all elements of this array, - * going left to right. */ - extension [T](arr: IArray[T]) def foldLeft[U: ClassTag](z: U)(op: (U, T) => U): U = - genericArrayOps(arr).foldLeft(z)(op) - - /** Applies a binary operator to all elements of this array and a start value, - * going right to left. */ - extension [T](arr: IArray[T]) def foldRight[U: ClassTag](z: U)(op: (T, U) => U): U = - genericArrayOps(arr).foldRight(z)(op) - - /** Tests whether a predicate holds for all elements of this array. */ - extension [T](arr: IArray[T]) def forall(p: T => Boolean): Boolean = - genericArrayOps(arr).forall(p) - - /** Apply `f` to each element for its side effects. */ - extension [T](arr: IArray[T]) def foreach[U](f: T => U): Unit = - genericArrayOps(arr).foreach(f) - - /** Selects the first element of this array. */ - extension [T](arr: IArray[T]) def head: T = - genericArrayOps(arr).head - - /** Optionally selects the first element. */ - extension [T](arr: IArray[T]) def headOption: Option[T] = - genericArrayOps(arr).headOption - - /** Finds index of first occurrence of some value in this array after or at some start index. */ - extension [T](arr: IArray[T]) def indexOf(elem: T, from: Int = 0): Int = - // `asInstanceOf` needed because `elem` does not have type `arr.T` - // We could use `arr.iterator.indexOf(elem, from)` or `arr.indexWhere(_ == elem, from)` - // but these would incur some overhead. - genericArrayOps(arr).indexOf(elem.asInstanceOf, from) - - /** Finds index of the first element satisfying some predicate after or at some start index. */ - extension [T](arr: IArray[T]) def indexWhere(p: T => Boolean, from: Int = 0): Int = - genericArrayOps(arr).indexWhere(p, from) - - /** Produces the range of all indices of this sequence. */ - extension [T](arr: IArray[T]) def indices: Range = - genericArrayOps(arr).indices - - /** The initial part of the array without its last element. */ - extension [T](arr: IArray[T]) def init: IArray[T] = - genericArrayOps(arr).init - - /** Tests whether the array is empty. */ - extension [T](arr: IArray[T]) def isEmpty: Boolean = - genericArrayOps(arr).isEmpty - - /** An iterator yielding the elemenst of this array. */ - extension [T](arr: IArray[T]) def iterator: Iterator[T] = - genericArrayOps(arr).iterator - - /** Selects the last element. */ - extension [T](arr: IArray[T]) def last: T = - genericArrayOps(arr).last - - /** Optionally selects the last element. */ - extension [T](arr: IArray[T]) def lastOption: Option[T] = - genericArrayOps(arr).lastOption - - /** Finds index of last occurrence of some value in this array before or at a given end index. */ - extension [T](arr: IArray[T]) def lastIndexOf(elem: T, end: Int = arr.length - 1): Int = - // see: same issue in `indexOf` - genericArrayOps(arr).lastIndexOf(elem.asInstanceOf, end) - - /** Finds index of last element satisfying some predicate before or at given end index. */ - extension [T](arr: IArray[T]) def lastIndexWhere(p: T => Boolean, end: Int = arr.length - 1): Int = - genericArrayOps(arr).lastIndexWhere(p, end) - - /** Builds a new array by applying a function to all elements of this array. */ - extension [T](arr: IArray[T]) def map[U: ClassTag](f: T => U): IArray[U] = - genericArrayOps(arr).map(f) - - /** Tests whether the array is not empty. */ - extension [T](arr: IArray[T]) def nonEmpty: Boolean = - genericArrayOps(arr).nonEmpty - - /** A pair of, first, all elements that satisfy predicate `p` and, second, all elements that do not. */ - extension [T](arr: IArray[T]) def partition(p: T => Boolean): (IArray[T], IArray[T]) = - genericArrayOps(arr).partition(p) - - /** Returns a new array with the elements in reversed order. */ - extension [T](arr: IArray[T]) def reverse: IArray[T] = - genericArrayOps(arr).reverse - - /** Computes a prefix scan of the elements of the array. */ - extension [T](arr: IArray[T]) def scan[U >: T: ClassTag](z: U)(op: (U, U) => U): IArray[U] = - genericArrayOps(arr).scan(z)(op) - - /** Produces an array containing cumulative results of applying the binary - * operator going left to right. */ - extension [T](arr: IArray[T]) def scanLeft[U: ClassTag](z: U)(op: (U, T) => U): IArray[U] = - genericArrayOps(arr).scanLeft(z)(op) - - /** Produces an array containing cumulative results of applying the binary - * operator going right to left. */ - extension [T](arr: IArray[T]) def scanRight[U: ClassTag](z: U)(op: (T, U) => U): IArray[U] = - genericArrayOps(arr).scanRight(z)(op) - - /** The size of this array. */ - extension [T](arr: IArray[T]) def size: Int = - arr.length - - /** Selects the interval of elements between the given indices. */ - extension [T](arr: IArray[T]) def slice(from: Int, until: Int): IArray[T] = - genericArrayOps(arr).slice(from, until) - - /** Sorts this array according to the Ordering which results from transforming - * an implicitly given Ordering with a transformation function. */ - extension [T](arr: IArray[T]) def sortBy[U: ClassTag](f: T => U)(using math.Ordering[U]): IArray[T] = - genericArrayOps(arr).sortBy(f) - - /** Sorts this array according to a comparison function. */ - extension [T](arr: IArray[T]) def sortWith(f: (T, T) => Boolean): IArray[T] = - genericArrayOps(arr).sortWith(f) - - /** Sorts this array according to an Ordering. */ - extension [T](arr: IArray[T]) def sorted(using math.Ordering[T]): IArray[T] = - genericArrayOps(arr).sorted - - /** Splits this array into a prefix/suffix pair according to a predicate. */ - extension [T](arr: IArray[T]) def span(p: T => Boolean): (IArray[T], IArray[T]) = - genericArrayOps(arr).span(p) - - /** Splits this array into two at a given position. */ - extension [T](arr: IArray[T]) def splitAt(n: Int): (IArray[T], IArray[T]) = - genericArrayOps(arr).splitAt(n) - - /** Tests whether this array starts with the given array. */ - extension [T](arr: IArray[T]) def startsWith[U >: T: ClassTag](that: IArray[U], offset: Int = 0): Boolean = - genericArrayOps(arr).startsWith(that) - - /** The rest of the array without its first element. */ - extension [T](arr: IArray[T]) def tail: IArray[T] = - genericArrayOps(arr).tail - - /** An array containing the first `n` elements of this array. */ - extension [T](arr: IArray[T]) def take(n: Int): IArray[T] = - genericArrayOps(arr).take(n) - - /** An array containing the last `n` elements of this array. */ - extension [T](arr: IArray[T]) def takeRight(n: Int): IArray[T] = - genericArrayOps(arr).takeRight(n) - - /** Takes longest prefix of elements that satisfy a predicate. */ - extension [T](arr: IArray[T]) def takeWhile(p: T => Boolean): IArray[T] = - genericArrayOps(arr).takeWhile(p) - - /** Returns a mutable copy of this immutable array. */ - extension [T](arr: IArray[T]) def toArray: Array[T] = - arr.clone.asInstanceOf[Array[T]] - - /** Converts an array of pairs into an array of first elements and an array of second elements. */ - extension [U: ClassTag, V: ClassTag](arr: IArray[(U, V)]) def unzip: (IArray[U], IArray[V]) = - genericArrayOps(arr).unzip - - /** Returns an array formed from this array and another iterable collection - * by combining corresponding elements in pairs. - * If one of the two collections is longer than the other, its remaining elements are ignored. */ - extension [T](arr: IArray[T]) def zip[U: ClassTag](that: IArray[U]): IArray[(T, U)] = - genericArrayOps(arr).zip(that) - } + /** The selection operation on an immutable array. + * + * @param arr the immutable array + * @param n the index of the element to select + * @return the element of the array at the given index + */ + extension (arr: IArray[Byte]) def apply(n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n) + extension (arr: IArray[Short]) def apply(n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n) + extension (arr: IArray[Char]) def apply(n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n) + extension (arr: IArray[Int]) def apply(n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n) + extension (arr: IArray[Long]) def apply(n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n) + extension (arr: IArray[Float]) def apply(n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n) + extension (arr: IArray[Double]) def apply(n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n) + extension [T <: Object](arr: IArray[T]) def apply (n: Int): T = arr.asInstanceOf[Array[T]].apply(n) + extension [T](arr: IArray[T]) def apply (n: Int): T = arr.asInstanceOf[Array[T]].apply(n) + + /** The number of elements in an immutable array + * @param arr the immutable array + */ + extension (arr: IArray[Byte]) def length: Int = arr.asInstanceOf[Array[Byte]].length + extension (arr: IArray[Short]) def length: Int = arr.asInstanceOf[Array[Short]].length + extension (arr: IArray[Char]) def length: Int = arr.asInstanceOf[Array[Char]].length + extension (arr: IArray[Int]) def length: Int = arr.asInstanceOf[Array[Int]].length + extension (arr: IArray[Long]) def length: Int = arr.asInstanceOf[Array[Long]].length + extension (arr: IArray[Float]) def length: Int = arr.asInstanceOf[Array[Float]].length + extension (arr: IArray[Double]) def length: Int = arr.asInstanceOf[Array[Double]].length + extension (arr: IArray[Object]) def length: Int = arr.asInstanceOf[Array[Object]].length + extension [T](arr: IArray[T]) def length: Int = arr.asInstanceOf[Array[T]].length + + /** Returns this array concatenated with the given array. */ + extension [T](arr: IArray[T]) def ++ [U >: T: ClassTag](that: IArray[U]): IArray[U] = + genericArrayOps(arr) ++ that + + /** Tests whether this array contains a given value as an element. */ + extension [T](arr: IArray[T]) def contains(elem: T): Boolean = + // `genericArrayOps(arr).contains(elem)` does not work because `elem` does not have type `arr.T` + // but we can use `exists` instead, which is how `ArrayOps#contains` itself is implemented: + genericArrayOps(arr).exists(_ == elem) + + /** Copy elements of this array to another array. */ + extension [T](arr: IArray[T]) def copyToArray[U >: T](xs: Array[U]): Int = + genericArrayOps(arr).copyToArray(xs) + + /** Copy elements of this array to another array. */ + extension [T](arr: IArray[T]) def copyToArray[U >: T](xs: Array[U], start: Int): Int = + genericArrayOps(arr).copyToArray(xs, start) + + /** Copy elements of this array to another array. */ + extension [T](arr: IArray[T]) def copyToArray[U >: T](xs: Array[U], start: Int, len: Int): Int = + genericArrayOps(arr).copyToArray(xs, start, len) + + /** Counts the number of elements in this array which satisfy a predicate */ + extension [T](arr: IArray[T]) def count(p: T => Boolean): Int = + genericArrayOps(arr).count(p) + + /** The rest of the array without its `n` first elements. */ + extension [T](arr: IArray[T]) def drop(n: Int): IArray[T] = + genericArrayOps(arr).drop(n) + + /** The rest of the array without its `n` last elements. */ + extension [T](arr: IArray[T]) def dropRight(n: Int): IArray[T] = + genericArrayOps(arr).dropRight(n) + + /** Drops longest prefix of elements that satisfy a predicate. */ + extension [T](arr: IArray[T]) def dropWhile(p: T => Boolean): IArray[T] = + genericArrayOps(arr).dropWhile(p) + + /** Tests whether a predicate holds for at least one element of this array. */ + extension [T](arr: IArray[T]) def exists(p: T => Boolean): Boolean = + genericArrayOps(arr).exists(p) + + /** Selects all elements of this array which satisfy a predicate. */ + extension [T](arr: IArray[T]) def filter(p: T => Boolean): IArray[T] = + genericArrayOps(arr).filter(p) + + /** Selects all elements of this array which do not satisfy a predicate. */ + extension [T](arr: IArray[T]) def filterNot(p: T => Boolean): IArray[T] = + genericArrayOps(arr).filterNot(p) + + /** Finds the first element of the array satisfying a predicate, if any. */ + extension [T](arr: IArray[T]) def find(p: T => Boolean): Option[T] = + genericArrayOps(arr).find(p) + + /** Builds a new array by applying a function to all elements of this array + * and using the elements of the resulting collections. */ + extension [T](arr: IArray[T]) def flatMap[U: ClassTag](f: T => IterableOnce[U]): IArray[U] = + genericArrayOps(arr).flatMap(f) + + /** Flattens a two-dimensional array by concatenating all its rows + * into a single array. */ + extension [T](arr: IArray[T]) def flatten[U: ClassTag](using T => Iterable[U]): IArray[U] = + genericArrayOps(arr).flatten + + /** Folds the elements of this array using the specified associative binary operator. */ + extension [T](arr: IArray[T]) def fold[U >: T: ClassTag](z: U)(op: (U, U) => U): U = + genericArrayOps(arr).fold(z)(op) + + /** Applies a binary operator to a start value and all elements of this array, + * going left to right. */ + extension [T](arr: IArray[T]) def foldLeft[U: ClassTag](z: U)(op: (U, T) => U): U = + genericArrayOps(arr).foldLeft(z)(op) + + /** Applies a binary operator to all elements of this array and a start value, + * going right to left. */ + extension [T](arr: IArray[T]) def foldRight[U: ClassTag](z: U)(op: (T, U) => U): U = + genericArrayOps(arr).foldRight(z)(op) + + /** Tests whether a predicate holds for all elements of this array. */ + extension [T](arr: IArray[T]) def forall(p: T => Boolean): Boolean = + genericArrayOps(arr).forall(p) + + /** Apply `f` to each element for its side effects. */ + extension [T](arr: IArray[T]) def foreach[U](f: T => U): Unit = + genericArrayOps(arr).foreach(f) + + /** Selects the first element of this array. */ + extension [T](arr: IArray[T]) def head: T = + genericArrayOps(arr).head + + /** Optionally selects the first element. */ + extension [T](arr: IArray[T]) def headOption: Option[T] = + genericArrayOps(arr).headOption + + /** Finds index of first occurrence of some value in this array after or at some start index. */ + extension [T](arr: IArray[T]) def indexOf(elem: T, from: Int = 0): Int = + // `asInstanceOf` needed because `elem` does not have type `arr.T` + // We could use `arr.iterator.indexOf(elem, from)` or `arr.indexWhere(_ == elem, from)` + // but these would incur some overhead. + genericArrayOps(arr).indexOf(elem.asInstanceOf, from) + + /** Finds index of the first element satisfying some predicate after or at some start index. */ + extension [T](arr: IArray[T]) def indexWhere(p: T => Boolean, from: Int = 0): Int = + genericArrayOps(arr).indexWhere(p, from) + + /** Produces the range of all indices of this sequence. */ + extension [T](arr: IArray[T]) def indices: Range = + genericArrayOps(arr).indices + + /** The initial part of the array without its last element. */ + extension [T](arr: IArray[T]) def init: IArray[T] = + genericArrayOps(arr).init + + /** Tests whether the array is empty. */ + extension [T](arr: IArray[T]) def isEmpty: Boolean = + genericArrayOps(arr).isEmpty + + /** An iterator yielding the elemenst of this array. */ + extension [T](arr: IArray[T]) def iterator: Iterator[T] = + genericArrayOps(arr).iterator + + /** Selects the last element. */ + extension [T](arr: IArray[T]) def last: T = + genericArrayOps(arr).last + + /** Optionally selects the last element. */ + extension [T](arr: IArray[T]) def lastOption: Option[T] = + genericArrayOps(arr).lastOption + + /** Finds index of last occurrence of some value in this array before or at a given end index. */ + extension [T](arr: IArray[T]) def lastIndexOf(elem: T, end: Int = arr.length - 1): Int = + // see: same issue in `indexOf` + genericArrayOps(arr).lastIndexOf(elem.asInstanceOf, end) + + /** Finds index of last element satisfying some predicate before or at given end index. */ + extension [T](arr: IArray[T]) def lastIndexWhere(p: T => Boolean, end: Int = arr.length - 1): Int = + genericArrayOps(arr).lastIndexWhere(p, end) + + /** Builds a new array by applying a function to all elements of this array. */ + extension [T](arr: IArray[T]) def map[U: ClassTag](f: T => U): IArray[U] = + genericArrayOps(arr).map(f) + + /** Tests whether the array is not empty. */ + extension [T](arr: IArray[T]) def nonEmpty: Boolean = + genericArrayOps(arr).nonEmpty + + /** A pair of, first, all elements that satisfy predicate `p` and, second, all elements that do not. */ + extension [T](arr: IArray[T]) def partition(p: T => Boolean): (IArray[T], IArray[T]) = + genericArrayOps(arr).partition(p) + + /** Returns a new array with the elements in reversed order. */ + extension [T](arr: IArray[T]) def reverse: IArray[T] = + genericArrayOps(arr).reverse + + /** Computes a prefix scan of the elements of the array. */ + extension [T](arr: IArray[T]) def scan[U >: T: ClassTag](z: U)(op: (U, U) => U): IArray[U] = + genericArrayOps(arr).scan(z)(op) + + /** Produces an array containing cumulative results of applying the binary + * operator going left to right. */ + extension [T](arr: IArray[T]) def scanLeft[U: ClassTag](z: U)(op: (U, T) => U): IArray[U] = + genericArrayOps(arr).scanLeft(z)(op) + + /** Produces an array containing cumulative results of applying the binary + * operator going right to left. */ + extension [T](arr: IArray[T]) def scanRight[U: ClassTag](z: U)(op: (T, U) => U): IArray[U] = + genericArrayOps(arr).scanRight(z)(op) + + /** The size of this array. */ + extension [T](arr: IArray[T]) def size: Int = + arr.length + + /** Selects the interval of elements between the given indices. */ + extension [T](arr: IArray[T]) def slice(from: Int, until: Int): IArray[T] = + genericArrayOps(arr).slice(from, until) + + /** Sorts this array according to the Ordering which results from transforming + * an implicitly given Ordering with a transformation function. */ + extension [T](arr: IArray[T]) def sortBy[U: ClassTag](f: T => U)(using math.Ordering[U]): IArray[T] = + genericArrayOps(arr).sortBy(f) + + /** Sorts this array according to a comparison function. */ + extension [T](arr: IArray[T]) def sortWith(f: (T, T) => Boolean): IArray[T] = + genericArrayOps(arr).sortWith(f) + + /** Sorts this array according to an Ordering. */ + extension [T](arr: IArray[T]) def sorted(using math.Ordering[T]): IArray[T] = + genericArrayOps(arr).sorted + + /** Splits this array into a prefix/suffix pair according to a predicate. */ + extension [T](arr: IArray[T]) def span(p: T => Boolean): (IArray[T], IArray[T]) = + genericArrayOps(arr).span(p) + + /** Splits this array into two at a given position. */ + extension [T](arr: IArray[T]) def splitAt(n: Int): (IArray[T], IArray[T]) = + genericArrayOps(arr).splitAt(n) + + /** Tests whether this array starts with the given array. */ + extension [T](arr: IArray[T]) def startsWith[U >: T: ClassTag](that: IArray[U], offset: Int = 0): Boolean = + genericArrayOps(arr).startsWith(that) + + /** The rest of the array without its first element. */ + extension [T](arr: IArray[T]) def tail: IArray[T] = + genericArrayOps(arr).tail + + /** An array containing the first `n` elements of this array. */ + extension [T](arr: IArray[T]) def take(n: Int): IArray[T] = + genericArrayOps(arr).take(n) + + /** An array containing the last `n` elements of this array. */ + extension [T](arr: IArray[T]) def takeRight(n: Int): IArray[T] = + genericArrayOps(arr).takeRight(n) + + /** Takes longest prefix of elements that satisfy a predicate. */ + extension [T](arr: IArray[T]) def takeWhile(p: T => Boolean): IArray[T] = + genericArrayOps(arr).takeWhile(p) + + /** Returns a mutable copy of this immutable array. */ + extension [T](arr: IArray[T]) def toArray: Array[T] = + arr.clone.asInstanceOf[Array[T]] + + /** Converts an array of pairs into an array of first elements and an array of second elements. */ + extension [U: ClassTag, V: ClassTag](arr: IArray[(U, V)]) def unzip: (IArray[U], IArray[V]) = + genericArrayOps(arr).unzip + + /** Returns an array formed from this array and another iterable collection + * by combining corresponding elements in pairs. + * If one of the two collections is longer than the other, its remaining elements are ignored. */ + extension [T](arr: IArray[T]) def zip[U: ClassTag](that: IArray[U]): IArray[(T, U)] = + genericArrayOps(arr).zip(that) + end opaques type IArray[+T] = opaques.IArray[T]