@@ -72,59 +72,61 @@ object StagedTuple {
7272 res.as[Res ]
7373 }
7474
75- def headStaged [Tup <: NonEmptyTuple : Type ](tup : Expr [Tup ], size : Option [Int ]): Expr [Head [Tup ]] = {
76- if (! specialize) '(dynamicHead(~tup))
77- else {
78- val resVal = size match {
79- case Some (1 ) =>
80- '((~tup.as[Tuple1[_]])._1)
81- case Some (2 ) =>
82- '((~tup.as[Tuple2[_, _]])._1)
83- case Some (3 ) =>
84- '((~tup.as[Tuple3[_, _, _]])._1)
85- case Some (4 ) =>
86- '((~tup.as[Tuple4[_, _, _, _]])._1)
87- case Some (n) if n > 4 && n <= $MaxSpecialized =>
88- '((~tup.as[Product]).productElement(0))
89- case Some (n) if n > $MaxSpecialized =>
90- '((~tup.as[TupleXXL]).elems(0))
91- case None =>
92- '(dynamicHead(~tup))
75+ def headStaged [Head : Type ](tup : Expr [NonEmptyTuple ], size : Option [Int ]): Expr [Head ] = {
76+ val res =
77+ if (! specialize) '(dynamicHead(~tup))
78+ else {
79+ size match {
80+ case Some (1 ) =>
81+ '((~tup.as[Tuple1[_]])._1)
82+ case Some (2 ) =>
83+ '((~tup.as[Tuple2[_, _]])._1)
84+ case Some (3 ) =>
85+ '((~tup.as[Tuple3[_, _, _]])._1)
86+ case Some (4 ) =>
87+ '((~tup.as[Tuple4[_, _, _, _]])._1)
88+ case Some (n) if n > 4 && n <= $MaxSpecialized =>
89+ '((~tup.as[Product]).productElement(0))
90+ case Some (n) if n > $MaxSpecialized =>
91+ '((~tup.as[TupleXXL]).elems(0))
92+ case None =>
93+ '(dynamicHead(~tup))
94+ }
9395 }
94- resVal.as[Head [Tup ]]
95- }
96+ res.as[Head ]
9697 }
9798
98- def tailStaged [Tup <: NonEmptyTuple : Type ](tup : Expr [Tup ], size : Option [Int ]): Expr [Tail [Tup ]] = {
99- if (! specialize) '(dynamicTail[Tup](~tup))
100- else {
101- val res = size match {
102- case Some (1 ) =>
103- '()
104- case Some (2 ) =>
105- tup.as[Tuple2 [_, _]].bind(t => '(Tuple1((~t)._2)))
106- case Some (3 ) =>
107- tup.as[Tuple3 [_, _, _]].bind(t => '(Tuple2((~t)._2, (~t)._3)))
108- case Some (4 ) =>
109- tup.as[Tuple4 [_, _, _, _]].bind(t => '(Tuple3((~t)._2, (~t)._3, (~t)._4)))
110- case Some (5 ) =>
111- tup.as[Tuple5 [_, _, _, _, _]].bind(t => '(Tuple4((~t)._2, (~t)._3, (~t)._4, (~t)._5)))
112- case Some (n) if n > 5 =>
113- val arr = toArrayStaged(tup, size)
114- fromArrayStaged('((~arr).tail) , Some(n - 1))
115- case None =>
116- '(dynamicTail(~tup))
99+ def tailStaged [Tail <: Tuple : Type ](tup : Expr [NonEmptyTuple ], size : Option [Int ]): Expr [Tail ] = {
100+ val res =
101+ if (! specialize) '(dynamicTail(~tup))
102+ else {
103+ size match {
104+ case Some (1 ) =>
105+ '()
106+ case Some (2 ) =>
107+ tup.as[Tuple2 [_, _]].bind(t => '(Tuple1((~t)._2)))
108+ case Some (3 ) =>
109+ tup.as[Tuple3 [_, _, _]].bind(t => '(Tuple2((~t)._2, (~t)._3)))
110+ case Some (4 ) =>
111+ tup.as[Tuple4 [_, _, _, _]].bind(t => '(Tuple3((~t)._2, (~t)._3, (~t)._4)))
112+ case Some (5 ) =>
113+ tup.as[Tuple5 [_, _, _, _, _]].bind(t => '(Tuple4((~t)._2, (~t)._3, (~t)._4, (~t)._5)))
114+ case Some (n) if n > 5 =>
115+ val arr = toArrayStaged(tup, size)
116+ fromArrayStaged('((~arr).tail) , Some(n - 1))
117+ case None =>
118+ '(dynamicTail(~tup))
119+ }
117120 }
118- res.as[Tail [Tup ]]
119- }
121+ res.as[Tail ]
120122 }
121123
122- def applyStaged [Tup <: NonEmptyTuple : Type , N <: Int : Type ](tup : Expr [Tup ], size : Option [Int ], n : Expr [N ], nValue : Option [Int ]): Expr [Elem [ Tup , N ] ] = {
123- if (! specialize) '(dynamicApply(~tup, ~n))
124+ def applyStaged [Elem : Type ](tup : Expr [NonEmptyTuple ], size : Option [Int ], n : Expr [Int ], nValue : Option [Int ]): Expr [Elem ] = {
125+ if (! specialize) ( '(dynamicApply(~tup, ~n))).as[Elem]
124126 else {
125- def fallbackApply (): Expr [Elem [ Tup , N ] ] = nValue match {
127+ def fallbackApply (): Expr [Elem ] = nValue match {
126128 case Some (n) => quoted.QuoteError (" index out of bounds: " + n)
127- case None => '(dynamicApply(~tup, ~n))
129+ case None => ( '(dynamicApply(~tup, ~n))).as[Elem]
128130 }
129131 val res = size match {
130132 case Some (1 ) =>
@@ -171,78 +173,81 @@ object StagedTuple {
171173 }
172174 case _ => fallbackApply()
173175 }
174- res.as[Elem [ Tup , N ] ]
176+ res.as[Elem ]
175177 }
176178 }
177179
178- def stagedCons [T <: Tuple & Singleton : Type , H : Type ](self : Expr [T ], x : Expr [H ], tailSize : Option [Int ]): Expr [H *: T ] =
179- if (! specialize) '(dynamic_*:[T, H](~self, ~x))
180- else {
181- val res = tailSize match {
182- case Some (0 ) =>
183- '(Tuple1(~x))
184- case Some (1 ) =>
185- self.as[Tuple1 [_]].bind(t => '(Tuple2(~x, (~t)._1)))
186- case Some (2 ) =>
187- self.as[Tuple2 [_, _]].bind(t => '(Tuple3(~x, (~t)._1, (~t)._2)))
188- case Some (3 ) =>
189- self.as[Tuple3 [_, _, _]].bind(t => '(Tuple4(~x, (~t)._1, (~t)._2, (~t)._3)))
190- case Some (4 ) =>
191- self.as[Tuple4 [_, _, _, _]].bind(t => '(Tuple5(~x, (~t)._1, (~t)._2, (~t)._3, (~t)._4)))
192- case Some (n) =>
193- fromArrayStaged('($consArray(~x, ~toArrayStaged(self, tailSize))), Some(n + 1))
194- case _ =>
195- '(dynamic_*:[T, H](~self, ~x))
196- }
197- res.as[H *: T ]
180+ def stagedCons [Res <: NonEmptyTuple : Type , H : Type ](self : Expr [Tuple ], x : Expr [H ], tailSize : Option [Int ]): Expr [Res ] = {
181+ val res =
182+ if (! specialize) '(dynamic_*:(~self, ~x))
183+ else {
184+ tailSize match {
185+ case Some (0 ) =>
186+ '(Tuple1(~x))
187+ case Some (1 ) =>
188+ self.as[Tuple1 [_]].bind(t => '(Tuple2(~x, (~t)._1)))
189+ case Some (2 ) =>
190+ self.as[Tuple2 [_, _]].bind(t => '(Tuple3(~x, (~t)._1, (~t)._2)))
191+ case Some (3 ) =>
192+ self.as[Tuple3 [_, _, _]].bind(t => '(Tuple4(~x, (~t)._1, (~t)._2, (~t)._3)))
193+ case Some (4 ) =>
194+ self.as[Tuple4 [_, _, _, _]].bind(t => '(Tuple5(~x, (~t)._1, (~t)._2, (~t)._3, (~t)._4)))
195+ case Some (n) =>
196+ fromArrayStaged('($consArray(~x, ~toArrayStaged(self, tailSize))), Some(n + 1))
197+ case _ =>
198+ '(dynamic_*:(~self, ~x))
199+ }
200+ }
201+ res.as[Res ]
198202 }
199203
200- 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 ]] = {
201- if (! specialize) '(dynamic_++[Self, That](~self, ~that))
202- else {
203- def genericConcat (xs : Expr [Tuple ], ys : Expr [Tuple ]): Expr [Tuple ] =
204- fromArrayStaged[Tuple ]('((~toArrayStaged(xs, None)) ++ (~toArrayStaged(ys, None))), None)
205-
206- val res = selfSize match {
207- case Some (0 ) =>
208- that
209- case Some (1 ) =>
210- if (thatSize.contains(0 )) self
211- else stagedCons(that, self.as[Tuple1 [_]], thatSize)
212- case Some (2 ) =>
213- val self2 = self.as[Tuple2 [_, _]]
214- thatSize match {
215- case Some (0 ) => self
216- case Some (1 ) =>
217- self2.bind { t =>
218- that.as[Tuple1 [_]].bind(u => '(Tuple3((~t)._1, (~t)._2, (~u)._1)))
219- }
220- case Some (2 ) =>
221- self2.bind { t =>
222- that.as[Tuple2 [_, _]].bind(u => '(Tuple4((~t)._1, (~t)._2, (~u)._1, (~u)._2)))
223- }
224- case _ =>
225- genericConcat(self, that)
226- }
227- case Some (3 ) =>
228- val self2 = self.as[Tuple3 [_, _, _]]
229- thatSize match {
230- case Some (0 ) => self
231- case Some (1 ) =>
232- self2.bind { t =>
233- that.as[Tuple1 [_]].bind(u => '(Tuple4((~t)._1, (~t)._2, (~t)._3, (~u)._1)))
234- }
235- case _ =>
236- genericConcat(self, that)
237- }
238- case Some (_) =>
239- if (thatSize.contains(0 )) self
240- else genericConcat(self, that)
241- case None =>
242- '(dynamic_++(~self, ~that))
204+ // FIXME: remove Concat[Self, That]
205+ def stagedConcat [Concat <: Tuple : Type ](self : Expr [Tuple ], selfSize : Option [Int ], that : Expr [Tuple ], thatSize : Option [Int ]): Expr [Concat ] = {
206+ val res =
207+ if (! specialize) '(dynamic_++(~self, ~that))
208+ else {
209+ def genericConcat (xs : Expr [Tuple ], ys : Expr [Tuple ]): Expr [Tuple ] =
210+ fromArrayStaged[Tuple ]('((~toArrayStaged(xs, None)) ++ (~toArrayStaged(ys, None))), None)
211+ selfSize match {
212+ case Some (0 ) =>
213+ that
214+ case Some (1 ) =>
215+ if (thatSize.contains(0 )) self
216+ else stagedCons(that, self.as[Tuple1 [_]], thatSize)
217+ case Some (2 ) =>
218+ val self2 = self.as[Tuple2 [_, _]]
219+ thatSize match {
220+ case Some (0 ) => self
221+ case Some (1 ) =>
222+ self2.bind { t =>
223+ that.as[Tuple1 [_]].bind(u => '(Tuple3((~t)._1, (~t)._2, (~u)._1)))
224+ }
225+ case Some (2 ) =>
226+ self2.bind { t =>
227+ that.as[Tuple2 [_, _]].bind(u => '(Tuple4((~t)._1, (~t)._2, (~u)._1, (~u)._2)))
228+ }
229+ case _ =>
230+ genericConcat(self, that)
231+ }
232+ case Some (3 ) =>
233+ val self2 = self.as[Tuple3 [_, _, _]]
234+ thatSize match {
235+ case Some (0 ) => self
236+ case Some (1 ) =>
237+ self2.bind { t =>
238+ that.as[Tuple1 [_]].bind(u => '(Tuple4((~t)._1, (~t)._2, (~t)._3, (~u)._1)))
239+ }
240+ case _ =>
241+ genericConcat(self, that)
242+ }
243+ case Some (_) =>
244+ if (thatSize.contains(0 )) self
245+ else genericConcat(self, that)
246+ case None =>
247+ '(dynamic_++(~self, ~that))
248+ }
243249 }
244- res.as[Concat [Self , That ]]
245- }
250+ res.as[Concat ]
246251 }
247252
248253 private implicit class ExprOps [U : Type ](expr : Expr [U ]) {
0 commit comments