diff --git a/library/src-scala3/scala/StagedTuple.scala b/library/src-scala3/scala/StagedTuple.scala new file mode 100644 index 000000000000..7035fd730856 --- /dev/null +++ b/library/src-scala3/scala/StagedTuple.scala @@ -0,0 +1,259 @@ +package scala + +import scala.quoted._ + +object StagedTuple { + import Tuple._ + import NonEmptyTuple._ + + def toArrayStaged(tup: Expr[Tuple], size: Option[Int]): Expr[Array[Object]] = { + if (!specialize) '(dynamicToArray(~tup)) + else size match { + case Some(0) => + '($emptyArray) + case Some(1) => + tup.as[Tuple1[Object]].bind(t => '(Array((~t)._1))) + case Some(2) => + tup.as[Tuple2[Object, Object]].bind(t => '(Array((~t)._1, (~t)._2))) + case Some(3) => + tup.as[Tuple3[Object, Object, Object]].bind(t => '(Array((~t)._1, (~t)._2, (~t)._3))) + case Some(4) => + tup.as[Tuple4[Object, Object, Object, Object]].bind(t => '(Array((~t)._1, (~t)._2, (~t)._3, (~t)._4))) + case Some(n) if n <= $MaxSpecialized => + '($toArray(~tup, ~n.toExpr)) + case Some(n) => + '((~tup.as[TupleXXL]).elems) + case None => + '(dynamicToArray(~tup)) + } + } + + def fromArrayStaged[T <: Tuple : Type](xs: Expr[Array[Object]], size: Option[Int]): Expr[T] = { + if (!specialize) '(dynamicFromArray[T](~xs)) + else { + val tup: Expr[Any] = size match { + case Some(0) => '() + case Some(1) => '(Tuple1( (~xs)(0))) + case Some(2) => '(Tuple2( (~xs)(0), (~xs)(1))) + case Some(3) => '(Tuple3( (~xs)(0), (~xs)(1), (~xs)(2))) + case Some(4) => '(Tuple4( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3))) + case Some(5) => '(Tuple5( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4))) + case Some(6) => '(Tuple6( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5))) + case Some(7) => '(Tuple7( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6))) + case Some(8) => '(Tuple8( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6), (~xs)(7))) + case Some(9) => '(Tuple9( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6), (~xs)(7), (~xs)(8))) + case Some(10) => '(Tuple10((~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6), (~xs)(7), (~xs)(8), (~xs)(9))) + case Some(11) => '(Tuple11((~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6), (~xs)(7), (~xs)(8), (~xs)(9), (~xs)(10))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(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))) + case Some(_) => '(TupleXXL(~xs)) + case None => '(dynamicFromArray[T](~xs)) + } + tup.as[T] + } + } + + def sizeStaged[Res <: Int : Type](tup: Expr[Tuple], size: Option[Int]): Expr[Res] = { + val res = + if (!specialize) '(dynamicSize(~tup)) + else size match { + case Some(n) => n.toExpr + case None => '(dynamicSize(~tup)) + } + res.as[Res] + } + + def headStaged[Tup <: NonEmptyTuple : Type](tup: Expr[Tup], size: Option[Int]): Expr[Head[Tup]] = { + if (!specialize) '(dynamicHead(~tup)) + else { + val resVal = size match { + case Some(1) => + '((~tup.as[Tuple1[_]])._1) + case Some(2) => + '((~tup.as[Tuple2[_, _]])._1) + case Some(3) => + '((~tup.as[Tuple3[_, _, _]])._1) + case Some(4) => + '((~tup.as[Tuple4[_, _, _, _]])._1) + case Some(n) if n > 4 && n <= $MaxSpecialized => + '((~tup.as[Product]).productElement(0)) + case Some(n) if n > $MaxSpecialized => + '((~tup.as[TupleXXL]).elems(0)) + case None => + '(dynamicHead(~tup)) + } + resVal.as[Head[Tup]] + } + } + + def tailStaged[Tup <: NonEmptyTuple : Type](tup: Expr[Tup], size: Option[Int]): Expr[Tail[Tup]] = { + if (!specialize) '(dynamicTail[Tup](~tup)) + else { + val res = size match { + case Some(1) => + '() + case Some(2) => + tup.as[Tuple2[_, _]].bind(t => '(Tuple1((~t)._2))) + case Some(3) => + tup.as[Tuple3[_, _, _]].bind(t => '(Tuple2((~t)._2, (~t)._3))) + case Some(4) => + tup.as[Tuple4[_, _, _, _]].bind(t => '(Tuple3((~t)._2, (~t)._3, (~t)._4))) + case Some(5) => + tup.as[Tuple5[_, _, _, _, _]].bind(t => '(Tuple4((~t)._2, (~t)._3, (~t)._4, (~t)._5))) + case Some(n) if n > 5 => + val arr = toArrayStaged(tup, size) + fromArrayStaged('((~arr).tail) , Some(n - 1)) + case None => + '(dynamicTail(~tup)) + } + res.as[Tail[Tup]] + } + } + + def applyStaged[Tup <: NonEmptyTuple : Type, N <: Int : Type](tup: Expr[Tup], size: Option[Int], n: Expr[N], nValue: Option[Int]): Expr[Elem[Tup, N]] = { + if (!specialize) '(dynamicApply(~tup, ~n)) + else { + def fallbackApply(): Expr[Elem[Tup, N]] = nValue match { + case Some(n) => quoted.QuoteError("index out of bounds: " + n) + case None => '(dynamicApply(~tup, ~n)) + } + val res = size match { + case Some(1) => + val t = tup.as[Tuple1[_]] + nValue match { + case Some(0) => '((~t)._1) + case _ => fallbackApply() + } + case Some(2) => + val t = tup.as[Tuple2[_, _]] + nValue match { + case Some(0) => '((~t)._1) + case Some(1) => '((~t)._2) + case _ => fallbackApply() + } + case Some(3) => + val t = tup.as[Tuple3[_, _, _]] + nValue match { + case Some(0) => '((~t)._1) + case Some(1) => '((~t)._2) + case Some(2) => '((~t)._3) + case _ => fallbackApply() + } + case Some(4) => + val t = tup.as[Tuple4[_, _, _, _]] + nValue match { + case Some(0) => '((~t)._1) + case Some(1) => '((~t)._2) + case Some(2) => '((~t)._3) + case Some(3) => '((~t)._4) + case _ => fallbackApply() + } + case Some(s) if s > 4 && s <= $MaxSpecialized => + val t = tup.as[Product] + nValue match { + case Some(n) if n >= 0 && n < s => '((~t).productElement(~n.toExpr)) + case _ => fallbackApply() + } + case Some(s) if s > $MaxSpecialized => + val t = tup.as[TupleXXL] + nValue match { + case Some(n) if n >= 0 && n < s => '((~t).elems(~n.toExpr)) + case _ => fallbackApply() + } + case _ => fallbackApply() + } + res.as[Elem[Tup, N]] + } + } + + def stagedCons[T <: Tuple & Singleton : Type, H : Type](self: Expr[T], x: Expr[H], tailSize: Option[Int]): Expr[H *: T] = + if (!specialize) '(dynamic_*:[T, H](~self, ~x)) + else { + val res = tailSize match { + case Some(0) => + '(Tuple1(~x)) + case Some(1) => + self.as[Tuple1[_]].bind(t => '(Tuple2(~x, (~t)._1))) + case Some(2) => + self.as[Tuple2[_, _]].bind(t => '(Tuple3(~x, (~t)._1, (~t)._2))) + case Some(3) => + self.as[Tuple3[_, _, _]].bind(t => '(Tuple4(~x, (~t)._1, (~t)._2, (~t)._3))) + case Some(4) => + self.as[Tuple4[_, _, _, _]].bind(t => '(Tuple5(~x, (~t)._1, (~t)._2, (~t)._3, (~t)._4))) + case Some(n) => + fromArrayStaged('($consArray(~x, ~toArrayStaged(self, tailSize))), Some(n + 1)) + case _ => + '(dynamic_*:[T, H](~self, ~x)) + } + res.as[H *: T] + } + + def stagedConcat[Self <: Tuple & Singleton : Type, That <: Tuple & Singleton : Type](self: Expr[Self], selfSize: Option[Int], that: Expr[That], thatSize: Option[Int]): Expr[Concat[Self, That]] = { + if (!specialize) '(dynamic_++[Self, That](~self, ~that)) + else { + def genericConcat(xs: Expr[Tuple], ys: Expr[Tuple]): Expr[Tuple] = + fromArrayStaged[Tuple]('((~toArrayStaged(xs, None)) ++ (~toArrayStaged(ys, None))), None) + + val res = selfSize match { + case Some(0) => + that + case Some(1) => + if (thatSize.contains(0)) self + else stagedCons(that, self.as[Tuple1[_]], thatSize) + case Some(2) => + val self2 = self.as[Tuple2[_, _]] + thatSize match { + case Some(0) => self + case Some(1) => + self2.bind { t => + that.as[Tuple1[_]].bind(u => '(Tuple3((~t)._1, (~t)._2, (~u)._1))) + } + case Some(2) => + self2.bind { t => + that.as[Tuple2[_, _]].bind(u => '(Tuple4((~t)._1, (~t)._2, (~u)._1, (~u)._2))) + } + case _ => + genericConcat(self, that) + } + case Some(3) => + val self2 = self.as[Tuple3[_, _, _]] + thatSize match { + case Some(0) => self + case Some(1) => + self2.bind { t => + that.as[Tuple1[_]].bind(u => '(Tuple4((~t)._1, (~t)._2, (~t)._3, (~u)._1))) + } + case _ => + genericConcat(self, that) + } + case Some(_) => + if (thatSize.contains(0)) self + else genericConcat(self, that) + case None => + '(dynamic_++(~self, ~that)) + } + res.as[Concat[Self, That]] + } + } + + private implicit class ExprOps[U: Type](expr: Expr[U]) { + + def as[T: Type]: Expr[T] = '{ (~expr).asInstanceOf[T] } + + def bind[T](in: Expr[U] => Expr[T]): Expr[T] = '{ + val t: U = (~expr) + ~(in('(t))) + } + + } + +} diff --git a/library/src-scala3/scala/Tuple.scala b/library/src-scala3/scala/Tuple.scala index 7350fccaa8c9..ee12658d41b4 100644 --- a/library/src-scala3/scala/Tuple.scala +++ b/library/src-scala3/scala/Tuple.scala @@ -4,114 +4,25 @@ import typelevel._ sealed trait Tuple extends Any { import Tuple._ + import StagedTuple._ inline def toArray: Array[Object] = - /*if (specialize) - inline constValueOpt[BoundedSize[this.type]] match { - case Some(0) => - $emptyArray - case Some(1) => - val t = asInstanceOf[Tuple1[Object]] - Array(t._1) - case Some(2) => - val t = asInstanceOf[Tuple2[Object, Object]] - Array(t._1, t._2) - case Some(3) => - val t = asInstanceOf[Tuple3[Object, Object, Object]] - Array(t._1, t._2, t._3) - case Some(4) => - val t = asInstanceOf[Tuple4[Object, Object, Object, Object]] - Array(t._1, t._2, t._3, t._4) - case Some(n) if n <= $MaxSpecialized => - $toArray(this, n) - case Some(n) => - asInstanceOf[TupleXXL].elems - case None => - dynamicToArray(this) - } - else*/ dynamicToArray(this) + ~toArrayStaged('(this), constValueOpt[BoundedSize[this.type]]) inline def *: [H] (x: H): H *: this.type = - /*if (specialize) { - type Result = H *: this.type - inline constValueOpt[BoundedSize[this.type]] match { - case Some(0) => - Tuple1(x).asInstanceOf[Result] - case Some(1) => - Tuple2(x, asInstanceOf[Tuple1[_]]._1).asInstanceOf[Result] - case Some(2) => - val t = asInstanceOf[Tuple2[_, _]] - Tuple3(x, t._1, t._2).asInstanceOf[Result] - case Some(3) => - val t = asInstanceOf[Tuple3[_, _, _]] - Tuple4(x, t._1, t._2, t._3).asInstanceOf[Result] - case Some(4) => - val t = asInstanceOf[Tuple4[_, _, _, _]] - Tuple5(x, t._1, t._2, t._3, t._4).asInstanceOf[Result] - case Some(n) => - fromArray[Result]($consArray(x, toArray)) - case _ => - dynamic_*:[this.type, H](this, x) - } - } - else*/ dynamic_*:[this.type, H](this, x) + ~stagedCons('(this), '(x), constValueOpt[BoundedSize[this.type]]) inline def ++(that: Tuple): Concat[this.type, that.type] = - /*if (specialize) { - type Result = Concat[this.type, that.type] - inline constValueOpt[BoundedSize[this.type]] match { - case Some(0) => - that.asInstanceOf[Result] - case Some(1) => - if (constValue[BoundedSize[that.type]] == 0) this.asInstanceOf[Result] - else (asInstanceOf[Tuple1[_]]._1 *: that).asInstanceOf[Result] - case Some(2) => - val t = asInstanceOf[Tuple2[_, _]] - inline constValue[BoundedSize[that.type]] match { - case 0 => this.asInstanceOf[Result] - case 1 => - val u = that.asInstanceOf[Tuple1[_]] - Tuple3(t._1, t._2, u._1).asInstanceOf[Result] - case 2 => - val u = that.asInstanceOf[Tuple2[_, _]] - Tuple4(t._1, t._2, u._1, u._2).asInstanceOf[Result] - case _ => - genericConcat[Result](this, that).asInstanceOf[Result] - } - case Some(3) => - val t = asInstanceOf[Tuple3[_, _, _]] - inline constValue[BoundedSize[that.type]] match { - case 0 => this.asInstanceOf[Result] - case 1 => - val u = that.asInstanceOf[Tuple1[_]] - Tuple4(t._1, t._2, t._3, u._1).asInstanceOf[Result] - case _ => - genericConcat[Result](this, that).asInstanceOf[Result] - } - case Some(_) => - if (constValue[BoundedSize[that.type]] == 0) this.asInstanceOf[Result] - else genericConcat[Result](this, that).asInstanceOf[Result] - case None => - dynamic_++[this.type, that.type](this, that) - } - } - else*/ dynamic_++[this.type, that.type](this, that) - - inline def genericConcat[T <: Tuple](xs: Tuple, ys: Tuple): Tuple = - fromArray[T](xs.toArray ++ ys.toArray) + ~stagedConcat('(this), constValueOpt[BoundedSize[this.type]], '(that), constValueOpt[BoundedSize[that.type]]) inline def size: Size[this.type] = - /*if (specialize) { - type Result = Size[this.type] - inline constValueOpt[BoundedSize[this.type]] match { - case Some(n) => n.asInstanceOf[Result] - case _ => dynamicSize(this) - } - } - else*/ dynamicSize(this) + ~sizeStaged[Size[this.type]]('(this), constValueOpt[BoundedSize[this.type]]) + } object Tuple { + import StagedTuple._ + inline val $MaxSpecialized = 22 inline private val XXL = $MaxSpecialized + 1 @@ -175,34 +86,7 @@ object Tuple { } inline def fromArray[T <: Tuple](xs: Array[Object]): T = - /*if (specialize) - inline constValue[BoundedSize[T]] match { - case 0 => ().asInstanceOf[T] - case 1 => Tuple1(xs(0)).asInstanceOf[T] - case 2 => Tuple2(xs(0), xs(1)).asInstanceOf[T] - case 3 => Tuple3(xs(0), xs(1), xs(2)).asInstanceOf[T] - case 4 => Tuple4(xs(0), xs(1), xs(2), xs(3)).asInstanceOf[T] - case 5 => Tuple5(xs(0), xs(1), xs(2), xs(3), xs(4)).asInstanceOf[T] - case 6 => Tuple6(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5)).asInstanceOf[T] - case 7 => Tuple7(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6)).asInstanceOf[T] - case 8 => Tuple8(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7)).asInstanceOf[T] - case 9 => Tuple9(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8)).asInstanceOf[T] - 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] - 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] - 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] - 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] - 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] - 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] - 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] - 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] - 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] - 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] - 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] - 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] - 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] - case _ => TupleXXL(xs).asInstanceOf[T] - } - else */dynamicFromArray[T](xs) + ~fromArrayStaged[T]('(xs), constValueOpt[BoundedSize[this.type]]) def dynamicFromArray[T <: Tuple](xs: Array[Object]): T = xs.length match { case 0 => ().asInstanceOf[T] @@ -295,119 +179,17 @@ object Tuple { abstract sealed class NonEmptyTuple extends Tuple { import Tuple._ import NonEmptyTuple._ + import StagedTuple._ inline def head: Head[this.type] = - /*if (specialize) { - type Result = Head[this.type] - val resVal = inline constValueOpt[BoundedSize[this.type]] match { - case Some(1) => - val t = asInstanceOf[Tuple1[_]] - t._1 - case Some(2) => - val t = asInstanceOf[Tuple2[_, _]] - t._1 - case Some(3) => - val t = asInstanceOf[Tuple3[_, _, _]] - t._1 - case Some(4) => - val t = asInstanceOf[Tuple4[_, _, _, _]] - t._1 - case Some(n) if n > 4 && n <= $MaxSpecialized => - asInstanceOf[Product].productElement(0) - case Some(n) if n > $MaxSpecialized => - val t = asInstanceOf[TupleXXL] - t.elems(0) - case None => - dynamicHead[this.type](this) - } - resVal.asInstanceOf[Result] - } - else*/ dynamicHead[this.type](this) + ~headStaged[this.type]('(this), constValueOpt[BoundedSize[this.type]]) inline def tail: Tail[this.type] = - /*if (specialize) { - type Result = Tail[this.type] - inline constValueOpt[BoundedSize[this.type]] match { - case Some(1) => - ().asInstanceOf[Result] - case Some(2) => - val t = asInstanceOf[Tuple2[_, _]] - Tuple1(t._2).asInstanceOf[Result] - case Some(3) => - val t = asInstanceOf[Tuple3[_, _, _]] - Tuple2(t._2, t._3).asInstanceOf[Result] - case Some(4) => - val t = asInstanceOf[Tuple4[_, _, _, _]] - Tuple3(t._2, t._3, t._4).asInstanceOf[Result] - case Some(5) => - val t = asInstanceOf[Tuple5[_, _, _, _, _]] - Tuple4(t._2, t._3, t._4, t._5).asInstanceOf[Result] - case Some(n) if n > 5 => - fromArray[Result](toArray.tail) - case None => - dynamicTail[this.type](this) - } - } - else*/ dynamicTail[this.type](this) - - /* - inline def fallbackApply(n: Int) = - inline constValueOpt[n.type] match { - case Some(n: Int) => error("index out of bounds: ", n) - case None => dynamicApply[this.type](this, n) - } - */ + ~tailStaged[this.type]('(this), constValueOpt[BoundedSize[this.type]]) inline def apply(n: Int): Elem[this.type, n.type] = - /*if (specialize) { - type Result = Elem[this.type, n.type] - inline constValueOpt[Size[this.type]] match { - case Some(1) => - val t = asInstanceOf[Tuple1[_]] - inline constValueOpt[n.type] match { - case Some(0) => t._1.asInstanceOf[Result] - case _ => fallbackApply(n).asInstanceOf[Result] - } - case Some(2) => - val t = asInstanceOf[Tuple2[_, _]] - inline constValueOpt[n.type] match { - case Some(0) => t._1.asInstanceOf[Result] - case Some(1) => t._2.asInstanceOf[Result] - case _ => fallbackApply(n).asInstanceOf[Result] - } - case Some(3) => - val t = asInstanceOf[Tuple3[_, _, _]] - inline constValueOpt[n.type] match { - case Some(0) => t._1.asInstanceOf[Result] - case Some(1) => t._2.asInstanceOf[Result] - case Some(2) => t._3.asInstanceOf[Result] - case _ => fallbackApply(n).asInstanceOf[Result] - } - case Some(4) => - val t = asInstanceOf[Tuple4[_, _, _, _]] - inline constValueOpt[n.type] match { - case Some(0) => t._1.asInstanceOf[Result] - case Some(1) => t._2.asInstanceOf[Result] - case Some(2) => t._3.asInstanceOf[Result] - case Some(3) => t._4.asInstanceOf[Result] - case _ => fallbackApply(n).asInstanceOf[Result] - } - case Some(s) if s > 4 && s <= $MaxSpecialized => - val t = asInstanceOf[Product] - inline constValueOpt[n.type] match { - case Some(n) if n >= 0 && n < s => t.productElement(n).asInstanceOf[Result] - case _ => fallbackApply(n).asInstanceOf[Result] - } - case Some(s) if s > $MaxSpecialized => - val t = asInstanceOf[TupleXXL] - inline constValueOpt[n.type] match { - case Some(n) if n >= 0 && n < s => t.elems(n).asInstanceOf[Result] - case _ => fallbackApply(n).asInstanceOf[Result] - } - case _ => fallbackApply(n).asInstanceOf[Result] - } - } - else*/ dynamicApply[this.type](this, n) + ~applyStaged[this.type, n.type]('(this), constValueOpt[Size[this.type]], '(n), constValueOpt[n.type]) + } object NonEmptyTuple { @@ -433,7 +215,7 @@ object NonEmptyTuple { case self: Tuple2[_, _] => Tuple1(self._2) case self: Tuple3[_, _, _] => Tuple2(self._2, self._3) case self: Tuple4[_, _, _, _] => Tuple3(self._2, self._3, self._4) - case _ => dynamicFromArray[Result](self.toArray.tail) + case _ => dynamicFromArray[Result](dynamicToArray(self).tail) } res.asInstanceOf[Result] } @@ -452,5 +234,6 @@ object NonEmptyTuple { sealed class *:[+H, +T <: Tuple] extends NonEmptyTuple object *: { - def unapply[H, T <: Tuple](x: H *: T) = (x.head, x.tail) + def unapply[H, T <: Tuple](x: H *: T): (H, T) = + (NonEmptyTuple.dynamicHead(x), NonEmptyTuple.dynamicTail(x)) }