Skip to content

Commit 85c4bb3

Browse files
committed
Refactor IArray so that creation methods can be inlined
With the new restrictions on inlined methods and opaque types, we need to refactor IArray if we want to inline creation methods.
1 parent cd02a22 commit 85c4bb3

File tree

1 file changed

+62
-58
lines changed

1 file changed

+62
-58
lines changed

library/src-bootstrapped/scala/IArray.scala

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,70 @@ import reflect.ClassTag
44
/** An immutable array. An `IArray[T]` has the same representation as an `Array[T]`,
55
* but it cannot be updated. Unlike regular arrays, immutable arrays are covariant.
66
*/
7-
opaque type IArray[+T] = Array[_ <: T]
8-
9-
/** Defines extension methods for immutable arrays */
10-
implicit object arrayOps {
11-
12-
/** The selection operation on an immutable array.
13-
*
14-
* @param arr the immutable array
15-
* @param n the index of the element to select
16-
* @return the element of the array at the given index
17-
*/
18-
def (arr: IArray[Byte]) apply (n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n)
19-
def (arr: IArray[Short]) apply (n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n)
20-
def (arr: IArray[Char]) apply (n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n)
21-
def (arr: IArray[Int]) apply (n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n)
22-
def (arr: IArray[Long]) apply (n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n)
23-
def (arr: IArray[Float]) apply (n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n)
24-
def (arr: IArray[Double]) apply (n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n)
25-
def (arr: IArray[T]) apply[T <: Object] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
26-
def (arr: IArray[T]) apply[T] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
27-
28-
/** The number of elements in an immutable array
29-
* @param arr the immutable array
30-
*/
31-
def (arr: IArray[Byte]) length: Int = arr.asInstanceOf[Array[Byte]].length
32-
def (arr: IArray[Short]) length: Int = arr.asInstanceOf[Array[Short]].length
33-
def (arr: IArray[Char]) length: Int = arr.asInstanceOf[Array[Char]].length
34-
def (arr: IArray[Int]) length: Int = arr.asInstanceOf[Array[Int]].length
35-
def (arr: IArray[Long]) length: Int = arr.asInstanceOf[Array[Long]].length
36-
def (arr: IArray[Float]) length: Int = arr.asInstanceOf[Array[Float]].length
37-
def (arr: IArray[Double]) length: Int = arr.asInstanceOf[Array[Double]].length
38-
def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length
39-
def (arr: IArray[T]) length[T] : Int = arr.asInstanceOf[Array[T]].length
7+
object opaques {
8+
opaque type IArray[+T] = Array[_ <: T]
9+
10+
/** Defines extension methods for immutable arrays */
11+
given arrayOps {
12+
13+
/** The selection operation on an immutable array.
14+
*
15+
* @param arr the immutable array
16+
* @param n the index of the element to select
17+
* @return the element of the array at the given index
18+
*/
19+
def (arr: IArray[Byte]) apply (n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n)
20+
def (arr: IArray[Short]) apply (n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n)
21+
def (arr: IArray[Char]) apply (n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n)
22+
def (arr: IArray[Int]) apply (n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n)
23+
def (arr: IArray[Long]) apply (n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n)
24+
def (arr: IArray[Float]) apply (n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n)
25+
def (arr: IArray[Double]) apply (n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n)
26+
def (arr: IArray[T]) apply[T <: Object] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
27+
def (arr: IArray[T]) apply[T] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
28+
29+
/** The number of elements in an immutable array
30+
* @param arr the immutable array
31+
*/
32+
def (arr: IArray[Byte]) length: Int = arr.asInstanceOf[Array[Byte]].length
33+
def (arr: IArray[Short]) length: Int = arr.asInstanceOf[Array[Short]].length
34+
def (arr: IArray[Char]) length: Int = arr.asInstanceOf[Array[Char]].length
35+
def (arr: IArray[Int]) length: Int = arr.asInstanceOf[Array[Int]].length
36+
def (arr: IArray[Long]) length: Int = arr.asInstanceOf[Array[Long]].length
37+
def (arr: IArray[Float]) length: Int = arr.asInstanceOf[Array[Float]].length
38+
def (arr: IArray[Double]) length: Int = arr.asInstanceOf[Array[Double]].length
39+
def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length
40+
def (arr: IArray[T]) length[T] : Int = arr.asInstanceOf[Array[T]].length
41+
}
4042
}
43+
type IArray[+T] = opaques.IArray[T]
4144

4245
object IArray {
4346

4447
/** An immutable array of length 0.
4548
*/
46-
def empty[T: ClassTag]: IArray[T] = new Array[T](0)
49+
def empty[T: ClassTag]: IArray[T] = new Array[T](0).asInstanceOf
4750

4851
/** An immutable array with given elements.
4952
*/
50-
def apply[T: ClassTag](xs: T*): IArray[T] = Array(xs: _*)
51-
def apply(x: Boolean, xs: Boolean*): IArray[Boolean] = Array(x, xs: _*)
52-
def apply(x: Byte, xs: Byte*): IArray[Byte] = Array(x, xs: _*)
53-
def apply(x: Short, xs: Short*): IArray[Short] = Array(x, xs: _*)
54-
def apply(x: Char, xs: Char*): IArray[Char] = Array(x, xs: _*)
55-
def apply(x: Int, xs: Int*): IArray[Int] = Array(x, xs: _*)
56-
def apply(x: Long, xs: Long*): IArray[Long] = Array(x, xs: _*)
57-
def apply(x: Float, xs: Float*): IArray[Float] = Array(x, xs: _*)
58-
def apply(x: Double, xs: Double*): IArray[Double] = Array(x, xs: _*)
59-
def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*)
53+
def apply[T: ClassTag](xs: T*): IArray[T] = Array(xs: _*).asInstanceOf
54+
def apply(x: Boolean, xs: Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf
55+
def apply(x: Byte, xs: Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf
56+
def apply(x: Short, xs: Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf
57+
def apply(x: Char, xs: Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf
58+
def apply(x: Int, xs: Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf
59+
def apply(x: Long, xs: Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf
60+
def apply(x: Float, xs: Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf
61+
def apply(x: Double, xs: Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf
62+
def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf
6063

6164
/** Concatenates all arrays into a single immutable array.
6265
*
6366
* @param xss the given immutable arrays
6467
* @return the array created from concatenating `xss`
6568
*/
66-
def concat[T: ClassTag](xss: IArray[T]*): IArray[T] = Array.concat[T](xss.asInstanceOf[Seq[Array[T]]]: _*)
69+
def concat[T: ClassTag](xss: IArray[T]*): IArray[T] =
70+
Array.concat[T](xss.asInstanceOf[Seq[Array[T]]]: _*).asInstanceOf
6771

6872
/** Returns an immutable array that contains the results of some element computation a number
6973
* of times. Each element is determined by a separate computation.
@@ -72,7 +76,7 @@ object IArray {
7276
* @param elem the element computation
7377
*/
7478
def fill[T: ClassTag](n: Int)(elem: => T): IArray[T] =
75-
Array.fill(n)(elem)
79+
Array.fill(n)(elem).asInstanceOf
7680

7781
/** Returns a two-dimensional immutable array that contains the results of some element computation a number
7882
* of times. Each element is determined by a separate computation.
@@ -82,7 +86,7 @@ object IArray {
8286
* @param elem the element computation
8387
*/
8488
def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): IArray[IArray[T]] =
85-
Array.fill(n1, n2)(elem)
89+
Array.fill(n1, n2)(elem).asInstanceOf
8690

8791
/** Returns a three-dimensional immutable array that contains the results of some element computation a number
8892
* of times. Each element is determined by a separate computation.
@@ -93,7 +97,7 @@ object IArray {
9397
* @param elem the element computation
9498
*/
9599
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): IArray[IArray[IArray[T]]] =
96-
Array.fill(n1, n2, n3)(elem)
100+
Array.fill(n1, n2, n3)(elem).asInstanceOf
97101

98102
/** Returns a four-dimensional immutable array that contains the results of some element computation a number
99103
* of times. Each element is determined by a separate computation.
@@ -105,7 +109,7 @@ object IArray {
105109
* @param elem the element computation
106110
*/
107111
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): IArray[IArray[IArray[IArray[T]]]] =
108-
Array.fill(n1, n2, n3, n4)(elem)
112+
Array.fill(n1, n2, n3, n4)(elem).asInstanceOf
109113

110114
/** Returns a five-dimensional immutable array that contains the results of some element computation a number
111115
* of times. Each element is determined by a separate computation.
@@ -118,7 +122,7 @@ object IArray {
118122
* @param elem the element computation
119123
*/
120124
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): IArray[IArray[IArray[IArray[IArray[T]]]]] =
121-
Array.fill(n1, n2, n3, n4, n5)(elem)
125+
Array.fill(n1, n2, n3, n4, n5)(elem).asInstanceOf
122126

123127
/** Returns an immutable array containing values of a given function over a range of integer
124128
* values starting from 0.
@@ -127,7 +131,7 @@ object IArray {
127131
* @param f The function computing element values
128132
*/
129133
def tabulate[T: ClassTag](n: Int)(f: Int => T): IArray[T] =
130-
Array.tabulate(n)(f)
134+
Array.tabulate(n)(f).asInstanceOf
131135

132136
/** Returns a two-dimensional immutable array containing values of a given function
133137
* over ranges of integer values starting from `0`.
@@ -137,7 +141,7 @@ object IArray {
137141
* @param f The function computing element values
138142
*/
139143
def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): IArray[IArray[T]] =
140-
Array.tabulate(n1, n2)(f)
144+
Array.tabulate(n1, n2)(f).asInstanceOf
141145

142146
/** Returns a three-dimensional immutable array containing values of a given function
143147
* over ranges of integer values starting from `0`.
@@ -148,7 +152,7 @@ object IArray {
148152
* @param f The function computing element values
149153
*/
150154
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): IArray[IArray[IArray[T]]] =
151-
Array.tabulate(n1, n2, n3)(f)
155+
Array.tabulate(n1, n2, n3)(f).asInstanceOf
152156

153157
/** Returns a four-dimensional immutable array containing values of a given function
154158
* over ranges of integer values starting from `0`.
@@ -160,7 +164,7 @@ object IArray {
160164
* @param f The function computing element values
161165
*/
162166
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): IArray[IArray[IArray[IArray[T]]]] =
163-
Array.tabulate(n1, n2, n3, n4)(f)
167+
Array.tabulate(n1, n2, n3, n4)(f).asInstanceOf
164168

165169
/** Returns a five-dimensional immutable array containing values of a given function
166170
* over ranges of integer values starting from `0`.
@@ -173,7 +177,7 @@ object IArray {
173177
* @param f The function computing element values
174178
*/
175179
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]]]]] =
176-
Array.tabulate(n1, n2, n3, n4, n5)(f)
180+
Array.tabulate(n1, n2, n3, n4, n5)(f).asInstanceOf
177181

