@@ -25,7 +25,7 @@ sealed trait Tuple extends Any {
2525 case Some (n) =>
2626 asInstanceOf [TupleXXL ].elems
2727 case None =>
28- error( " .toArray cannot be applied to tuple of unknown size " )
28+ dynamicToArray( this )
2929 }
3030
3131 rewrite def *: [H ] (x : H ): H *: this .type = {
@@ -47,7 +47,7 @@ sealed trait Tuple extends Any {
4747 case Some (n) =>
4848 fromArray[Result ]($consArray(x, toArray))
4949 case _ =>
50- error( " *: cannot be applied to tuple of unknown size " )
50+ dynamic _*: [ this . type , H ]( this , x )
5151 }
5252 }
5353
@@ -86,12 +86,20 @@ sealed trait Tuple extends Any {
8686 if (constValue[BoundedSize [that.type ]] == 0 ) this .asInstanceOf [Result ]
8787 else genericConcat[Result ](this , that).asInstanceOf [Result ]
8888 case None =>
89- error( " ++ cannot be applied to tuple of unknown size " )
89+ dynamic_ ++ [ this . type , that. type ]( this , that )
9090 }
9191 }
9292
9393 rewrite def genericConcat [T <: Tuple ](xs : Tuple , ys : Tuple ): Tuple =
9494 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+ }
95103}
96104
97105object Tuple {
@@ -183,10 +191,98 @@ object Tuple {
183191 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 ]
184192 case _ => TupleXXL (xs).asInstanceOf [T ]
185193 }
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+ }
186281}
187282
188283abstract sealed class NonEmptyTuple extends Tuple {
189284 import Tuple ._
285+ import NonEmptyTuple ._
190286
191287 rewrite def head : Head [this .type ] = {
192288 type Result = Head [this .type ]
@@ -209,7 +305,7 @@ abstract sealed class NonEmptyTuple extends Tuple {
209305 val t = asInstanceOf [TupleXXL ]
210306 t.elems(0 )
211307 case None =>
212- error( " .head cannot be applied to tuple of unknown size " )
308+ dynamicHead[ this . type ]( this )
213309 }
214310 resVal.asInstanceOf [Result ]
215311 }
@@ -234,54 +330,101 @@ abstract sealed class NonEmptyTuple extends Tuple {
234330 case Some (n) if n > 5 =>
235331 fromArray[Result ](toArray.tail)
236332 case None =>
237- error( " .tail cannot be applied to tuple of unknown size " )
333+ dynamicTail[ this . type ]( this )
238334 }
239335 }
240336
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+ }
242342
243- rewrite def apply (transparent n : Int ): Elem [this .type , n.type ] = {
343+ rewrite def apply (n : Int ): Elem [this .type , n.type ] = {
244344 type Result = Elem [this .type , n.type ]
245345 rewrite constValueOpt[BoundedSize [this .type ]] match {
246346 case Some (1 ) =>
247347 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 ]
251351 }
252352 case Some (2 ) =>
253353 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 ]
258358 }
259359 case Some (3 ) =>
260360 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 ]
266366 }
267367 case Some (4 ) =>
268368 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 ]
275375 }
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)
284426 }
427+ res.asInstanceOf [Result ]
285428 }
286429}
287430
0 commit comments