Skip to content

Add regression tests for Tuple and code some cleanup #6512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 16, 2019
1 change: 1 addition & 0 deletions compiler/test/dotty/tools/dotc/CompilationTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class CompilationTests extends ParallelTesting {
compileFile("tests/run-custom-args/i5256.scala", allowDeepSubtypes),
compileFile("tests/run-custom-args/fors.scala", defaultOptions and "-strict"),
compileFile("tests/run-custom-args/no-useless-forwarders.scala", defaultOptions and "-Xmixin-force-forwarders:false"),
compileFilesInDir("tests/run-deep-subtype", allowDeepSubtypes),
compileFilesInDir("tests/run", defaultOptions)
).checkRuns()
}
Expand Down
63 changes: 22 additions & 41 deletions library/src-3.x/scala/Tuple.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import annotation.showAsInfix
import compiletime._
import internal._

import scala.runtime.DynamicTuple

sealed trait Tuple extends Any {
import Tuple._

inline def toArray: Array[Object] =
inline constValueOpt[BoundedSize[this.type]] match {
case Some(0) =>
scala.runtime.DynamicTuple.empty$Array
DynamicTuple.empty$Array
case Some(1) =>
val t = asInstanceOf[Tuple1[Object]]
Array(t._1)
Expand All @@ -22,12 +24,12 @@ sealed trait Tuple extends Any {
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 <= scala.runtime.DynamicTuple.MaxSpecialized =>
to$Array(this, n)
case Some(n) if n <= DynamicTuple.MaxSpecialized =>
DynamicTuple.to$Array(this, n)
case Some(n) =>
asInstanceOf[TupleXXL].elems
case None =>
runtime.DynamicTuple.dynamicToArray(this)
DynamicTuple.dynamicToArray(this)
}

inline def *: [H, This >: this.type <: Tuple] (x: H): H *: This = {
Expand All @@ -47,9 +49,9 @@ sealed trait Tuple extends Any {
val t = asInstanceOf[Tuple4[_, _, _, _]]
Tuple5(x, t._1, t._2, t._3, t._4).asInstanceOf[Result]
case Some(n) =>
knownTupleFromArray[H *: this.type](cons$Array(x, toArray))
knownTupleFromArray[H *: this.type](DynamicTuple.cons$Array(x, toArray))
case _ =>
runtime.DynamicTuple.dynamic_*:[This, H](this, x)
DynamicTuple.dynamic_*:[This, H](this, x)
}
}

Expand All @@ -72,7 +74,7 @@ sealed trait Tuple extends Any {
val u = that.asInstanceOf[Tuple2[_, _]]
Tuple4(t._1, t._2, u._1, u._2).asInstanceOf[Result]
case _ =>
genericConcat[Result](this, that).asInstanceOf[Result]
knownTupleFromArray[Result](this.toArray ++ that.toArray)
}
case Some(3) =>
val t = asInstanceOf[Tuple3[_, _, _]]
Expand All @@ -82,24 +84,21 @@ sealed trait Tuple extends Any {
val u = that.asInstanceOf[Tuple1[_]]
Tuple4(t._1, t._2, t._3, u._1).asInstanceOf[Result]
case _ =>
genericConcat[Result](this, that).asInstanceOf[Result]
knownTupleFromArray[Result](this.toArray ++ that.toArray)
}
case Some(_) =>
if (constValue[BoundedSize[that.type]] == 0) this.asInstanceOf[Result]
else genericConcat[Result](this, that).asInstanceOf[Result]
else knownTupleFromArray[Result](this.toArray ++ that.toArray)
case None =>
runtime.DynamicTuple.dynamic_++[This, that.type](this, that)
DynamicTuple.dynamic_++[This, that.type](this, that)
}
}

inline def genericConcat[T <: Tuple](xs: Tuple, ys: Tuple): Tuple =
knownTupleFromArray[T](xs.toArray ++ ys.toArray)

inline def size[This >: this.type <: Tuple]: Size[This] = {
type Result = Size[This]
inline constValueOpt[BoundedSize[this.type]] match {
case Some(n) => n.asInstanceOf[Result]
case _ => runtime.DynamicTuple.dynamicSize(this)
case _ => DynamicTuple.dynamicSize(this)
}
}

