Skip to content

Commit 34adaad

Browse files
author
Antoine Brunner
committed
Finish implementing tuple.splitAt
1 parent 2d9c1ec commit 34adaad

File tree

2 files changed

+29
-6
lines changed

2 files changed

+29
-6
lines changed

library/src/scala/Tuple.scala

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ sealed trait Tuple extends Any {
5050
*/
5151
inline def map[F[_]](f: [t] => t => F[t]): Map[this.type, F] =
5252
DynamicTuple.dynamicMap(this, f)
53+
54+
inline def splitAt[This >: this.type <: Tuple](n: Int): Split[This, n.type] =
55+
DynamicTuple.dynamicSplitAt[This, n.type](this, n)
5356
}
5457

5558
object Tuple {
@@ -65,7 +68,7 @@ object Tuple {
6568
}
6669

6770
/** Type of the concatenation of two tuples */
68-
type Concat[+X <: Tuple, +Y <: Tuple] <: Tuple = X match {
71+
type Concat[X <: Tuple, +Y <: Tuple] <: Tuple = X match {
6972
case Unit => Y
7073
case x1 *: xs1 => x1 *: Concat[xs1, Y]
7174
}
@@ -117,16 +120,16 @@ object Tuple {
117120
type IsMappedBy[F[_]] = [X <: Tuple] =>> X =:= Map[InverseMap[X, F], F]
118121

119122
/** Transforms a tuple `(T1, ..., Tn)` into `(T1, ..., Ti)`. */
120-
type Take[+T <: Tuple, N <: Int] = N match {
123+
type Take[T <: Tuple, N <: Int] <: Tuple = N match {
121124
case 0 => Unit
122125
case S[n1] => T match {
123126
case Unit => Unit
124-
case x *: xs => Concat[x *: Unit, Take[xs, n1]]
127+
case x *: xs => x *: Take[xs, n1]
125128
}
126129
}
127130

128131
/** Transforms a tuple `(T1, ..., Tn)` into `(Ti+1, ..., Tn)`. */
129-
type Drop[+T <: Tuple, N <: Int] = N match {
132+
type Drop[T <: Tuple, N <: Int] <: Tuple = N match {
130133
case 0 => T
131134
case S[n1] => T match {
132135
case Unit => Unit
@@ -137,7 +140,7 @@ object Tuple {
137140
/** Splits a tuple (T1, ..., Tn) into a pair of two tuples `(T1, ..., Ti)` and
138141
* `(Ti+1, ..., Tn)`.
139142
*/
140-
type Split[+T <: Tuple, N <: Int] = (Take[T, N], Drop[T, N]) = (Take[T, N], Drop[T, N])
143+
type Split[T <: Tuple, N <: Int] = (Take[T, N], Drop[T, N])
141144

142145
/** Convert an array into a tuple of unknown arity and types */
143146
def fromArray[T](xs: Array[T]): Tuple = {

library/src/scala/runtime/DynamicTuple.scala

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package scala.runtime
22

3-
import scala.Tuple.{ Concat, Size, Head, Tail, Elem, Zip, Map }
3+
import scala.Tuple.{ Concat, Size, Head, Tail, Elem, Zip, Map, Split }
44

55
object DynamicTuple {
66
inline val MaxSpecialized = 22
@@ -264,6 +264,26 @@ object DynamicTuple {
264264
.asInstanceOf[Map[This, F]]
265265
}
266266

267+
def dynamicSplitAt[This <: Tuple, N <: Int](self: This, n: N): Split[This, N] = {
268+
type Result = Split[This, N]
269+
val (arr1, arr2) = (self: Any) match {
270+
case xxl: TupleXXL =>
271+
xxl.elems.asInstanceOf[Array[Object]].splitAt(n)
272+
case _ =>
273+
val size = self.asInstanceOf[Product].productArity
274+
val arr1 = new Array[Object](n)
275+
val arr2 = new Array[Object](size - n)
276+
val it = self.asInstanceOf[Product].productIterator
277+
itToArray(it, n, arr1, 0)
278+
itToArray(it, size - n, arr2, 0)
279+
(arr1, arr2)
280+
}
281+
(
282+
dynamicFromIArray(arr1.asInstanceOf[IArray[Object]]),
283+
dynamicFromIArray(arr2.asInstanceOf[IArray[Object]])
284+
).asInstanceOf[Result]
285+
}
286+
267287
def consIterator(head: Any, tail: Tuple): Iterator[Any] =
268288
Iterator.single(head) ++ tail.asInstanceOf[Product].productIterator
269289

0 commit comments

Comments
 (0)