Skip to content

Commit 7c6c11f

Browse files
committed
Move IArray to src-bootstrapped
1 parent 3f93494 commit 7c6c11f

File tree

2 files changed

+278
-0
lines changed

2 files changed

+278
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
package scala
2+
import reflect.ClassTag
3+
4+
object opaques:
5+
opaque type IArray[+T] = Array[_ <: T]
6+
7+
private[scala] type Sub[A] >: Array[A] <: IArray[A]
8+
private[scala] type Sup[A] >: IArray[A] <: Array[_ <: A]
9+
10+
given arrayOps: Object with {
11+
12+
extension (arr: IArray[Byte]) def apply(n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n)
13+
extension (arr: IArray[Short]) def apply(n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n)
14+
extension (arr: IArray[Char]) def apply(n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n)
15+
extension (arr: IArray[Int]) def apply(n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n)
16+
extension (arr: IArray[Long]) def apply(n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n)
17+
extension (arr: IArray[Float]) def apply(n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n)
18+
extension (arr: IArray[Double]) def apply(n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n)
19+
extension [T <: Object](arr: IArray[T]) def apply (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
20+
extension [T](arr: IArray[T]) def apply (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
21+
22+
extension (arr: IArray[Byte]) def length: Int = arr.asInstanceOf[Array[Byte]].length
23+
extension (arr: IArray[Short]) def length: Int = arr.asInstanceOf[Array[Short]].length
24+
extension (arr: IArray[Char]) def length: Int = arr.asInstanceOf[Array[Char]].length
25+
extension (arr: IArray[Int]) def length: Int = arr.asInstanceOf[Array[Int]].length
26+
extension (arr: IArray[Long]) def length: Int = arr.asInstanceOf[Array[Long]].length
27+
extension (arr: IArray[Float]) def length: Int = arr.asInstanceOf[Array[Float]].length
28+
extension (arr: IArray[Double]) def length: Int = arr.asInstanceOf[Array[Double]].length
29+
extension (arr: IArray[Object]) def length: Int = arr.asInstanceOf[Array[Object]].length
30+
extension [T](arr: IArray[T]) def length: Int = arr.asInstanceOf[Array[T]].length
31+
32+
extension [T, U >: T: ClassTag](arr: IArray[T]) def ++(that: IArray[U]): IArray[U] =
33+
genericArrayOps(arr) ++ that
34+
35+
extension [T](arr: IArray[T]) def contains(elem: T): Boolean =
36+
genericArrayOps(arr).exists(_ == elem)
37+
38+
extension [T, U >: T](arr: IArray[T]) def copyToArray(xs: Array[U]): Int =
39+
genericArrayOps(arr).copyToArray(xs)
40+
41+
extension [T, U >: T](arr: IArray[T]) def copyToArray(xs: Array[U], start: Int): Int =
42+
genericArrayOps(arr).copyToArray(xs, start)
43+
44+
extension [T, U >: T](arr: IArray[T]) def copyToArray(xs: Array[U], start: Int, len: Int): Int =
45+
genericArrayOps(arr).copyToArray(xs, start, len)
46+
47+
extension [T](arr: IArray[T]) def count(p: T => Boolean): Int =
48+
genericArrayOps(arr).count(p)
49+
50+
extension [T](arr: IArray[T]) def drop(n: Int): IArray[T] =
51+
genericArrayOps(arr).drop(n)
52+
53+
extension [T](arr: IArray[T]) def dropRight(n: Int): IArray[T] =
54+
genericArrayOps(arr).dropRight(n)
55+
56+
extension [T](arr: IArray[T]) def dropWhile(p: T => Boolean): IArray[T] =
57+
genericArrayOps(arr).dropWhile(p)
58+
59+
extension [T](arr: IArray[T]) def exists(p: T => Boolean): Boolean =
60+
genericArrayOps(arr).exists(p)
61+
62+
extension [T](arr: IArray[T]) def filter(p: T => Boolean): IArray[T] =
63+
genericArrayOps(arr).filter(p)
64+
65+
extension [T](arr: IArray[T]) def filterNot(p: T => Boolean): IArray[T] =
66+
genericArrayOps(arr).filterNot(p)
67+
68+
extension [T](arr: IArray[T]) def find(p: T => Boolean): Option[T] =
69+
genericArrayOps(arr).find(p)
70+
71+
extension [T, U: ClassTag](arr: IArray[T]) def flatMap(f: T => IterableOnce[U]): IArray[U] =
72+
genericArrayOps(arr).flatMap(f)
73+
74+
extension [T, U: ClassTag](arr: IArray[T]) def flatten(using T => Iterable[U]): IArray[U] =
75+
genericArrayOps(arr).flatten
76+
77+
extension [T, U >: T: ClassTag](arr: IArray[T]) def fold(z: U)(op: (U, U) => U): U =
78+
genericArrayOps(arr).fold(z)(op)
79+
80+
extension [T, U: ClassTag](arr: IArray[T]) def foldLeft(z: U)(op: (U, T) => U): U =
81+
genericArrayOps(arr).foldLeft(z)(op)
82+
83+
extension [T, U: ClassTag](arr: IArray[T]) def foldRight(z: U)(op: (T, U) => U): U =
84+
genericArrayOps(arr).foldRight(z)(op)
85+
86+
extension [T](arr: IArray[T]) def forall(p: T => Boolean): Boolean =
87+
genericArrayOps(arr).forall(p)
88+
89+
extension [T, U](arr: IArray[T]) def foreach(f: T => U): Unit =
90+
genericArrayOps(arr).foreach(f)
91+
92+
extension [T](arr: IArray[T]) def head: T =
93+
genericArrayOps(arr).head
94+
95+
extension [T](arr: IArray[T]) def headOption: Option[T] =
96+
genericArrayOps(arr).headOption
97+
98+
extension [T](arr: IArray[T]) def indexOf(elem: T, from: Int = 0): Int =
99+
// `asInstanceOf` needed because `elem` does not have type `arr.T`
100+
// We could use `arr.iterator.indexOf(elem, from)` or `arr.indexWhere(_ == elem, from)`
101+
// but these would incur some overhead.
102+
genericArrayOps(arr).indexOf(elem.asInstanceOf, from)
103+
104+
extension [T](arr: IArray[T]) def indexWhere(p: T => Boolean, from: Int = 0): Int =
105+
genericArrayOps(arr).indexWhere(p, from)
106+
107+
extension [T](arr: IArray[T]) def indices: Range =
108+
genericArrayOps(arr).indices
109+
110+
extension [T](arr: IArray[T]) def init: IArray[T] =
111+
genericArrayOps(arr).init
112+
113+
extension [T](arr: IArray[T]) def isEmpty: Boolean =
114+
genericArrayOps(arr).isEmpty
115+
116+
extension [T](arr: IArray[T]) def iterator: Iterator[T] =
117+
genericArrayOps(arr).iterator
118+
119+
extension [T](arr: IArray[T]) def last: T =
120+
genericArrayOps(arr).last
121+
122+
extension [T](arr: IArray[T]) def lastOption: Option[T] =
123+
genericArrayOps(arr).lastOption
124+
125+
extension [T](arr: IArray[T]) def lastIndexOf(elem: T, end: Int = arr.length - 1): Int =
126+
// see: same issue in `indexOf`
127+
genericArrayOps(arr).lastIndexOf(elem.asInstanceOf, end)
128+
129+
extension [T](arr: IArray[T]) def lastIndexWhere(p: T => Boolean, end: Int = arr.length - 1): Int =
130+
genericArrayOps(arr).lastIndexWhere(p, end)
131+
132+
extension [T, U: ClassTag](arr: IArray[T]) def map(f: T => U): IArray[U] =
133+
genericArrayOps(arr).map(f)
134+
135+
extension [T](arr: IArray[T]) def nonEmpty: Boolean =
136+
genericArrayOps(arr).nonEmpty
137+
138+
extension [T](arr: IArray[T]) def partition(p: T => Boolean): (IArray[T], IArray[T]) =
139+
genericArrayOps(arr).partition(p)
140+
141+
extension [T](arr: IArray[T]) def reverse: IArray[T] =
142+
genericArrayOps(arr).reverse
143+
144+
extension [T, U >: T: ClassTag](arr: IArray[T]) def scan(z: U)(op: (U, U) => U): IArray[U] =
145+
genericArrayOps(arr).scan(z)(op)
146+
147+
extension [T, U: ClassTag](arr: IArray[T]) def scanLeft(z: U)(op: (U, T) => U): IArray[U] =
148+
genericArrayOps(arr).scanLeft(z)(op)
149+
150+
extension [T, U: ClassTag](arr: IArray[T]) def scanRight(z: U)(op: (T, U) => U): IArray[U] =
151+
genericArrayOps(arr).scanRight(z)(op)
152+
153+
extension [T](arr: IArray[T]) def size: Int =
154+
arr.length
155+
156+
extension [T](arr: IArray[T]) def slice(from: Int, until: Int): IArray[T] =
157+
genericArrayOps(arr).slice(from, until)
158+
159+
extension [T, U: ClassTag](arr: IArray[T]) def sortBy(f: T => U)(using math.Ordering[U]): IArray[T] =
160+
genericArrayOps(arr).sortBy(f)
161+
162+
extension [T](arr: IArray[T]) def sortWith(f: (T, T) => Boolean): IArray[T] =
163+
genericArrayOps(arr).sortWith(f)
164+
165+
extension [T](arr: IArray[T]) def sorted(using math.Ordering[T]): IArray[T] =
166+
genericArrayOps(arr).sorted
167+
168+
extension [T](arr: IArray[T]) def span(p: T => Boolean): (IArray[T], IArray[T]) =
169+
genericArrayOps(arr).span(p)
170+
171+
extension [T](arr: IArray[T]) def splitAt(n: Int): (IArray[T], IArray[T]) =
172+
genericArrayOps(arr).splitAt(n)
173+
174+
extension [T, U >: T: ClassTag](arr: IArray[T]) def startsWith(that: IArray[U], offset: Int = 0): Boolean =
175+
genericArrayOps(arr).startsWith(that)
176+
177+
extension [T](arr: IArray[T]) def tail: IArray[T] =
178+
genericArrayOps(arr).tail
179+
180+
extension [T](arr: IArray[T]) def take(n: Int): IArray[T] =
181+
genericArrayOps(arr).take(n)
182+
183+
extension [T](arr: IArray[T]) def takeRight(n: Int): IArray[T] =
184+
genericArrayOps(arr).takeRight(n)
185+
186+
extension [T](arr: IArray[T]) def takeWhile(p: T => Boolean): IArray[T] =
187+
genericArrayOps(arr).takeWhile(p)
188+
189+
extension [T](arr: IArray[T]) def toArray: Array[T] =
190+
arr.clone.asInstanceOf[Array[T]]
191+
192+
extension [U: ClassTag, V: ClassTag](arr: IArray[(U, V)]) def unzip: (IArray[U], IArray[V]) =
193+
genericArrayOps(arr).unzip
194+
195+
extension [T, U: ClassTag](arr: IArray[T]) def zip(that: IArray[U]): IArray[(T, U)] =
196+
genericArrayOps(arr).zip(that)
197+
}
198+
end opaques
199+
200+
type IArray[+T] = opaques.IArray[T]
201+
202+
object IArray {
203+
import opaques.Sub
204+
import opaques.Sup
205+
206+
private given [A]: Conversion[Array[A], IArray[A]] = identity[Sub[A]]
207+
208+
def unsafeFromArray[T](s: Array[T]): IArray[T] = s
209+
210+
def empty[T: ClassTag]: IArray[T] = new Array[T](0)
211+
212+
def emptyBooleanIArray: IArray[Boolean] = Array.emptyBooleanArray
213+
def emptyByteIArray: IArray[Byte] = Array.emptyByteArray
214+
def emptyCharIArray: IArray[Char] = Array.emptyCharArray
215+
def emptyDoubleIArray: IArray[Double] = Array.emptyDoubleArray
216+
def emptyFloatIArray: IArray[Float] = Array.emptyFloatArray
217+
def emptyIntIArray: IArray[Int] = Array.emptyIntArray
218+
def emptyLongIArray: IArray[Long] = Array.emptyLongArray
219+
def emptyShortIArray: IArray[Short] = Array.emptyShortArray
220+
def emptyObjectIArray: IArray[Object] = Array.emptyObjectArray
221+
222+
inline def apply[T](inline xs: T*)(using inline ct: ClassTag[T]): IArray[T] = Array(xs: _*).asInstanceOf
223+
inline def apply(inline x: Boolean, inline xs: Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf
224+
inline def apply(inline x: Byte, inline xs: Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf
225+
inline def apply(inline x: Short, inline xs: Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf
226+
inline def apply(inline x: Char, inline xs: Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf
227+
inline def apply(inline x: Int, inline xs: Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf
228+
inline def apply(inline x: Long, inline xs: Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf
229+
inline def apply(inline x: Float, inline xs: Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf
230+
inline def apply(inline x: Double, inline xs: Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf
231+
inline def apply(inline x: Unit, inline xs: Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf
232+
233+
def concat[T: ClassTag](xss: IArray[T]*): IArray[T] =
234+
// `Array.concat` should arguably take in a `Seq[Array[_ <: T]]`,
235+
// but since it currently takes a `Seq[Array[T]]` we have to perform a cast,
236+
// knowing tacitly that `concat` is not going to do the wrong thing.
237+
Array.concat[T](xss.asInstanceOf[Seq[Array[T]]]: _*)
238+
239+
def fill[T: ClassTag](n: Int)(elem: => T): IArray[T] =
240+
Array.fill(n)(elem)
241+
242+
def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): IArray[IArray[T]] =
243+
// We cannot avoid a cast here as Array.fill creates inner arrays out of our control:
244+
Array.fill(n1, n2)(elem).asInstanceOf
245+
246+
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): IArray[IArray[IArray[T]]] =
247+
Array.fill(n1, n2, n3)(elem).asInstanceOf
248+
249+
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): IArray[IArray[IArray[IArray[T]]]] =
250+
Array.fill(n1, n2, n3, n4)(elem).asInstanceOf
251+
252+
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): IArray[IArray[IArray[IArray[IArray[T]]]]] =
253+
Array.fill(n1, n2, n3, n4, n5)(elem).asInstanceOf
254+
255+
def tabulate[T: ClassTag](n: Int)(f: Int => T): IArray[T] =
256+
Array.tabulate(n)(f)
257+
258+
def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): IArray[IArray[T]] =
259+
Array.tabulate(n1, n2)(f).asInstanceOf
260+
261+
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): IArray[IArray[IArray[T]]] =
262+
Array.tabulate(n1, n2, n3)(f).asInstanceOf
263+
264+
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): IArray[IArray[IArray[IArray[T]]]] =
265+
Array.tabulate(n1, n2, n3, n4)(f).asInstanceOf
266+
267+
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): IArray[IArray[IArray[IArray[IArray[T]]]]] =
268+
Array.tabulate(n1, n2, n3, n4, n5)(f).asInstanceOf
269+
270+
def range(start: Int, end: Int): IArray[Int] = Array.range(start, end)
271+
272+
def range(start: Int, end: Int, step: Int): IArray[Int] = Array.range(start, end, step)
273+
274+
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): IArray[T] = Array.iterate(start, len)(f)
275+
276+
def unapplySeq[T](x: IArray[T]) =
277+
Array.unapplySeq((x: Sup[T]): Array[_ <: T])
278+
}

0 commit comments

Comments
 (0)