Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Commit 2acb675

Browse files
committed
Remove the boilerplate associated with the new design (and more)
- The respective `CC` types are exposed (to `protected[this]`) through aliases `IterableCC`, `SortedIterableCC`, `MapCC` and `SortedMapCC` in the respective `Ops` traits, plus a `BitSetC` for the shared `BitSetOps` trait. - This allows defining `fromSpecificIterable`, `newSpecificBuilder` and `empty` (for all but `Iterable`) in the respective collection traits `Iterable`, `SortedSet`, `Map` and `SortedMap` (*not* in their `Ops` traits) where the `CC` type is visible and set to a concrete type but can still be refined in subtypes. This gives us a valid implementation until a concrete collection type with a refined `CC` gets defined. In this case the inherited implementations have the wrong type, so the user is forced to override them. - Implementations of `fromSpecificIterable`, `newSpecificBuilder` and `empty` can be removed from almost all collection implementations except the ones where they need to be refined even further than what a factory can provide (e.g. `IntMap`, `PriorityQueue`). - Factories are generally overridden in abstract collection types that refine a `CC` (e.g. `Iterable` -> `Seq` -> `immutable.Set` -> `immutable.IndexedSeq`) so that concrete implementations without further refinement do not need to override them. - DefaultMap is deprecated because there is no more boilerplate left that it could implement. - `sortedFromIterable`, `mapFromIterable` and `sortedMapFromIterable` are treated the same way as `fromIterable`. They are implemented as `inline final` calls to the respective factory method. Fixes #335
1 parent 8d6c04a commit 2acb675

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+192
-421
lines changed

collections/src/main/scala/strawman/collection/BitSet.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ import scala.Predef.{assert, intWrapper}
1818
* @define coll bitset
1919
* @define Coll `BitSet`
2020
*/
21-
trait BitSet extends SortedSet[Int] with BitSetOps[BitSet]
21+
trait BitSet extends SortedSet[Int] with BitSetOps[BitSet] {
22+
override protected[this] def fromSpecificIterable(coll: Iterable[Int]): BitSetC = bitSetFactory.fromSpecific(coll)
23+
override protected[this] def newSpecificBuilder(): Builder[Int, BitSetC] = bitSetFactory.newBuilder()
24+
override def empty: BitSetC = bitSetFactory.empty
25+
}
2226

