From 1acaefd08e08b8719cba318ea746af992678c071 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 11 Jun 2018 17:18:02 +0200 Subject: [PATCH] Factor out strict implementations of transformation operations. Add StrictOptimizedMapOps and StrictOptimizedSortedMapOps. Only operations that were implemented more than once have been factored out. Some other operations could be factored out so that they could be reused by custom collection implementations. Fixes scala/collection-strawman#325 --- .../StrictOptimizedIterableOps.scala | 60 +++------- .../collection/StrictOptimizedMapOps.scala | 29 +++++ .../scala/collection/StrictOptimizedOps.scala | 109 ++++++++++++++++++ .../collection/StrictOptimizedSeqOps.scala | 12 +- .../collection/StrictOptimizedSetOps.scala | 17 +++ .../StrictOptimizedSortedMapOps.scala | 27 +++++ .../StrictOptimizedSortedSetOps.scala | 61 ++++------ .../scala/collection/immutable/BitSet.scala | 3 +- .../collection/immutable/ChampHashMap.scala | 5 +- .../scala/collection/immutable/HashMap.scala | 5 +- .../scala/collection/immutable/ListMap.scala | 3 +- .../scala/collection/immutable/TreeMap.scala | 3 +- .../scala/collection/mutable/BitSet.scala | 3 +- .../scala/collection/mutable/HashMap.scala | 6 +- .../collection/mutable/LinkedHashMap.scala | 3 +- .../collection/mutable/LinkedHashSet.scala | 3 +- .../scala/collection/mutable/ListMap.scala | 3 +- .../scala/collection/mutable/TreeMap.scala | 6 +- 18 files changed, 247 insertions(+), 111 deletions(-) create mode 100644 src/library/scala/collection/StrictOptimizedMapOps.scala create mode 100644 src/library/scala/collection/StrictOptimizedOps.scala create mode 100644 src/library/scala/collection/StrictOptimizedSetOps.scala create mode 100644 src/library/scala/collection/StrictOptimizedSortedMapOps.scala diff --git a/src/library/scala/collection/StrictOptimizedIterableOps.scala b/src/library/scala/collection/StrictOptimizedIterableOps.scala index b43271c51a71..e0a8acbf746b 100644 --- a/src/library/scala/collection/StrictOptimizedIterableOps.scala +++ b/src/library/scala/collection/StrictOptimizedIterableOps.scala @@ -5,9 +5,10 @@ import scala.annotation.unchecked.uncheckedVariance import scala.language.higherKinds /** - * Trait that overrides operations to take advantage of strict builders. + * Trait that overrides iterable operations to take advantage of strict builders. * * @tparam A Elements type + * @tparam CC Collection type constructor * @tparam C Collection type */ trait StrictOptimizedIterableOps[+A, +CC[_], +C] @@ -70,54 +71,23 @@ trait StrictOptimizedIterableOps[+A, +CC[_], +C] // the view-based implementations, but they turn out to be slightly faster because // a couple of indirection levels are removed - override def map[B](f: A => B): CC[B] = { - val b = iterableFactory.newBuilder[B] - val it = iterator - while (it.hasNext) { - b += f(it.next()) - } - b.result() - } + override def map[B](f: A => B): CC[B] = + StrictOptimizedOps.map(iterator, iterableFactory.newBuilder, f) - override def flatMap[B](f: A => IterableOnce[B]): CC[B] = { - val b = iterableFactory.newBuilder[B] - val it = iterator - while (it.hasNext) { - b ++= f(it.next()) - } - b.result() - } + override def flatMap[B](f: A => IterableOnce[B]): CC[B] = + StrictOptimizedOps.flatMap(iterator, iterableFactory.newBuilder, f) - override def collect[B](pf: PartialFunction[A, B]): CC[B] = { - val b = iterableFactory.newBuilder[B] - val it = iterator - while (it.hasNext) { - val elem = it.next() - if (pf.isDefinedAt(elem)) { - b += pf.apply(elem) - } - } - b.result() - } + override def concat[B >: A](suffix: Iterable[B]): CC[B] = + StrictOptimizedOps.concat(iterator, suffix.iterator, iterableFactory.newBuilder[B]) - override def flatten[B](implicit toIterableOnce: A => IterableOnce[B]): CC[B] = { - val b = iterableFactory.newBuilder[B] - val it = iterator - while (it.hasNext) { - b ++= toIterableOnce(it.next()) - } - b.result() - } + override def collect[B](pf: PartialFunction[A, B]): CC[B] = + StrictOptimizedOps.collect(iterator, iterableFactory.newBuilder, pf) - override def zip[B](that: Iterable[B]): CC[(A @uncheckedVariance, B)] = { - val b = iterableFactory.newBuilder[(A, B)] - val it1 = iterator - val it2 = that.iterator - while (it1.hasNext && it2.hasNext) { - b += ((it1.next(), it2.next())) - } - b.result() - } + override def flatten[B](implicit toIterableOnce: A => IterableOnce[B]): CC[B] = + StrictOptimizedOps.flatten(iterator, iterableFactory.newBuilder) + + override def zip[B](that: Iterable[B]): CC[(A @uncheckedVariance, B)] = + StrictOptimizedOps.zip(iterator, that.iterator, iterableFactory.newBuilder[(A, B)]) override def zipWithIndex: CC[(A @uncheckedVariance, Int)] = { val b = iterableFactory.newBuilder[(A, Int)] diff --git a/src/library/scala/collection/StrictOptimizedMapOps.scala b/src/library/scala/collection/StrictOptimizedMapOps.scala new file mode 100644 index 000000000000..61f59eb31772 --- /dev/null +++ b/src/library/scala/collection/StrictOptimizedMapOps.scala @@ -0,0 +1,29 @@ +package scala.collection + +import scala.language.higherKinds + +/** + * Trait that overrides map operations to take advantage of strict builders. + * + * @tparam K Type of keys + * @tparam V Type of values + * @tparam CC Collection type constructor + * @tparam C Collection type + */ +trait StrictOptimizedMapOps[K, +V, +CC[_, _] <: IterableOps[_, AnyConstr, _], +C] + extends MapOps[K, V, CC, C] + with StrictOptimizedIterableOps[(K, V), Iterable, C] { + + override def map[K2, V2](f: ((K, V)) => (K2, V2)): CC[K2, V2] = + StrictOptimizedOps.map(iterator, mapFactory.newBuilder, f) + + override def flatMap[K2, V2](f: ((K, V)) => IterableOnce[(K2, V2)]): CC[K2, V2] = + StrictOptimizedOps.flatMap(iterator, mapFactory.newBuilder, f) + + override def concat[V2 >: V](suffix: Iterable[(K, V2)]): CC[K, V2] = + StrictOptimizedOps.concat(iterator, suffix.iterator, mapFactory.newBuilder) + + override def collect[K2, V2](pf: PartialFunction[(K, V), (K2, V2)]): CC[K2, V2] = + StrictOptimizedOps.collect(iterator, mapFactory.newBuilder, pf) + +} diff --git a/src/library/scala/collection/StrictOptimizedOps.scala b/src/library/scala/collection/StrictOptimizedOps.scala new file mode 100644 index 000000000000..00b3b0bd4ec4 --- /dev/null +++ b/src/library/scala/collection/StrictOptimizedOps.scala @@ -0,0 +1,109 @@ +package scala.collection + +/** + * Convenient implementations of transformation operations + * based on builders. + * + * All the methods defined here are expected to be called with + * freshly created iterators and builders. + */ +object StrictOptimizedOps { + + /** + * @param it Iterator to map elements from + * @param b Builder to use to build the resulting collection + * @param f Element transformation function + * @tparam A Type of elements of the source collection (e.g. `Int`) + * @tparam B Type of elements of the resulting collection (e.g. `String`) + * @tparam C Type of the resulting collection (e.g. `List[String]`) + * @return The resulting collection + */ + @inline def map[A, B, C](it: Iterator[A], b: mutable.Builder[B, C], f: A => B): C = { + while (it.hasNext) { + b += f(it.next()) + } + b.result() + } + + /** + * @param it Iterator to flatMap elements from + * @param b Builder to use to build the resulting collection + * @param f Element transformation function + * @tparam A Type of elements of the source collection (e.g. `Int`) + * @tparam B Type of elements of the resulting collection (e.g. `String`) + * @tparam C Type of the resulting collection (e.g. `List[String]`) + * @return The resulting collection + */ + @inline def flatMap[A, B, C](it: Iterator[A], b: mutable.Builder[B, C], f: A => IterableOnce[B]): C = { + while (it.hasNext) { + b ++= f(it.next()) + } + b.result() + } + + /** + * @param it1 Iterator of the first collection + * @param it2 Iterator of the second collection + * @param b Builder to use to build the resulting collection + * @tparam A Type of elements (e.g. `Int`) + * @tparam C Type of the resulting collection (e.g. `List[Int]`) + * @return The resulting collection + */ + @inline def concat[A, C](it1: Iterator[A], it2: Iterator[A], b: mutable.Builder[A, C]): C = { + b ++= it1 + b ++= it2 + b.result() + } + + /** + * @param it Iterator to collect elements from + * @param b Builder to use to build the resulting collection + * @param pf Element transformation partial function + * @tparam A Type of elements of the source collection (e.g. `Int`) + * @tparam B Type of elements of the resulting collection (e.g. `String`) + * @tparam C Type of the resulting collection (e.g. `List[String]`) + * @return The resulting collection + */ + @inline def collect[A, B, C](it: Iterator[A], b: mutable.Builder[B, C], pf: PartialFunction[A, B]): C = { + while (it.hasNext) { + val elem = it.next() + if (pf.isDefinedAt(elem)) { + b += pf.apply(elem) + } + } + b.result() + } + + /** + * @param it Iterator to flatten elements from + * @param b Builder to use to build the resulting collection + * @param toIterableOnce Evidence that `A` can be seen as an `IterableOnce[B]` + * @tparam A Type of elements of the source collection (e.g. `List[Int]`) + * @tparam B Type of elements of the resulting collection (e.g. `Int`) + * @tparam C Type of the resulting collection (e.g. `List[Int]`) + * @return The resulting collection + */ + @inline def flatten[A, B, C](it: Iterator[A], b: mutable.Builder[B, C])(implicit toIterableOnce: A => IterableOnce[B]): C = { + while (it.hasNext) { + b ++= toIterableOnce(it.next()) + } + b.result() + } + + /** + * @param it1 Iterator of the first collection + * @param it2 Iterator of the second collection + * @param b Builder to use to build the resulting collection + * @tparam A Type of elements of the first collection (e.g. `Int`) + * @tparam B Type of elements of the second collection (e.g. `String`) + * @tparam C Type of the resulting collection (e.g. `List[(Int, String)]`) + * @return The resulting collection + */ + @inline def zip[A, B, C](it1: Iterator[A], it2: Iterator[B], b: mutable.Builder[(A, B), C]): C = { + while (it1.hasNext && it2.hasNext) { + b += ((it1.next(), it2.next())) + } + b.result() + } + +} diff --git a/src/library/scala/collection/StrictOptimizedSeqOps.scala b/src/library/scala/collection/StrictOptimizedSeqOps.scala index ef84939644b0..a43574d77340 100644 --- a/src/library/scala/collection/StrictOptimizedSeqOps.scala +++ b/src/library/scala/collection/StrictOptimizedSeqOps.scala @@ -8,8 +8,8 @@ import scala.language.higherKinds */ trait StrictOptimizedSeqOps [+A, +CC[_], +C] extends Any - with SeqOps[A, CC, C] - with StrictOptimizedIterableOps[A, CC, C] { + with StrictOptimizedIterableOps[A, CC, C] + with SeqOps[A, CC, C] { override def distinctBy[B](f: A => B): C = { val builder = newSpecificBuilder @@ -45,12 +45,8 @@ trait StrictOptimizedSeqOps [+A, +CC[_], +C] b.result() } - override def appendedAll[B >: A](suffix: Iterable[B]): CC[B] = { - val b = iterableFactory.newBuilder[B] - b ++= this - b ++= suffix - b.result() - } + override def appendedAll[B >: A](suffix: Iterable[B]): CC[B] = + StrictOptimizedOps.concat(iterator, suffix.iterator, iterableFactory.newBuilder) override def prependedAll[B >: A](prefix: Iterable[B]): CC[B] = { val b = iterableFactory.newBuilder[B] diff --git a/src/library/scala/collection/StrictOptimizedSetOps.scala b/src/library/scala/collection/StrictOptimizedSetOps.scala new file mode 100644 index 000000000000..95709f9fa186 --- /dev/null +++ b/src/library/scala/collection/StrictOptimizedSetOps.scala @@ -0,0 +1,17 @@ +package scala.collection + +/** + * Trait that overrides set operations to take advantage of strict builders. + * + * @tparam A Elements type + * @tparam CC Collection type constructor + * @tparam C Collection type + */ +trait StrictOptimizedSetOps[A, +CC[_], +C <: SetOps[A, CC, C]] + extends SetOps[A, CC, C] + with StrictOptimizedIterableOps[A, CC, C] { + + override def concat(that: Iterable[A]): C = + StrictOptimizedOps.concat(iterator, that.iterator, newSpecificBuilder) + +} diff --git a/src/library/scala/collection/StrictOptimizedSortedMapOps.scala b/src/library/scala/collection/StrictOptimizedSortedMapOps.scala new file mode 100644 index 000000000000..c2b3d70fdcd7 --- /dev/null +++ b/src/library/scala/collection/StrictOptimizedSortedMapOps.scala @@ -0,0 +1,27 @@ +package scala.collection + +/** + * Trait that overrides sorted map operations to take advantage of strict builders. + * + * @tparam K Type of keys + * @tparam V Type of values + * @tparam CC Collection type constructor + * @tparam C Collection type + */ +trait StrictOptimizedSortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _], +C <: SortedMapOps[K, V, CC, C]] + extends SortedMapOps[K, V, CC, C] + with StrictOptimizedMapOps[K, V, Map, C] { + + override def map[K2, V2](f: ((K, V)) => (K2, V2))(implicit ordering: Ordering[K2]): CC[K2, V2] = + StrictOptimizedOps.map(iterator, sortedMapFactory.newBuilder, f) + + override def flatMap[K2, V2](f: ((K, V)) => IterableOnce[(K2, V2)])(implicit ordering: Ordering[K2]): CC[K2, V2] = + StrictOptimizedOps.flatMap(iterator, sortedMapFactory.newBuilder, f) + + override def concat[V2 >: V](xs: Iterable[(K, V2)]): CC[K, V2] = + StrictOptimizedOps.concat(iterator, xs.iterator, sortedMapFactory.newBuilder) + + override def collect[K2, V2](pf: PartialFunction[(K, V), (K2, V2)])(implicit ordering: Ordering[K2]): CC[K2, V2] = + StrictOptimizedOps.collect(iterator, sortedMapFactory.newBuilder, pf) + +} diff --git a/src/library/scala/collection/StrictOptimizedSortedSetOps.scala b/src/library/scala/collection/StrictOptimizedSortedSetOps.scala index 349f736707d3..4d23f4655666 100644 --- a/src/library/scala/collection/StrictOptimizedSortedSetOps.scala +++ b/src/library/scala/collection/StrictOptimizedSortedSetOps.scala @@ -5,48 +5,27 @@ package collection import scala.annotation.unchecked.uncheckedVariance import scala.language.higherKinds +/** + * Trait that overrides sorted set operations to take advantage of strict builders. + * + * @tparam A Elements type + * @tparam CC Collection type constructor + * @tparam C Collection type + */ trait StrictOptimizedSortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]] extends SortedSetOps[A, CC, C] - with StrictOptimizedIterableOps[A, Set, C] { - - override def map[B : Ordering](f: A => B): CC[B] = { - val b = sortedIterableFactory.newBuilder[B] - val it = iterator - while (it.hasNext) { - b += f(it.next()) - } - b.result() - } - - override def flatMap[B : Ordering](f: A => IterableOnce[B]): CC[B] = { - val b = sortedIterableFactory.newBuilder[B] - val it = iterator - while (it.hasNext) { - b ++= f(it.next()) - } - b.result() - } - - override def zip[B](that: Iterable[B])(implicit ev: Ordering[(A @uncheckedVariance, B)]): CC[(A @uncheckedVariance, B)] = { // sound bcs of VarianceNot - val b = sortedIterableFactory.newBuilder[(A, B)] - val it1 = iterator - val it2 = that.iterator - while (it1.hasNext && it2.hasNext) { - b += ((it1.next(), it2.next())) - } - b.result() - } - - override def collect[B : Ordering](pf: PartialFunction[A, B]): CC[B] = { - val b = sortedIterableFactory.newBuilder[B] - val it = iterator - while (it.hasNext) { - val elem = it.next() - if (pf.isDefinedAt(elem)) { - b += pf.apply(elem) - } - } - b.result() - } + with StrictOptimizedSetOps[A, Set, C] { + + override def map[B : Ordering](f: A => B): CC[B] = + StrictOptimizedOps.map(iterator, sortedIterableFactory.newBuilder, f) + + override def flatMap[B : Ordering](f: A => IterableOnce[B]): CC[B] = + StrictOptimizedOps.flatMap(iterator, sortedIterableFactory.newBuilder, f) + + override def zip[B](that: Iterable[B])(implicit ev: Ordering[(A @uncheckedVariance, B)]): CC[(A @uncheckedVariance, B)] = + StrictOptimizedOps.zip(iterator, that.iterator, sortedIterableFactory.newBuilder[(A, B)]) + + override def collect[B : Ordering](pf: PartialFunction[A, B]): CC[B] = + StrictOptimizedOps.collect(iterator, sortedIterableFactory.newBuilder, pf) } diff --git a/src/library/scala/collection/immutable/BitSet.scala b/src/library/scala/collection/immutable/BitSet.scala index 0eeccdfe427c..8afab975d1a8 100644 --- a/src/library/scala/collection/immutable/BitSet.scala +++ b/src/library/scala/collection/immutable/BitSet.scala @@ -22,7 +22,8 @@ sealed abstract class BitSet with collection.BitSet with SortedSetOps[Int, SortedSet, BitSet] with collection.BitSetOps[BitSet] - with StrictOptimizedIterableOps[Int, Set, BitSet] { + with StrictOptimizedIterableOps[Int, Set, BitSet] + with StrictOptimizedSortedSetOps[Int, SortedSet, BitSet] { def bitSetFactory = BitSet diff --git a/src/library/scala/collection/immutable/ChampHashMap.scala b/src/library/scala/collection/immutable/ChampHashMap.scala index e91a84add9ed..457b9d48f365 100644 --- a/src/library/scala/collection/immutable/ChampHashMap.scala +++ b/src/library/scala/collection/immutable/ChampHashMap.scala @@ -3,7 +3,7 @@ package collection.immutable import java.io.{ObjectInputStream, ObjectOutputStream} -import collection.{IterableFactory, Iterator, MapFactory, StrictOptimizedIterableOps} +import collection.{IterableFactory, Iterator, MapFactory, StrictOptimizedIterableOps, StrictOptimizedMapOps} import collection.Hashing.{computeHash, keepBits} import scala.annotation.unchecked.{uncheckedVariance => uV} import java.lang.Integer.bitCount @@ -26,7 +26,8 @@ import scala.collection.mutable.{Builder, ImmutableBuilder} final class ChampHashMap[K, +V] private[immutable] (val rootNode: MapNode[K, V], val cachedJavaKeySetHashCode: Int, val cachedSize: Int) extends AbstractMap[K, V] with MapOps[K, V, ChampHashMap, ChampHashMap[K, V]] - with StrictOptimizedIterableOps[(K, V), Iterable /* ChampHashMap */, ChampHashMap[K, V]] { + with StrictOptimizedIterableOps[(K, V), Iterable, ChampHashMap[K, V]] + with StrictOptimizedMapOps[K, V, ChampHashMap, ChampHashMap[K, V]] { override def mapFactory: MapFactory[ChampHashMap] = ChampHashMap diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index aa160084c65b..ebc9c2c91032 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -3,7 +3,7 @@ package collection.immutable import java.io.{ObjectInputStream, ObjectOutputStream} -import collection.{Iterator, MapFactory, StrictOptimizedIterableOps} +import collection.{Iterator, MapFactory, StrictOptimizedIterableOps, StrictOptimizedMapOps} import collection.Hashing.{computeHash, keepBits} import scala.annotation.unchecked.{uncheckedVariance => uV} import java.lang.{Integer, String, System} @@ -30,7 +30,8 @@ import scala.collection.mutable.{Builder, ImmutableBuilder} sealed abstract class HashMap[K, +V] extends AbstractMap[K, V] with MapOps[K, V, HashMap, HashMap[K, V]] - with StrictOptimizedIterableOps[(K, V), Iterable, HashMap[K, V]] { + with StrictOptimizedIterableOps[(K, V), Iterable, HashMap[K, V]] + with StrictOptimizedMapOps[K, V, HashMap, HashMap[K, V]] { import HashMap.{bufferSize, liftMerger, Merger, MergeFunction, nullToEmpty} diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index bf13677a3afd..2eb19b9c5388 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -44,7 +44,8 @@ import scala.collection.mutable.{Builder, ImmutableBuilder} sealed class ListMap[K, +V] extends AbstractMap[K, V] with MapOps[K, V, ListMap, ListMap[K, V]] - with StrictOptimizedIterableOps[(K, V), Iterable, ListMap[K, V]] { + with StrictOptimizedIterableOps[(K, V), Iterable, ListMap[K, V]] + with StrictOptimizedMapOps[K, V, ListMap, ListMap[K, V]] { override def mapFactory: MapFactory[ListMap] = ListMap diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index 275181c5911e..34f221c1c841 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -29,7 +29,8 @@ final class TreeMap[K, +V] private (tree: RB.Tree[K, V])(implicit val ordering: extends AbstractMap[K, V] with SortedMap[K, V] with SortedMapOps[K, V, TreeMap, TreeMap[K, V]] - with StrictOptimizedIterableOps[(K, V), Iterable, TreeMap[K, V]] { + with StrictOptimizedIterableOps[(K, V), Iterable, TreeMap[K, V]] + with StrictOptimizedSortedMapOps[K, V, TreeMap, TreeMap[K, V]] { def this()(implicit ordering: Ordering[K]) = this(null)(ordering) diff --git a/src/library/scala/collection/mutable/BitSet.scala b/src/library/scala/collection/mutable/BitSet.scala index a2b0e14f3e90..eb22d806e3bc 100644 --- a/src/library/scala/collection/mutable/BitSet.scala +++ b/src/library/scala/collection/mutable/BitSet.scala @@ -29,7 +29,8 @@ class BitSet(protected[collection] final var elems: Array[Long]) with collection.BitSet with SortedSetOps[Int, SortedSet, BitSet] with collection.BitSetOps[BitSet] - with StrictOptimizedIterableOps[Int, Set, BitSet] { + with StrictOptimizedIterableOps[Int, Set, BitSet] + with StrictOptimizedSortedSetOps[Int, SortedSet, BitSet] { def this(initSize: Int) = this(new Array[Long](math.max((initSize + 63) >> 6, 1))) diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala index 5c23c1d9faea..3c5675ec414d 100644 --- a/src/library/scala/collection/mutable/HashMap.scala +++ b/src/library/scala/collection/mutable/HashMap.scala @@ -1,8 +1,7 @@ package scala package collection.mutable -import scala.collection.{Iterator, MapFactory, StrictOptimizedIterableOps} - +import scala.collection.{Iterator, MapFactory, StrictOptimizedIterableOps, StrictOptimizedMapOps} import java.lang.String /** This class implements mutable maps using a hashtable. @@ -22,7 +21,8 @@ import java.lang.String class HashMap[K, V] extends AbstractMap[K, V] with MapOps[K, V, HashMap, HashMap[K, V]] - with StrictOptimizedIterableOps[(K, V), Iterable, HashMap[K, V]] { + with StrictOptimizedIterableOps[(K, V), Iterable, HashMap[K, V]] + with StrictOptimizedMapOps[K, V, HashMap, HashMap[K, V]] { override def mapFactory: MapFactory[HashMap] = HashMap diff --git a/src/library/scala/collection/mutable/LinkedHashMap.scala b/src/library/scala/collection/mutable/LinkedHashMap.scala index d19acc86d083..7f6899ff6f76 100644 --- a/src/library/scala/collection/mutable/LinkedHashMap.scala +++ b/src/library/scala/collection/mutable/LinkedHashMap.scala @@ -47,7 +47,8 @@ object LinkedHashMap extends MapFactory[LinkedHashMap] { class LinkedHashMap[K, V] extends AbstractMap[K, V] with MapOps[K, V, LinkedHashMap, LinkedHashMap[K, V]] - with StrictOptimizedIterableOps[(K, V), Iterable, LinkedHashMap[K, V]] { + with StrictOptimizedIterableOps[(K, V), Iterable, LinkedHashMap[K, V]] + with StrictOptimizedMapOps[K, V, LinkedHashMap, LinkedHashMap[K, V]] { override def mapFactory: MapFactory[LinkedHashMap] = LinkedHashMap diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index 48d03eeffc00..b5094574e34d 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -22,7 +22,8 @@ package mutable */ class LinkedHashSet[A] extends AbstractSet[A] - with SetOps[A, LinkedHashSet, LinkedHashSet[A]] { + with SetOps[A, LinkedHashSet, LinkedHashSet[A]] + with StrictOptimizedIterableOps[A, LinkedHashSet, LinkedHashSet[A]] { override def iterableFactory: IterableFactory[LinkedHashSet] = LinkedHashSet diff --git a/src/library/scala/collection/mutable/ListMap.scala b/src/library/scala/collection/mutable/ListMap.scala index 324c315367a2..2748b88822a3 100644 --- a/src/library/scala/collection/mutable/ListMap.scala +++ b/src/library/scala/collection/mutable/ListMap.scala @@ -28,7 +28,8 @@ import scala.collection.immutable.List class ListMap[K, V] extends AbstractMap[K, V] with MapOps[K, V, ListMap, ListMap[K, V]] - with StrictOptimizedIterableOps[(K, V), Iterable, ListMap[K, V]] { + with StrictOptimizedIterableOps[(K, V), Iterable, ListMap[K, V]] + with StrictOptimizedMapOps[K, V, ListMap, ListMap[K, V]] { override def mapFactory: MapFactory[ListMap] = ListMap diff --git a/src/library/scala/collection/mutable/TreeMap.scala b/src/library/scala/collection/mutable/TreeMap.scala index 5ba1535893bd..ec59e077d83d 100644 --- a/src/library/scala/collection/mutable/TreeMap.scala +++ b/src/library/scala/collection/mutable/TreeMap.scala @@ -1,9 +1,8 @@ package scala package collection.mutable -import collection.{Iterator, SortedMapFactory, StrictOptimizedIterableOps} +import collection.{Iterator, SortedMapFactory, StrictOptimizedIterableOps, StrictOptimizedSortedMapOps} import collection.mutable.{RedBlackTree => RB} - import java.lang.String /** @@ -23,7 +22,8 @@ sealed class TreeMap[K, V] private (tree: RB.Tree[K, V])(implicit val ordering: extends AbstractMap[K, V] with SortedMap[K, V] with SortedMapOps[K, V, TreeMap, TreeMap[K, V]] - with StrictOptimizedIterableOps[(K, V), Iterable, TreeMap[K, V]] { + with StrictOptimizedIterableOps[(K, V), Iterable, TreeMap[K, V]] + with StrictOptimizedSortedMapOps[K, V, TreeMap, TreeMap[K, V]] { override def sortedMapFactory = TreeMap