Skip to content

Commit f2f2eac

Browse files
authored
Merge pull request scala#7647 from szeiger/issue/10940
Clean up StrictOptimizedOps traits
2 parents 4b979cc + 2e2a860 commit f2f2eac

18 files changed

+86
-67
lines changed

src/library/scala/collection/Iterable.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,6 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
342342
@deprecated("Use .view.slice(from, until) instead of .view(from, until)", "2.13.0")
343343
@`inline` final def view(from: Int, until: Int): View[A] = view.slice(from, until)
344344

345-
//TODO Can there be a useful lazy implementation of this method? Otherwise mark it as being always strict
346345
/** Transposes this $coll of iterable collections into
347346
* a $coll of ${coll}s.
348347
*
@@ -517,7 +516,9 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
517516
drop(1)
518517
}
519518

520-
/** The initial part of the collection without its last element. */
519+
/** The initial part of the collection without its last element.
520+
* $willForceEvaluation
521+
*/
521522
def init: C = {
522523
if (isEmpty) throw new UnsupportedOperationException
523524
dropRight(1)
@@ -603,6 +604,8 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
603604
* def occurrences[A](as: Seq[A]): Map[A, Int] =
604605
* as.groupMapReduce(identity)(_ => 1)(_ + _)
605606
* }}}
607+
*
608+
* $willForceEvaluation
606609
*/
607610
def groupMapReduce[K, B](key: A => K)(f: A => B)(reduce: (B, B) => B): immutable.Map[K, B] = {
608611
val m = mutable.Map.empty[K, B]
@@ -637,6 +640,7 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
637640
* The head of the collection is the last cumulative result.
638641
* $willNotTerminateInf
639642
* $orderDependent
643+
* $willForceEvaluation
640644
*
641645
* Example:
642646
* {{{
@@ -810,6 +814,8 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
810814
* $coll and the final one will be an empty $coll, with the intervening
811815
* values the results of successive applications of `init`.
812816
*
817+
* $willForceEvaluation
818+
*
813819
* @return an iterator over all the inits of this $coll
814820
* @example `List(1,2,3).inits = Iterator(List(1,2,3), List(1,2), List(1), Nil)`
815821
*/

src/library/scala/collection/LinearSeq.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ trait LinearSeqOps[+A, +CC[X] <: LinearSeq[X], +C <: LinearSeq[A] with LinearSeq
239239
Iterator.iterate(coll)(_.tail).takeWhile(_.nonEmpty) ++ Iterator.single(newSpecificBuilder.result())
240240
}
241241

242-
trait StrictOptimizedLinearSeqOps[+A, +CC[X] <: LinearSeq[X], +C <: LinearSeq[A] with StrictOptimizedLinearSeqOps[A, CC, C]] extends LinearSeqOps[A, CC, C] with StrictOptimizedSeqOps[A, CC, C] {
242+
trait StrictOptimizedLinearSeqOps[+A, +CC[X] <: LinearSeq[X], +C <: LinearSeq[A] with StrictOptimizedLinearSeqOps[A, CC, C]] extends Any with LinearSeqOps[A, CC, C] with StrictOptimizedSeqOps[A, CC, C] {
243243
// A more efficient iterator implementation than the default LinearSeqIterator
244244
override def iterator: Iterator[A] = new AbstractIterator[A] {
245245
private[this] var current: Iterable[A] = toIterable

src/library/scala/collection/Seq.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any
225225
/** Returns new $coll with elements in reversed order.
226226
*
227227
* $willNotTerminateInf
228+
* $willForceEvaluation
228229
*
229230
* @return A new $coll with all elements of this $coll in reversed order.
230231
*/
@@ -710,6 +711,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any
710711

711712
/** Sorts this $coll according to a comparison function.
712713
* $willNotTerminateInf
714+
* $willForceEvaluation
713715
*
714716
* The sort is stable. That is, elements that are equal (as determined by
715717
* `lt`) appear in the same order in the sorted sequence as in the original.
@@ -729,6 +731,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any
729731
/** Sorts this $coll according to the Ordering which results from transforming
730732
* an implicitly given Ordering with a transformation function.
731733
* $willNotTerminateInf
734+
* $willForceEvaluation
732735
*
733736
* The sort is stable. That is, elements that are equal (as determined by
734737
* `ord.compare`) appear in the same order in the sorted sequence as in the original.
@@ -753,6 +756,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any
753756
def sortBy[B](f: A => B)(implicit ord: Ordering[B]): C = sorted(ord on f)
754757

755758
/** Produces the range of all indices of this sequence.
759+
* $willForceEvaluation
756760
*
757761
* @return a `Range` value from `0` to one less than the length of this $coll.
758762
*/

src/library/scala/collection/StrictOptimizedSeqOps.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ import scala.language.higherKinds
2020
*/
2121
trait StrictOptimizedSeqOps [+A, +CC[_], +C]
2222
extends Any
23-
with StrictOptimizedIterableOps[A, CC, C]
24-
with SeqOps[A, CC, C] {
23+
with SeqOps[A, CC, C]
24+
with StrictOptimizedIterableOps[A, CC, C] {
2525

2626
override def distinctBy[B](f: A => B): C = {
2727
val builder = newSpecificBuilder

src/library/scala/collection/immutable/BitSet.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ sealed abstract class BitSet
3030
extends AbstractSet[Int]
3131
with SortedSet[Int]
3232
with SortedSetOps[Int, SortedSet, BitSet]
33-
with StrictOptimizedIterableOps[Int, Set, BitSet]
3433
with StrictOptimizedSortedSetOps[Int, SortedSet, BitSet]
3534
with collection.BitSet
3635
with collection.BitSetOps[BitSet] {

src/library/scala/collection/immutable/HashMap.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import java.lang.System.arraycopy
1919
import scala.annotation.unchecked.{uncheckedVariance => uV}
2020
import scala.collection.Hashing.improve
2121
import scala.collection.mutable.Builder
22-
import scala.collection.{Iterator, MapFactory, StrictOptimizedIterableOps, StrictOptimizedMapOps, mutable}
22+
import scala.collection.{Iterator, MapFactory, StrictOptimizedIterableOps, mutable}
2323
import scala.util.hashing.MurmurHash3
2424
import scala.runtime.Statics.releaseFence
2525

@@ -37,8 +37,6 @@ import scala.runtime.Statics.releaseFence
3737

3838
final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode: MapNode[K, V])
3939
extends AbstractMap[K, V]
40-
with MapOps[K, V, HashMap, HashMap[K, V]]
41-
with StrictOptimizedIterableOps[(K, V), Iterable, HashMap[K, V]]
4240
with StrictOptimizedMapOps[K, V, HashMap, HashMap[K, V]] {
4341

4442
def this() = this(MapNode.empty)

src/library/scala/collection/immutable/HashSet.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ import scala.runtime.Statics.releaseFence
3434
*/
3535
final class HashSet[A] private[immutable] (val rootNode: SetNode[A])
3636
extends AbstractSet[A]
37-
with SetOps[A, HashSet, HashSet[A]]
38-
with StrictOptimizedIterableOps[A, HashSet, HashSet[A]] {
37+
with StrictOptimizedSetOps[A, HashSet, HashSet[A]] {
3938

4039
releaseFence()
4140

src/library/scala/collection/immutable/IntMap.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,7 @@ import IntMap._
180180
* @define willNotTerminateInf
181181
*/
182182
sealed abstract class IntMap[+T] extends AbstractMap[Int, T]
183-
with MapOps[Int, T, Map, IntMap[T]]
184-
with StrictOptimizedIterableOps[(Int, T), Iterable, IntMap[T]] {
183+
with StrictOptimizedMapOps[Int, T, Map, IntMap[T]] {
185184

186185
override protected def fromSpecific(coll: scala.collection.IterableOnce[(Int, T) @uncheckedVariance]): IntMap[T] =
187186
intMapFrom[T](coll)

src/library/scala/collection/immutable/ListMap.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ import scala.runtime.Statics.releaseFence
4545
sealed class ListMap[K, +V]
4646
extends AbstractMap[K, V]
4747
with SeqMap[K, V]
48-
with MapOps[K, V, ListMap, ListMap[K, V]]
49-
with StrictOptimizedIterableOps[(K, V), Iterable, ListMap[K, V]]
5048
with StrictOptimizedMapOps[K, V, ListMap, ListMap[K, V]] {
5149

5250
override def mapFactory: MapFactory[ListMap] = ListMap

src/library/scala/collection/immutable/ListSet.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ import scala.annotation.tailrec
4242
*/
4343
sealed class ListSet[A]
4444
extends AbstractSet[A]
45-
with SetOps[A, ListSet, ListSet[A]]
46-
with StrictOptimizedIterableOps[A, ListSet, ListSet[A]] {
45+
with StrictOptimizedSetOps[A, ListSet, ListSet[A]] {
4746

4847
override protected[this] def className: String = "ListSet"
4948

src/library/scala/collection/immutable/LongMap.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,7 @@ private[immutable] class LongMapKeyIterator[V](it: LongMap[V]) extends LongMapIt
176176
* @define willNotTerminateInf
177177
*/
178178
sealed abstract class LongMap[+T] extends AbstractMap[Long, T]
179-
with MapOps[Long, T, Map, LongMap[T]]
180-
with StrictOptimizedIterableOps[(Long, T), Iterable, LongMap[T]] {
179+
with StrictOptimizedMapOps[Long, T, Map, LongMap[T]] {
181180

182181
override protected def fromSpecific(coll: scala.collection.IterableOnce[(Long, T)] @uncheckedVariance): LongMap[T] = {
183182
//TODO should this be the default implementation of this method in StrictOptimizedIterableOps?

src/library/scala/collection/immutable/Map.scala

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ trait MapOps[K, +V, +CC[X, +Y] <: MapOps[X, Y, CC, _], +C <: MapOps[K, V, CC, C]
8383
/** Creates a new $coll from this $coll by removing all elements of another
8484
* collection.
8585
*
86+
* $willForceEvaluation
87+
*
8688
* @param keys the collection containing the removed elements.
8789
* @return a new $coll that contains all elements of the current $coll
8890
* except one less occurrence of each of the elements of `elems`.
@@ -143,13 +145,6 @@ trait MapOps[K, +V, +CC[X, +Y] <: MapOps[X, Y, CC, _], +C <: MapOps[K, V, CC, C]
143145
*/
144146
def transform[W](f: (K, V) => W): CC[K, W] = map { case (k, v) => (k, f(k, v)) }
145147

146-
override def concat [V1 >: V](that: collection.IterableOnce[(K, V1)]): CC[K, V1] = {
147-
var result: CC[K, V1] = coll
148-
val it = that.iterator
149-
while (it.hasNext) result = result + it.next()
150-
result
151-
}
152-
153148
override def keySet: Set[K] = new ImmutableKeySet
154149

155150
/** The implementation class of the set returned by `keySet` */
@@ -160,6 +155,20 @@ trait MapOps[K, +V, +CC[X, +Y] <: MapOps[X, Y, CC, _], +C <: MapOps[K, V, CC, C]
160155

161156
}
162157

158+
trait StrictOptimizedMapOps[K, +V, +CC[X, +Y] <: MapOps[X, Y, CC, _], +C <: MapOps[K, V, CC, C]]
159+
extends MapOps[K, V, CC, C]
160+
with collection.StrictOptimizedMapOps[K, V, CC, C]
161+
with StrictOptimizedIterableOps[(K, V), Iterable, C] {
162+
163+
override def concat [V1 >: V](that: collection.IterableOnce[(K, V1)]): CC[K, V1] = {
164+
var result: CC[K, V1] = coll
165+
val it = that.iterator
166+
while (it.hasNext) result = result + it.next()
167+
result
168+
}
169+
}
170+
171+
163172
/**
164173
* $factoryInfo
165174
* @define coll immutable map

src/library/scala/collection/immutable/Set.scala

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,6 @@ trait SetOps[A, +CC[X], +C <: SetOps[A, CC, C]]
5858
@deprecatedOverriding("This method should be final, but is not due to scala/bug#10853", "2.13.0")
5959
/*@`inline` final*/ override def - (elem: A): C = excl(elem)
6060

61-
override def concat(that: collection.IterableOnce[A]): C = {
62-
var result: C = coll
63-
val it = that.iterator
64-
while (it.hasNext) result = result + it.next()
65-
result
66-
}
67-
6861
def diff(that: collection.Set[A]): C =
6962
toIterable.foldLeft(empty)((result, elem) => if (that contains elem) result else result + elem)
7063

@@ -81,6 +74,19 @@ trait SetOps[A, +CC[X], +C <: SetOps[A, CC, C]]
8174
override /*final*/ def -- (that: IterableOnce[A]): C = removedAll(that)
8275
}
8376

77+
trait StrictOptimizedSetOps[A, +CC[X], +C <: SetOps[A, CC, C]]
78+
extends SetOps[A, CC, C]
79+
with collection.StrictOptimizedSetOps[A, CC, C]
80+
with StrictOptimizedIterableOps[A, CC, C] {
81+
82+
override def concat(that: collection.IterableOnce[A]): C = {
83+
var result: C = coll
84+
val it = that.iterator
85+
while (it.hasNext) result = result + it.next()
86+
result
87+
}
88+
}
89+
8490
/**
8591
* $factoryInfo
8692
* @define coll immutable set

src/library/scala/collection/immutable/SortedMap.scala

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -51,36 +51,42 @@ trait SortedMap[K, +V]
5151
}
5252

5353
trait SortedMapOps[K, +V, +CC[X, +Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _], +C <: SortedMapOps[K, V, CC, C]]
54-
extends MapOps[K, V, Map, C]
55-
with collection.SortedMapOps[K, V, CC, C] { self =>
56-
protected def coll: C with CC[K, V]
57-
58-
def unsorted: Map[K, V]
59-
60-
override def keySet: SortedSet[K] = new ImmutableKeySortedSet
61-
62-
/** The implementation class of the set returned by `keySet` */
63-
protected class ImmutableKeySortedSet extends AbstractSet[K] with SortedSet[K] with GenKeySet with GenKeySortedSet {
64-
def rangeImpl(from: Option[K], until: Option[K]): SortedSet[K] = {
65-
val map = self.rangeImpl(from, until)
66-
new map.ImmutableKeySortedSet
67-
}
68-
def incl(elem: K): SortedSet[K] = fromSpecific(this).incl(elem)
69-
def excl(elem: K): SortedSet[K] = fromSpecific(this).excl(elem)
70-
}
54+
extends MapOps[K, V, Map, C] with collection.SortedMapOps[K, V, CC, C] { self =>
55+
56+
protected def coll: C with CC[K, V]
57+
58+
def unsorted: Map[K, V]
7159

72-
// We override these methods to fix their return type (which would be `Map` otherwise)
73-
def updated[V1 >: V](key: K, value: V1): CC[K, V1]
74-
@`inline` final override def +[V1 >: V](kv: (K, V1)): CC[K, V1] = updated(kv._1, kv._2)
60+
override def keySet: SortedSet[K] = new ImmutableKeySortedSet
7561

76-
override def concat[V2 >: V](xs: collection.IterableOnce[(K, V2)]): CC[K, V2] = {
77-
var result: CC[K, V2] = coll
78-
val it = xs.iterator
79-
while (it.hasNext) result = result + it.next()
80-
result
62+
/** The implementation class of the set returned by `keySet` */
63+
protected class ImmutableKeySortedSet extends AbstractSet[K] with SortedSet[K] with GenKeySet with GenKeySortedSet {
64+
def rangeImpl(from: Option[K], until: Option[K]): SortedSet[K] = {
65+
val map = self.rangeImpl(from, until)
66+
new map.ImmutableKeySortedSet
8167
}
68+
def incl(elem: K): SortedSet[K] = fromSpecific(this).incl(elem)
69+
def excl(elem: K): SortedSet[K] = fromSpecific(this).excl(elem)
70+
}
71+
72+
// We override these methods to fix their return type (which would be `Map` otherwise)
73+
def updated[V1 >: V](key: K, value: V1): CC[K, V1]
74+
@`inline` final override def +[V1 >: V](kv: (K, V1)): CC[K, V1] = updated(kv._1, kv._2)
8275

83-
override def transform[W](f: (K, V) => W): CC[K, W] = map({ case (k, v) => (k, f(k, v)) })
76+
override def transform[W](f: (K, V) => W): CC[K, W] = map({ case (k, v) => (k, f(k, v)) })
77+
}
78+
79+
trait StrictOptimizedSortedMapOps[K, +V, +CC[X, +Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _], +C <: SortedMapOps[K, V, CC, C]]
80+
extends SortedMapOps[K, V, CC, C]
81+
with collection.StrictOptimizedSortedMapOps[K, V, CC, C]
82+
with StrictOptimizedMapOps[K, V, Map, C] {
83+
84+
override def concat[V2 >: V](xs: collection.IterableOnce[(K, V2)]): CC[K, V2] = {
85+
var result: CC[K, V2] = coll
86+
val it = xs.iterator
87+
while (it.hasNext) result = result + it.next()
88+
result
89+
}
8490
}
8591

8692
@SerialVersionUID(3L)

src/library/scala/collection/immutable/StrictOptimizedSeqOps.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ import scala.language.higherKinds
2020
* Trait that overrides operations to take advantage of strict builders.
2121
*/
2222
trait StrictOptimizedSeqOps[+A, +CC[_], +C]
23-
extends SeqOps[A, CC, C]
24-
with collection.StrictOptimizedSeqOps[A, CC, C] {
23+
extends Any
24+
with SeqOps[A, CC, C]
25+
with collection.StrictOptimizedSeqOps[A, CC, C]
26+
with StrictOptimizedIterableOps[A, CC, C] {
2527

2628
override def distinctBy[B](f: A => B): C = {
2729
if (lengthCompare(1) <= 0) coll

src/library/scala/collection/immutable/TreeMap.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ import scala.collection.mutable.{Builder, ReusableBuilder}
4040
final class TreeMap[K, +V] private (private val tree: RB.Tree[K, V])(implicit val ordering: Ordering[K])
4141
extends AbstractMap[K, V]
4242
with SortedMap[K, V]
43-
with SortedMapOps[K, V, TreeMap, TreeMap[K, V]]
44-
with StrictOptimizedIterableOps[(K, V), Iterable, TreeMap[K, V]]
45-
with StrictOptimizedMapOps[K, V, Map, TreeMap[K, V]]
4643
with StrictOptimizedSortedMapOps[K, V, TreeMap, TreeMap[K, V]] {
4744

4845
def this()(implicit ordering: Ordering[K]) = this(null)(ordering)

src/library/scala/collection/immutable/TreeSet.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[
3939
extends AbstractSet[A]
4040
with SortedSet[A]
4141
with SortedSetOps[A, TreeSet, TreeSet[A]]
42-
with StrictOptimizedIterableOps[A, Set, TreeSet[A]]
4342
with StrictOptimizedSortedSetOps[A, TreeSet, TreeSet[A]] {
4443

4544
if (ordering eq null) throw new NullPointerException("ordering must not be null")

src/library/scala/collection/immutable/VectorMap.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ final class VectorMap[K, +V] private (
3737
private[immutable] val underlying: Map[K, (Int, V)], dummy: Boolean)
3838
extends AbstractMap[K, V]
3939
with SeqMap[K, V]
40-
with MapOps[K, V, VectorMap, VectorMap[K, V]]
41-
with StrictOptimizedIterableOps[(K, V), Iterable, VectorMap[K, V]] {
40+
with StrictOptimizedMapOps[K, V, VectorMap, VectorMap[K, V]] {
4241

4342
import VectorMap._
4443

0 commit comments

Comments
 (0)