Expand Down Expand Up @@ -144,25 +143,7 @@ object Tuple {

private[scala] type BoundedSize[X] = BoundedSizeRecur[X, 23]

val $emptyArray = Array[Object]()

def to$Array(xs: Tuple, n: Int) = {
val arr = new Array[Object](n)
var i = 0
var it = xs.asInstanceOf[Product].productIterator
while (i < n) {
arr(i) = it.next().asInstanceOf[Object]
i += 1
}
arr
}

def cons$Array[H](x: H, elems: Array[Object]): Array[Object] = {
val elems1 = new Array[Object](elems.length + 1)
elems1(0) = x.asInstanceOf[Object]
System.arraycopy(elems, 0, elems1, 1, elems.length)
elems1
}
private[scala] val $emptyArray = Array[Object]()

private[scala] inline def knownTupleFromArray[T <: Tuple](xs: Array[Object]): T =
inline constValue[BoundedSize[T]] match {
Expand Down Expand Up @@ -197,7 +178,7 @@ object Tuple {
case xs: Array[Object] => xs
case xs => xs.map(_.asInstanceOf[Object])
}
runtime.DynamicTuple.dynamicFromArray[Tuple](xs2)
DynamicTuple.dynamicFromArray[Tuple](xs2)
}

}
Expand All @@ -220,13 +201,13 @@ sealed trait NonEmptyTuple extends Tuple {
case Some(4) =>
val t = asInstanceOf[Tuple4[_, _, _, _]]
t._1
case Some(n) if n > 4 && n <= scala.runtime.DynamicTuple.MaxSpecialized =>
case Some(n) if n > 4 && n <= DynamicTuple.MaxSpecialized =>
asInstanceOf[Product].productElement(0)
case Some(n) if n > scala.runtime.DynamicTuple.MaxSpecialized =>
case Some(n) if n > DynamicTuple.MaxSpecialized =>
val t = asInstanceOf[TupleXXL]
t.elems(0)
case None =>
scala.runtime.DynamicTuple.dynamicHead[this.type](this)
DynamicTuple.dynamicHead[this.type](this)
}
resVal.asInstanceOf[Result]
}
Expand All @@ -251,14 +232,14 @@ sealed trait NonEmptyTuple extends Tuple {
case Some(n) if n > 5 =>
knownTupleFromArray[Result](toArray.tail)
case None =>
runtime.DynamicTuple.dynamicTail[This](this)
DynamicTuple.dynamicTail[This](this)
}
}

inline def fallbackApply(n: Int) =
inline constValueOpt[n.type] match {
case Some(n: Int) => error("index out of bounds: ", n)
case None => runtime.DynamicTuple.dynamicApply[this.type, n.type](this, n)
case None => DynamicTuple.dynamicApply[this.type, n.type](this, n)
}

inline def apply[This >: this.type <: NonEmptyTuple](n: Int): Elem[This, n.type] = {
Expand Down Expand Up @@ -294,13 +275,13 @@ sealed trait NonEmptyTuple extends Tuple {
case Some(3) => t._4.asInstanceOf[Result]
case _ => fallbackApply(n).asInstanceOf[Result]
}
case Some(s) if s > 4 && s <= scala.runtime.DynamicTuple.MaxSpecialized =>
case Some(s) if s > 4 && s <= DynamicTuple.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 > scala.runtime.DynamicTuple.MaxSpecialized =>
case Some(s) if s > DynamicTuple.MaxSpecialized =>
val t = asInstanceOf[TupleXXL]
inline constValueOpt[n.type] match {
case Some(n) if n >= 0 && n < s => t.elems(n).asInstanceOf[Result]
Expand Down
170 changes: 170 additions & 0 deletions tests/run-deep-subtype/Tuple-apply.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import scala.reflect.ClassTag

object Test {
def main(args: Array[String]): Unit = {

assert(1 == Tuple1(1).apply(0))
assert(1 == (1, 2).apply(0))
assert(2 == (1, 2).apply(1))
assert(1 == (1, 2, 3).apply(0))
assert(2 == (1, 2, 3).apply(1))
assert(3 == (1, 2, 3).apply(2))
assert(1 == (1, 2, 3, 4).apply(0))
assert(2 == (1, 2, 3, 4).apply(1))
assert(3 == (1, 2, 3, 4).apply(2))
assert(4 == (1, 2, 3, 4).apply(3))
assert(1 == (1, 2, 3, 4, 5).apply(0))
assert(2 == (1, 2, 3, 4, 5).apply(1))
assert(3 == (1, 2, 3, 4, 5).apply(2))
assert(4 == (1, 2, 3, 4, 5).apply(3))
assert(5 == (1, 2, 3, 4, 5).apply(4))
// TODO improve performace
// assert(1 == (1, 2, 3, 4, 5, 6).apply(0))
// assert(2 == (1, 2, 3, 4, 5, 6).apply(1))
// assert(3 == (1, 2, 3, 4, 5, 6).apply(2))
// assert(4 == (1, 2, 3, 4, 5, 6).apply(3))
// assert(5 == (1, 2, 3, 4, 5, 6).apply(4))
// assert(6 == (1, 2, 3, 4, 5, 6).apply(5))
// assert(1 == (1, 2, 3, 4, 5, 6, 7).apply(0))
// assert(2 == (1, 2, 3, 4, 5, 6, 7).apply(1))
// assert(3 == (1, 2, 3, 4, 5, 6, 7).apply(2))
// assert(4 == (1, 2, 3, 4, 5, 6, 7).apply(3))
// assert(5 == (1, 2, 3, 4, 5, 6, 7).apply(4))
// assert(6 == (1, 2, 3, 4, 5, 6, 7).apply(5))
// assert(7 == (1, 2, 3, 4, 5, 6, 7).apply(6))
// assert(1 == (1, 2, 3, 4, 5, 6, 7, 8).apply(0))
// assert(2 == (1, 2, 3, 4, 5, 6, 7, 8).apply(1))
// assert(3 == (1, 2, 3, 4, 5, 6, 7, 8).apply(2))
// assert(4 == (1, 2, 3, 4, 5, 6, 7, 8).apply(3))
// assert(5 == (1, 2, 3, 4, 5, 6, 7, 8).apply(4))
// assert(6 == (1, 2, 3, 4, 5, 6, 7, 8).apply(5))
// assert(7 == (1, 2, 3, 4, 5, 6, 7, 8).apply(6))
// assert(8 == (1, 2, 3, 4, 5, 6, 7, 8).apply(7))
// assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(0))
// assert(2 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(1))
// assert(3 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(2))
// assert(4 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(3))
// assert(5 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(4))
// assert(6 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(5))
// assert(7 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(6))
// assert(8 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(7))
// assert(9 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(8))
// assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(0))
// assert(2 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(1))
// assert(3 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(2))
// assert(4 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(3))
// assert(5 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(4))
// assert(6 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(5))
// assert(7 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(6))
// assert(8 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(7))
// assert(9 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(8))
// assert(10 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(9))

assert(1 == Tuple1(1).apply(0))
assert(1 == (1, 2).apply(0))
assert(1 == (1, 2, 3).apply(0))
assert(1 == (1, 2, 3, 4).apply(0))
assert(1 == (1, 2, 3, 4, 5).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23).apply(0))
assert(1 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24).apply(0))
assert(1 == (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).apply(0))

assert(1 == Tuple1(1).apply(0))
assert(2 == (1, 2).apply(1))
assert(3 == (1, 2, 3).apply(2))
assert(4 == (1, 2, 3, 4).apply(3))
assert(5 == (1, 2, 3, 4, 5).apply(4))
assert(6 == (1, 2, 3, 4, 5, 6).apply(5))
assert(7 == (1, 2, 3, 4, 5, 6, 7).apply(6))
assert(8 == (1, 2, 3, 4, 5, 6, 7, 8).apply(7))
assert(9 == (1, 2, 3, 4, 5, 6, 7, 8, 9).apply(8))
assert(10 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10).apply(9))
assert(11 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11).apply(10))
assert(12 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12).apply(11))
assert(13 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13).apply(12))
assert(14 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14).apply(13))
assert(15 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15).apply(14))
assert(16 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16).apply(15))
assert(17 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17).apply(16))
assert(18 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18).apply(17))
assert(19 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19).apply(18))
assert(20 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20).apply(19))
assert(21 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21).apply(20))
assert(22 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22).apply(21))
assert(23 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23).apply(22))
assert(24 == (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24).apply(23))
assert(25 == (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).apply(24))

