Skip to content

Commit 49f254a

Browse files
authored
Merge pull request #6514 from dotty-staging/add-tuple-fromProduct
Add Tuple.fromProduct
2 parents 2f68297 + 2301af8 commit 49f254a

File tree

4 files changed

+215
-0
lines changed

4 files changed

+215
-0
lines changed

library/src-3.x/scala/Tuple.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ object Tuple {
200200
runtime.DynamicTuple.dynamicFromArray[Tuple](xs2)
201201
}
202202

203+
def fromProduct(product: Product): Tuple =
204+
runtime.DynamicTuple.dynamicFromProduct[Tuple](product)
205+
203206
}
204207

205208
sealed trait NonEmptyTuple extends Tuple {

library/src-3.x/scala/runtime/DynamicTuple.scala

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,125 @@ object DynamicTuple {
5757
case _ => TupleXXL(xs).asInstanceOf[T]
5858
}
5959

60+
def dynamicFromProduct[T <: Tuple](xs: Product): T = (xs.productArity match {
61+
case 1 =>
62+
xs match {
63+
case xs: Tuple1[_] => xs
64+
case xs => Tuple1(xs.productElement(0))
65+
}
66+
case 2 =>
67+
xs match {
68+
case xs: Tuple2[_, _] => xs
69+
case xs => Tuple2(xs.productElement(0), xs.productElement(1))
70+
}
71+
case 3 =>
72+
xs match {
73+
case xs: Tuple3[_, _, _] => xs
74+
case xs => Tuple3(xs.productElement(0), xs.productElement(1), xs.productElement(2))
75+
}
76+
case 4 =>
77+
xs match {
78+
case xs: Tuple4[_, _, _, _] => xs
79+
case xs => Tuple4(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3))
80+
}
81+
case 5 =>
82+
xs match {
83+
case xs: Tuple5[_, _, _, _, _] => xs
84+
case xs => Tuple5(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4))
85+
}
86+
case 6 =>
87+
xs match {
88+
case xs: Tuple6[_, _, _, _, _, _] => xs
89+
case xs => Tuple6(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5))
90+
}
91+
case 7 =>
92+
xs match {
93+
case xs: Tuple7[_, _, _, _, _, _, _] => xs
94+
case xs => Tuple7(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6))
95+
}
96+
case 8 =>
97+
xs match {
98+
case xs: Tuple8[_, _, _, _, _, _, _, _] => xs
99+
case xs => Tuple8(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7))
100+
}
101+
case 9 =>
102+
xs match {
103+
case xs: Tuple9[_, _, _, _, _, _, _, _, _] => xs
104+
case xs => Tuple9(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8))
105+
}
106+
case 10 =>
107+
xs match {
108+
case xs: Tuple10[_, _, _, _, _, _, _, _, _, _] => xs
109+
case xs => Tuple10(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9))
110+
}
111+
case 11 =>
112+
xs match {
113+
case xs: Tuple11[_, _, _, _, _, _, _, _, _, _, _] => xs
114+
case xs => Tuple11(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10))
115+
}
116+
case 12 =>
117+
xs match {
118+
case xs: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _] => xs
119+
case xs => Tuple12(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11))
120+
}
121+
case 13 =>
122+
xs match {
123+
case xs: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _] => xs
124+
case xs => Tuple13(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12))
125+
}
126+
case 14 =>
127+
xs match {
128+
case xs: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
129+
case xs => Tuple14(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13))
130+
}
131+
case 15 =>
132+
xs match {
133+
case xs: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
134+
case xs => Tuple15(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13), xs.productElement(14))
135+
}
136+
case 16 =>
137+
xs match {
138+
case xs: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
139+
case xs => Tuple16(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13), xs.productElement(14), xs.productElement(15))
140+
}
141+
case 17 =>
142+
xs match {
143+
case xs: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
144+
case xs => Tuple17(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13), xs.productElement(14), xs.productElement(15), xs.productElement(16))
145+
}
146+
case 18 =>
147+
xs match {
148+
case xs: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
149+
case xs => Tuple18(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13), xs.productElement(14), xs.productElement(15), xs.productElement(16), xs.productElement(17))
150+
}
151+
case 19 =>
152+
xs match {
153+
case xs: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
154+
case xs => Tuple19(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13), xs.productElement(14), xs.productElement(15), xs.productElement(16), xs.productElement(17), xs.productElement(18))
155+
}
156+
case 20 =>
157+
xs match {
158+
case xs: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
159+
case xs => Tuple20(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13), xs.productElement(14), xs.productElement(15), xs.productElement(16), xs.productElement(17), xs.productElement(18), xs.productElement(19))
160+
}
161+
case 21 =>
162+
xs match {
163+
case xs: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
164+
case xs => Tuple21(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13), xs.productElement(14), xs.productElement(15), xs.productElement(16), xs.productElement(17), xs.productElement(18), xs.productElement(19), xs.productElement(20))
165+
}
166+
case 22 =>
167+
xs match {
168+
case xs: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] => xs
169+
case xs => Tuple22(xs.productElement(0), xs.productElement(1), xs.productElement(2), xs.productElement(3), xs.productElement(4), xs.productElement(5), xs.productElement(6), xs.productElement(7), xs.productElement(8), xs.productElement(9), xs.productElement(10), xs.productElement(11), xs.productElement(12), xs.productElement(13), xs.productElement(14), xs.productElement(15), xs.productElement(16), xs.productElement(17), xs.productElement(18), xs.productElement(19), xs.productElement(20), xs.productElement(21))
170+
}
171+
case _ =>
172+
xs match {
173+
case xs: TupleXXL => xs
174+
case xs => TupleXXL(xs.productIterator.map(_.asInstanceOf[Object]).toArray)
175+
}
176+
}).asInstanceOf[T]
177+
178+
60179
def dynamicToArray(self: Tuple): Array[Object] = (self: Any) match {
61180
case self: Unit =>
62181
scala.runtime.DynamicTuple.empty$Array

tests/run/Tuple-fromProduct.check

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
(1)
2+
(1,2)
3+
(1,2,3)
4+
(1,2,3,4)
5+
(1,2,3,4,5)
6+
(1,2,3,4,5,6)
7+
(1,2,3,4,5,6,7)
8+
(1,2,3,4,5,6,7,8)
9+
(1,2,3,4,5,6,7,8,9)
10+
(1,2,3,4,5,6,7,8,9,10)
11+
(1,2,3,4,5,6,7,8,9,10,11)
12+
(1,2,3,4,5,6,7,8,9,10,11,12)
13+
(1,2,3,4,5,6,7,8,9,10,11,12,13)
14+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
15+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
16+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
17+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17)
18+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)
19+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
20+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
21+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
22+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)
23+
(1)
24+
(1,2)
25+
(1,2,3)
26+
(1,2,3,4)
27+
(1,2,3,4,5)
28+
(1,2,3,4,5,6)
29+
(1,2,3,4,5,6,7)
30+
(1,2,3,4,5,6,7,8)
31+
(1,2,3,4,5,6,7,8,9)
32+
(1,2,3,4,5,6,7,8,9,10)
33+
(1,2,3,4,5,6,7,8,9,10,11)
34+
(1,2,3,4,5,6,7,8,9,10,11,12)
35+
(1,2,3,4,5,6,7,8,9,10,11,12,13)
36+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14)
37+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
38+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16)
39+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17)
40+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18)
41+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19)
42+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20)
43+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
44+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)
45+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23)
46+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24)
47+
(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25)

