Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions library/src/scala/collection/ArrayOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ object ArrayOps {
/** Creates a new non-strict filter which combines this filter with the given predicate.
*
* @param q the additional predicate to apply in conjunction with `p`
* @return a new `WithFilter` that retains only elements satisfying both `p` and `q`
*/
def withFilter(q: A => Boolean): WithFilter[A]^{this, q} = new WithFilter[A](a => p(a) && q(a), xs)
}
Expand Down Expand Up @@ -392,24 +393,28 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
/** An array containing the first `n` elements of this array.
*
* @param n the number of elements to take from this array
* @return a new array containing the first `n` elements of this array, all elements if `n` exceeds the array length, or an empty array if `n` is non-positive
*/
def take(n: Int): Array[A] = slice(0, n)

/** The rest of the array without its `n` first elements.
*
* @param n the number of elements to drop from the front of this array
* @return a new array containing all elements of this array except the first `n`, an empty array if `n` exceeds the array length, or a copy of all elements if `n` is non-positive
*/
def drop(n: Int): Array[A] = slice(n, xs.length)

/** An array containing the last `n` elements of this array.
*
* @param n the number of elements to take from the end of this array
* @return a new array containing the last `n` elements of this array, or all elements if `n` exceeds the array length
*/
def takeRight(n: Int): Array[A] = drop(xs.length - max(n, 0))

/** The rest of the array without its `n` last elements.
*
* @param n the number of elements to drop from the end of this array
* @return a new array containing all elements of this array except the last `n`, or empty if `n` exceeds the array length
*/
def dropRight(n: Int): Array[A] = take(xs.length - max(n, 0))

