Skip to content

Commit 769cd8a

Browse files
author
Antoine Brunner
committed
Add take and drop methods on Tuples
1 parent e4dfcf5 commit 769cd8a

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

library/src/scala/Tuple.scala

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,31 @@ sealed trait Tuple extends Any {
4343
inline def zip[This >: this.type <: Tuple, T2 <: Tuple](t2: T2): Zip[This, T2] =
4444
DynamicTuple.dynamicZip(this, t2)
4545

46-
/** Called on a tuple `(a1, ..., an)`, returns a new tuple `(f(a1), ..., f(an))`.
47-
* The result is typed as `(F[A1], ..., F[An])` if the tuple type is fully known.
48-
* If the tuple is of the form `a1 *: ... *: Tuple` (that is, the tail is not known
49-
* to be the cons type.
50-
*/
46+
/** Called on a tuple `(a1, ..., an)`, returns a new tuple `(f(a1), ..., f(an))`.
47+
* The result is typed as `(F[A1], ..., F[An])` if the tuple type is fully known.
48+
* If the tuple is of the form `a1 *: ... *: Tuple` (that is, the tail is not known
49+
* to be the cons type.
50+
*/
5151
inline def map[F[_]](f: [t] => t => F[t]): Map[this.type, F] =
5252
DynamicTuple.dynamicMap(this, f)
5353

54+
/** Given a tuple `(a1, ..., am)`, returns the tuple `(a1, ..., an)` consisting
55+
* of its first n elements.
56+
*/
57+
inline def take[This >: this.type <: Tuple](n: Int): Take[This, n.type] =
58+
DynamicTuple.dynamicTake[This, n.type](this, n)
59+
60+
61+
/** Given a tuple `(a1, ..., am)`, returns the tuple `(an+1, ..., am)` consisting
62+
* all its elements except the first n ones.
63+
*/
64+
inline def drop[This >: this.type <: Tuple](n: Int): Drop[This, n.type] =
65+
DynamicTuple.dynamicDrop[This, n.type](this, n)
66+
67+
/** Given a tuple `(a1, ..., am)`, returns a pair of the tuple `(a1, ..., an)`
68+
* consisting of the first n elements, and the tuple `(an+1, ..., am)` consisting
69+
* of the remaining elements.
70+
*/
5471
inline def splitAt[This >: this.type <: Tuple](n: Int): Split[This, n.type] =
5572
DynamicTuple.dynamicSplitAt[This, n.type](this, n)
5673
}

library/src/scala/runtime/DynamicTuple.scala

Lines changed: 28 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, Split }
3+
import scala.Tuple.{ Concat, Size, Head, Tail, Elem, Zip, Map, Take, Drop, Split }
44

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

267+
def dynamicTake[This <: Tuple, N <: Int](self: This, n: N): Take[This, N] = {
268+
type Result = Take[This, N]
269+
val arr = (self: Any) match {
270+
case xxl: TupleXXL =>
271+
xxl.elems.asInstanceOf[Array[Object]].take(n)
272+
case _ =>
273+
val arr = new Array[Object](n)
274+
itToArray(self.asInstanceOf[Product].productIterator, n, arr, 0)
275+
arr
276+
}
277+
dynamicFromIArray(arr.asInstanceOf[IArray[Object]]).asInstanceOf[Result]
278+
}
279+
280+
def dynamicDrop[This <: Tuple, N <: Int](self: This, n: N): Drop[This, N] = {
281+
type Result = Drop[This, N]
282+
val arr = (self: Any) match {
283+
case xxl: TupleXXL =>
284+
xxl.elems.asInstanceOf[Array[Object]].drop(n)
285+
case _ =>
286+
val size = self.asInstanceOf[Product].productArity - n
287+
val arr = new Array[Object](size)
288+
itToArray(self.asInstanceOf[Product].productIterator.drop(n), size, arr, 0)
289+
arr
290+
}
291+
dynamicFromIArray(arr.asInstanceOf[IArray[Object]]).asInstanceOf[Result]
292+
}
293+
267294
def dynamicSplitAt[This <: Tuple, N <: Int](self: This, n: N): Split[This, N] = {
268295
type Result = Split[This, N]
269296
val (arr1, arr2) = (self: Any) match {

0 commit comments

Comments
 (0)