178182
/** Returns an immutable array containing a sequence of increasing integers in a range.
179183
*
@@ -182,7 +186,7 @@ object IArray {
182186
* @return the immutable array with values in range `start, start + 1, ..., end - 1`
183187
* up to, but excluding, `end`.
184188
*/
185-
def range(start: Int, end: Int): IArray[Int] = Array.range(start, end)
189+
def range(start: Int, end: Int): IArray[Int] = Array.range(start, end).asInstanceOf
186190

187191
/** Returns an immutable array containing equally spaced values in some integer interval.
188192
*
@@ -191,7 +195,7 @@ object IArray {
191195
* @param step the increment value of the array (may not be zero)
192196
* @return the immutable array with values in `start, start + step, ...` up to, but excluding `end`
193197
*/
194-
def range(start: Int, end: Int, step: Int): IArray[Int] = Array.range(start, end, step)
198+
def range(start: Int, end: Int, step: Int): IArray[Int] = Array.range(start, end, step).asInstanceOf
195199

196200
/** Returns an immutable array containing repeated applications of a function to a start value.
197201
*
@@ -200,7 +204,7 @@ object IArray {
200204
* @param f the function that is repeatedly applied
201205
* @return the immutable array returning `len` values in the sequence `start, f(start), f(f(start)), ...`
202206
*/
203-
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): IArray[T] = Array.iterate(start, len)(f)
207+
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): IArray[T] = Array.iterate(start, len)(f).asInstanceOf
204208

205209
/** Returns a decomposition of the array into a sequence. This supports
206210
* a pattern match like `{ case IArray(x,y,z) => println('3 elements')}`.

0 commit comments

Comments
 (0)