@@ -25,7 +25,7 @@ sealed trait Tuple extends Any {
25
25
case Some (n) =>
26
26
asInstanceOf [TupleXXL ].elems
27
27
case None =>
28
- error( " .toArray cannot be applied to tuple of unknown size " )
28
+ dynamicToArray( this )
29
29
}
30
30
31
31
rewrite def *: [H ] (x : H ): H *: this .type = {
@@ -47,7 +47,7 @@ sealed trait Tuple extends Any {
47
47
case Some (n) =>
48
48
fromArray[Result ]($consArray(x, toArray))
49
49
case _ =>
50
- error( " *: cannot be applied to tuple of unknown size " )
50
+ dynamic _*: [ this . type , H ]( this , x )
51
51
}
52
52
}
53
53
@@ -86,12 +86,20 @@ sealed trait Tuple extends Any {
86
86
if (constValue[BoundedSize [that.type ]] == 0 ) this .asInstanceOf [Result ]
87
87
else genericConcat[Result ](this , that).asInstanceOf [Result ]
88
88
case None =>
89
- error( " ++ cannot be applied to tuple of unknown size " )
89
+ dynamic_ ++ [ this . type , that. type ]( this , that )
90
90
}
91
91
}
92
92
93
93
rewrite def genericConcat [T <: Tuple ](xs : Tuple , ys : Tuple ): Tuple =
94
94
fromArray[T ](xs.toArray ++ ys.toArray)
95
+
96
+ rewrite def size : Size [this .type ] = {
97
+ type Result = Size [this .type ]
98
+ rewrite constValueOpt[BoundedSize [this .type ]] match {
99
+ case Some (n) => n.asInstanceOf [Result ]
100
+ case _ => dynamicSize(this ).asInstanceOf [Result ]
101
+ }
102
+ }
95
103
}
96
104
97
105
object Tuple {
@@ -183,10 +191,98 @@ object Tuple {
183
191
case 22 => Tuple22 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 ), xs(15 ), xs(16 ), xs(17 ), xs(18 ), xs(19 ), xs(20 ), xs(21 )).asInstanceOf [T ]
184
192
case _ => TupleXXL (xs).asInstanceOf [T ]
185
193
}
194
+
195
+ def dynamicFromArray [T <: Tuple ](xs : Array [Object ]): T = xs.length match {
196
+ case 0 => ().asInstanceOf [T ]
197
+ case 1 => Tuple1 (xs(0 )).asInstanceOf [T ]
198
+ case 2 => Tuple2 (xs(0 ), xs(1 )).asInstanceOf [T ]
199
+ case 3 => Tuple3 (xs(0 ), xs(1 ), xs(2 )).asInstanceOf [T ]
200
+ case 4 => Tuple4 (xs(0 ), xs(1 ), xs(2 ), xs(3 )).asInstanceOf [T ]
201
+ case 5 => Tuple5 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 )).asInstanceOf [T ]
202
+ case 6 => Tuple6 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 )).asInstanceOf [T ]
203
+ case 7 => Tuple7 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 )).asInstanceOf [T ]
204
+ case 8 => Tuple8 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 )).asInstanceOf [T ]
205
+ case 9 => Tuple9 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 )).asInstanceOf [T ]
206
+ case 10 => Tuple10 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 )).asInstanceOf [T ]
207
+ case 11 => Tuple11 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 )).asInstanceOf [T ]
208
+ case 12 => Tuple12 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 )).asInstanceOf [T ]
209
+ case 13 => Tuple13 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 )).asInstanceOf [T ]
210
+ case 14 => Tuple14 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 )).asInstanceOf [T ]
211
+ case 15 => Tuple15 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 )).asInstanceOf [T ]
212
+ case 16 => Tuple16 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 ), xs(15 )).asInstanceOf [T ]
213
+ case 17 => Tuple17 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 ), xs(15 ), xs(16 )).asInstanceOf [T ]
214
+ case 18 => Tuple18 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 ), xs(15 ), xs(16 ), xs(17 )).asInstanceOf [T ]
215
+ case 19 => Tuple19 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 ), xs(15 ), xs(16 ), xs(17 ), xs(18 )).asInstanceOf [T ]
216
+ case 20 => Tuple20 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 ), xs(15 ), xs(16 ), xs(17 ), xs(18 ), xs(19 )).asInstanceOf [T ]
217
+ case 21 => Tuple21 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 ), xs(15 ), xs(16 ), xs(17 ), xs(18 ), xs(19 ), xs(20 )).asInstanceOf [T ]
218
+ case 22 => Tuple22 (xs(0 ), xs(1 ), xs(2 ), xs(3 ), xs(4 ), xs(5 ), xs(6 ), xs(7 ), xs(8 ), xs(9 ), xs(10 ), xs(11 ), xs(12 ), xs(13 ), xs(14 ), xs(15 ), xs(16 ), xs(17 ), xs(18 ), xs(19 ), xs(20 ), xs(21 )).asInstanceOf [T ]
219
+ case _ => TupleXXL (xs).asInstanceOf [T ]
220
+ }
221
+
222
+ def dynamicToArray (self : Tuple ): Array [Object ] = (self : Any ) match {
223
+ case self : Unit =>
224
+ $emptyArray
225
+ case self : Tuple1 [_] =>
226
+ val t = self.asInstanceOf [Tuple1 [Object ]]
227
+ Array (t._1)
228
+ case self : Tuple2 [_, _] =>
229
+ val t = self.asInstanceOf [Tuple2 [Object , Object ]]
230
+ Array (t._1, t._2)
231
+ case self : Tuple3 [_, _, _] =>
232
+ val t = self.asInstanceOf [Tuple3 [Object , Object , Object ]]
233
+ Array (t._1, t._2, t._3)
234
+ case self : Tuple4 [_, _, _, _] =>
235
+ val t = self.asInstanceOf [Tuple4 [Object , Object , Object , Object ]]
236
+ Array (t._1, t._2, t._3, t._4)
237
+ case self : TupleXXL =>
238
+ asInstanceOf [TupleXXL ].elems
239
+ case self : Product =>
240
+ val arr = new Array [Object ](self.productArity)
241
+ for (i <- 0 until arr.length) arr(i) = self.productElement(i).asInstanceOf [Object ]
242
+ arr
243
+ }
244
+
245
+ def dynamic_*: [This <: Tuple , H ] (self : Tuple , x : H ): H *: This = {
246
+ type Result = H *: This
247
+ (self : Any ) match {
248
+ case Unit =>
249
+ Tuple1 (x).asInstanceOf [Result ]
250
+ case self : Tuple1 [_] =>
251
+ Tuple2 (x, self._1).asInstanceOf [Result ]
252
+ case self : Tuple2 [_, _] =>
253
+ Tuple3 (x, self._1, self._2).asInstanceOf [Result ]
254
+ case self : Tuple3 [_, _, _] =>
255
+ Tuple4 (x, self._1, self._2, self._3).asInstanceOf [Result ]
256
+ case self : Tuple4 [_, _, _, _] =>
257
+ Tuple5 (x, self._1, self._2, self._3, self._4).asInstanceOf [Result ]
258
+ case _ =>
259
+ dynamicFromArray[Result ]($consArray(x, dynamicToArray(self)))
260
+ }
261
+ }
262
+
263
+ def dynamic_++ [This <: Tuple , That <: Tuple ](self : This , that : That ): Concat [This , That ] = {
264
+ type Result = Concat [This , That ]
265
+ (this : Any ) match {
266
+ case self : Unit => return self.asInstanceOf [Result ]
267
+ case _ =>
268
+ }
269
+ (that : Any ) match {
270
+ case that : Unit => return self.asInstanceOf [Result ]
271
+ case _ =>
272
+ }
273
+ dynamicFromArray[Result ](dynamicToArray(self) ++ dynamicToArray(that))
274
+ }
275
+
276
+ def dynamicSize [This <: Tuple ](self : This ) = (self : Any ) match {
277
+ case self : Unit => 0
278
+ case self : TupleXXL => self.elems.length
279
+ case self : Product => self.productArity
280
+ }
186
281
}
187
282
188
283
abstract sealed class NonEmptyTuple extends Tuple {
189
284
import Tuple ._
285
+ import NonEmptyTuple ._
190
286
191
287
rewrite def head : Head [this .type ] = {
192
288
type Result = Head [this .type ]
@@ -209,7 +305,7 @@ abstract sealed class NonEmptyTuple extends Tuple {
209
305
val t = asInstanceOf [TupleXXL ]
210
306
t.elems(0 )
211
307
case None =>
212
- error( " .head cannot be applied to tuple of unknown size " )
308
+ dynamicHead[ this . type ]( this )
213
309
}
214
310
resVal.asInstanceOf [Result ]
215
311
}
@@ -234,54 +330,101 @@ abstract sealed class NonEmptyTuple extends Tuple {
234
330
case Some (n) if n > 5 =>
235
331
fromArray[Result ](toArray.tail)
236
332
case None =>
237
- error( " .tail cannot be applied to tuple of unknown size " )
333
+ dynamicTail[ this . type ]( this )
238
334
}
239
335
}
240
336
241
- rewrite def indexOutOfBounds = error(" index out of bounds" )
337
+ rewrite def fallbackApply (n : Int ) =
338
+ rewrite constValueOpt[n.type ] match {
339
+ case Some (n : Int ) => error(" index out of bounds" , n)
340
+ case None => dynamicApply[this .type ](this , n)
341
+ }
242
342
243
- rewrite def apply (transparent n : Int ): Elem [this .type , n.type ] = {
343
+ rewrite def apply (n : Int ): Elem [this .type , n.type ] = {
244
344
type Result = Elem [this .type , n.type ]
245
345
rewrite constValueOpt[BoundedSize [this .type ]] match {
246
346
case Some (1 ) =>
247
347
val t = asInstanceOf [Tuple1 [_]]
248
- rewrite n match {
249
- case 0 => t._1.asInstanceOf [Result ]
250
- case _ => indexOutOfBounds
348
+ rewrite constValueOpt[n. type ] match {
349
+ case Some ( 0 ) => t._1.asInstanceOf [Result ]
350
+ case _ => fallbackApply(n). asInstanceOf [ Result ]
251
351
}
252
352
case Some (2 ) =>
253
353
val t = asInstanceOf [Tuple2 [_, _]]
254
- rewrite n match {
255
- case 0 => t._1.asInstanceOf [Result ]
256
- case 1 => t._2.asInstanceOf [Result ]
257
- case _ => indexOutOfBounds
354
+ rewrite constValueOpt[n. type ] match {
355
+ case Some ( 0 ) => t._1.asInstanceOf [Result ]
356
+ case Some ( 1 ) => t._2.asInstanceOf [Result ]
357
+ case _ => fallbackApply(n). asInstanceOf [ Result ]
258
358
}
259
359
case Some (3 ) =>
260
360
val t = asInstanceOf [Tuple3 [_, _, _]]
261
- rewrite n match {
262
- case 0 => t._1.asInstanceOf [Result ]
263
- case 1 => t._2.asInstanceOf [Result ]
264
- case 2 => t._3.asInstanceOf [Result ]
265
- case _ => indexOutOfBounds
361
+ rewrite constValueOpt[n. type ] match {
362
+ case Some ( 0 ) => t._1.asInstanceOf [Result ]
363
+ case Some ( 1 ) => t._2.asInstanceOf [Result ]
364
+ case Some ( 2 ) => t._3.asInstanceOf [Result ]
365
+ case _ => fallbackApply(n). asInstanceOf [ Result ]
266
366
}
267
367
case Some (4 ) =>
268
368
val t = asInstanceOf [Tuple4 [_, _, _, _]]
269
- rewrite n match {
270
- case 0 => t._1.asInstanceOf [Result ]
271
- case 1 => t._2.asInstanceOf [Result ]
272
- case 2 => t._3.asInstanceOf [Result ]
273
- case 3 => t._4.asInstanceOf [Result ]
274
- case _ => indexOutOfBounds
369
+ rewrite constValueOpt[n. type ] match {
370
+ case Some ( 0 ) => t._1.asInstanceOf [Result ]
371
+ case Some ( 1 ) => t._2.asInstanceOf [Result ]
372
+ case Some ( 2 ) => t._3.asInstanceOf [Result ]
373
+ case Some ( 3 ) => t._4.asInstanceOf [Result ]
374
+ case _ => fallbackApply(n). asInstanceOf [ Result ]
275
375
}
276
- case Some (s) if s > 4 && s <= $MaxSpecialized && n >= 0 && n < s =>
277
- asInstanceOf [Product ].productElement(n).asInstanceOf [Result ]
278
- case Some (s) if s > $MaxSpecialized && n >= 0 && n < s =>
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" )
376
+ case Some (s) if s > 4 && s <= $MaxSpecialized =>
377
+ val t = asInstanceOf [Product ]
378
+ rewrite constValueOpt[n.type ] match {
379
+ case Some (n) if n >= 0 && n < s => t.productElement(n).asInstanceOf [Result ]
380
+ case _ => fallbackApply(n).asInstanceOf [Result ]
381
+ }
382
+ case Some (s) if s > $MaxSpecialized =>
383
+ val t = asInstanceOf [TupleXXL ]
384
+ rewrite constValueOpt[n.type ] match {
385
+ case Some (n) if n >= 0 && n < s => t.elems(n).asInstanceOf [Result ]
386
+ case _ => fallbackApply(n).asInstanceOf [Result ]
387
+ }
388
+ case _ => fallbackApply(n).asInstanceOf [Result ]
389
+ }
390
+ }
391
+ }
392
+
393
+ object NonEmptyTuple {
394
+ import Tuple ._
395
+
396
+ def dynamicHead [This <: NonEmptyTuple ] (self : This ): Head [This ] = {
397
+ type Result = Head [This ]
398
+ val res = (self : Any ) match {
399
+ case self : Tuple1 [_] => self._1
400
+ case self : Tuple2 [_, _] => self._1
401
+ case self : Tuple3 [_, _, _] => self._1
402
+ case self : Tuple4 [_, _, _, _] => self._1
403
+ case self : TupleXXL => self.elems(0 )
404
+ case self : Product => self.productElement(0 )
405
+ }
406
+ res.asInstanceOf [Result ]
407
+ }
408
+
409
+ def dynamicTail [This <: NonEmptyTuple ] (self : This ): Tail [This ] = {
410
+ type Result = Tail [This ]
411
+ val res = (self : Any ) match {
412
+ case self : Tuple1 [_] => self._1
413
+ case self : Tuple2 [_, _] => Tuple1 (self._2)
414
+ case self : Tuple3 [_, _, _] => Tuple2 (self._2, self._3)
415
+ case self : Tuple4 [_, _, _, _] => Tuple3 (self._2, self._3, self._4)
416
+ case _ => dynamicFromArray[Result ](self.toArray.tail)
417
+ }
418
+ res.asInstanceOf [Result ]
419
+ }
420
+
421
+ def dynamicApply [This <: NonEmptyTuple ] (self : This , n : Int ): Elem [This , n.type ] = {
422
+ type Result = Elem [This , n.type ]
423
+ val res = (self : Any ) match {
424
+ case self : TupleXXL => self.elems(n)
425
+ case self : Product => self.productElement(n)
284
426
}
427
+ res.asInstanceOf [Result ]
285
428
}
286
429
}
287
430
0 commit comments