assert(1 == (1 *: ()).apply(0))
assert(1 == (1 *: 2 *: ()).apply(0))
assert(1 == (1 *: 2 *: 3 *: ()).apply(0))
assert(1 == (1 *: 2 *: 3 *: 4 *: ()).apply(0))
assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: ()).apply(0))
assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: ()).apply(0))
assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: ()).apply(0))
// FIXME performace
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: ()).apply(0))
// assert(1 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: 24 *: ()).apply(0))
// assert(1 == (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 *: ()).apply(0))

assert(1 == (1 *: ()).apply(0))
assert(2 == (1 *: 2 *: ()).apply(1))
assert(3 == (1 *: 2 *: 3 *: ()).apply(2))
assert(4 == (1 *: 2 *: 3 *: 4 *: ()).apply(3))
assert(5 == (1 *: 2 *: 3 *: 4 *: 5 *: ()).apply(4))
assert(6 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: ()).apply(5))
assert(7 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: ()).apply(6))
// FIXME performace
// assert(8 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: ()).apply(7))
// assert(9 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: ()).apply(8))
// assert(10 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: ()).apply(9))
// assert(11 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: ()).apply(10))
// assert(12 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: ()).apply(11))
// assert(13 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: ()).apply(12))
// assert(14 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: ()).apply(13))
// assert(15 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: ()).apply(14))
// assert(16 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: ()).apply(15))
// assert(17 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: ()).apply(16))
// assert(18 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: ()).apply(17))
// assert(19 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: ()).apply(18))
// assert(20 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: ()).apply(19))
// assert(21 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: ()).apply(20))
// assert(22 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: ()).apply(21))
// assert(23 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: ()).apply(22))
// assert(24 == (1 *: 2 *: 3 *: 4 *: 5 *: 6 *: 7 *: 8 *: 9 *: 10 *: 11 *: 12 *: 13 *: 14 *: 15 *: 16 *: 17 *: 18 *: 19 *: 20 *: 21 *: 22 *: 23 *: 24 *: ()).apply(23))
// assert(25 == (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 *: ()).apply(24))

}
}
Loading