@@ -45,6 +45,46 @@ sealed trait Tuple extends Any {
4545 fromArray[resTpe.Type ]($consArray(x, toArray))
4646 }
4747 }
48+
49+ rewrite def ++ (that : Tuple ): Tuple = {
50+ erased val resTpe = Typed (_concat(this , that))
51+ rewrite _size(this ) match {
52+ case 0 =>
53+ that
54+ case 1 =>
55+ if (_size(that) == 0 ) this
56+ else (asInstanceOf [Tuple1 [_]]._1 *: that).asInstanceOf [resTpe.Type ]
57+ case 2 =>
58+ val t = asInstanceOf [Tuple2 [_, _]]
59+ rewrite _size(that) match {
60+ case 0 => this
61+ case 1 =>
62+ val u = that.asInstanceOf [Tuple1 [_]]
63+ Tuple3 (t._1, t._2, u._1).asInstanceOf [resTpe.Type ]
64+ case 2 =>
65+ val u = that.asInstanceOf [Tuple2 [_, _]]
66+ Tuple4 (t._1, t._2, u._1, u._2).asInstanceOf [resTpe.Type ]
67+ case _ =>
68+ genericConcat[resTpe.Type ](this , that)
69+ }
70+ case 3 =>
71+ val t = asInstanceOf [Tuple3 [_, _, _]]
72+ rewrite _size(that) match {
73+ case 0 => this
74+ case 1 =>
75+ val u = that.asInstanceOf [Tuple1 [_]]
76+ Tuple4 (t._1, t._2, t._3, u._1).asInstanceOf [resTpe.Type ]
77+ case _ =>
78+ genericConcat[resTpe.Type ](this , that)
79+ }
80+ case _ =>
81+ if (_size(that) == 0 ) this
82+ else genericConcat[resTpe.Type ](this , that)
83+ }
84+ }
85+
86+ rewrite def genericConcat [T <: Tuple ](xs : Tuple , ys : Tuple ): Tuple =
87+ fromArray[T ](xs.toArray ++ ys.toArray)
4888}
4989
5090object Tuple {
@@ -83,6 +123,20 @@ object Tuple {
83123 case _ : (x *: _) => erasedValue[x]
84124 }
85125
126+ private [scala] rewrite def _tail (xs : Tuple ): Tuple = rewrite xs match {
127+ case _ : (_ *: xs1) => erasedValue[xs1]
128+ }
129+
130+ private [scala] rewrite def _index (xs : Tuple , n : Int ): Any = rewrite xs match {
131+ case _ : (x *: _) if n == 0 => erasedValue[x]
132+ case _ : (_ *: xs1) if n > 0 => _index(erasedValue[xs1], n - 1 )
133+ }
134+
135+ private [scala] rewrite def _concat (xs : Tuple , ys : Tuple ): Tuple = rewrite xs match {
136+ case _ : Unit => ys
137+ case _ : (x1 *: xs1) => _pair(erasedValue[x1], _concat(erasedValue[xs1], ys))
138+ }
139+
86140 rewrite def fromArray [T <: Tuple ](xs : Array [Object ]): T =
87141 rewrite _size(erasedValue[T ]) match {
88142 case 0 => ().asInstanceOf [T ]
@@ -140,8 +194,63 @@ sealed class *:[+H, +T <: Tuple] extends Tuple {
140194 resVal.asInstanceOf [resTpe.Type ]
141195 }
142196
143- rewrite def tail : T = ???
197+ rewrite def tail : Tuple = {
198+ erased val resTpe = Typed (_tail(this ))
199+ rewrite _size(this ) match {
200+ case 1 =>
201+ ()
202+ case 2 =>
203+ val t = asInstanceOf [Tuple2 [_, _]]
204+ Tuple1 (t._2).asInstanceOf [resTpe.Type ]
205+ case 3 =>
206+ val t = asInstanceOf [Tuple3 [_, _, _]]
207+ Tuple2 (t._2, t._3).asInstanceOf [resTpe.Type ]
208+ case 4 =>
209+ val t = asInstanceOf [Tuple4 [_, _, _, _]]
210+ Tuple3 (t._2, t._3, t._4).asInstanceOf [resTpe.Type ]
211+ case 5 =>
212+ val t = asInstanceOf [Tuple5 [_, _, _, _, _]]
213+ Tuple4 (t._2, t._3, t._4, t._5).asInstanceOf [resTpe.Type ]
214+ case n if n > 5 =>
215+ fromArray[resTpe.Type ](toArray.tail)
216+ }
217+ }
144218
219+ rewrite def apply (n : Int ): Any = {
220+ erased val resTpe = Typed (_index(this , n))
221+ rewrite _size(this ) match {
222+ case 1 =>
223+ val t = asInstanceOf [Tuple1 [_]]
224+ rewrite n match {
225+ case 0 => t._1.asInstanceOf [resTpe.Type ]
226+ }
227+ case 2 =>
228+ val t = asInstanceOf [Tuple2 [_, _]]
229+ rewrite n match {
230+ case 0 => t._1.asInstanceOf [resTpe.Type ]
231+ case 1 => t._2.asInstanceOf [resTpe.Type ]
232+ }
233+ case 3 =>
234+ val t = asInstanceOf [Tuple3 [_, _, _]]
235+ rewrite n match {
236+ case 0 => t._1.asInstanceOf [resTpe.Type ]
237+ case 1 => t._2.asInstanceOf [resTpe.Type ]
238+ case 2 => t._3.asInstanceOf [resTpe.Type ]
239+ }
240+ case 4 =>
241+ val t = asInstanceOf [Tuple4 [_, _, _, _]]
242+ rewrite n match {
243+ case 0 => t._1.asInstanceOf [resTpe.Type ]
244+ case 1 => t._2.asInstanceOf [resTpe.Type ]
245+ case 2 => t._3.asInstanceOf [resTpe.Type ]
246+ case 3 => t._4.asInstanceOf [resTpe.Type ]
247+ }
248+ case s if s > 4 && s <= $MaxSpecialized && n >= 0 && n < s =>
249+ asInstanceOf [Product ].productElement(n).asInstanceOf [resTpe.Type ]
250+ case s if s > $MaxSpecialized && n >= 0 && n < s =>
251+ asInstanceOf [TupleXXL ].elems(n).asInstanceOf [resTpe.Type ]
252+ }
253+ }
145254}
146255
147256object *: {
0 commit comments