Expand Down Expand Up @@ -507,6 +512,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
/** A pair of, first, all elements that satisfy predicate `p` and, second, all elements that do not.
*
* @param p the predicate used to partition the elements
* @return a pair of arrays: the first containing all elements that satisfy `p`, the second containing all elements that do not
*/
def partition(p: A => Boolean): (Array[A], Array[A]) = {
val res1, res2 = ArrayBuilder.make[A]
Expand Down Expand Up @@ -1070,6 +1076,8 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
* partial function to it.
*
* @tparam B the result type of the partial function
* @param pf the partial function applied to the first element on which it is defined
* @return an option value containing `pf` applied to the first element on which it is defined, or `None` if no such element exists
*/
def collectFirst[B](@deprecatedName("f","2.13.9") pf: PartialFunction[A, B]^): Option[B] = {
val fallback: Any => Any = ArrayOps.fallback
Expand Down Expand Up @@ -1178,6 +1186,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
*
* @tparam B the element type of the returned array, a supertype of `A`
* @param x the element to append
* @return a new array consisting of all elements of this array followed by `x`
*/
def appended[B >: A : ClassTag](x: B): Array[B] = {
val dest = Array.copyAs[B](xs, xs.length+1)
Expand All @@ -1191,6 +1200,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
*
* @tparam B the element type of the returned array, a supertype of `A`
* @param x the element to prepend
* @return a new array consisting of `x` followed by all elements of this array
*/
def prepended[B >: A : ClassTag](x: B): Array[B] = {
val dest = new Array[B](xs.length + 1)
Expand All @@ -1205,6 +1215,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
*
* @tparam B the element type of the returned array, a supertype of `A`
* @param prefix the collection to prepend
* @return a new array consisting of all elements of `prefix` followed by all elements of this array
*/
def prependedAll[B >: A : ClassTag](prefix: IterableOnce[B]^): Array[B] = {
val b = ArrayBuilder.make[B]
Expand All @@ -1220,6 +1231,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
*
* @tparam B the element type of the returned array, a supertype of `A`
* @param prefix the array to prepend
* @return a new array consisting of all elements of `prefix` followed by all elements of this array
*/
def prependedAll[B >: A : ClassTag](prefix: Array[? <: B]): Array[B] = {
val dest = Array.copyAs[B](prefix, prefix.length+xs.length)
Expand All @@ -1235,6 +1247,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
*
* @tparam B the element type of the returned array, a supertype of `A`
* @param suffix the collection to append
* @return a new array consisting of all elements of this array followed by all elements of `suffix`
*/
def appendedAll[B >: A : ClassTag](suffix: IterableOnce[B]^): Array[B] = {
val b = ArrayBuilder.make[B]
Expand All @@ -1248,6 +1261,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
*
* @tparam B the element type of the returned array, a supertype of `A`
* @param suffix the array to append
* @return a new array consisting of all elements of this array followed by all elements of `suffix`
*/
def appendedAll[B >: A : ClassTag](suffix: Array[? <: B]): Array[B] = {
val dest = Array.copyAs[B](xs, xs.length+suffix.length)
Expand Down Expand Up @@ -1284,6 +1298,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
* @param from The start index from which to patch
* @param other The patch values
* @param replaced The number of values in the original array that are replaced by the patch.
* @return a new array consisting of the elements of this array with `replaced` elements starting at `from` replaced by the elements of `other` (subject to the edge cases noted above)
*/
def patch[B >: A : ClassTag](from: Int, other: IterableOnce[B]^, replaced: Int): Array[B] = {
val b = ArrayBuilder.make[B]
Expand Down Expand Up @@ -1514,6 +1529,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
*
* @tparam B the type of the elements of the array.
* @param xs the array to fill.
* @return the number of elements actually copied
*/
def copyToArray[B >: A](xs: Array[B]): Int = copyToArray(xs, 0)

Expand All @@ -1525,6 +1541,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
* @tparam B the type of the elements of the array.
* @param xs the array to fill.
* @param start the starting index within the destination array.
* @return the number of elements actually copied
*/
def copyToArray[B >: A](xs: Array[B], start: Int): Int = copyToArray(xs, start, Int.MaxValue)

Expand All @@ -1537,6 +1554,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
* @param xs the array to fill.
* @param start the starting index within the destination array.
* @param len the maximal number of elements to copy.
* @return the number of elements actually copied
*/
def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Int = {
val copied = IterableOnce.elemsToCopyToArray(this.xs.length, xs.length, start, len)
Expand All @@ -1549,6 +1567,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
/** Creates a copy of this array with the specified element type.
*
* @tparam B the element type of the copy, a supertype of `A`
* @return a new `Array[B]` containing all elements of this array
*/
def toArray[B >: A: ClassTag]: Array[B] = {
val destination = new Array[B](xs.length)
Expand All @@ -1560,6 +1579,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
/** Counts the number of elements in this array which satisfy a predicate.
*
* @param p the predicate used to test elements
* @return the number of elements of this array for which `p` returns `true`
*/
def count(p: A => Boolean): Int = {
var i, res = 0
Expand All @@ -1576,6 +1596,7 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
*
* @tparam B the element type of the prefix array, a supertype of `A`
* @param that the array to test as a prefix
* @return `true` if this array has `that` as a prefix, `false` otherwise
*/
@`inline` def startsWith[B >: A](that: Array[B]): Boolean = startsWith(that, 0)

Expand Down
2 changes: 2 additions & 0 deletions library/src/scala/collection/BitSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,14 @@ transparent trait BitSetOps[+C <: BitSet & BitSetOps[C]]
* **Note:** requires `idx >= 0`
*
* @param idx the index of the word to retrieve, must be non-negative
* @return the 64-bit word at position `idx`, or `0L` if `idx` is outside the range of the set
*/
protected[collection] def word(idx: Int): Long

/** Creates a new set of this kind from an array of longs
*
* @param elems the array of 64-bit words representing the bit mask for the new set
* @return a new bitset of type `C` whose contents are given by the bit mask in `elems` (the array is used directly and not copied)
*/
protected[collection] def fromBitMaskNoCopy(elems: Array[Long]): C

Expand Down
18 changes: 18 additions & 0 deletions library/src/scala/collection/BuildFrom.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ trait BuildFrom[-From, -A, +C] extends Any { self =>
* Building collections with `fromSpecific` is preferred because it can be lazy for lazy collections.
*
* @param from the source collection providing the factory for creating the builder
* @return a new `Builder` that accepts elements of type `A` and produces a collection of type `C`
*/
def newBuilder(from: From): Builder[A, C]

Expand All @@ -44,6 +45,7 @@ trait BuildFrom[-From, -A, +C] extends Any { self =>
/** Partially apply a BuildFrom to a Factory.
*
* @param from the source collection to partially apply, producing a `Factory` bound to it
* @return a `Factory` that builds collections of type `C` from elements of type `A`, using `from` as the source collection
*/
def toFactory(from: From): Factory[A, C] = new Factory[A, C] {
def fromSpecific(it: IterableOnce[A]^): C^{it} = self.fromSpecific(from)(it)
Expand All @@ -56,6 +58,11 @@ object BuildFrom extends BuildFromLowPriority1 {
/** Builds the source collection type from a MapOps.
*
* @tparam CC the higher-kinded type constructor of the map collection (e.g. `HashMap`)
* @tparam K0 the key type of the source map
* @tparam V0 the value type of the source map
* @tparam K the key type of the resulting map
* @tparam V the value type of the resulting map
* @return a `BuildFrom` instance that builds a `CC[K, V]` from `(K, V)` pairs, using the `mapFactory` of the source `CC[K0, V0]`
*/
implicit def buildFromMapOps[CC[X, Y] <: Map[X, Y] & MapOps[X, Y, CC, ?], K0, V0, K, V]: BuildFrom[CC[K0, V0] & Map[K0, V0], (K, V), CC[K, V] & Map[K, V]] = new BuildFrom[CC[K0, V0], (K, V), CC[K, V]] {
//TODO: Reuse a prototype instance
Expand All @@ -66,6 +73,11 @@ object BuildFrom extends BuildFromLowPriority1 {
/** Builds the source collection type from a SortedMapOps.
*
* @tparam CC the higher-kinded type constructor of the sorted map collection (e.g. `TreeMap`)
* @tparam K0 the key type of the source sorted map
* @tparam V0 the value type of the source sorted map
* @tparam K the key type of the resulting sorted map, which must have an `Ordering`
* @tparam V the value type of the resulting sorted map
* @return a `BuildFrom` instance that builds a `CC[K, V]` from `(K, V)` pairs, using the `sortedMapFactory` of the source `CC[K0, V0]`
*/
implicit def buildFromSortedMapOps[CC[X, Y] <: SortedMap[X, Y] & SortedMapOps[X, Y, CC, ?], K0, V0, K : Ordering, V]: BuildFrom[CC[K0, V0] & SortedMap[K0, V0], (K, V), CC[K, V] & SortedMap[K, V]] = new BuildFrom[CC[K0, V0], (K, V), CC[K, V]] {
def newBuilder(from: CC[K0, V0]): Builder[(K, V), CC[K, V]] = (from: SortedMapOps[K0, V0, CC, ?]).sortedMapFactory.newBuilder[K, V]
Expand Down Expand Up @@ -109,6 +121,9 @@ trait BuildFromLowPriority1 extends BuildFromLowPriority2 {
/** Builds the source collection type from an Iterable with SortedOps.
*
* @tparam CC the higher-kinded type constructor of the sorted set collection (e.g. `TreeSet`)
* @tparam A0 the element type of the source sorted set
* @tparam A the element type of the resulting sorted set, which must have an `Ordering`
* @return a `BuildFrom` instance that builds a sorted `CC[A]` (requiring an `Ordering[A]`) from elements of type `A`, using the `sortedIterableFactory` of the source `CC[A0]`
*/
// Restating the upper bound of CC in the result type seems redundant, but it serves to prune the
// implicit search space for faster compilation and reduced change of divergence. See the compilation
Expand All @@ -129,6 +144,9 @@ trait BuildFromLowPriority2 {
/** Builds the source collection type from an IterableOps.
*
* @tparam CC the higher-kinded type constructor of the iterable collection (e.g. `List`, `Vector`)
* @tparam A0 the element type of the source iterable
* @tparam A the element type of the resulting iterable
* @return a `BuildFrom` instance that builds a `CC[A]` from elements of type `A`, using the `iterableFactory` of the source `CC[A0]`
*/
implicit def buildFromIterableOps[CC[X] <: Iterable[X] & IterableOps[X, CC, ?], A0, A]: BuildFrom[CC[A0], A, CC[A]] = new BuildFrom[CC[A0], A, CC[A]] {
//TODO: Reuse a prototype instance
Expand Down
7 changes: 7 additions & 0 deletions library/src/scala/collection/Factory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,9 @@ trait IterableFactory[+CC[_]] extends Serializable, caps.Pure {
def from[A](source: IterableOnce[A]^): CC[A]^{source}

/** An empty $coll.
*
* @tparam A the type of the ${coll}'s elements
* @return an empty $coll of type `CC[A]`
*/
def empty[A]: CC[A]

Expand Down Expand Up @@ -415,6 +417,7 @@ trait MapFactory[+CC[_, _]] extends Serializable { self =>
*
* @tparam K the type of the keys
* @tparam V the type of the values
* @return an empty map of type `CC[K, V]`
*/
def empty[K, V]: CC[K, V]

Expand All @@ -423,6 +426,7 @@ trait MapFactory[+CC[_, _]] extends Serializable { self =>
* @tparam K the type of the keys
* @tparam V the type of the values
* @param it the source collection of key-value pairs
* @return a new map of type `CC[K, V]` containing the bindings from `it`
*/
def from[K, V](it: IterableOnce[(K, V)]^): CC[K, V]^{it}

Expand All @@ -431,20 +435,23 @@ trait MapFactory[+CC[_, _]] extends Serializable { self =>
* @tparam K the type of the keys
* @tparam V the type of the values
* @param elems the key-value pairs to include in the map
* @return a new map of type `CC[K, V]` containing the given `elems`
*/
def apply[K, V](elems: (K, V)*): CC[K, V] = from(elems)

/** The default builder for Map objects.
*
* @tparam K the type of the keys
* @tparam V the type of the values
* @return a new `Builder` that accepts key-value pairs and produces a `CC[K, V]`
*/
def newBuilder[K, V]: Builder[(K, V), CC[K, V]]

/** The default Factory instance for maps.
*
* @tparam K the type of the keys
* @tparam V the type of the values
* @return a `Factory` that builds a `CC[K, V]` from a collection of key-value pairs
*/
implicit def mapFactory[K, V]: Factory[(K, V), CC[K, V]] = MapFactory.toFactory(this)
}
Expand Down
4 changes: 4 additions & 0 deletions library/src/scala/collection/IndexedSeq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ transparent trait IndexedSeqOps[+A, +CC[_], +C] extends Any with SeqOps[A, CC, C
*
* @tparam A the element type of the sequence
* @tparam CC the type constructor for the resulting collection (e.g., `IndexedSeq`)
* @tparam C the type of the concrete collection being sliced
* @param s the underlying indexed sequence from which slices are produced
* @param size the number of elements in each slice; must be positive
* @param step the distance between the starting positions of successive slices; must be positive
*/
private final class IndexedSeqSlidingIterator[A, CC[_], C](s: IndexedSeqOps[A, CC, C]^, size: Int, step: Int)
extends AbstractIterator[C^{s}] {
Expand Down
1 change: 1 addition & 0 deletions library/src/scala/collection/Iterable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,7 @@ transparent trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] w
* @param key the discriminator function
* @param f the element transformation function
* @param reduce the reduction function used to combine values mapped to the same key
* @return a map associating each key `k` produced by `key` with the reduction of all values produced by applying `f` to elements that map to `k`
*/
def groupMapReduce[K, B](key: A => K)(f: A => B)(reduce: (B, B) => B): immutable.Map[K, B] = {
val m = mutable.Map.empty[K, B]
Expand Down
3 changes: 3 additions & 0 deletions library/src/scala/collection/IterableOnce.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ trait IterableOnce[+A] extends Any { this: IterableOnce[A]^ =>
* streams.
*
* @tparam S the type of the returned `Stepper`, determined by the implicit `StepperShape`
* @param shape the `StepperShape` that determines the concrete `Stepper` subtype to return
* @return a `Stepper` over the elements of this $coll, using a primitive-typed `Stepper` subclass for `Int`/`Long`/`Double` (and related) element types
*/
def stepper[S <: Stepper[?]](implicit shape: StepperShape[A, S]): S^{this} = {
import convert.impl._
Expand Down Expand Up @@ -345,6 +347,7 @@ object IterableOnce {
*
* @tparam A the element type of the collection
* @tparam CC the type constructor for the collection's "same element type" results (e.g., `List` for `List[Int]`)
* @tparam C the concrete collection type returned by operations that preserve it (e.g., `List[Int]` when `CC` is `List`)
*/
transparent trait IterableOnceOps[+A, +CC[_], +C] extends Any { this: IterableOnce[A]^ =>
/////////////////////////////////////////////////////////////// Abstract methods that must be implemented
Expand Down
Loading
Loading