tests/run/Tuple-fromProduct.scala

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
5+
def testProduct(product: Product): Unit = {
6+
val t: Tuple = Tuple.fromProduct(product)
7+
println(t)
8+
}
9+
10+
testProduct(Tuple1(1))
11+
testProduct((1, 2))
12+
testProduct((1, 2, 3))
13+
testProduct((1, 2, 3, 4))
14+
testProduct((1, 2, 3, 4, 5))
15+
testProduct((1, 2, 3, 4, 5, 6))
16+
testProduct((1, 2, 3, 4, 5, 6, 7))
17+
testProduct((1, 2, 3, 4, 5, 6, 7, 8))
18+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9))
19+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
20+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11))
21+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
22+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13))
23+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14))
24+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15))
25+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16))
26+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17))
27+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18))
28+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19))
29+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20))
30+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21))
31+
testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22))
32+
// FIXME ProductN for N > 22 does not extends product
33+
// testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23))
34+
// testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24))
35+
// testProduct((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25))
36+
37+
class MyProduct(val productArity: Int) extends Product {
38+
def productElement(n: Int): Any = n + 1
39+
def canEqual(that: Any): Boolean = false
40+
}
41+
42+
for (i <- 1 to 25)
43+
testProduct(new MyProduct(i))
44+
45+
}
46+
}

0 commit comments

Comments
 (0)