Skip to content

Commit cd84a64

Browse files
committed
Use staged macros to implement parts of Tuple
1 parent 8ce3ea2 commit cd84a64

File tree

2 files changed

+92
-61
lines changed

2 files changed

+92
-61
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package scala
2+
3+
import scala.quoted._
4+
5+
object StagedTuple {
6+
import Tuple._
7+
8+
def toArrayStaged(tup: Expr[Tuple], size: Option[Int]): Expr[Array[Object]] = {
9+
if (!specialize) '(dynamicToArray(~tup))
10+
else size match {
11+
case Some(0) =>
12+
'($emptyArray)
13+
case Some(1) =>
14+
tup.as[Tuple1[Object]].bind(t => '(Array((~t)._1)))
15+
case Some(2) =>
16+
tup.as[Tuple2[Object, Object]].bind(t => '(Array((~t)._1, (~t)._2)))
17+
case Some(3) =>
18+
tup.as[Tuple3[Object, Object, Object]].bind(t => '(Array((~t)._1, (~t)._2, (~t)._3)))
19+
case Some(4) =>
20+
tup.as[Tuple4[Object, Object, Object, Object]].bind(t => '(Array((~t)._1, (~t)._2, (~t)._3, (~t)._4)))
21+
case Some(n) if n <= $MaxSpecialized =>
22+
'($toArray(~tup, ~n.toExpr))
23+
case Some(n) =>
24+
'((~tup.as[TupleXXL]).elems)
25+
case None =>
26+
'(dynamicToArray(~tup))
27+
}
28+
}
29+
30+
def fromArrayStaged[T <: Tuple : Type](xs: Expr[Array[Object]], size: Int): Expr[T] = {
31+
if (!specialize) '(dynamicFromArray[T](~xs))
32+
else {
33+
val tup = size match {
34+
case 0 => '()
35+
case 1 => '(Tuple1( (~xs)(0)))
36+
case 2 => '(Tuple2( (~xs)(0), (~xs)(1)))
37+
case 3 => '(Tuple3( (~xs)(0), (~xs)(1), (~xs)(2)))
38+
case 4 => '(Tuple4( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3)))
39+
case 5 => '(Tuple5( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4)))
40+
case 6 => '(Tuple6( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5)))
41+
case 7 => '(Tuple7( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6)))
42+
case 8 => '(Tuple8( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6), (~xs)(7)))
43+
case 9 => '(Tuple9( (~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6), (~xs)(7), (~xs)(8)))
44+
case 10 => '(Tuple10((~xs)(0), (~xs)(1), (~xs)(2), (~xs)(3), (~xs)(4), (~xs)(5), (~xs)(6), (~xs)(7), (~xs)(8), (~xs)(9)))
45+
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)))
46+
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)))
47+
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)))
48+
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)))
49+
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)))
50+
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)))
51+
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)))
52+
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)))
53+
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)))
54+
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)))
55+
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)))
56+
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)))
57+
case _ => '(TupleXXL(~xs))
58+
}
59+
tup.as[T]
60+
}
61+
}
62+
63+
def sizeStaged[Res <: Int : Type](tup: Expr[Tuple], size: Option[Int]): Expr[Res] = {
64+
val res =
65+
if (!specialize) '(dynamicSize(~tup).asInstanceOf[Res])
66+
else size match {
67+
case Some(n) => n.toExpr
68+
case None => '(dynamicSize(~tup).asInstanceOf[Res])
69+
}
70+
res.as[Res]
71+
}
72+
73+
private implicit class ExprOps[U: Type](expr: Expr[U]) {
74+
75+
def as[T: Type]: Expr[T] = '{ (~expr).asInstanceOf[T] }
76+
77+
def bind[T](in: Expr[U] => Expr[T]): Expr[T] = '{
78+
val t: U = (~expr)
79+
~(in('(t)))
80+
}
81+
82+
}
83+
84+
}

library/src-scala3/scala/Tuple.scala

Lines changed: 8 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,10 @@ import typelevel._
44

