Skip to content

Commit 3e3f57b

Browse files
committed
Add reverse method to NonEmptyTuple
1 parent 0967522 commit 3e3f57b

File tree

4 files changed

+226
-0
lines changed

4 files changed

+226
-0
lines changed

library/src/scala/Tuple.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@ object Tuple {
185185
*/
186186
type IsMappedBy[F[_]] = [X <: Tuple] =>> X =:= Map[InverseMap[X, F], F]
187187

188+
/** Type of the reversed tuple */
189+
@experimental
190+
type Reverse[X <: Tuple] <: Tuple = X match {
191+
case EmptyTuple => EmptyTuple
192+
case x *: xs =>
193+
Concat[Reverse[xs], x *: EmptyTuple]
194+
}
195+
188196
/** Transforms a tuple `(T1, ..., Tn)` into `(T1, ..., Ti)`. */
189197
type Take[T <: Tuple, N <: Int] <: Tuple = N match {
190198
case 0 => EmptyTuple
@@ -301,6 +309,12 @@ sealed trait NonEmptyTuple extends Tuple {
301309
inline def tail[This >: this.type <: NonEmptyTuple]: Tail[This] =
302310
runtime.Tuples.tail(this).asInstanceOf[Tail[This]]
303311

312+
/** Given a tuple `(a1, ..., am)`, returns the reversed tuple `(am, ..., a1)`
313+
* consisting all its elements.
314+
*/
315+
@experimental
316+
inline def reverse[This >: this.type <: NonEmptyTuple]: Reverse[This] =
317+
runtime.Tuples.reverse(this).asInstanceOf[Reverse[This]]
304318
}
305319

306320
@showAsInfix

library/src/scala/runtime/Tuples.scala

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,76 @@ object Tuples {
372372
}
373373
}
374374

375+
// Reverse for TupleXXL
376+
private def xxlReverse(xxl: TupleXXL): Tuple = {
377+
if (xxl.productArity == 22) {
378+
val elems = xxl.elems
379+
Tuple22(
380+
elems(21), elems(20), elems(19), elems(18), elems(17), elems(16),
381+
elems(15), elems(14), elems(13), elems(12), elems(11), elems(10),
382+
elems(9), elems(8), elems(7), elems(6), elems(5), elems(4),
383+
elems(3), elems(2), elems(1), elems(0)
384+
)
385+
} else {
386+
TupleXXL.fromIArray(xxl.elems.reverse.asInstanceOf[IArray[Object]]).asInstanceOf[Tuple]
387+
}
388+
}
389+
390+
// Reverse for Tuple1 to Tuple22
391+
private def specialCaseReverse(self: Tuple): Tuple = {
392+
(self: Any) match {
393+
case self: Tuple1[_] =>
394+
self
395+
case self: Tuple2[_, _] =>
396+
Tuple2(self._2, self._1)
397+
case self: Tuple3[_, _, _] =>
398+
Tuple3(self._3, self._2, self._1)
399+
case self: Tuple4[_, _, _, _] =>
400+
Tuple4(self._4, self._3, self._2, self._1)
401+
case self: Tuple5[_, _, _, _, _] =>
402+
Tuple5(self._5, self._4, self._3, self._2, self._1)
403+
case self: Tuple6[_, _, _, _, _, _] =>
404+
Tuple6(self._6, self._5, self._4, self._3, self._2, self._1)
405+
case self: Tuple7[_, _, _, _, _, _, _] =>
406+
Tuple7(self._7, self._6, self._5, self._4, self._3, self._2, self._1)
407+
case self: Tuple8[_, _, _, _, _, _, _, _] =>
408+
Tuple8(self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
409+
case self: Tuple9[_, _, _, _, _, _, _, _, _] =>
410+
Tuple9(self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
411+
case self: Tuple10[_, _, _, _, _, _, _, _, _, _] =>
412+
Tuple10(self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
413+
case self: Tuple11[_, _, _, _, _, _, _, _, _, _, _] =>
414+
Tuple11(self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
415+
case self: Tuple12[_, _, _, _, _, _, _, _, _, _, _, _] =>
416+
Tuple12(self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
417+
case self: Tuple13[_, _, _, _, _, _, _, _, _, _, _, _, _] =>
418+
Tuple13(self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
419+
case self: Tuple14[_, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
420+
Tuple14(self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
421+
case self: Tuple15[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
422+
Tuple15(self._15, self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
423+
case self: Tuple16[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
424+
Tuple16(self._16, self._15, self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
425+
case self: Tuple17[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
426+
Tuple17(self._17, self._16, self._15, self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
427+
case self: Tuple18[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
428+
Tuple18(self._18, self._17, self._16, self._15, self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
429+
case self: Tuple19[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
430+
Tuple19(self._19, self._18, self._17, self._16, self._15, self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
431+
case self: Tuple20[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
432+
Tuple20(self._20, self._19, self._18, self._17, self._16, self._15, self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
433+
case self: Tuple21[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
434+
Tuple21(self._21, self._20, self._19, self._18, self._17, self._16, self._15, self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
435+
case self: Tuple22[_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _] =>
436+
Tuple22(self._22, self._21, self._20, self._19, self._18, self._17, self._16, self._15, self._14, self._13, self._12, self._11, self._10, self._9, self._8, self._7, self._6, self._5, self._4, self._3, self._2, self._1)
437+
}
438+
}
439+
440+
def reverse(self: NonEmptyTuple): Tuple = (self: Any) match {
441+
case xxl: TupleXXL => xxlReverse(xxl)
442+
case _ => specialCaseReverse(self)
443+
}
444+
375445
// Init for Tuple1 to Tuple22
376446
private def specialCaseInit(self: Tuple): Tuple = {
377447
(self: Any) match {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
(0)
2+
(0,0)
3+
(1,0,0)
4+
(2,1,0,0)
5+
(3,2,1,0,0)
6+
(4,3,2,1,0,0)
7+
(5,4,3,2,1,0,0)
8+
(6,5,4,3,2,1,0,0)
9+
(7,6,5,4,3,2,1,0,0)
10+
(8,7,6,5,4,3,2,1,0,0)
11+
(9,8,7,6,5,4,3,2,1,0,0)
12+
(10,9,8,7,6,5,4,3,2,1,0,0)
13+
(11,10,9,8,7,6,5,4,3,2,1,0,0)
14+
(12,11,10,9,8,7,6,5,4,3,2,1,0,0)
15+
(13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
16+
(14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
17+
(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
18+
(16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
19+
(17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
20+
(18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
21+
(19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
22+
(20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
23+
(21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
24+
(22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
25+
(23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
26+
(24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0)
27+
(1)
28+
(2,1)
29+
(3,2,1)
30+
(4,3,2,1)
31+
(5,4,3,2,1)
32+
(6,5,4,3,2,1)
33+
(7,6,5,4,3,2,1)
34+
(8,7,6,5,4,3,2,1)
35+
(9,8,7,6,5,4,3,2,1)
36+
(10,9,8,7,6,5,4,3,2,1)
37+
(11,10,9,8,7,6,5,4,3,2,1)
38+
(12,11,10,9,8,7,6,5,4,3,2,1)
39+
(13,12,11,10,9,8,7,6,5,4,3,2,1)
40+
(14,13,12,11,10,9,8,7,6,5,4,3,2,1)
41+
(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
42+
(16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
43+
(17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
44+
(18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
45+
(19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
46+
(20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
47+
(21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
48+
(22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
49+
(23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
50+
(24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
51+
(25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
52+
(1)
53+
(2,1)
54+
(3,2,1)
55+
(4,3,2,1)
56+
(5,4,3,2,1)
57+
(6,5,4,3,2,1)
58+
(7,6,5,4,3,2,1)
59+
(8,7,6,5,4,3,2,1)
60+
(9,8,7,6,5,4,3,2,1)
61+
(10,9,8,7,6,5,4,3,2,1)
62+
(11,10,9,8,7,6,5,4,3,2,1)
63+
(12,11,10,9,8,7,6,5,4,3,2,1)
64+
(13,12,11,10,9,8,7,6,5,4,3,2,1)
65+
(14,13,12,11,10,9,8,7,6,5,4,3,2,1)
66+
(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
67+
(16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
68+
(17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
69+
(18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
70+
(19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
71+
(20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
72+
(21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
73+
(22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
74+
(23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
75+
(24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
76+
(25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import scala.reflect.ClassTag
2+
3+
object Test {
4+
def main(args: Array[String]): Unit = {
5+
6+
def testArray[T: ClassTag](n: Int, elem: Int => T): Unit = {
7+
val t: Int *: Tuple = 0 *: Tuple.fromArray(Array.tabulate(n)(elem))
8+
println(t.reverse)
9+
}
10+
11+
for (i <- 0 to 25)
12+
testArray(i, j => j)
13+
14+
println(Tuple1(1).reverse)
15+
println((1, 2).reverse)
16+
println((1, 2, 3).reverse)
17+
println((1, 2, 3, 4).reverse)
18+
println((1, 2, 3, 4, 5).reverse)
19+
println((1, 2, 3, 4, 5, 6).reverse)
20+
println((1, 2, 3, 4, 5, 6, 7).reverse)
21+
println((1, 2, 3, 4, 5, 6, 7, 8).reverse)
22+
println((1, 2, 3, 4, 5, 6, 7, 8, 9).reverse)
23+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10).reverse)
24+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).reverse)
25+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12).reverse)
26+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13).reverse)
27+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14).reverse)
28+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15).reverse)
29+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16).reverse)
30+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17).reverse)
31+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18).reverse)
32+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19).reverse)
33+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20).reverse)
34+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21).reverse)
35+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22).reverse)
36+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23).reverse)
37+
println((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24).reverse)
38+
println((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).reverse)
39+
40+
println((1 *: Tuple()).reverse)
41+
println((1 *: 2 *: Tuple()).reverse)
42+
println((1 *: 2 *: 3 *: Tuple()).reverse)
43+
println((1 *: 2 *: 3 *: 4 *: Tuple()).reverse)
44+
println((1 *: 2 *: 3 *: 4 *: 5 *: Tuple()).reverse)
45+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: Tuple()).reverse)
46+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: Tuple()).reverse)
47+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: Tuple()).reverse)
48+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: Tuple()).reverse)
49+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: Tuple()).reverse)
50+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: Tuple()).reverse)
51+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: Tuple()).reverse)
52+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: Tuple()).reverse)
53+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: Tuple()).reverse)
54+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: Tuple()).reverse)
55+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: Tuple()).reverse)
56+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: Tuple()).reverse)
57+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: Tuple()).reverse)
58+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: Tuple()).reverse)
59+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: Tuple()).reverse)
60+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: Tuple()).reverse)
61+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: Tuple()).reverse)
62+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: Tuple()).reverse)
63+
println((1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: 24 *: Tuple()).reverse)
64+
println((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 *: Tuple()).reverse)
65+
}
66+
}

0 commit comments

Comments
 (0)