From d21d32ea27e0f04946179d8aee11b23ffb8f1344 Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Sun, 1 Dec 2019 16:37:01 +0100 Subject: [PATCH 01/12] Add map extension method to DynamicTuple --- library/src/scala/runtime/DynamicTuple.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/library/src/scala/runtime/DynamicTuple.scala b/library/src/scala/runtime/DynamicTuple.scala index 53d44f75d449..0eb342a0edc3 100644 --- a/library/src/scala/runtime/DynamicTuple.scala +++ b/library/src/scala/runtime/DynamicTuple.scala @@ -1,8 +1,15 @@ package scala.runtime import scala.Tuple.{ Concat, Size, Head, Tail, Elem, Zip, Map } +import scala.reflect.ClassTag object DynamicTuple { + + given iarrayOps: [T](arr: IArray[T]) { + def map[U: ClassTag](f: T => U): IArray[U] = + arr.asInstanceOf[Array[T]].map(f).asInstanceOf[IArray[U]] + } + inline val MaxSpecialized = 22 inline private val XXL = MaxSpecialized + 1 From a9ba00e87ae54ca9e1245e6768802542ba31a230 Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Wed, 11 Dec 2019 21:16:03 +0100 Subject: [PATCH 02/12] Add all common methods of Scala2's ArrayOps to the IArray extension methods --- library/src/scala/runtime/DynamicTuple.scala | 154 ++++++++++++++++++- 1 file changed, 153 insertions(+), 1 deletion(-) diff --git a/library/src/scala/runtime/DynamicTuple.scala b/library/src/scala/runtime/DynamicTuple.scala index 0eb342a0edc3..22e301477a13 100644 --- a/library/src/scala/runtime/DynamicTuple.scala +++ b/library/src/scala/runtime/DynamicTuple.scala @@ -6,8 +6,160 @@ import scala.reflect.ClassTag object DynamicTuple { given iarrayOps: [T](arr: IArray[T]) { + def ++[U >: T: ClassTag](that: IArray[U]): IArray[U] = + (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf + + def contains(elem: T): Boolean = + arr.asInstanceOf[Array[T]].contains(elem) + + def count(p: T => Boolean): Int = + arr.asInstanceOf[Array[T]].count(p) + + def drop(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].drop(n).asInstanceOf + + def dropRight(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf + + def dropWhile(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf + + def exists(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].exists(p).asInstanceOf + + def filter(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].filter(p).asInstanceOf + + def filterNot(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf + + def find(p: T => Boolean): Option[T] = + arr.asInstanceOf[Array[T]].find(p).asInstanceOf + + def flatMap[U: ClassTag](f: T => IterableOnce[U]): IArray[U] = + arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf + + def flatten[U: ClassTag](given T => Iterable[U]): IArray[U] = + arr.asInstanceOf[Array[T]].flatten.asInstanceOf + + def fold[U >: T: ClassTag](z: U)(op: (U, U) => U): U = + arr.asInstanceOf[Array[T]].fold(z)(op).asInstanceOf + + def foldLeft[U >: T: ClassTag](z: U)(op: (U, T) => U): U = + arr.asInstanceOf[Array[T]].foldLeft(z)(op).asInstanceOf + + def foldRight[U >: T: ClassTag](z: U)(op: (T, U) => U): U = + arr.asInstanceOf[Array[T]].foldRight(z)(op).asInstanceOf + + def forall(p: T => Boolean): Boolean = + arr.asInstanceOf[Array[T]].forall(p) + + def foreach[U](f: T => U): Unit = + arr.asInstanceOf[Array[T]].foreach(f) + + def head: T = + arr.asInstanceOf[Array[T]].head + + def headOption: Option[T] = + arr.asInstanceOf[Array[T]].headOption + + def indexOf(elem: T, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].indexOf(elem, from) + + def indexWhere(p: T => Boolean, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].indexWhere(p, from) + + def indices: Range = + arr.asInstanceOf[Array[T]].indices.asInstanceOf + + def init: IArray[T] = + arr.asInstanceOf[Array[T]].init.asInstanceOf + + def isEmpty: Boolean = + arr.asInstanceOf[Array[T]].isEmpty + + def iterator: Iterator[T] = + arr.asInstanceOf[Array[T]].iterator + + def last: T = + arr.asInstanceOf[Array[T]].last + + def lastOption: Option[T] = + arr.asInstanceOf[Array[T]].lastOption + + def lastIndexOf(elem: T, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].lastIndexOf(elem, from) + + def lastIndexWhere(p: T => Boolean, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].lastIndexWhere(p, from) + def map[U: ClassTag](f: T => U): IArray[U] = - arr.asInstanceOf[Array[T]].map(f).asInstanceOf[IArray[U]] + arr.asInstanceOf[Array[T]].map(f).asInstanceOf + + def nonEmpty: Boolean = + arr.asInstanceOf[Array[T]].nonEmpty + + def partition(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].partition(p) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def reverse: IArray[T] = + arr.asInstanceOf[Array[T]].reverse.asInstanceOf + + def scan[U >: T: ClassTag](z: U)(op: (U, U) => U): Array[U] = + arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf + + def scanLeft[U: ClassTag](z: U)(op: (U, T) => U): Array[U] = + arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf + + def scanRight[U: ClassTag](z: U)(op: (T, U) => U): Array[U] = + arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf + + def size: Int = + arr.asInstanceOf[Array[T]].size + + def slice(from: Int, until: Int): Array[T] = + arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf + + def sortBy[U: ClassTag](f: T => U)(given math.Ordering[U]): IArray[T] = + arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf + + def sortWith(f: (T, T) => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf + + def sorted(given math.Ordering[T]): IArray[T] = + arr.asInstanceOf[Array[T]].sorted.asInstanceOf + + def span(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].span(p) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def splitAt(n: Int): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].splitAt(n) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def startsWith[U >: T: ClassTag](that: IArray[U], offset: Int = 0): Boolean = + arr.asInstanceOf[Array[T]].startsWith(that.asInstanceOf[Array[U]]) + + def tail: IArray[T] = + arr.asInstanceOf[Array[T]].tail.asInstanceOf + + def take(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].take(n).asInstanceOf + + def takeRight(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf + + def takeWhile(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf + + def unzip[U: ClassTag, V: ClassTag](given T => (U, V)): (IArray[U], IArray[V]) = + arr.asInstanceOf[Array[T]].unzip(asPair, ct1, ct2) match { + case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) + } + + def zip[U: ClassTag](that: IterableOnce[U]): IArray[(T, U)] = + arr.asInstanceOf[Array[T]].zip(that).asInstanceOf } inline val MaxSpecialized = 22 From 7444d02afde3f63bbab7a08b0640d689301e277a Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Thu, 12 Dec 2019 21:07:39 +0100 Subject: [PATCH 03/12] Move extension methods to IArray class --- library/src-bootstrapped/scala/IArray.scala | 161 +++++++++++++++++++ library/src/scala/runtime/DynamicTuple.scala | 157 ------------------ 2 files changed, 161 insertions(+), 157 deletions(-) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index 85b7188c49a0..b1f07a869697 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -223,4 +223,165 @@ object IArray { * @return sequence wrapped in a [[scala.Some]], if `x` is a Seq, otherwise `None` */ def unapplySeq[T](x: IArray[T]) = Array.unapplySeq[T](x.asInstanceOf[Array[T]]) + + + + /** All the methods on Array[T] that don't mutate in-place can be used with IArray[T]. + */ + given arrayOps: [T](arr: IArray[T]) { + def ++[U >: T: ClassTag](that: IArray[U]): IArray[U] = + (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf + + def contains(elem: T): Boolean = + arr.asInstanceOf[Array[T]].contains(elem) + + def count(p: T => Boolean): Int = + arr.asInstanceOf[Array[T]].count(p) + + def drop(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].drop(n).asInstanceOf + + def dropRight(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf + + def dropWhile(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf + + def exists(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].exists(p).asInstanceOf + + def filter(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].filter(p).asInstanceOf + + def filterNot(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf + + def find(p: T => Boolean): Option[T] = + arr.asInstanceOf[Array[T]].find(p).asInstanceOf + + def flatMap[U: ClassTag](f: T => IterableOnce[U]): IArray[U] = + arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf + + def flatten[U: ClassTag](given T => Iterable[U]): IArray[U] = + arr.asInstanceOf[Array[T]].flatten.asInstanceOf + + def fold[U >: T: ClassTag](z: U)(op: (U, U) => U): U = + arr.asInstanceOf[Array[T]].fold(z)(op).asInstanceOf + + def foldLeft[U >: T: ClassTag](z: U)(op: (U, T) => U): U = + arr.asInstanceOf[Array[T]].foldLeft(z)(op).asInstanceOf + + def foldRight[U >: T: ClassTag](z: U)(op: (T, U) => U): U = + arr.asInstanceOf[Array[T]].foldRight(z)(op).asInstanceOf + + def forall(p: T => Boolean): Boolean = + arr.asInstanceOf[Array[T]].forall(p) + + def foreach[U](f: T => U): Unit = + arr.asInstanceOf[Array[T]].foreach(f) + + def head: T = + arr.asInstanceOf[Array[T]].head + + def headOption: Option[T] = + arr.asInstanceOf[Array[T]].headOption + + def indexOf(elem: T, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].indexOf(elem, from) + + def indexWhere(p: T => Boolean, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].indexWhere(p, from) + + def indices: Range = + arr.asInstanceOf[Array[T]].indices.asInstanceOf + + def init: IArray[T] = + arr.asInstanceOf[Array[T]].init.asInstanceOf + + def isEmpty: Boolean = + arr.asInstanceOf[Array[T]].isEmpty + + def iterator: Iterator[T] = + arr.asInstanceOf[Array[T]].iterator + + def last: T = + arr.asInstanceOf[Array[T]].last + + def lastOption: Option[T] = + arr.asInstanceOf[Array[T]].lastOption + + def lastIndexOf(elem: T, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].lastIndexOf(elem, from) + + def lastIndexWhere(p: T => Boolean, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].lastIndexWhere(p, from) + + def map[U: ClassTag](f: T => U): IArray[U] = + arr.asInstanceOf[Array[T]].map(f).asInstanceOf + + def nonEmpty: Boolean = + arr.asInstanceOf[Array[T]].nonEmpty + + def partition(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].partition(p) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def reverse: IArray[T] = + arr.asInstanceOf[Array[T]].reverse.asInstanceOf + + def scan[U >: T: ClassTag](z: U)(op: (U, U) => U): Array[U] = + arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf + + def scanLeft[U: ClassTag](z: U)(op: (U, T) => U): Array[U] = + arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf + + def scanRight[U: ClassTag](z: U)(op: (T, U) => U): Array[U] = + arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf + + def size: Int = + arr.asInstanceOf[Array[T]].size + + def slice(from: Int, until: Int): Array[T] = + arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf + + def sortBy[U: ClassTag](f: T => U)(given math.Ordering[U]): IArray[T] = + arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf + + def sortWith(f: (T, T) => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf + + def sorted(given math.Ordering[T]): IArray[T] = + arr.asInstanceOf[Array[T]].sorted.asInstanceOf + + def span(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].span(p) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def splitAt(n: Int): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].splitAt(n) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def startsWith[U >: T: ClassTag](that: IArray[U], offset: Int = 0): Boolean = + arr.asInstanceOf[Array[T]].startsWith(that.asInstanceOf[Array[U]]) + + def tail: IArray[T] = + arr.asInstanceOf[Array[T]].tail.asInstanceOf + + def take(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].take(n).asInstanceOf + + def takeRight(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf + + def takeWhile(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf + + def unzip[U: ClassTag, V: ClassTag](given T => (U, V)): (IArray[U], IArray[V]) = + arr.asInstanceOf[Array[T]].unzip(asPair, ct1, ct2) match { + case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) + } + + def zip[U: ClassTag](that: IterableOnce[U]): IArray[(T, U)] = + arr.asInstanceOf[Array[T]].zip(that).asInstanceOf + } } \ No newline at end of file diff --git a/library/src/scala/runtime/DynamicTuple.scala b/library/src/scala/runtime/DynamicTuple.scala index 22e301477a13..494cdcac783c 100644 --- a/library/src/scala/runtime/DynamicTuple.scala +++ b/library/src/scala/runtime/DynamicTuple.scala @@ -5,163 +5,6 @@ import scala.reflect.ClassTag object DynamicTuple { - given iarrayOps: [T](arr: IArray[T]) { - def ++[U >: T: ClassTag](that: IArray[U]): IArray[U] = - (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf - - def contains(elem: T): Boolean = - arr.asInstanceOf[Array[T]].contains(elem) - - def count(p: T => Boolean): Int = - arr.asInstanceOf[Array[T]].count(p) - - def drop(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].drop(n).asInstanceOf - - def dropRight(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf - - def dropWhile(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf - - def exists(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].exists(p).asInstanceOf - - def filter(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].filter(p).asInstanceOf - - def filterNot(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf - - def find(p: T => Boolean): Option[T] = - arr.asInstanceOf[Array[T]].find(p).asInstanceOf - - def flatMap[U: ClassTag](f: T => IterableOnce[U]): IArray[U] = - arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf - - def flatten[U: ClassTag](given T => Iterable[U]): IArray[U] = - arr.asInstanceOf[Array[T]].flatten.asInstanceOf - - def fold[U >: T: ClassTag](z: U)(op: (U, U) => U): U = - arr.asInstanceOf[Array[T]].fold(z)(op).asInstanceOf - - def foldLeft[U >: T: ClassTag](z: U)(op: (U, T) => U): U = - arr.asInstanceOf[Array[T]].foldLeft(z)(op).asInstanceOf - - def foldRight[U >: T: ClassTag](z: U)(op: (T, U) => U): U = - arr.asInstanceOf[Array[T]].foldRight(z)(op).asInstanceOf - - def forall(p: T => Boolean): Boolean = - arr.asInstanceOf[Array[T]].forall(p) - - def foreach[U](f: T => U): Unit = - arr.asInstanceOf[Array[T]].foreach(f) - - def head: T = - arr.asInstanceOf[Array[T]].head - - def headOption: Option[T] = - arr.asInstanceOf[Array[T]].headOption - - def indexOf(elem: T, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].indexOf(elem, from) - - def indexWhere(p: T => Boolean, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].indexWhere(p, from) - - def indices: Range = - arr.asInstanceOf[Array[T]].indices.asInstanceOf - - def init: IArray[T] = - arr.asInstanceOf[Array[T]].init.asInstanceOf - - def isEmpty: Boolean = - arr.asInstanceOf[Array[T]].isEmpty - - def iterator: Iterator[T] = - arr.asInstanceOf[Array[T]].iterator - - def last: T = - arr.asInstanceOf[Array[T]].last - - def lastOption: Option[T] = - arr.asInstanceOf[Array[T]].lastOption - - def lastIndexOf(elem: T, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].lastIndexOf(elem, from) - - def lastIndexWhere(p: T => Boolean, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].lastIndexWhere(p, from) - - def map[U: ClassTag](f: T => U): IArray[U] = - arr.asInstanceOf[Array[T]].map(f).asInstanceOf - - def nonEmpty: Boolean = - arr.asInstanceOf[Array[T]].nonEmpty - - def partition(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].partition(p) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } - - def reverse: IArray[T] = - arr.asInstanceOf[Array[T]].reverse.asInstanceOf - - def scan[U >: T: ClassTag](z: U)(op: (U, U) => U): Array[U] = - arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf - - def scanLeft[U: ClassTag](z: U)(op: (U, T) => U): Array[U] = - arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf - - def scanRight[U: ClassTag](z: U)(op: (T, U) => U): Array[U] = - arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf - - def size: Int = - arr.asInstanceOf[Array[T]].size - - def slice(from: Int, until: Int): Array[T] = - arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf - - def sortBy[U: ClassTag](f: T => U)(given math.Ordering[U]): IArray[T] = - arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf - - def sortWith(f: (T, T) => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf - - def sorted(given math.Ordering[T]): IArray[T] = - arr.asInstanceOf[Array[T]].sorted.asInstanceOf - - def span(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].span(p) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } - - def splitAt(n: Int): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].splitAt(n) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } - - def startsWith[U >: T: ClassTag](that: IArray[U], offset: Int = 0): Boolean = - arr.asInstanceOf[Array[T]].startsWith(that.asInstanceOf[Array[U]]) - - def tail: IArray[T] = - arr.asInstanceOf[Array[T]].tail.asInstanceOf - - def take(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].take(n).asInstanceOf - - def takeRight(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf - - def takeWhile(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf - - def unzip[U: ClassTag, V: ClassTag](given T => (U, V)): (IArray[U], IArray[V]) = - arr.asInstanceOf[Array[T]].unzip(asPair, ct1, ct2) match { - case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) - } - - def zip[U: ClassTag](that: IterableOnce[U]): IArray[(T, U)] = - arr.asInstanceOf[Array[T]].zip(that).asInstanceOf - } - inline val MaxSpecialized = 22 inline private val XXL = MaxSpecialized + 1 From 9b62e78b03992ed6f540c1bb4adb299c679f13be Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Thu, 12 Dec 2019 21:34:27 +0100 Subject: [PATCH 04/12] Adapt the extension to the (yet) new syntax --- library/src-bootstrapped/scala/IArray.scala | 119 ++++++++++---------- 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index b1f07a869697..7deb539c8fbc 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -228,160 +228,163 @@ object IArray { /** All the methods on Array[T] that don't mutate in-place can be used with IArray[T]. */ - given arrayOps: [T](arr: IArray[T]) { - def ++[U >: T: ClassTag](that: IArray[U]): IArray[U] = + given arrayOps: Object { + def [T, U >: T: ClassTag](arr: IArray[T]) ++(that: IArray[U]): IArray[U] = (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf - def contains(elem: T): Boolean = + def [T](arr: IArray[T])contains(elem: T): Boolean = arr.asInstanceOf[Array[T]].contains(elem) - def count(p: T => Boolean): Int = + def [T](arr: IArray[T]) count(p: T => Boolean): Int = arr.asInstanceOf[Array[T]].count(p) - def drop(n: Int): IArray[T] = + def [T](arr: IArray[T]) drop(n: Int): IArray[T] = arr.asInstanceOf[Array[T]].drop(n).asInstanceOf - def dropRight(n: Int): IArray[T] = + def [T](arr: IArray[T]) dropRight(n: Int): IArray[T] = arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf - def dropWhile(p: T => Boolean): IArray[T] = + def [T](arr: IArray[T]) dropWhile(p: T => Boolean): IArray[T] = arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf - def exists(p: T => Boolean): IArray[T] = + def [T](arr: IArray[T]) exists(p: T => Boolean): IArray[T] = arr.asInstanceOf[Array[T]].exists(p).asInstanceOf - def filter(p: T => Boolean): IArray[T] = + def [T](arr: IArray[T]) filter(p: T => Boolean): IArray[T] = arr.asInstanceOf[Array[T]].filter(p).asInstanceOf - def filterNot(p: T => Boolean): IArray[T] = + def [T](arr: IArray[T]) filterNot(p: T => Boolean): IArray[T] = arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf - def find(p: T => Boolean): Option[T] = + def [T](arr: IArray[T]) find(p: T => Boolean): Option[T] = arr.asInstanceOf[Array[T]].find(p).asInstanceOf - def flatMap[U: ClassTag](f: T => IterableOnce[U]): IArray[U] = + def [T, U: ClassTag](arr: IArray[T]) flatMap(f: T => IterableOnce[U]): IArray[U] = arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf - def flatten[U: ClassTag](given T => Iterable[U]): IArray[U] = + def [T, U: ClassTag](arr: IArray[T]) flatten(given T => Iterable[U]): IArray[U] = arr.asInstanceOf[Array[T]].flatten.asInstanceOf - def fold[U >: T: ClassTag](z: U)(op: (U, U) => U): U = + def [T, U >: T: ClassTag](arr: IArray[T]) fold(z: U)(op: (U, U) => U): U = arr.asInstanceOf[Array[T]].fold(z)(op).asInstanceOf - def foldLeft[U >: T: ClassTag](z: U)(op: (U, T) => U): U = + def [T, U >: T: ClassTag](arr: IArray[T]) foldLeft(z: U)(op: (U, T) => U): U = arr.asInstanceOf[Array[T]].foldLeft(z)(op).asInstanceOf - def foldRight[U >: T: ClassTag](z: U)(op: (T, U) => U): U = + def [T, U >: T: ClassTag](arr: IArray[T]) foldRight(z: U)(op: (T, U) => U): U = arr.asInstanceOf[Array[T]].foldRight(z)(op).asInstanceOf - def forall(p: T => Boolean): Boolean = + def [T](arr: IArray[T]) forall(p: T => Boolean): Boolean = arr.asInstanceOf[Array[T]].forall(p) - def foreach[U](f: T => U): Unit = + def [T, U](arr: IArray[T]) foreach(f: T => U): Unit = arr.asInstanceOf[Array[T]].foreach(f) - def head: T = + def [T](arr: IArray[T]) head: T = arr.asInstanceOf[Array[T]].head - def headOption: Option[T] = + def [T](arr: IArray[T]) headOption: Option[T] = arr.asInstanceOf[Array[T]].headOption - def indexOf(elem: T, from: Int = 0): Int = + def [T](arr: IArray[T]) indexOf(elem: T, from: Int = 0): Int = arr.asInstanceOf[Array[T]].indexOf(elem, from) - def indexWhere(p: T => Boolean, from: Int = 0): Int = + def [T](arr: IArray[T]) indexWhere(p: T => Boolean, from: Int = 0): Int = arr.asInstanceOf[Array[T]].indexWhere(p, from) - def indices: Range = + def [T](arr: IArray[T]) indices: Range = arr.asInstanceOf[Array[T]].indices.asInstanceOf - def init: IArray[T] = + def [T](arr: IArray[T]) init: IArray[T] = arr.asInstanceOf[Array[T]].init.asInstanceOf - def isEmpty: Boolean = + def [T](arr: IArray[T]) isEmpty: Boolean = arr.asInstanceOf[Array[T]].isEmpty - def iterator: Iterator[T] = + def [T](arr: IArray[T]) iterator: Iterator[T] = arr.asInstanceOf[Array[T]].iterator - def last: T = + def [T](arr: IArray[T]) last: T = arr.asInstanceOf[Array[T]].last - def lastOption: Option[T] = + def [T](arr: IArray[T]) lastOption: Option[T] = arr.asInstanceOf[Array[T]].lastOption - def lastIndexOf(elem: T, from: Int = 0): Int = + def [T](arr: IArray[T]) lastIndexOf(elem: T, from: Int = 0): Int = arr.asInstanceOf[Array[T]].lastIndexOf(elem, from) - def lastIndexWhere(p: T => Boolean, from: Int = 0): Int = + def [T](arr: IArray[T]) lastIndexWhere(p: T => Boolean, from: Int = 0): Int = arr.asInstanceOf[Array[T]].lastIndexWhere(p, from) - def map[U: ClassTag](f: T => U): IArray[U] = + def [T, U: ClassTag](arr: IArray[T]) map(f: T => U): IArray[U] = arr.asInstanceOf[Array[T]].map(f).asInstanceOf - def nonEmpty: Boolean = + def [T](arr: IArray[T]) nonEmpty: Boolean = arr.asInstanceOf[Array[T]].nonEmpty - def partition(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].partition(p) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } + def [T](arr: IArray[T]) partition(p: T => Boolean): (IArray[T], IArray[T]) = + arr.asInstanceOf[Array[T]].partition(p) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } - def reverse: IArray[T] = + def [T](arr: IArray[T]) reverse: IArray[T] = arr.asInstanceOf[Array[T]].reverse.asInstanceOf - def scan[U >: T: ClassTag](z: U)(op: (U, U) => U): Array[U] = + def [T, U >: T: ClassTag](arr: IArray[T]) scan(z: U)(op: (U, U) => U): Array[U] = arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf - def scanLeft[U: ClassTag](z: U)(op: (U, T) => U): Array[U] = + def [T, U: ClassTag](arr: IArray[T]) scanLeft(z: U)(op: (U, T) => U): Array[U] = arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf - def scanRight[U: ClassTag](z: U)(op: (T, U) => U): Array[U] = + def [T, U: ClassTag](arr: IArray[T]) scanRight(z: U)(op: (T, U) => U): Array[U] = arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf - def size: Int = + def [T](arr: IArray[T]) size: Int = arr.asInstanceOf[Array[T]].size - def slice(from: Int, until: Int): Array[T] = + def [T](arr: IArray[T]) slice(from: Int, until: Int): Array[T] = arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf - def sortBy[U: ClassTag](f: T => U)(given math.Ordering[U]): IArray[T] = + def [T, U: ClassTag](arr: IArray[T]) sortBy(f: T => U)(given math.Ordering[U]): IArray[T] = arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf - def sortWith(f: (T, T) => Boolean): IArray[T] = + def [T](arr: IArray[T]) sortWith(f: (T, T) => Boolean): IArray[T] = arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf - def sorted(given math.Ordering[T]): IArray[T] = + def [T](arr: IArray[T]) sorted(given math.Ordering[T]): IArray[T] = arr.asInstanceOf[Array[T]].sorted.asInstanceOf - def span(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].span(p) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } + def [T](arr: IArray[T]) span(p: T => Boolean): (IArray[T], IArray[T]) = + arr.asInstanceOf[Array[T]].span(p) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } - def splitAt(n: Int): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].splitAt(n) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } + def [T](arr: IArray[T]) splitAt(n: Int): (IArray[T], IArray[T]) = + arr.asInstanceOf[Array[T]].splitAt(n) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } - def startsWith[U >: T: ClassTag](that: IArray[U], offset: Int = 0): Boolean = + def [T, U >: T: ClassTag](arr: IArray[T]) startsWith(that: IArray[U], offset: Int = 0): Boolean = arr.asInstanceOf[Array[T]].startsWith(that.asInstanceOf[Array[U]]) - def tail: IArray[T] = + def [T](arr: IArray[T]) tail: IArray[T] = arr.asInstanceOf[Array[T]].tail.asInstanceOf - def take(n: Int): IArray[T] = + def [T](arr: IArray[T]) take(n: Int): IArray[T] = arr.asInstanceOf[Array[T]].take(n).asInstanceOf - def takeRight(n: Int): IArray[T] = + def [T](arr: IArray[T]) takeRight(n: Int): IArray[T] = arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf - def takeWhile(p: T => Boolean): IArray[T] = + def [T](arr: IArray[T]) takeWhile(p: T => Boolean): IArray[T] = arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf - def unzip[U: ClassTag, V: ClassTag](given T => (U, V)): (IArray[U], IArray[V]) = - arr.asInstanceOf[Array[T]].unzip(asPair, ct1, ct2) match { + def [T, U: ClassTag, V: ClassTag](arr: IArray[T]) unzip(given T => (U, V)): (IArray[U], IArray[V]) = + arr.asInstanceOf[Array[T]].unzip match { case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) } - def zip[U: ClassTag](that: IterableOnce[U]): IArray[(T, U)] = + def [T, U: ClassTag](arr: IArray[T]) zip(that: IterableOnce[U]): IArray[(T, U)] = arr.asInstanceOf[Array[T]].zip(that).asInstanceOf } } \ No newline at end of file From 777636f82016d7e6237c9b5690884d0639ea3c45 Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Sat, 14 Dec 2019 14:51:42 +0100 Subject: [PATCH 05/12] Add test file --- tests/run-bootstrapped/iarray-extmtds.check | 1 + tests/run-bootstrapped/iarray-extmtds.scala | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 tests/run-bootstrapped/iarray-extmtds.check create mode 100644 tests/run-bootstrapped/iarray-extmtds.scala diff --git a/tests/run-bootstrapped/iarray-extmtds.check b/tests/run-bootstrapped/iarray-extmtds.check new file mode 100644 index 000000000000..e4d79cc03ddb --- /dev/null +++ b/tests/run-bootstrapped/iarray-extmtds.check @@ -0,0 +1 @@ +IArray(1,2) \ No newline at end of file diff --git a/tests/run-bootstrapped/iarray-extmtds.scala b/tests/run-bootstrapped/iarray-extmtds.scala new file mode 100644 index 000000000000..466116d954f6 --- /dev/null +++ b/tests/run-bootstrapped/iarray-extmtds.scala @@ -0,0 +1,5 @@ + +object Test extends App { + val arr = IArray[Int](1, 2, 3) + println(arr.take(2)) +} From e47663c358a4f4c5b031d8703853e02381a35026 Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Sun, 15 Dec 2019 09:57:04 +0100 Subject: [PATCH 06/12] Made IArray extension methods compile --- library/src-bootstrapped/scala/IArray.scala | 324 ++++++++++---------- 1 file changed, 160 insertions(+), 164 deletions(-) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index 7deb539c8fbc..673cb98e3523 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -38,6 +38,166 @@ object opaques def (arr: IArray[Double]) length: Int = arr.asInstanceOf[Array[Double]].length def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length def [T](arr: IArray[T]) length: Int = arr.asInstanceOf[Array[T]].length + + /** All the methods on Array[T] that don't mutate in-place can be used with IArray[T]. + */ + def [T, U >: T: ClassTag](arr: IArray[T]) ++(that: IArray[U]): IArray[U] = + (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf + + def [T](arr: IArray[T])contains(elem: T): Boolean = + arr.asInstanceOf[Array[T]].contains(elem) + + def [T](arr: IArray[T]) count(p: T => Boolean): Int = + arr.asInstanceOf[Array[T]].count(p) + + def [T](arr: IArray[T]) drop(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].drop(n).asInstanceOf + + def [T](arr: IArray[T]) dropRight(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf + + def [T](arr: IArray[T]) dropWhile(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf + + def [T](arr: IArray[T]) exists(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].exists(p).asInstanceOf + + def [T](arr: IArray[T]) filter(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].filter(p).asInstanceOf + + def [T](arr: IArray[T]) filterNot(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf + + def [T](arr: IArray[T]) find(p: T => Boolean): Option[T] = + arr.asInstanceOf[Array[T]].find(p).asInstanceOf + + def [T, U: ClassTag](arr: IArray[T]) flatMap(f: T => IterableOnce[U]): IArray[U] = + arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf + + def [T, U: ClassTag](arr: IArray[T]) flatten(given T => Iterable[U]): IArray[U] = + arr.asInstanceOf[Array[T]].flatten.asInstanceOf + + def [T, U >: T: ClassTag](arr: IArray[T]) fold(z: U)(op: (U, U) => U): U = + arr.asInstanceOf[Array[T]].fold(z)(op).asInstanceOf + + def [T, U >: T: ClassTag](arr: IArray[T]) foldLeft(z: U)(op: (U, T) => U): U = + arr.asInstanceOf[Array[T]].foldLeft(z)(op).asInstanceOf + + def [T, U >: T: ClassTag](arr: IArray[T]) foldRight(z: U)(op: (T, U) => U): U = + arr.asInstanceOf[Array[T]].foldRight(z)(op).asInstanceOf + + def [T](arr: IArray[T]) forall(p: T => Boolean): Boolean = + arr.asInstanceOf[Array[T]].forall(p) + + def [T, U](arr: IArray[T]) foreach(f: T => U): Unit = + arr.asInstanceOf[Array[T]].foreach(f) + + def [T](arr: IArray[T]) head: T = + arr.asInstanceOf[Array[T]].head + + def [T](arr: IArray[T]) headOption: Option[T] = + arr.asInstanceOf[Array[T]].headOption + + def [T](arr: IArray[T]) indexOf(elem: T, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].indexOf(elem, from) + + def [T](arr: IArray[T]) indexWhere(p: T => Boolean, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].indexWhere(p, from) + + def [T](arr: IArray[T]) indices: Range = + arr.asInstanceOf[Array[T]].indices.asInstanceOf + + def [T](arr: IArray[T]) init: IArray[T] = + arr.asInstanceOf[Array[T]].init.asInstanceOf + + def [T](arr: IArray[T]) isEmpty: Boolean = + arr.asInstanceOf[Array[T]].isEmpty + + def [T](arr: IArray[T]) iterator: Iterator[T] = + arr.asInstanceOf[Array[T]].iterator + + def [T](arr: IArray[T]) last: T = + arr.asInstanceOf[Array[T]].last + + def [T](arr: IArray[T]) lastOption: Option[T] = + arr.asInstanceOf[Array[T]].lastOption + + def [T](arr: IArray[T]) lastIndexOf(elem: T, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].lastIndexOf(elem, from) + + def [T](arr: IArray[T]) lastIndexWhere(p: T => Boolean, from: Int = 0): Int = + arr.asInstanceOf[Array[T]].lastIndexWhere(p, from) + + def [T, U: ClassTag](arr: IArray[T]) map(f: T => U): IArray[U] = + arr.asInstanceOf[Array[T]].map(f).asInstanceOf + + def [T](arr: IArray[T]) nonEmpty: Boolean = + arr.asInstanceOf[Array[T]].nonEmpty + + def [T](arr: IArray[T]) partition(p: T => Boolean): (IArray[T], IArray[T]) = + arr.asInstanceOf[Array[T]].partition(p) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def [T](arr: IArray[T]) reverse: IArray[T] = + arr.asInstanceOf[Array[T]].reverse.asInstanceOf + + def [T, U >: T: ClassTag](arr: IArray[T]) scan(z: U)(op: (U, U) => U): Array[U] = + arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf + + def [T, U: ClassTag](arr: IArray[T]) scanLeft(z: U)(op: (U, T) => U): Array[U] = + arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf + + def [T, U: ClassTag](arr: IArray[T]) scanRight(z: U)(op: (T, U) => U): Array[U] = + arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf + + def [T](arr: IArray[T]) size: Int = + arr.asInstanceOf[Array[T]].size + + def [T](arr: IArray[T]) slice(from: Int, until: Int): Array[T] = + arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf + + def [T, U: ClassTag](arr: IArray[T]) sortBy(f: T => U)(given math.Ordering[U]): IArray[T] = + arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf + + def [T](arr: IArray[T]) sortWith(f: (T, T) => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf + + def [T](arr: IArray[T]) sorted(given math.Ordering[T]): IArray[T] = + arr.asInstanceOf[Array[T]].sorted.asInstanceOf + + def [T](arr: IArray[T]) span(p: T => Boolean): (IArray[T], IArray[T]) = + arr.asInstanceOf[Array[T]].span(p) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def [T](arr: IArray[T]) splitAt(n: Int): (IArray[T], IArray[T]) = + arr.asInstanceOf[Array[T]].splitAt(n) match { + case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) + } + + def [T, U >: T: ClassTag](arr: IArray[T]) startsWith(that: IArray[U], offset: Int = 0): Boolean = + arr.asInstanceOf[Array[T]].startsWith(that.asInstanceOf[Array[U]]) + + def [T](arr: IArray[T]) tail: IArray[T] = + arr.asInstanceOf[Array[T]].tail.asInstanceOf + + def [T](arr: IArray[T]) take(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].take(n).asInstanceOf + + def [T](arr: IArray[T]) takeRight(n: Int): IArray[T] = + arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf + + def [T](arr: IArray[T]) takeWhile(p: T => Boolean): IArray[T] = + arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf + + // def [T, U: ClassTag, V: ClassTag](arr: IArray[T]) unzip(given T => (U, V)): (IArray[U], IArray[V]) = + // arr.asInstanceOf[Array[T]].unzip match { + // case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) + // } + + def [T, U: ClassTag](arr: IArray[T]) zip(that: IterableOnce[U]): IArray[(T, U)] = + arr.asInstanceOf[Array[T]].zip(that).asInstanceOf end opaques type IArray[+T] = opaques.IArray[T] @@ -223,168 +383,4 @@ object IArray { * @return sequence wrapped in a [[scala.Some]], if `x` is a Seq, otherwise `None` */ def unapplySeq[T](x: IArray[T]) = Array.unapplySeq[T](x.asInstanceOf[Array[T]]) - - - - /** All the methods on Array[T] that don't mutate in-place can be used with IArray[T]. - */ - given arrayOps: Object { - def [T, U >: T: ClassTag](arr: IArray[T]) ++(that: IArray[U]): IArray[U] = - (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf - - def [T](arr: IArray[T])contains(elem: T): Boolean = - arr.asInstanceOf[Array[T]].contains(elem) - - def [T](arr: IArray[T]) count(p: T => Boolean): Int = - arr.asInstanceOf[Array[T]].count(p) - - def [T](arr: IArray[T]) drop(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].drop(n).asInstanceOf - - def [T](arr: IArray[T]) dropRight(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf - - def [T](arr: IArray[T]) dropWhile(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf - - def [T](arr: IArray[T]) exists(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].exists(p).asInstanceOf - - def [T](arr: IArray[T]) filter(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].filter(p).asInstanceOf - - def [T](arr: IArray[T]) filterNot(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf - - def [T](arr: IArray[T]) find(p: T => Boolean): Option[T] = - arr.asInstanceOf[Array[T]].find(p).asInstanceOf - - def [T, U: ClassTag](arr: IArray[T]) flatMap(f: T => IterableOnce[U]): IArray[U] = - arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf - - def [T, U: ClassTag](arr: IArray[T]) flatten(given T => Iterable[U]): IArray[U] = - arr.asInstanceOf[Array[T]].flatten.asInstanceOf - - def [T, U >: T: ClassTag](arr: IArray[T]) fold(z: U)(op: (U, U) => U): U = - arr.asInstanceOf[Array[T]].fold(z)(op).asInstanceOf - - def [T, U >: T: ClassTag](arr: IArray[T]) foldLeft(z: U)(op: (U, T) => U): U = - arr.asInstanceOf[Array[T]].foldLeft(z)(op).asInstanceOf - - def [T, U >: T: ClassTag](arr: IArray[T]) foldRight(z: U)(op: (T, U) => U): U = - arr.asInstanceOf[Array[T]].foldRight(z)(op).asInstanceOf - - def [T](arr: IArray[T]) forall(p: T => Boolean): Boolean = - arr.asInstanceOf[Array[T]].forall(p) - - def [T, U](arr: IArray[T]) foreach(f: T => U): Unit = - arr.asInstanceOf[Array[T]].foreach(f) - - def [T](arr: IArray[T]) head: T = - arr.asInstanceOf[Array[T]].head - - def [T](arr: IArray[T]) headOption: Option[T] = - arr.asInstanceOf[Array[T]].headOption - - def [T](arr: IArray[T]) indexOf(elem: T, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].indexOf(elem, from) - - def [T](arr: IArray[T]) indexWhere(p: T => Boolean, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].indexWhere(p, from) - - def [T](arr: IArray[T]) indices: Range = - arr.asInstanceOf[Array[T]].indices.asInstanceOf - - def [T](arr: IArray[T]) init: IArray[T] = - arr.asInstanceOf[Array[T]].init.asInstanceOf - - def [T](arr: IArray[T]) isEmpty: Boolean = - arr.asInstanceOf[Array[T]].isEmpty - - def [T](arr: IArray[T]) iterator: Iterator[T] = - arr.asInstanceOf[Array[T]].iterator - - def [T](arr: IArray[T]) last: T = - arr.asInstanceOf[Array[T]].last - - def [T](arr: IArray[T]) lastOption: Option[T] = - arr.asInstanceOf[Array[T]].lastOption - - def [T](arr: IArray[T]) lastIndexOf(elem: T, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].lastIndexOf(elem, from) - - def [T](arr: IArray[T]) lastIndexWhere(p: T => Boolean, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].lastIndexWhere(p, from) - - def [T, U: ClassTag](arr: IArray[T]) map(f: T => U): IArray[U] = - arr.asInstanceOf[Array[T]].map(f).asInstanceOf - - def [T](arr: IArray[T]) nonEmpty: Boolean = - arr.asInstanceOf[Array[T]].nonEmpty - - def [T](arr: IArray[T]) partition(p: T => Boolean): (IArray[T], IArray[T]) = - arr.asInstanceOf[Array[T]].partition(p) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } - - def [T](arr: IArray[T]) reverse: IArray[T] = - arr.asInstanceOf[Array[T]].reverse.asInstanceOf - - def [T, U >: T: ClassTag](arr: IArray[T]) scan(z: U)(op: (U, U) => U): Array[U] = - arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf - - def [T, U: ClassTag](arr: IArray[T]) scanLeft(z: U)(op: (U, T) => U): Array[U] = - arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf - - def [T, U: ClassTag](arr: IArray[T]) scanRight(z: U)(op: (T, U) => U): Array[U] = - arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf - - def [T](arr: IArray[T]) size: Int = - arr.asInstanceOf[Array[T]].size - - def [T](arr: IArray[T]) slice(from: Int, until: Int): Array[T] = - arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf - - def [T, U: ClassTag](arr: IArray[T]) sortBy(f: T => U)(given math.Ordering[U]): IArray[T] = - arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf - - def [T](arr: IArray[T]) sortWith(f: (T, T) => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf - - def [T](arr: IArray[T]) sorted(given math.Ordering[T]): IArray[T] = - arr.asInstanceOf[Array[T]].sorted.asInstanceOf - - def [T](arr: IArray[T]) span(p: T => Boolean): (IArray[T], IArray[T]) = - arr.asInstanceOf[Array[T]].span(p) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } - - def [T](arr: IArray[T]) splitAt(n: Int): (IArray[T], IArray[T]) = - arr.asInstanceOf[Array[T]].splitAt(n) match { - case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) - } - - def [T, U >: T: ClassTag](arr: IArray[T]) startsWith(that: IArray[U], offset: Int = 0): Boolean = - arr.asInstanceOf[Array[T]].startsWith(that.asInstanceOf[Array[U]]) - - def [T](arr: IArray[T]) tail: IArray[T] = - arr.asInstanceOf[Array[T]].tail.asInstanceOf - - def [T](arr: IArray[T]) take(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].take(n).asInstanceOf - - def [T](arr: IArray[T]) takeRight(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf - - def [T](arr: IArray[T]) takeWhile(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf - - def [T, U: ClassTag, V: ClassTag](arr: IArray[T]) unzip(given T => (U, V)): (IArray[U], IArray[V]) = - arr.asInstanceOf[Array[T]].unzip match { - case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) - } - - def [T, U: ClassTag](arr: IArray[T]) zip(that: IterableOnce[U]): IArray[(T, U)] = - arr.asInstanceOf[Array[T]].zip(that).asInstanceOf - } } \ No newline at end of file From 94439fc230a33ee1e7aa36560232d23b1765428e Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Tue, 17 Dec 2019 08:11:11 +0100 Subject: [PATCH 07/12] Fix unzip issue --- library/src-bootstrapped/scala/IArray.scala | 8 ++++---- tests/run-bootstrapped/iarray-extmtds.scala | 11 +++++++++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index 673cb98e3523..055ab1d11f1e 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -191,10 +191,10 @@ object opaques def [T](arr: IArray[T]) takeWhile(p: T => Boolean): IArray[T] = arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf - // def [T, U: ClassTag, V: ClassTag](arr: IArray[T]) unzip(given T => (U, V)): (IArray[U], IArray[V]) = - // arr.asInstanceOf[Array[T]].unzip match { - // case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) - // } + def [U: ClassTag, V: ClassTag](arr: IArray[(U, V)]) unzip: (IArray[U], IArray[V]) = + arr.asInstanceOf[Array[(U, V)]].unzip match { + case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) + } def [T, U: ClassTag](arr: IArray[T]) zip(that: IterableOnce[U]): IArray[(T, U)] = arr.asInstanceOf[Array[T]].zip(that).asInstanceOf diff --git a/tests/run-bootstrapped/iarray-extmtds.scala b/tests/run-bootstrapped/iarray-extmtds.scala index 466116d954f6..75cc08fcdeb7 100644 --- a/tests/run-bootstrapped/iarray-extmtds.scala +++ b/tests/run-bootstrapped/iarray-extmtds.scala @@ -1,5 +1,12 @@ object Test extends App { - val arr = IArray[Int](1, 2, 3) - println(arr.take(2)) + def assertNew[T, U](expr: => IArray[T], original: IArray[U]): Unit = { + val result = expr + assert(result ne original, "IArray was mutated in place") + println(result) + } + + val arr = Array[Int](1,2,3,4,5,6,7,8,9,10) + + assertNew(arr.filter(_ % 2 == 0), arr) } From 092a49d49787f0f2bd19f517a2b31373d7fe7b68 Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Tue, 17 Dec 2019 14:53:55 +0100 Subject: [PATCH 08/12] Add explicit type casts everywhere needed --- library/src-bootstrapped/scala/IArray.scala | 68 ++++++++++----------- tests/run-bootstrapped/iarray-extmtds.check | 12 +++- tests/run-bootstrapped/iarray-extmtds.scala | 38 ++++++++++-- 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index 055ab1d11f1e..f4f72f6d7da0 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -42,49 +42,49 @@ object opaques /** All the methods on Array[T] that don't mutate in-place can be used with IArray[T]. */ def [T, U >: T: ClassTag](arr: IArray[T]) ++(that: IArray[U]): IArray[U] = - (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf + (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf[IArray[U]] - def [T](arr: IArray[T])contains(elem: T): Boolean = + def [T](arr: IArray[T]) contains(elem: T): Boolean = arr.asInstanceOf[Array[T]].contains(elem) def [T](arr: IArray[T]) count(p: T => Boolean): Int = arr.asInstanceOf[Array[T]].count(p) def [T](arr: IArray[T]) drop(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].drop(n).asInstanceOf + arr.asInstanceOf[Array[T]].drop(n).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) dropRight(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf + arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) dropWhile(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf + arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) exists(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].exists(p).asInstanceOf + arr.asInstanceOf[Array[T]].exists(p).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) filter(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].filter(p).asInstanceOf + arr.asInstanceOf[Array[T]].filter(p).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) filterNot(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf + arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) find(p: T => Boolean): Option[T] = - arr.asInstanceOf[Array[T]].find(p).asInstanceOf + arr.asInstanceOf[Array[T]].find(p) def [T, U: ClassTag](arr: IArray[T]) flatMap(f: T => IterableOnce[U]): IArray[U] = - arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf + arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf[IArray[U]] def [T, U: ClassTag](arr: IArray[T]) flatten(given T => Iterable[U]): IArray[U] = - arr.asInstanceOf[Array[T]].flatten.asInstanceOf + arr.asInstanceOf[Array[T]].flatten.asInstanceOf[IArray[U]] def [T, U >: T: ClassTag](arr: IArray[T]) fold(z: U)(op: (U, U) => U): U = - arr.asInstanceOf[Array[T]].fold(z)(op).asInstanceOf + arr.asInstanceOf[Array[T]].fold(z)(op) def [T, U >: T: ClassTag](arr: IArray[T]) foldLeft(z: U)(op: (U, T) => U): U = - arr.asInstanceOf[Array[T]].foldLeft(z)(op).asInstanceOf + arr.asInstanceOf[Array[T]].foldLeft(z)(op) def [T, U >: T: ClassTag](arr: IArray[T]) foldRight(z: U)(op: (T, U) => U): U = - arr.asInstanceOf[Array[T]].foldRight(z)(op).asInstanceOf + arr.asInstanceOf[Array[T]].foldRight(z)(op) def [T](arr: IArray[T]) forall(p: T => Boolean): Boolean = arr.asInstanceOf[Array[T]].forall(p) @@ -105,10 +105,10 @@ object opaques arr.asInstanceOf[Array[T]].indexWhere(p, from) def [T](arr: IArray[T]) indices: Range = - arr.asInstanceOf[Array[T]].indices.asInstanceOf + arr.asInstanceOf[Array[T]].indices def [T](arr: IArray[T]) init: IArray[T] = - arr.asInstanceOf[Array[T]].init.asInstanceOf + arr.asInstanceOf[Array[T]].init.asInstanceOf[IArray[T]] def [T](arr: IArray[T]) isEmpty: Boolean = arr.asInstanceOf[Array[T]].isEmpty @@ -129,7 +129,7 @@ object opaques arr.asInstanceOf[Array[T]].lastIndexWhere(p, from) def [T, U: ClassTag](arr: IArray[T]) map(f: T => U): IArray[U] = - arr.asInstanceOf[Array[T]].map(f).asInstanceOf + arr.asInstanceOf[Array[T]].map(f).asInstanceOf[IArray[U]] def [T](arr: IArray[T]) nonEmpty: Boolean = arr.asInstanceOf[Array[T]].nonEmpty @@ -140,31 +140,31 @@ object opaques } def [T](arr: IArray[T]) reverse: IArray[T] = - arr.asInstanceOf[Array[T]].reverse.asInstanceOf + arr.asInstanceOf[Array[T]].reverse.asInstanceOf[IArray[T]] - def [T, U >: T: ClassTag](arr: IArray[T]) scan(z: U)(op: (U, U) => U): Array[U] = - arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf + def [T, U >: T: ClassTag](arr: IArray[T]) scan(z: U)(op: (U, U) => U): IArray[U] = + arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf[IArray[U]] - def [T, U: ClassTag](arr: IArray[T]) scanLeft(z: U)(op: (U, T) => U): Array[U] = - arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf + def [T, U: ClassTag](arr: IArray[T]) scanLeft(z: U)(op: (U, T) => U): IArray[U] = + arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf[IArray[U]] - def [T, U: ClassTag](arr: IArray[T]) scanRight(z: U)(op: (T, U) => U): Array[U] = - arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf + def [T, U: ClassTag](arr: IArray[T]) scanRight(z: U)(op: (T, U) => U): IArray[U] = + arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf[IArray[U]] def [T](arr: IArray[T]) size: Int = arr.asInstanceOf[Array[T]].size - def [T](arr: IArray[T]) slice(from: Int, until: Int): Array[T] = - arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf + def [T](arr: IArray[T]) slice(from: Int, until: Int): IArray[T] = + arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf[IArray[T]] def [T, U: ClassTag](arr: IArray[T]) sortBy(f: T => U)(given math.Ordering[U]): IArray[T] = - arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf + arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) sortWith(f: (T, T) => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf + arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) sorted(given math.Ordering[T]): IArray[T] = - arr.asInstanceOf[Array[T]].sorted.asInstanceOf + arr.asInstanceOf[Array[T]].sorted.asInstanceOf[IArray[T]] def [T](arr: IArray[T]) span(p: T => Boolean): (IArray[T], IArray[T]) = arr.asInstanceOf[Array[T]].span(p) match { @@ -180,16 +180,16 @@ object opaques arr.asInstanceOf[Array[T]].startsWith(that.asInstanceOf[Array[U]]) def [T](arr: IArray[T]) tail: IArray[T] = - arr.asInstanceOf[Array[T]].tail.asInstanceOf + arr.asInstanceOf[Array[T]].tail.asInstanceOf[IArray[T]] def [T](arr: IArray[T]) take(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].take(n).asInstanceOf + arr.asInstanceOf[Array[T]].take(n).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) takeRight(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf + arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) takeWhile(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf + arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf[IArray[T]] def [U: ClassTag, V: ClassTag](arr: IArray[(U, V)]) unzip: (IArray[U], IArray[V]) = arr.asInstanceOf[Array[(U, V)]].unzip match { @@ -197,7 +197,7 @@ object opaques } def [T, U: ClassTag](arr: IArray[T]) zip(that: IterableOnce[U]): IArray[(T, U)] = - arr.asInstanceOf[Array[T]].zip(that).asInstanceOf + arr.asInstanceOf[Array[T]].zip(that).asInstanceOf[IArray[(T, U)]] end opaques type IArray[+T] = opaques.IArray[T] diff --git a/tests/run-bootstrapped/iarray-extmtds.check b/tests/run-bootstrapped/iarray-extmtds.check index e4d79cc03ddb..59e226cdee1e 100644 --- a/tests/run-bootstrapped/iarray-extmtds.check +++ b/tests/run-bootstrapped/iarray-extmtds.check @@ -1 +1,11 @@ -IArray(1,2) \ No newline at end of file +IArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) +true +false +5 +IArray(9, 10) +IArray(1, 2) +IArray(8, 9, 10) +true +IArray(2, 4, 6, 8, 10) +IArray(1, 3, 5, 7, 9) +Some(5) diff --git a/tests/run-bootstrapped/iarray-extmtds.scala b/tests/run-bootstrapped/iarray-extmtds.scala index 75cc08fcdeb7..6c90f068c658 100644 --- a/tests/run-bootstrapped/iarray-extmtds.scala +++ b/tests/run-bootstrapped/iarray-extmtds.scala @@ -1,12 +1,40 @@ object Test extends App { - def assertNew[T, U](expr: => IArray[T], original: IArray[U]): Unit = { + def arrToString[T](arr: IArray[T]): Unit = + arr.asInstanceOf[Array[T]].mkString("IArray(", ", ", ")") + + // This is used to check the correct result, as well as checking that the IArray was not mutated in place + def assertNew[T, U](expr: => IArray[T], sources: IArray[U]*): Unit = { val result = expr - assert(result ne original, "IArray was mutated in place") - println(result) + + sources.foreach(source => + assert(result.asInstanceOf[AnyRef] ne source.asInstanceOf[AnyRef], "IArray was mutated in place") + ) + + println(arrToString(result)) } - val arr = Array[Int](1,2,3,4,5,6,7,8,9,10) + val arr1 = IArray[Int](1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val arr2 = IArray[Int](11, 12, 13, 14, 15, 16, 17, 18, 19, 20) + + assertNew(arr1 ++ arr2, arr1, arr2) + + println(arr1.contains(1)) + println(arr1.contains(25)) + + println(arr1.count(_ % 2 == 0)) + + assertNew(arr1.drop(8), arr1) + + assertNew(arr1.dropRight(8), arr1) + + assertNew(arr1.dropWhile(_ < 8)) + + println(arr1.exists(_ % 6 == 0)) + + assertNew(arr1.filter(_ % 2 == 0), arr1) + + assertNew(arr1.filterNot(_ % 2 == 0), arr1) - assertNew(arr.filter(_ % 2 == 0), arr) + println(arr1.find(_ % 5 == 0)) } From b3d10888e5b01a83af2da34fb67ac7ddb48c3b3f Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Tue, 17 Dec 2019 20:15:04 +0100 Subject: [PATCH 09/12] Remove unwanted change --- library/src/scala/runtime/DynamicTuple.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/src/scala/runtime/DynamicTuple.scala b/library/src/scala/runtime/DynamicTuple.scala index 494cdcac783c..53d44f75d449 100644 --- a/library/src/scala/runtime/DynamicTuple.scala +++ b/library/src/scala/runtime/DynamicTuple.scala @@ -1,10 +1,8 @@ package scala.runtime import scala.Tuple.{ Concat, Size, Head, Tail, Elem, Zip, Map } -import scala.reflect.ClassTag object DynamicTuple { - inline val MaxSpecialized = 22 inline private val XXL = MaxSpecialized + 1 From b8bdbf30e6e10f6b0e082d5716f797eadce314a0 Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Thu, 19 Dec 2019 11:48:16 +0100 Subject: [PATCH 10/12] Implement a test for every extension method --- library/src-bootstrapped/scala/IArray.scala | 106 +++++++++--------- tests/run-bootstrapped/iarray-extmtds.check | 66 +++++++++-- tests/run-bootstrapped/iarray-extmtds.scala | 117 +++++++++++++++++--- 3 files changed, 214 insertions(+), 75 deletions(-) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index f4f72f6d7da0..6030dff2a256 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -42,162 +42,162 @@ object opaques /** All the methods on Array[T] that don't mutate in-place can be used with IArray[T]. */ def [T, U >: T: ClassTag](arr: IArray[T]) ++(that: IArray[U]): IArray[U] = - (arr.asInstanceOf[Array[T]] ++ that.asInstanceOf[Array[U]]).asInstanceOf[IArray[U]] + (genericArrayOps(arr) ++ that.asInstanceOf[Array[U]]).asInstanceOf[IArray[U]] def [T](arr: IArray[T]) contains(elem: T): Boolean = - arr.asInstanceOf[Array[T]].contains(elem) + genericArrayOps(arr.asInstanceOf[Array[T]]).contains(elem) def [T](arr: IArray[T]) count(p: T => Boolean): Int = - arr.asInstanceOf[Array[T]].count(p) + genericArrayOps(arr).count(p) def [T](arr: IArray[T]) drop(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].drop(n).asInstanceOf[IArray[T]] + genericArrayOps(arr).drop(n).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) dropRight(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].dropRight(n).asInstanceOf[IArray[T]] + genericArrayOps(arr).dropRight(n).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) dropWhile(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].dropWhile(p).asInstanceOf[IArray[T]] + genericArrayOps(arr).dropWhile(p).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) exists(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].exists(p).asInstanceOf[IArray[T]] + genericArrayOps(arr).exists(p).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) filter(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].filter(p).asInstanceOf[IArray[T]] + genericArrayOps(arr).filter(p).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) filterNot(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].filterNot(p).asInstanceOf[IArray[T]] + genericArrayOps(arr).filterNot(p).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) find(p: T => Boolean): Option[T] = - arr.asInstanceOf[Array[T]].find(p) + genericArrayOps(arr).find(p) def [T, U: ClassTag](arr: IArray[T]) flatMap(f: T => IterableOnce[U]): IArray[U] = - arr.asInstanceOf[Array[T]].flatMap(f).asInstanceOf[IArray[U]] + genericArrayOps(arr).flatMap(f).asInstanceOf[IArray[U]] def [T, U: ClassTag](arr: IArray[T]) flatten(given T => Iterable[U]): IArray[U] = - arr.asInstanceOf[Array[T]].flatten.asInstanceOf[IArray[U]] + genericArrayOps(arr).flatten.asInstanceOf[IArray[U]] def [T, U >: T: ClassTag](arr: IArray[T]) fold(z: U)(op: (U, U) => U): U = - arr.asInstanceOf[Array[T]].fold(z)(op) + genericArrayOps(arr).fold(z)(op) - def [T, U >: T: ClassTag](arr: IArray[T]) foldLeft(z: U)(op: (U, T) => U): U = - arr.asInstanceOf[Array[T]].foldLeft(z)(op) + def [T, U: ClassTag](arr: IArray[T]) foldLeft(z: U)(op: (U, T) => U): U = + genericArrayOps(arr).foldLeft(z)(op) - def [T, U >: T: ClassTag](arr: IArray[T]) foldRight(z: U)(op: (T, U) => U): U = - arr.asInstanceOf[Array[T]].foldRight(z)(op) + def [T, U: ClassTag](arr: IArray[T]) foldRight(z: U)(op: (T, U) => U): U = + genericArrayOps(arr).foldRight(z)(op) def [T](arr: IArray[T]) forall(p: T => Boolean): Boolean = - arr.asInstanceOf[Array[T]].forall(p) + genericArrayOps(arr).forall(p) def [T, U](arr: IArray[T]) foreach(f: T => U): Unit = - arr.asInstanceOf[Array[T]].foreach(f) + genericArrayOps(arr).foreach(f) def [T](arr: IArray[T]) head: T = - arr.asInstanceOf[Array[T]].head + genericArrayOps(arr).head def [T](arr: IArray[T]) headOption: Option[T] = - arr.asInstanceOf[Array[T]].headOption + genericArrayOps(arr).headOption def [T](arr: IArray[T]) indexOf(elem: T, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].indexOf(elem, from) + genericArrayOps(arr.asInstanceOf[Array[T]]).indexOf(elem, from) def [T](arr: IArray[T]) indexWhere(p: T => Boolean, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].indexWhere(p, from) + genericArrayOps(arr).indexWhere(p, from) def [T](arr: IArray[T]) indices: Range = - arr.asInstanceOf[Array[T]].indices + genericArrayOps(arr).indices def [T](arr: IArray[T]) init: IArray[T] = - arr.asInstanceOf[Array[T]].init.asInstanceOf[IArray[T]] + genericArrayOps(arr).init.asInstanceOf[IArray[T]] def [T](arr: IArray[T]) isEmpty: Boolean = - arr.asInstanceOf[Array[T]].isEmpty + genericArrayOps(arr).isEmpty def [T](arr: IArray[T]) iterator: Iterator[T] = - arr.asInstanceOf[Array[T]].iterator + genericArrayOps(arr).iterator def [T](arr: IArray[T]) last: T = - arr.asInstanceOf[Array[T]].last + genericArrayOps(arr).last def [T](arr: IArray[T]) lastOption: Option[T] = - arr.asInstanceOf[Array[T]].lastOption + genericArrayOps(arr).lastOption def [T](arr: IArray[T]) lastIndexOf(elem: T, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].lastIndexOf(elem, from) + genericArrayOps(arr.asInstanceOf[Array[T]]).lastIndexOf(elem, from) def [T](arr: IArray[T]) lastIndexWhere(p: T => Boolean, from: Int = 0): Int = - arr.asInstanceOf[Array[T]].lastIndexWhere(p, from) + genericArrayOps(arr).lastIndexWhere(p, from) def [T, U: ClassTag](arr: IArray[T]) map(f: T => U): IArray[U] = - arr.asInstanceOf[Array[T]].map(f).asInstanceOf[IArray[U]] + genericArrayOps(arr).map(f).asInstanceOf[IArray[U]] def [T](arr: IArray[T]) nonEmpty: Boolean = - arr.asInstanceOf[Array[T]].nonEmpty + genericArrayOps(arr).nonEmpty def [T](arr: IArray[T]) partition(p: T => Boolean): (IArray[T], IArray[T]) = - arr.asInstanceOf[Array[T]].partition(p) match { + genericArrayOps(arr).partition(p) match { case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) } def [T](arr: IArray[T]) reverse: IArray[T] = - arr.asInstanceOf[Array[T]].reverse.asInstanceOf[IArray[T]] + genericArrayOps(arr).reverse.asInstanceOf[IArray[T]] def [T, U >: T: ClassTag](arr: IArray[T]) scan(z: U)(op: (U, U) => U): IArray[U] = - arr.asInstanceOf[Array[T]].scan(z)(op).asInstanceOf[IArray[U]] + genericArrayOps(arr).scan(z)(op).asInstanceOf[IArray[U]] def [T, U: ClassTag](arr: IArray[T]) scanLeft(z: U)(op: (U, T) => U): IArray[U] = - arr.asInstanceOf[Array[T]].scanLeft(z)(op).asInstanceOf[IArray[U]] + genericArrayOps(arr).scanLeft(z)(op).asInstanceOf[IArray[U]] def [T, U: ClassTag](arr: IArray[T]) scanRight(z: U)(op: (T, U) => U): IArray[U] = - arr.asInstanceOf[Array[T]].scanRight(z)(op).asInstanceOf[IArray[U]] + genericArrayOps(arr).scanRight(z)(op).asInstanceOf[IArray[U]] def [T](arr: IArray[T]) size: Int = - arr.asInstanceOf[Array[T]].size + arr.length def [T](arr: IArray[T]) slice(from: Int, until: Int): IArray[T] = - arr.asInstanceOf[Array[T]].slice(from, until).asInstanceOf[IArray[T]] + genericArrayOps(arr).slice(from, until).asInstanceOf[IArray[T]] def [T, U: ClassTag](arr: IArray[T]) sortBy(f: T => U)(given math.Ordering[U]): IArray[T] = - arr.asInstanceOf[Array[T]].sortBy(f).asInstanceOf[IArray[T]] + genericArrayOps(arr).sortBy(f).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) sortWith(f: (T, T) => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].sortWith(f).asInstanceOf[IArray[T]] + genericArrayOps(arr).sortWith(f).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) sorted(given math.Ordering[T]): IArray[T] = - arr.asInstanceOf[Array[T]].sorted.asInstanceOf[IArray[T]] + genericArrayOps(arr).sorted.asInstanceOf[IArray[T]] def [T](arr: IArray[T]) span(p: T => Boolean): (IArray[T], IArray[T]) = - arr.asInstanceOf[Array[T]].span(p) match { + genericArrayOps(arr).span(p) match { case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) } def [T](arr: IArray[T]) splitAt(n: Int): (IArray[T], IArray[T]) = - arr.asInstanceOf[Array[T]].splitAt(n) match { + genericArrayOps(arr).splitAt(n) match { case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) } def [T, U >: T: ClassTag](arr: IArray[T]) startsWith(that: IArray[U], offset: Int = 0): Boolean = - arr.asInstanceOf[Array[T]].startsWith(that.asInstanceOf[Array[U]]) + genericArrayOps(arr).startsWith(that.asInstanceOf[Array[U]]) def [T](arr: IArray[T]) tail: IArray[T] = - arr.asInstanceOf[Array[T]].tail.asInstanceOf[IArray[T]] + genericArrayOps(arr).tail.asInstanceOf[IArray[T]] def [T](arr: IArray[T]) take(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].take(n).asInstanceOf[IArray[T]] + genericArrayOps(arr).take(n).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) takeRight(n: Int): IArray[T] = - arr.asInstanceOf[Array[T]].takeRight(n).asInstanceOf[IArray[T]] + genericArrayOps(arr).takeRight(n).asInstanceOf[IArray[T]] def [T](arr: IArray[T]) takeWhile(p: T => Boolean): IArray[T] = - arr.asInstanceOf[Array[T]].takeWhile(p).asInstanceOf[IArray[T]] + genericArrayOps(arr).takeWhile(p).asInstanceOf[IArray[T]] def [U: ClassTag, V: ClassTag](arr: IArray[(U, V)]) unzip: (IArray[U], IArray[V]) = - arr.asInstanceOf[Array[(U, V)]].unzip match { + genericArrayOps(arr).unzip match { case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) } - def [T, U: ClassTag](arr: IArray[T]) zip(that: IterableOnce[U]): IArray[(T, U)] = - arr.asInstanceOf[Array[T]].zip(that).asInstanceOf[IArray[(T, U)]] + def [T, U: ClassTag](arr: IArray[T]) zip(that: IArray[U]): IArray[(T, U)] = + genericArrayOps(arr).zip(that).asInstanceOf[IArray[(T, U)]] end opaques type IArray[+T] = opaques.IArray[T] diff --git a/tests/run-bootstrapped/iarray-extmtds.check b/tests/run-bootstrapped/iarray-extmtds.check index 59e226cdee1e..584835a37ffc 100644 --- a/tests/run-bootstrapped/iarray-extmtds.check +++ b/tests/run-bootstrapped/iarray-extmtds.check @@ -1,11 +1,63 @@ -IArray(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) +IArray(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) true -false 5 -IArray(9, 10) -IArray(1, 2) -IArray(8, 9, 10) +IArray(9,10) +IArray(1,2) +IArray(8,9,10) true -IArray(2, 4, 6, 8, 10) -IArray(1, 3, 5, 7, 9) +IArray(2,4,6,8,10) +IArray(1,3,5,7,9) Some(5) +IArray(1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10) +IArray(1,2,3,4) +55 +12345678910 +10987654321 +false +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +Some(1) +-1 +3 +0,1,2,3,4,5,6,7,8,9 +IArray(1,2,3,4,5,6,7,8,9) +false +1,2,3 +10 +Some(20) +6 +3 +IArray(11,12,13,14,15,16,17,18,19,20) +true +IArray(2,4,6,8,10) +IArray(1,3,5,7,9) +IArray(10,9,8,7,6,5,4,3,2,1) +IArray(0,1,3,6,10,15,21,28,36,45,55) +IArray(,1,12,123,1234,12345,123456,1234567,12345678,123456789,12345678910) +IArray(10987654321,1098765432,109876543,10987654,1098765,109876,10987,1098,109,10,) +10 +IArray(6,7) +IArray(10,9,8,7,6,5,4,3,2,1) +IArray(10,1,2,3,4,5,6,7,8,9) +IArray(1,2,3,4,5,6,7,8,9,10) +IArray(1,2,3,4) +IArray(5,6,7,8,9,10) +IArray(1,2,3,4,5,6,7) +IArray(8,9,10) +false +IArray(2,3,4,5,6,7,8,9,10) +IArray(1,2,3) +IArray(7,8,9,10) +IArray(1,2) +IArray(1,2,3) +IArray(1,2,3) +IArray((1,11),(2,12),(3,13),(4,14),(5,15),(6,16),(7,17),(8,18),(9,19),(10,20)) diff --git a/tests/run-bootstrapped/iarray-extmtds.scala b/tests/run-bootstrapped/iarray-extmtds.scala index 6c90f068c658..bb9d10d0e994 100644 --- a/tests/run-bootstrapped/iarray-extmtds.scala +++ b/tests/run-bootstrapped/iarray-extmtds.scala @@ -1,40 +1,127 @@ object Test extends App { - def arrToString[T](arr: IArray[T]): Unit = - arr.asInstanceOf[Array[T]].mkString("IArray(", ", ", ")") + def printIArray[T](arr: IArray[T]): Unit = + println(arr.asInstanceOf[Array[T]].mkString("IArray(", ",", ")")) // This is used to check the correct result, as well as checking that the IArray was not mutated in place - def assertNew[T, U](expr: => IArray[T], sources: IArray[U]*): Unit = { - val result = expr - + def assertDifferent[T, U](expr: IArray[T], sources: IArray[U]*): Unit = { sources.foreach(source => - assert(result.asInstanceOf[AnyRef] ne source.asInstanceOf[AnyRef], "IArray was mutated in place") + assert(expr.asInstanceOf[AnyRef] ne source.asInstanceOf[AnyRef], "IArray was mutated in place") ) - println(arrToString(result)) + printIArray(expr) } val arr1 = IArray[Int](1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val arr2 = IArray[Int](11, 12, 13, 14, 15, 16, 17, 18, 19, 20) - assertNew(arr1 ++ arr2, arr1, arr2) + assertDifferent(arr1 ++ arr2, arr1, arr2) - println(arr1.contains(1)) - println(arr1.contains(25)) + println(arr1.contains(7)) println(arr1.count(_ % 2 == 0)) - assertNew(arr1.drop(8), arr1) + assertDifferent(arr1.drop(8), arr1) - assertNew(arr1.dropRight(8), arr1) + assertDifferent(arr1.dropRight(8), arr1) - assertNew(arr1.dropWhile(_ < 8)) + assertDifferent(arr1.dropWhile(_ < 8), arr1) println(arr1.exists(_ % 6 == 0)) - assertNew(arr1.filter(_ % 2 == 0), arr1) + assertDifferent(arr1.filter(_ % 2 == 0), arr1) - assertNew(arr1.filterNot(_ % 2 == 0), arr1) + assertDifferent(arr1.filterNot(_ % 2 == 0), arr1) println(arr1.find(_ % 5 == 0)) + + assertDifferent(arr1.flatMap(x => List(x, x)), arr1) + + val twoDArr = IArray(List(1, 2), List(3, 4)) + assertDifferent(twoDArr.flatten[List[Int], Int], twoDArr) + + println(arr1.fold(0)(_ + _)) + + println(arr1.foldLeft("")((acc, x) => acc + x.toString)) + + println(arr1.foldRight("")((x, acc) => acc + x.toString)) + + println(arr1.forall(_ > 5)) + + arr1.foreach(x => println(x)) + + println(arr2.head) + + println(arr1.headOption) + + println(arr1.indexOf(5, 7)) + + println(arr1.indexWhere(_ > 3, 1)) + + println(arr2.indices.mkString(",")) + + assertDifferent(arr1.init, arr1) + + println(arr1.isEmpty) + + println(arr1.iterator.take(3).mkString(",")) + + println(arr1.last) + + println(arr2.lastOption) + + println(arr2.lastIndexOf(17)) // Might be a bug + + println(arr1.lastIndexWhere(_ < 5)) // Might be a bug + + assertDifferent(arr1.map(_ + 10), arr1) + + println(arr1.nonEmpty) + + val (even, odd) = arr1.partition(_ % 2 == 0) + assertDifferent(even, arr1) + assertDifferent(odd, arr1) + + assertDifferent(arr1.reverse, arr1) + + assertDifferent(arr1.scan(0)(_ + _), arr1) + + assertDifferent(arr1.scanLeft("")((acc, x) => acc + x.toString), arr1) + + assertDifferent(arr1.scanRight("")((x, acc) => acc + x.toString), arr1) + + println(arr2.size) + + assertDifferent(arr1.slice(5,7), arr1) + + assertDifferent(arr1.sortBy(- _), arr1) + + assertDifferent(arr1.sortWith((x, y) => x.toString.length > y.toString.length || x < y), arr1) + + assertDifferent(arr1.sorted, arr1) + + val (smaller, greater) = arr1.span(_ < 5) + assertDifferent(smaller, arr1) + assertDifferent(greater, arr1) + + val (first, last) = arr1.splitAt(7) + assertDifferent(first, arr1) + assertDifferent(last, arr1) + + println(arr1.startsWith(IArray(1,2,3,4,5,6,42))) + + assertDifferent(arr1.tail, arr1) + + assertDifferent(arr1.take(3), arr1) + + assertDifferent(arr1.takeRight(4), arr1) + + assertDifferent(arr1.takeWhile(_ < 3), arr1) + + val tupArr = IArray[(Int, String)]((1, "1"), (2, "2"), (3, "3")) + val (ints, strings) = tupArr.unzip + assertDifferent(ints, tupArr) + assertDifferent(strings, tupArr) + + assertDifferent(arr1.zip(arr2), arr1, arr2) } From 7b61141aa740d5fd63ad409b1bc1f9bdaa884eae Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Fri, 20 Dec 2019 08:12:50 +0100 Subject: [PATCH 11/12] Fix a bug in lastIndexOf and lastIndexWhere --- library/src-bootstrapped/scala/IArray.scala | 8 ++++---- tests/run-bootstrapped/iarray-extmtds.scala | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index 6030dff2a256..ce494c98bedf 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -122,11 +122,11 @@ object opaques def [T](arr: IArray[T]) lastOption: Option[T] = genericArrayOps(arr).lastOption - def [T](arr: IArray[T]) lastIndexOf(elem: T, from: Int = 0): Int = - genericArrayOps(arr.asInstanceOf[Array[T]]).lastIndexOf(elem, from) + def [T](arr: IArray[T]) lastIndexOf(elem: T, end: Int = arr.length - 1): Int = + genericArrayOps(arr.asInstanceOf[Array[T]]).lastIndexOf(elem, end) - def [T](arr: IArray[T]) lastIndexWhere(p: T => Boolean, from: Int = 0): Int = - genericArrayOps(arr).lastIndexWhere(p, from) + def [T](arr: IArray[T]) lastIndexWhere(p: T => Boolean, end: Int = arr.length - 1): Int = + genericArrayOps(arr).lastIndexWhere(p, end) def [T, U: ClassTag](arr: IArray[T]) map(f: T => U): IArray[U] = genericArrayOps(arr).map(f).asInstanceOf[IArray[U]] diff --git a/tests/run-bootstrapped/iarray-extmtds.scala b/tests/run-bootstrapped/iarray-extmtds.scala index bb9d10d0e994..ddc7610dd794 100644 --- a/tests/run-bootstrapped/iarray-extmtds.scala +++ b/tests/run-bootstrapped/iarray-extmtds.scala @@ -70,9 +70,9 @@ object Test extends App { println(arr2.lastOption) - println(arr2.lastIndexOf(17)) // Might be a bug + println(arr2.lastIndexOf(17)) - println(arr1.lastIndexWhere(_ < 5)) // Might be a bug + println(arr1.lastIndexWhere(_ < 5)) assertDifferent(arr1.map(_ + 10), arr1) From 8216307cfa5928e65da9bcab6b3a98eb8a01aaad Mon Sep 17 00:00:00 2001 From: Antoine Brunner Date: Wed, 25 Dec 2019 21:51:11 +0100 Subject: [PATCH 12/12] Comment the extension methods (documentation copied from ArrayOps.scala) --- library/src-bootstrapped/scala/IArray.scala | 61 ++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index ce494c98bedf..7a2d2f68c39b 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -39,163 +39,220 @@ object opaques def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length def [T](arr: IArray[T]) length: Int = arr.asInstanceOf[Array[T]].length - /** All the methods on Array[T] that don't mutate in-place can be used with IArray[T]. - */ + /** Returns this array concatenated with the given array. */ def [T, U >: T: ClassTag](arr: IArray[T]) ++(that: IArray[U]): IArray[U] = (genericArrayOps(arr) ++ that.asInstanceOf[Array[U]]).asInstanceOf[IArray[U]] + /** Tests whether this array contains a given value as an element. */ def [T](arr: IArray[T]) contains(elem: T): Boolean = genericArrayOps(arr.asInstanceOf[Array[T]]).contains(elem) + /** Counts the number of elements in this array which satisfy a predicate */ def [T](arr: IArray[T]) count(p: T => Boolean): Int = genericArrayOps(arr).count(p) + /** The rest of the array without its `n` first elements. */ def [T](arr: IArray[T]) drop(n: Int): IArray[T] = genericArrayOps(arr).drop(n).asInstanceOf[IArray[T]] + /** The rest of the array without its `n` last elements. */ def [T](arr: IArray[T]) dropRight(n: Int): IArray[T] = genericArrayOps(arr).dropRight(n).asInstanceOf[IArray[T]] + /** Drops longest prefix of elements that satisfy a predicate. */ def [T](arr: IArray[T]) dropWhile(p: T => Boolean): IArray[T] = genericArrayOps(arr).dropWhile(p).asInstanceOf[IArray[T]] + /** Tests whether a predicate holds for at least one element of this array. */ def [T](arr: IArray[T]) exists(p: T => Boolean): IArray[T] = genericArrayOps(arr).exists(p).asInstanceOf[IArray[T]] + /** Selects all elements of this array which satisfy a predicate. */ def [T](arr: IArray[T]) filter(p: T => Boolean): IArray[T] = genericArrayOps(arr).filter(p).asInstanceOf[IArray[T]] + /** Selects all elements of this array which do not satisfy a predicate. */ def [T](arr: IArray[T]) filterNot(p: T => Boolean): IArray[T] = genericArrayOps(arr).filterNot(p).asInstanceOf[IArray[T]] + /** Finds the first element of the array satisfying a predicate, if any. */ def [T](arr: IArray[T]) 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. */ def [T, U: ClassTag](arr: IArray[T]) flatMap(f: T => IterableOnce[U]): IArray[U] = genericArrayOps(arr).flatMap(f).asInstanceOf[IArray[U]] + /** Flattens a two-dimensional array by concatenating all its rows + * into a single array. */ def [T, U: ClassTag](arr: IArray[T]) flatten(given T => Iterable[U]): IArray[U] = genericArrayOps(arr).flatten.asInstanceOf[IArray[U]] + /** Folds the elements of this array using the specified associative binary operator. */ def [T, U >: T: ClassTag](arr: IArray[T]) fold(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. */ def [T, U: ClassTag](arr: IArray[T]) foldLeft(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. */ def [T, U: ClassTag](arr: IArray[T]) foldRight(z: U)(op: (T, U) => U): U = genericArrayOps(arr).foldRight(z)(op) + /** Tests whether a predicate holds for all elements of this array. */ def [T](arr: IArray[T]) forall(p: T => Boolean): Boolean = genericArrayOps(arr).forall(p) + /** Apply `f` to each element for its side effects. */ def [T, U](arr: IArray[T]) foreach(f: T => U): Unit = genericArrayOps(arr).foreach(f) + /** Selects the first element of this array. */ def [T](arr: IArray[T]) head: T = genericArrayOps(arr).head + /** Optionally selects the first element. */ def [T](arr: IArray[T]) headOption: Option[T] = genericArrayOps(arr).headOption + /** Finds index of first occurrence of some value in this array after or at some start index. */ def [T](arr: IArray[T]) indexOf(elem: T, from: Int = 0): Int = genericArrayOps(arr.asInstanceOf[Array[T]]).indexOf(elem, from) + /** Finds index of the first element satisfying some predicate after or at some start index. */ def [T](arr: IArray[T]) indexWhere(p: T => Boolean, from: Int = 0): Int = genericArrayOps(arr).indexWhere(p, from) + /** Produces the range of all indices of this sequence. */ def [T](arr: IArray[T]) indices: Range = genericArrayOps(arr).indices + /** The initial part of the array without its last element. */ def [T](arr: IArray[T]) init: IArray[T] = genericArrayOps(arr).init.asInstanceOf[IArray[T]] + /** Tests whether the array is empty. */ def [T](arr: IArray[T]) isEmpty: Boolean = genericArrayOps(arr).isEmpty + /** An iterator yielding the elemenst of this array. */ def [T](arr: IArray[T]) iterator: Iterator[T] = genericArrayOps(arr).iterator + /** Selects the last element. */ def [T](arr: IArray[T]) last: T = genericArrayOps(arr).last + /** Optionally selects the last element. */ def [T](arr: IArray[T]) lastOption: Option[T] = genericArrayOps(arr).lastOption + /** Finds index of last occurrence of some value in this array before or at a given end index. */ def [T](arr: IArray[T]) lastIndexOf(elem: T, end: Int = arr.length - 1): Int = genericArrayOps(arr.asInstanceOf[Array[T]]).lastIndexOf(elem, end) + /** Finds index of last element satisfying some predicate before or at given end index. */ def [T](arr: IArray[T]) 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. */ def [T, U: ClassTag](arr: IArray[T]) map(f: T => U): IArray[U] = genericArrayOps(arr).map(f).asInstanceOf[IArray[U]] + /** Tests whether the array is not empty. */ def [T](arr: IArray[T]) nonEmpty: Boolean = genericArrayOps(arr).nonEmpty + /** A pair of, first, all elements that satisfy predicate `p` and, second, all elements that do not. */ def [T](arr: IArray[T]) partition(p: T => Boolean): (IArray[T], IArray[T]) = genericArrayOps(arr).partition(p) match { case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) } + /** Returns a new array with the elements in reversed order. */ def [T](arr: IArray[T]) reverse: IArray[T] = genericArrayOps(arr).reverse.asInstanceOf[IArray[T]] + /** Computes a prefix scan of the elements of the array. */ def [T, U >: T: ClassTag](arr: IArray[T]) scan(z: U)(op: (U, U) => U): IArray[U] = genericArrayOps(arr).scan(z)(op).asInstanceOf[IArray[U]] + /** Produces an array containing cumulative results of applying the binary + * operator going left to right. */ def [T, U: ClassTag](arr: IArray[T]) scanLeft(z: U)(op: (U, T) => U): IArray[U] = genericArrayOps(arr).scanLeft(z)(op).asInstanceOf[IArray[U]] + /** Produces an array containing cumulative results of applying the binary + * operator going right to left. */ def [T, U: ClassTag](arr: IArray[T]) scanRight(z: U)(op: (T, U) => U): IArray[U] = genericArrayOps(arr).scanRight(z)(op).asInstanceOf[IArray[U]] + /** The size of this array. */ def [T](arr: IArray[T]) size: Int = arr.length + /** Selects the interval of elements between the given indices. */ def [T](arr: IArray[T]) slice(from: Int, until: Int): IArray[T] = genericArrayOps(arr).slice(from, until).asInstanceOf[IArray[T]] + /** Sorts this array according to the Ordering which results from transforming + * an implicitly given Ordering with a transformation function. */ def [T, U: ClassTag](arr: IArray[T]) sortBy(f: T => U)(given math.Ordering[U]): IArray[T] = genericArrayOps(arr).sortBy(f).asInstanceOf[IArray[T]] + /** Sorts this array according to a comparison function. */ def [T](arr: IArray[T]) sortWith(f: (T, T) => Boolean): IArray[T] = genericArrayOps(arr).sortWith(f).asInstanceOf[IArray[T]] + /** Sorts this array according to an Ordering. */ def [T](arr: IArray[T]) sorted(given math.Ordering[T]): IArray[T] = genericArrayOps(arr).sorted.asInstanceOf[IArray[T]] + /** Splits this array into a prefix/suffix pair according to a predicate. */ def [T](arr: IArray[T]) span(p: T => Boolean): (IArray[T], IArray[T]) = genericArrayOps(arr).span(p) match { case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) } + /** Splits this array into two at a given position. */ def [T](arr: IArray[T]) splitAt(n: Int): (IArray[T], IArray[T]) = genericArrayOps(arr).splitAt(n) match { case (x, y) => (x.asInstanceOf[IArray[T]], y.asInstanceOf[IArray[T]]) } + /** Tests whether this array starts with the given array. */ def [T, U >: T: ClassTag](arr: IArray[T]) startsWith(that: IArray[U], offset: Int = 0): Boolean = genericArrayOps(arr).startsWith(that.asInstanceOf[Array[U]]) + /** The rest of the array without its first element. */ def [T](arr: IArray[T]) tail: IArray[T] = genericArrayOps(arr).tail.asInstanceOf[IArray[T]] + /** An array containing the first `n` elements of this array. */ def [T](arr: IArray[T]) take(n: Int): IArray[T] = genericArrayOps(arr).take(n).asInstanceOf[IArray[T]] + /** An array containing the last `n` elements of this array. */ def [T](arr: IArray[T]) takeRight(n: Int): IArray[T] = genericArrayOps(arr).takeRight(n).asInstanceOf[IArray[T]] + /** Takes longest prefix of elements that satisfy a predicate. */ def [T](arr: IArray[T]) takeWhile(p: T => Boolean): IArray[T] = genericArrayOps(arr).takeWhile(p).asInstanceOf[IArray[T]] + /** Converts an array of pairs into an array of first elements and an array of second elements. */ def [U: ClassTag, V: ClassTag](arr: IArray[(U, V)]) unzip: (IArray[U], IArray[V]) = genericArrayOps(arr).unzip match { case (x, y) => (x.asInstanceOf[IArray[U]], y.asInstanceOf[IArray[V]]) } + /** 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. */ def [T, U: ClassTag](arr: IArray[T]) zip(that: IArray[U]): IArray[(T, U)] = genericArrayOps(arr).zip(that).asInstanceOf[IArray[(T, U)]] end opaques