@@ -5,82 +5,88 @@ import typelevel._
5
5
sealed trait Tuple extends Any {
6
6
import Tuple ._
7
7
8
- rewrite def toArray : Array [Object ] = rewrite constValue [BoundedSize [this .type ]] match {
9
- case 0 =>
8
+ rewrite def toArray : Array [Object ] = rewrite constValueOpt [BoundedSize [this .type ]] match {
9
+ case Some ( 0 ) =>
10
10
$emptyArray
11
- case 1 =>
11
+ case Some ( 1 ) =>
12
12
val t = asInstanceOf [Tuple1 [Object ]]
13
13
Array (t._1)
14
- case 2 =>
14
+ case Some ( 2 ) =>
15
15
val t = asInstanceOf [Tuple2 [Object , Object ]]
16
16
Array (t._1, t._2)
17
- case 3 =>
17
+ case Some ( 3 ) =>
18
18
val t = asInstanceOf [Tuple3 [Object , Object , Object ]]
19
19
Array (t._1, t._2, t._3)
20
- case 4 =>
20
+ case Some ( 4 ) =>
21
21
val t = asInstanceOf [Tuple4 [Object , Object , Object , Object ]]
22
22
Array (t._1, t._2, t._3, t._4)
23
- case n if n <= $MaxSpecialized =>
23
+ case Some (n) if n <= $MaxSpecialized =>
24
24
$toArray(this , n)
25
- case n =>
25
+ case Some (n) =>
26
26
asInstanceOf [TupleXXL ].elems
27
+ case None =>
28
+ error(" .toArray cannot be applied to tuple of unknown size" )
27
29
}
28
30
29
- rewrite def *: [H ] (x : H ): Tuple = {
30
- erased val resTpe = Typed (_pair(x, this ))
31
- rewrite _size( this ) match {
32
- case 0 =>
33
- Tuple1 (x).asInstanceOf [resTpe. Type ]
34
- case 1 =>
35
- Tuple2 (x, asInstanceOf [Tuple1 [_]]._1).asInstanceOf [resTpe. Type ]
36
- case 2 =>
31
+ rewrite def *: [H ] (x : H ): H *: this . type = {
32
+ type Result = H *: this . type
33
+ rewrite constValueOpt[ BoundedSize [ this . type ]] match {
34
+ case Some ( 0 ) =>
35
+ Tuple1 (x).asInstanceOf [Result ]
36
+ case Some ( 1 ) =>
37
+ Tuple2 (x, asInstanceOf [Tuple1 [_]]._1).asInstanceOf [Result ]
38
+ case Some ( 2 ) =>
37
39
val t = asInstanceOf [Tuple2 [_, _]]
38
- Tuple3 (x, t._1, t._2).asInstanceOf [resTpe. Type ]
39
- case 3 =>
40
+ Tuple3 (x, t._1, t._2).asInstanceOf [Result ]
41
+ case Some ( 3 ) =>
40
42
val t = asInstanceOf [Tuple3 [_, _, _]]
41
- Tuple4 (x, t._1, t._2, t._3).asInstanceOf [resTpe. Type ]
42
- case 4 =>
43
+ Tuple4 (x, t._1, t._2, t._3).asInstanceOf [Result ]
44
+ case Some ( 4 ) =>
43
45
val t = asInstanceOf [Tuple4 [_, _, _, _]]
44
- Tuple5 (x, t._1, t._2, t._3, t._4).asInstanceOf [resTpe.Type ]
45
- case n =>
46
- fromArray[resTpe.Type ]($consArray(x, toArray))
46
+ Tuple5 (x, t._1, t._2, t._3, t._4).asInstanceOf [Result ]
47
+ case Some (n) =>
48
+ fromArray[Result ]($consArray(x, toArray))
49
+ case _ =>
50
+ error(" *: cannot be applied to tuple of unknown size" )
47
51
}
48
52
}
49
53
50
- rewrite def ++ (that : Tuple ): Tuple = {
54
+ rewrite def ++ (that : Tuple ): Concat [ this . type , that. type ] = {
51
55
type Result = Concat [this .type , that.type ]
52
- rewrite constValue [BoundedSize [this .type ]] match {
53
- case 0 =>
54
- that
55
- case 1 =>
56
- if (constValue[BoundedSize [that.type ]] == 0 ) this
56
+ rewrite constValueOpt [BoundedSize [this .type ]] match {
57
+ case Some ( 0 ) =>
58
+ that. asInstanceOf [ Result ]
59
+ case Some ( 1 ) =>
60
+ if (constValue[BoundedSize [that.type ]] == 0 ) this . asInstanceOf [ Result ]
57
61
else (asInstanceOf [Tuple1 [_]]._1 *: that).asInstanceOf [Result ]
58
- case 2 =>
62
+ case Some ( 2 ) =>
59
63
val t = asInstanceOf [Tuple2 [_, _]]
60
64
rewrite constValue[BoundedSize [that.type ]] match {
61
- case 0 => this
65
+ case 0 => this . asInstanceOf [ Result ]
62
66
case 1 =>
63
67
val u = that.asInstanceOf [Tuple1 [_]]
64
68
Tuple3 (t._1, t._2, u._1).asInstanceOf [Result ]
65
69
case 2 =>
66
70
val u = that.asInstanceOf [Tuple2 [_, _]]
67
71
Tuple4 (t._1, t._2, u._1, u._2).asInstanceOf [Result ]
68
72
case _ =>
69
- genericConcat[Result ](this , that)
73
+ genericConcat[Result ](this , that). asInstanceOf [ Result ]
70
74
}
71
- case 3 =>
75
+ case Some ( 3 ) =>
72
76
val t = asInstanceOf [Tuple3 [_, _, _]]
73
77
rewrite constValue[BoundedSize [that.type ]] match {
74
- case 0 => this
78
+ case 0 => this . asInstanceOf [ Result ]
75
79
case 1 =>
76
80
val u = that.asInstanceOf [Tuple1 [_]]
77
81
Tuple4 (t._1, t._2, t._3, u._1).asInstanceOf [Result ]
78
82
case _ =>
79
- genericConcat[Result ](this , that)
83
+ genericConcat[Result ](this , that). asInstanceOf [ Result ]
80
84
}
81
- case _ =>
82
- if (constValue[BoundedSize [that.type ]] == 0 ) this
83
- else genericConcat[Result ](this , that)
85
+ case Some (_) =>
86
+ if (constValue[BoundedSize [that.type ]] == 0 ) this .asInstanceOf [Result ]
87
+ else genericConcat[Result ](this , that).asInstanceOf [Result ]
88
+ case None =>
89
+ error(" ++ cannot be applied to tuple of unknown size" )
84
90
}
85
91
}
86
92
@@ -92,6 +98,14 @@ object Tuple {
92
98
transparent val $MaxSpecialized = 22
93
99
transparent private val XXL = $MaxSpecialized + 1
94
100
101
+ type Head [X <: NonEmptyTuple ] = X match {
102
+ case x *: _ => x
103
+ }
104
+
105
+ type Tail [X <: NonEmptyTuple ] <: Tuple = X match {
106
+ case _ *: xs => xs
107
+ }
108
+
95
109
type Concat [X <: Tuple , Y <: Tuple ] <: Tuple = X match {
96
110
case Unit => Y
97
111
case x1 *: xs1 => x1 *: Concat [xs1, Y ]
@@ -142,33 +156,6 @@ object Tuple {
142
156
elems1
143
157
}
144
158
145
- private [scala] rewrite def _pair [H , T <: Tuple ] (x : H , xs : T ): Tuple =
146
- erasedValue[H *: T ]
147
-
148
- private [scala] rewrite def _size (xs : Tuple ): Int =
149
- rewrite xs match {
150
- case _ : Unit => 0
151
- case _ : (_ *: xs1) => _size(erasedValue[xs1]) + 1
152
- }
153
-
154
- private [scala] rewrite def _head (xs : Tuple ): Any = rewrite xs match {
155
- case _ : (x *: _) => erasedValue[x]
156
- }
157
-
158
- private [scala] rewrite def _tail (xs : Tuple ): Tuple = rewrite xs match {
159
- case _ : (_ *: xs1) => erasedValue[xs1]
160
- }
161
-
162
- private [scala] rewrite def _index (xs : Tuple , n : Int ): Any = rewrite xs match {
163
- case _ : (x *: _) if n == 0 => erasedValue[x]
164
- case _ : (_ *: xs1) if n > 0 => _index(erasedValue[xs1], n - 1 )
165
- }
166
-
167
- private [scala] rewrite def _concat (xs : Tuple , ys : Tuple ): Tuple = rewrite xs match {
168
- case _ : Unit => ys
169
- case _ : (x1 *: xs1) => _pair(erasedValue[x1], _concat(erasedValue[xs1], ys))
170
- }
171
-
172
159
rewrite def fromArray [T <: Tuple ](xs : Array [Object ]): T =
173
160
rewrite constValue[BoundedSize [T ]] match {
174
161
case 0 => ().asInstanceOf [T ]
@@ -201,85 +188,99 @@ object Tuple {
201
188
abstract sealed class NonEmptyTuple extends Tuple {
202
189
import Tuple ._
203
190
204
- rewrite def head : Any = {
205
- erased val resTpe = Typed (_head( this ))
206
- val resVal = rewrite _size( this ) match {
207
- case 1 =>
191
+ rewrite def head : Head [ this . type ] = {
192
+ type Result = Head [ this . type ]
193
+ val resVal = rewrite constValueOpt[ BoundedSize [ this . type ]] match {
194
+ case Some ( 1 ) =>
208
195
val t = asInstanceOf [Tuple1 [_]]
209
196
t._1
210
- case 2 =>
197
+ case Some ( 2 ) =>
211
198
val t = asInstanceOf [Tuple2 [_, _]]
212
199
t._1
213
- case 3 =>
200
+ case Some ( 3 ) =>
214
201
val t = asInstanceOf [Tuple3 [_, _, _]]
215
202
t._1
216
- case 4 =>
203
+ case Some ( 4 ) =>
217
204
val t = asInstanceOf [Tuple4 [_, _, _, _]]
218
205
t._1
219
- case n if n > 4 && n <= $MaxSpecialized =>
206
+ case Some (n) if n > 4 && n <= $MaxSpecialized =>
220
207
asInstanceOf [Product ].productElement(0 )
221
- case n if n > $MaxSpecialized =>
208
+ case Some (n) if n > $MaxSpecialized =>
222
209
val t = asInstanceOf [TupleXXL ]
223
210
t.elems(0 )
211
+ case None =>
212
+ error(" .head cannot be applied to tuple of unknown size" )
224
213
}
225
- resVal.asInstanceOf [resTpe. Type ]
214
+ resVal.asInstanceOf [Result ]
226
215
}
227
216
228
- rewrite def tail : Tuple = {
229
- erased val resTpe = Typed (_tail( this ))
230
- rewrite _size( this ) match {
231
- case 1 =>
232
- ()
233
- case 2 =>
217
+ rewrite def tail : Tail [ this . type ] = {
218
+ type Result = Tail [ this . type ]
219
+ rewrite constValueOpt[ BoundedSize [ this . type ]] match {
220
+ case Some ( 1 ) =>
221
+ (). asInstanceOf [ Result ]
222
+ case Some ( 2 ) =>
234
223
val t = asInstanceOf [Tuple2 [_, _]]
235
- Tuple1 (t._2).asInstanceOf [resTpe. Type ]
236
- case 3 =>
224
+ Tuple1 (t._2).asInstanceOf [Result ]
225
+ case Some ( 3 ) =>
237
226
val t = asInstanceOf [Tuple3 [_, _, _]]
238
- Tuple2 (t._2, t._3).asInstanceOf [resTpe. Type ]
239
- case 4 =>
227
+ Tuple2 (t._2, t._3).asInstanceOf [Result ]
228
+ case Some ( 4 ) =>
240
229
val t = asInstanceOf [Tuple4 [_, _, _, _]]
241
- Tuple3 (t._2, t._3, t._4).asInstanceOf [resTpe. Type ]
242
- case 5 =>
230
+ Tuple3 (t._2, t._3, t._4).asInstanceOf [Result ]
231
+ case Some ( 5 ) =>
243
232
val t = asInstanceOf [Tuple5 [_, _, _, _, _]]
244
- Tuple4 (t._2, t._3, t._4, t._5).asInstanceOf [resTpe.Type ]
245
- case n if n > 5 =>
246
- fromArray[resTpe.Type ](toArray.tail)
233
+ Tuple4 (t._2, t._3, t._4, t._5).asInstanceOf [Result ]
234
+ case Some (n) if n > 5 =>
235
+ fromArray[Result ](toArray.tail)
236
+ case None =>
237
+ error(" .tail cannot be applied to tuple of unknown size" )
247
238
}
248
239
}
249
240
250
- rewrite def apply (n : Int ): Any = {
241
+ rewrite def indexOutOfBounds = error(" index out of bounds" )
242
+
243
+ rewrite def apply (transparent n : Int ): Elem [this .type , n.type ] = {
251
244
type Result = Elem [this .type , n.type ]
252
- rewrite constValue [BoundedSize [this .type ]] match {
253
- case 1 =>
245
+ rewrite constValueOpt [BoundedSize [this .type ]] match {
246
+ case Some ( 1 ) =>
254
247
val t = asInstanceOf [Tuple1 [_]]
255
248
rewrite n match {
256
249
case 0 => t._1.asInstanceOf [Result ]
250
+ case _ => indexOutOfBounds
257
251
}
258
- case 2 =>
252
+ case Some ( 2 ) =>
259
253
val t = asInstanceOf [Tuple2 [_, _]]
260
254
rewrite n match {
261
255
case 0 => t._1.asInstanceOf [Result ]
262
256
case 1 => t._2.asInstanceOf [Result ]
257
+ case _ => indexOutOfBounds
263
258
}
264
- case 3 =>
259
+ case Some ( 3 ) =>
265
260
val t = asInstanceOf [Tuple3 [_, _, _]]
266
261
rewrite n match {
267
262
case 0 => t._1.asInstanceOf [Result ]
268
263
case 1 => t._2.asInstanceOf [Result ]
269
264
case 2 => t._3.asInstanceOf [Result ]
265
+ case _ => indexOutOfBounds
270
266
}
271
- case 4 =>
267
+ case Some ( 4 ) =>
272
268
val t = asInstanceOf [Tuple4 [_, _, _, _]]
273
269
rewrite n match {
274
270
case 0 => t._1.asInstanceOf [Result ]
275
271
case 1 => t._2.asInstanceOf [Result ]
276
272
case 2 => t._3.asInstanceOf [Result ]
277
273
case 3 => t._4.asInstanceOf [Result ]
274
+ case _ => indexOutOfBounds
278
275
}
279
- case s if s > 4 && s <= $MaxSpecialized && n >= 0 && n < s =>
276
+ case Some (s) if s > 4 && s <= $MaxSpecialized && n >= 0 && n < s =>
280
277
asInstanceOf [Product ].productElement(n).asInstanceOf [Result ]
281
- case s if s > $MaxSpecialized && n >= 0 && n < s =>
278
+ case Some (s) if s > $MaxSpecialized && n >= 0 && n < s =>
282
279
asInstanceOf [TupleXXL ].elems(n).asInstanceOf [Result ]
280
+ case Some (s) =>
281
+ indexOutOfBounds
282
+ case None =>
283
+ error(" selection (...) cannot be applied to tuple of unknown size" )
283
284
}
284
285
}
285
286
}
0 commit comments