2327
object BitSet extends SpecificIterableFactory[Int, BitSet] {
2428
def empty: BitSet = immutable.BitSet.empty
@@ -31,6 +35,10 @@ trait BitSetOps[+C <: BitSet with BitSetOps[C]]
3135
extends SortedSetOps[Int, SortedSet, C] { self =>
3236
import BitSetOps._
3337

38+
def bitSetFactory: SpecificIterableFactory[Int, BitSetC]
39+
40+
protected[this] type BitSetC = C
41+
3442
final def ordering: Ordering[Int] = Ordering.Int
3543

3644
/** The number of words (each with 64 bits) making up the set */

collections/src/main/scala/strawman/collection/DefaultMap.scala

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,12 @@
99
package strawman
1010
package collection
1111

12+
import scala.deprecated
13+
1214
/** A default map which builds a default `immutable.Map` implementation for all
1315
* transformations.
1416
*
15-
* Instances that inherit from `DefaultMap[K, V]` still have to define:
16-
* {{{
17-
* def get(key: K): Option[V]
18-
* def iterator(): Iterator[(K, V)]
19-
* }}}
20-
*
21-
* It might also be advisable to override `foreach` or `size` if efficient
22-
* implementations can be found.
23-
*
2417
* @since 2.8
2518
*/
26-
trait DefaultMap[K, +V] extends Map[K, V] { self =>
27-
28-
// Members declared in IterableOps
29-
def iterableFactory: IterableFactory[Iterable] = Iterable
30-
protected[this] def fromSpecificIterable(coll: Iterable[(K, V)]): Map[K,V] = mapFactory.from(coll)
31-
protected[this] def newSpecificBuilder(): mutable.Builder[(K, V), Map[K,V]] = mapFactory.newBuilder()
32-
33-
// Members declared in MapOps
34-
def mapFactory: MapFactory[Map] = Map
35-
def empty: Map[K,V] = mapFactory.empty
36-
protected[this] def mapFromIterable[K2, V2](it: Iterable[(K2, V2)]): Map[K2,V2] = mapFactory.from(it)
37-
}
19+
@deprecated("DefaultMap is no longer necessary; extend Map directly", "2.13.0")
20+
trait DefaultMap[K, +V] extends Map[K, V]

collections/src/main/scala/strawman/collection/Iterable.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ trait Iterable[+A] extends IterableOnce[A] with IterableOps[A, Iterable, Iterabl
2626
//TODO scalac generates an override for this in AbstractMap; Making it final leads to a VerifyError
2727
protected[this] def coll: this.type = this
2828

29+
protected[this] def fromSpecificIterable(coll: Iterable[A]): IterableCC[A] = iterableFactory.from(coll)
30+
protected[this] def newSpecificBuilder(): Builder[A, IterableCC[A]] = iterableFactory.newBuilder[A]()
31+
32+
def iterableFactory: IterableFactory[IterableCC] = Iterable
2933
}
3034

3135
/** Base trait for Iterable operations
@@ -64,6 +68,8 @@ trait Iterable[+A] extends IterableOnce[A] with IterableOps[A, Iterable, Iterabl
6468
*/
6569
trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] {
6670

71+
protected[this] type IterableCC[X] = CC[X]
72+
6773
/**
6874
* @return This collection as an `Iterable[A]`. No new collection will be built if `this` is already an `Iterable[A]`.
6975
*/
@@ -91,7 +97,7 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] {
9197
/**
9298
* @return The companion object of this ${coll}, providing various factory methods.
9399
*/
94-
def iterableFactory: IterableFactory[CC]
100+
def iterableFactory: IterableFactory[IterableCC]
95101

96102
/**
97103
* @return a strict builder for the same collection type.
@@ -1220,4 +1226,4 @@ object Iterable extends IterableFactory.Delegate[Iterable](immutable.Iterable) {
12201226
implicit def toLazyZipOps[A, CC[X] <: Iterable[X]](that: CC[A]): LazyZipOps[A, CC[A]] = new LazyZipOps(that)
12211227
}
12221228

1223-
abstract class AbstractIterable[+A] extends Iterable[A]
1229+
abstract class AbstractIterable[+A] extends Iterable[A]

collections/src/main/scala/strawman/collection/Map.scala

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ trait Map[K, +V]
1515
with MapOps[K, V, Map, Map[K, V]]
1616
with Equals {
1717

18+
override protected[this] def fromSpecificIterable(coll: Iterable[(K, V)]): MapCC[K, V] = mapFactory.from(coll)
19+
override protected[this] def newSpecificBuilder(): mutable.Builder[(K, V), MapCC[K, V]] = mapFactory.newBuilder[K, V]()
20+
21+
def mapFactory: strawman.collection.MapFactory[MapCC] = Map
22+
23+
def empty: MapCC[K, V] = mapFactory.empty
24+
1825
def canEqual(that: Any): Boolean = true
1926

2027
override def equals(o: Any): Boolean = o match {
@@ -52,10 +59,12 @@ trait MapOps[K, +V, +CC[X, Y] <: MapOps[X, Y, CC, _], +C]
5259
with PartialFunction[K, V]
5360
with Equals {
5461

55-
/** Similar to fromIterable, but returns a Map collection type */
56-
protected[this] def mapFromIterable[K2, V2](it: Iterable[(K2, V2)]): CC[K2, V2]
62+
protected[this] type MapCC[K, V] = CC[K, V]
63+
64+
/** Similar to `fromIterable`, but returns a Map collection type */
65+
@`inline` protected[this] final def mapFromIterable[K2, V2](it: Iterable[(K2, V2)]): CC[K2, V2] = mapFactory.from(it)
5766

58-
def mapFactory: MapFactory[CC]
67+
def mapFactory: MapFactory[MapCC]
5968

6069
/** Optionally returns the value associated with a key.
6170
*
@@ -107,11 +116,7 @@ trait MapOps[K, +V, +CC[X, Y] <: MapOps[X, Y, CC, _], +C]
107116
*/
108117
@SerialVersionUID(3L)
109118
protected class KeySet extends Set[K] with GenKeySet {
110-
def iterableFactory: IterableFactory[Set] = Set
111-
protected[this] def fromSpecificIterable(coll: Iterable[K]): Set[K] = fromIterable(coll)
112-
protected[this] def newSpecificBuilder(): Builder[K, Set[K]] = iterableFactory.newBuilder()
113119
def diff(that: Set[K]): Set[K] = fromSpecificIterable(view.filterNot(that))
114-
def empty: Set[K] = iterableFactory.empty
115120
}
116121

117122
/** A generic trait that is reused by keyset implementations */

collections/src/main/scala/strawman/collection/Seq.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ trait Seq[+A]
2020
with SeqOps[A, Seq, Seq[A]]
2121
with Equals {
2222

23-
def iterableFactory: SeqFactory[Seq]
23+
override def iterableFactory: SeqFactory[IterableCC] = Seq
2424

2525
/** Method called from equality methods, so that user-defined subclasses can
2626
* refuse to be equal to other collections of the same kind.

collections/src/main/scala/strawman/collection/Set.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ trait Set[A]
2828

2929
override def hashCode(): Int = Set.setHash(toIterable)
3030

31+
def empty: IterableCC[A] = iterableFactory.empty
3132
}
3233

3334
/** Base trait for set operations

collections/src/main/scala/strawman/collection/SortedMap.scala

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,33 @@ import strawman.collection.immutable.TreeMap
55
import strawman.collection.mutable.Builder
66

77
import scala.annotation.unchecked.uncheckedVariance
8-
import scala.{Boolean, Int, Option, Ordering, PartialFunction, Serializable, SerialVersionUID, `inline`}
8+
import scala.{Boolean, Int, Option, Ordering, PartialFunction, Serializable, SerialVersionUID, `inline`, Any}
99

1010
/** Base type of sorted sets */
1111
trait SortedMap[K, +V]
1212
extends Map[K, V]
1313
with SortedMapOps[K, V, SortedMap, SortedMap[K, V]] {
14+
1415
def unsorted: Map[K, V] = this
16+
17+
override protected[this] def fromSpecificIterable(coll: Iterable[(K, V)]): SortedMapCC[K, V] = sortedMapFactory.from(coll)
18+
override protected[this] def newSpecificBuilder(): mutable.Builder[(K, V), SortedMapCC[K, V]] = sortedMapFactory.newBuilder[K, V]()
19+
20+
def sortedMapFactory: SortedMapFactory[SortedMapCC] = SortedMap
21+
22+
override def empty: SortedMapCC[K, V] = sortedMapFactory.empty
1523
}
1624

1725
trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _], +C <: SortedMapOps[K, V, CC, C]]
1826
extends MapOps[K, V, Map, C]
1927
with SortedOps[K, C] {
2028

21-
def sortedMapFactory: SortedMapFactory[CC]
29+
protected[this] type SortedMapCC[K, V] = CC[K, V]
30+
31+
def sortedMapFactory: SortedMapFactory[SortedMapCC]
2232

23-
protected[this] def sortedMapFromIterable[K2, V2](it: collection.Iterable[(K2, V2)])(implicit ordering: Ordering[K2]): CC[K2, V2]
33+
/** Similar to `mapFromIterable`, but returns a SortedMap collection type */
34+
@`inline` protected[this] final def sortedMapFromIterable[K2, V2](it: Iterable[(K2, V2)])(implicit ordering: Ordering[K2]): CC[K2, V2] = sortedMapFactory.from(it)
2435

2536
def unsorted: Map[K, V]
2637

@@ -91,13 +102,7 @@ trait SortedMapOps[K, +V, +CC[X, Y] <: Map[X, Y] with SortedMapOps[X, Y, CC, _],
91102
/** The implementation class of the set returned by `keySet` */
92103
@SerialVersionUID(3L)
93104
protected class KeySortedSet extends SortedSet[K] with GenKeySet with GenKeySortedSet {
94-
def iterableFactory: IterableFactory[Set] = Set
95-
def sortedIterableFactory: SortedIterableFactory[SortedSet] = SortedSet
96-
protected[this] def fromSpecificIterable(coll: Iterable[K]): SortedSet[K] = sortedFromIterable(coll)
97-
protected[this] def newSpecificBuilder(): Builder[K, SortedSet[K]] = sortedIterableFactory.newBuilder()
98-
protected[this] def sortedFromIterable[B: Ordering](it: Iterable[B]): SortedSet[B] = sortedFromIterable(it)
99105
def diff(that: Set[K]): SortedSet[K] = fromSpecificIterable(view.filterNot(that))
100-
def empty: SortedSet[K] = sortedIterableFactory.empty
101106
def rangeImpl(from: Option[K], until: Option[K]): SortedSet[K] = {
102107
val map = SortedMapOps.this.rangeImpl(from, until)
103108
new map.KeySortedSet

collections/src/main/scala/strawman/collection/SortedSet.scala

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
package strawman.collection
22

3-
import scala.{Boolean, Ordering, `inline`, None, Option, Some}
3+
import scala.{Boolean, Ordering, `inline`, None, Option, Some, Any}
44
import scala.annotation.unchecked.uncheckedVariance
55

66
/** Base type of sorted sets */
77
trait SortedSet[A] extends Set[A] with SortedSetOps[A, SortedSet, SortedSet[A]] {
88
def unsorted: Set[A] = this
9+
10+
override protected[this] def fromSpecificIterable(coll: Iterable[A]): SortedIterableCC[A] = sortedIterableFactory.from(coll)
11+
override protected[this] def newSpecificBuilder(): mutable.Builder[A, SortedIterableCC[A]] = sortedIterableFactory.newBuilder[A]()
12+
13+
def sortedIterableFactory: SortedIterableFactory[SortedIterableCC] = SortedSet
14+
15+
override def empty: SortedIterableCC[A] = sortedIterableFactory.empty
916
}
1017

1118
trait SortedSetOps[A, +CC[X] <: SortedSet[X], +C <: SortedSetOps[A, CC, C]]
1219
extends SetOps[A, Set, C]
1320
with SortedOps[A, C] {
1421

15-
def sortedIterableFactory: SortedIterableFactory[CC]
22+
protected[this] type SortedIterableCC[X] = CC[X]
1623

17-
protected[this] def sortedFromIterable[B: Ordering](it: Iterable[B]): CC[B]
24+
def sortedIterableFactory: SortedIterableFactory[SortedIterableCC]
25+
26+
/** Similar to `fromSpecificIterable`, but for a (possibly) different type of element.
27+
* Note that the return type is know `CC[E]`.
28+
*/
29+
@`inline` final protected[this] def sortedFromIterable[B: Ordering](it: Iterable[B]): CC[B] = sortedIterableFactory.from(it)
1830

1931
def unsorted: Set[A]
2032

collections/src/main/scala/strawman/collection/View.scala

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,7 @@ import scala.Predef.{<:<, intWrapper}
1515
trait View[+A] extends Iterable[A] with IterableOps[A, View, View[A]] {
1616
override def view = this
1717

18-
def iterableFactory = View
19-
20-
protected[this] def fromSpecificIterable(coll: Iterable[A]): View[A] = fromIterable(coll)
21-
22-
protected[this] def newSpecificBuilder(): Builder[A, View[A]] =
23-
immutable.IndexedSeq.newBuilder().mapResult(_.view)
18+
override def iterableFactory = View
2419

2520
override def toString = "View(?)"
2621

collections/src/main/scala/strawman/collection/concurrent/TrieMap.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -664,10 +664,7 @@ final class TrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater
664664

665665
def this() = this(Hashing.default, Equiv.universal)
666666

667-
def mapFactory: MapFactory[TrieMap] = TrieMap
668-
protected[this] def fromSpecificIterable(coll: collection.Iterable[(K, V)]): TrieMap[K,V] = TrieMap.from(coll)
669-
protected[this] def mapFromIterable[K2, V2](it: collection.Iterable[(K2, V2)]): TrieMap[K2,V2] = TrieMap.from(it)
670-
protected[this] def newSpecificBuilder(): Builder[(K, V), TrieMap[K,V]] = TrieMap.newBuilder[K, V]()
667+
override def mapFactory: MapFactory[TrieMap] = TrieMap
671668

672669
/* internal methods */
673670

0 commit comments

Comments
 (0)