55
sealed trait Tuple extends Any {
66
import Tuple._
7+
import StagedTuple._
78

89
inline def toArray: Array[Object] =
9-
/*if (specialize)
10-
inline constValueOpt[BoundedSize[this.type]] match {
11-
case Some(0) =>
12-
$emptyArray
13-
case Some(1) =>
14-
val t = asInstanceOf[Tuple1[Object]]
15-
Array(t._1)
16-
case Some(2) =>
17-
val t = asInstanceOf[Tuple2[Object, Object]]
18-
Array(t._1, t._2)
19-
case Some(3) =>
20-
val t = asInstanceOf[Tuple3[Object, Object, Object]]
21-
Array(t._1, t._2, t._3)
22-
case Some(4) =>
23-
val t = asInstanceOf[Tuple4[Object, Object, Object, Object]]
24-
Array(t._1, t._2, t._3, t._4)
25-
case Some(n) if n <= $MaxSpecialized =>
26-
$toArray(this, n)
27-
case Some(n) =>
28-
asInstanceOf[TupleXXL].elems
29-
case None =>
30-
dynamicToArray(this)
31-
}
32-
else*/ dynamicToArray(this)
10+
~toArrayStaged('(this), constValueOpt[BoundedSize[this.type]])
3311

3412
inline def *: [H] (x: H): H *: this.type =
3513
/*if (specialize) {
@@ -101,17 +79,13 @@ sealed trait Tuple extends Any {
10179
fromArray[T](xs.toArray ++ ys.toArray)
10280

10381
inline def size: Size[this.type] =
104-
/*if (specialize) {
105-
type Result = Size[this.type]
106-
inline constValueOpt[BoundedSize[this.type]] match {
107-
case Some(n) => n.asInstanceOf[Result]
108-
case _ => dynamicSize(this)
109-
}
110-
}
111-
else*/ dynamicSize(this)
82+
~sizeStaged[Size[this.type]]('(this), constValueOpt[BoundedSize[this.type]])
83+
11284
}
11385

11486
object Tuple {
87+
import StagedTuple._
88+
11589
inline val $MaxSpecialized = 22
11690
inline private val XXL = $MaxSpecialized + 1
11791

@@ -175,34 +149,7 @@ object Tuple {
175149
}
176150

177151
inline def fromArray[T <: Tuple](xs: Array[Object]): T =
178-
/*if (specialize)
179-
inline constValue[BoundedSize[T]] match {
180-
case 0 => ().asInstanceOf[T]
181-
case 1 => Tuple1(xs(0)).asInstanceOf[T]
182-
case 2 => Tuple2(xs(0), xs(1)).asInstanceOf[T]
183-
case 3 => Tuple3(xs(0), xs(1), xs(2)).asInstanceOf[T]
184-
case 4 => Tuple4(xs(0), xs(1), xs(2), xs(3)).asInstanceOf[T]
185-
case 5 => Tuple5(xs(0), xs(1), xs(2), xs(3), xs(4)).asInstanceOf[T]
186-
case 6 => Tuple6(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5)).asInstanceOf[T]
187-
case 7 => Tuple7(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6)).asInstanceOf[T]
188-
case 8 => Tuple8(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7)).asInstanceOf[T]
189-
case 9 => Tuple9(xs(0), xs(1), xs(2), xs(3), xs(4), xs(5), xs(6), xs(7), xs(8)).asInstanceOf[T]
190-
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]
191-
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]
192-
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]
193-
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]
194-
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]
195-
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]
196-
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]
197-
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]
198-
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]
199-
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]
200-
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]
201-
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]
202-
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]
203-
case _ => TupleXXL(xs).asInstanceOf[T]
204-
}
205-
else */dynamicFromArray[T](xs)
152+
~fromArrayStaged[T]('(xs), constValue[BoundedSize[this.type]])
206153

207154
def dynamicFromArray[T <: Tuple](xs: Array[Object]): T = xs.length match {
208155
case 0 => ().asInstanceOf[T]
@@ -433,7 +380,7 @@ object NonEmptyTuple {
433380
case self: Tuple2[_, _] => Tuple1(self._2)
434381
case self: Tuple3[_, _, _] => Tuple2(self._2, self._3)
435382
case self: Tuple4[_, _, _, _] => Tuple3(self._2, self._3, self._4)
436-
case _ => dynamicFromArray[Result](self.toArray.tail)
383+
case _ => dynamicFromArray[Result](dynamicToArray(self).tail)
437384
}
438385
res.asInstanceOf[Result]
439386
}

0 commit comments

Comments
 (0)