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

Commit 6cd15d1

Browse files
szeigerjulienrf
authored andcommitted
Retrofit BuildFrom into the new design
`BuildFrom` is like `FromSpecificIterable` but with an extra `From` argument, like in the final version of #45. `FromSpecificIterable` existed conceptually in that version as `BuildFrom[Any, …]` but didn’t have a separate type. This new version has separate abstractions for buildable (strict) collection types in the form of `StrictBuildFrom` and `FromSpecificIterableWithBuilder`. Since we can get a surrogate builder (through one of the new `Builder.from` methods) for any lazy collection and we can restrict code to work only with strict collections via the `Buildable` trait, this is not strictly necessary. The only reason for separating the `Builder` abstractions is to avoid exposing them in `FromSpecificIterable`. Even though everything can be built in a strict way, these abstractions sit on top of the lazy ones, not below them.
1 parent 9c7f58c commit 6cd15d1

21 files changed

+300
-131
lines changed
Lines changed: 75 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,107 @@
11
package strawman
22
package collection
33

4-
import strawman.collection.mutable.Builder
4+
import scala.language.implicitConversions
5+
6+
import strawman.collection.mutable.{ArrayBuffer, Builder}
57

68
import scala.{Any, Int, Nothing, Ordering}
79
import scala.annotation.unchecked.uncheckedVariance
810

11+
12+
/** Builds a collection of type `C` from elements of type `A` when a source collection of type `From` is available.
13+
* Implicit instances of `BuildFrom` are available for all collection types.
14+
*
15+
* @tparam From Type of source collection
16+
* @tparam A Type of elements (e.g. `Int`, `Boolean`, etc.)
17+
* @tparam C Type of collection (e.g. `List[Int]`, `TreeMap[Int, String]`, etc.)
18+
*/
19+
trait BuildFrom[-From, -A, +C] extends Any {
20+
def fromSpecificIterable(from: From)(it: Iterable[A]): C
21+
22+
/** Get a Builder for the collection. For non-strict collection types this will use an intermediate buffer.
23+
* Building collections with `fromSpecificIterable` is preferred because it can be lazy for lazy collections. */
24+
def newBuilder(from: From): Builder[A, C]
25+
}
26+
27+
object BuildFrom extends BuildFromLowPriority {
28+
/** Build the source collection type from a MapOps */
29+
implicit def buildFromMapOps[CC[K, V] <: Map[K, V] with MapOps[K, V, CC, _], A, B, E, F]: BuildFrom[CC[A, B], (E, F), CC[E, F]] = new BuildFrom[CC[A, B], (E, F), CC[E, F]] {
30+
//TODO: Reuse a prototype instance
31+
def newBuilder(from: CC[A, B]): Builder[(E, F), CC[E, F]] = from.mapFactory.newBuilder[E, F]()
32+
def fromSpecificIterable(from: CC[A, B])(it: Iterable[(E, F)]): CC[E, F] = from.mapFactory.fromIterable(it)
33+
}
34+
35+
/** Build the source collection type from a SortedMapOps */
36+
implicit def buildFromSortedMapOps[CC[K, V] <: SortedMap[K, V] with SortedMapOps[K, V, CC, _], A, B, E : Ordering, F]: BuildFrom[CC[A, B], (E, F), CC[E, F]] = new BuildFrom[CC[A, B], (E, F), CC[E, F]] {
37+
def newBuilder(from: CC[A, B]): Builder[(E, F), CC[E, F]] = from.sortedMapFactory.newBuilder[E, F]()
38+
def fromSpecificIterable(from: CC[A, B])(it: Iterable[(E, F)]): CC[E, F] = from.sortedMapFactory.fromSpecificIterable(it)
39+
}
40+
}
41+
42+
trait BuildFromLowPriority {
43+
/** Build the source collection type from an IterableOps */
44+
implicit def buildFromIterableOps[CC[X] <: Iterable[X] with IterableOps[X, CC, _], A, E]: BuildFrom[CC[A], E, CC[E]] = new BuildFrom[CC[A], E, CC[E]] {
45+
//TODO: Reuse a prototype instance
46+
def newBuilder(from: CC[A]): Builder[E, CC[E]] = from.iterableFactory.newBuilder[E]()
47+
def fromSpecificIterable(from: CC[A])(it: Iterable[E]): CC[E] = from.iterableFactory.fromIterable(it)
48+
}
49+
50+
/** Build the source collection type from an Iterable with SortedOps */
51+
implicit def buildFromSortedOps[CC[X] <: Iterable[X] with SortedOps[X, CC[X], CC], A, E : Ordering]: BuildFrom[CC[A], E, CC[E]] = new BuildFrom[CC[A], E, CC[E]] {
52+
def newBuilder(from: CC[A]): Builder[E, CC[E]] = from.sortedIterableFactory.newBuilder[E]()
53+
def fromSpecificIterable(from: CC[A])(it: Iterable[E]): CC[E] = from.sortedIterableFactory.fromSpecificIterable(it)
54+
}
55+
}
56+
957
/**
1058
* Builds a collection of type `C` from elements of type `A`
1159
* @tparam A Type of elements (e.g. `Int`, `Boolean`, etc.)
1260
* @tparam C Type of collection (e.g. `List[Int]`, `TreeMap[Int, String]`, etc.)
1361
*/
14-
trait FromSpecificIterable[-A, +C] extends Any {
62+
trait FromSpecificIterable[-A, +C] extends Any with BuildFrom[Any, A, C] {
63+
def fromSpecificIterable(from: Any)(it: Iterable[A]): C = fromSpecificIterable(it)
1564
def fromSpecificIterable(it: Iterable[A]): C
65+
def newBuilder(from: Any): Builder[A, C] = newBuilder
66+
def newBuilder: Builder[A, C]
1667
}
1768

1869
/** Base trait for companion objects of unconstrained collection types */
1970
trait IterableFactory[+CC[_]] {
20-
2171
def fromIterable[E](it: Iterable[E]): CC[E]
22-
2372
def empty[A]: CC[A]
24-
2573
def apply[A](xs: A*): CC[A] = fromIterable(View.Elems(xs: _*))
26-
2774
def fill[A](n: Int)(elem: => A): CC[A] = fromIterable(View.Fill(n)(elem))
28-
75+
def newBuilder[A](): Builder[A, CC[A]] = new ArrayBuffer[A]().mapResult(fromIterable _)
2976
}
3077

3178
object IterableFactory {
32-
import scala.language.implicitConversions
33-
3479
implicit def toSpecific[A, CC[_]](factory: IterableFactory[CC]): FromSpecificIterable[A, CC[A]] =
3580
new FromSpecificIterable[A, CC[A]] {
3681
def fromSpecificIterable(it: Iterable[A]): CC[A] = factory.fromIterable[A](it)
82+
def newBuilder: Builder[A, CC[A]] = factory.newBuilder[A]()
3783
}
3884

3985
class Delegate[CC[_]](delegate: IterableFactory[CC]) extends IterableFactory[CC] {
4086
def empty[A]: CC[A] = delegate.empty
4187
def fromIterable[E](it: Iterable[E]): CC[E] = delegate.fromIterable(it)
42-
}
43-
44-
}
45-
46-
trait IterableFactoryWithBuilder[+CC[_]] extends IterableFactory[CC] {
47-
def newBuilder[A](): Builder[A, CC[A]]
48-
}
49-
50-
object IterableFactoryWithBuilder {
51-
class Delegate[CC[_]](delegate: IterableFactoryWithBuilder[CC])
52-
extends IterableFactory.Delegate[CC](delegate)
53-
with IterableFactoryWithBuilder[CC] {
54-
def newBuilder[A](): Builder[A, CC[A]] = delegate.newBuilder()
88+
override def newBuilder[A](): Builder[A, CC[A]] = delegate.newBuilder[A]()
5589
}
5690
}
5791

5892
trait SpecificIterableFactory[-A, +C] extends FromSpecificIterable[A, C] {
5993
def empty: C
60-
6194
def apply(xs: A*): C = fromSpecificIterable(View.Elems(xs: _*))
62-
6395
def fill(n: Int)(elem: => A): C = fromSpecificIterable(View.Fill(n)(elem))
64-
}
65-
66-
trait SpecificIterableFactoryWithBuilder[-A, +C] extends SpecificIterableFactory[A, C] {
67-
def newBuilder(): Builder[A, C]
96+
def newBuilder: Builder[A, C] = new ArrayBuffer[A]().mapResult(fromSpecificIterable _)
6897
}
6998

7099
/** Factory methods for collections of kind `* −> * -> *` */
71-
trait MapFactory[+CC[_, _]] {
72-
100+
trait MapFactory[+CC[X, Y]] {
73101
def empty[K, V]: CC[K, V]
74102
def fromIterable[K, V](it: Iterable[(K, V)]): CC[K, V]
75-
76103
def apply[K, V](elems: (K, V)*): CC[K, V] = fromIterable(elems.toStrawman)
104+
def newBuilder[K, V](): Builder[(K, V), CC[K, V]] = new ArrayBuffer[(K, V)]().mapResult(fromIterable _)
77105
}
78106

79107
object MapFactory {
@@ -82,102 +110,58 @@ object MapFactory {
82110
implicit def toSpecific[K, V, CC[_, _]](factory: MapFactory[CC]): FromSpecificIterable[(K, V), CC[K, V]] =
83111
new FromSpecificIterable[(K, V), CC[K, V]] {
84112
def fromSpecificIterable(it: Iterable[(K, V)]): CC[K, V] = factory.fromIterable[K, V](it)
113+
def newBuilder: Builder[(K, V), CC[K, V]] = factory.newBuilder[K, V]()
85114
}
86115

87-
class Delegate[CC[_, _]](delegate: MapFactory[CC]) extends MapFactory[CC] {
88-
def fromIterable[K, V](it: Iterable[(K, V)]): CC[K, V] = delegate.fromIterable(it)
89-
def empty[K, V]: CC[K, V] = delegate.empty
116+
class Delegate[C[X, Y]](delegate: MapFactory[C]) extends MapFactory[C] {
117+
def fromIterable[K, V](it: Iterable[(K, V)]): C[K, V] = delegate.fromIterable(it)
118+
def empty[K, V]: C[K, V] = delegate.empty
119+
override def newBuilder[K, V](): Builder[(K, V), C[K, V]] = delegate.newBuilder()
90120
}
91-
92-
}
93-
94-
trait MapFactoryWithBuilder[+CC[_, _]] extends MapFactory[CC] {
95-
def newBuilder[K, V](): Builder[(K, V), CC[K, V]]
96-
}
97-
98-
object MapFactoryWithBuilder {
99-
100-
class Delegate[CC[_, _]](delegate: MapFactoryWithBuilder[CC])
101-
extends MapFactory.Delegate[CC](delegate)
102-
with MapFactoryWithBuilder[CC] {
103-
def newBuilder[K, V](): Builder[(K, V), CC[K, V]] = delegate.newBuilder()
104-
}
105-
106121
}
107122

108123
/** Base trait for companion objects of collections that require an implicit evidence */
109124
trait SortedIterableFactory[+CC[_]] {
110-
111125
def sortedFromIterable[E : Ordering](it: Iterable[E]): CC[E]
112-
113126
def empty[A : Ordering]: CC[A]
114-
115127
def apply[A : Ordering](xs: A*): CC[A] = sortedFromIterable(View.Elems(xs: _*))
116-
117128
def fill[A : Ordering](n: Int)(elem: => A): CC[A] = sortedFromIterable(View.Fill(n)(elem))
129+
def newBuilder[A : Ordering](): Builder[A, CC[A]] = new ArrayBuffer[A]().mapResult(sortedFromIterable[A] _)
118130
}
119131

120132
object SortedIterableFactory {
121-
import scala.language.implicitConversions
122-
123133
implicit def toSpecific[A: Ordering, CC[_]](factory: SortedIterableFactory[CC]): FromSpecificIterable[A, CC[A]] =
124134
new FromSpecificIterable[A, CC[A]] {
125135
def fromSpecificIterable(it: Iterable[A]): CC[A] = factory.sortedFromIterable[A](it)
136+
def newBuilder: Builder[A, CC[A]] = factory.newBuilder[A]()
126137
}
127138

128139
class Delegate[CC[_]](delegate: SortedIterableFactory[CC]) extends SortedIterableFactory[CC] {
129140
def empty[A : Ordering]: CC[A] = delegate.empty
130141
def sortedFromIterable[E : Ordering](it: Iterable[E]): CC[E] = delegate.sortedFromIterable(it)
131-
}
132-
133-
}
134-
135-
trait SortedIterableFactoryWithBuilder[+CC[_]] extends SortedIterableFactory[CC] {
136-
def newBuilder[A : Ordering](): Builder[A, CC[A]]
137-
}
138-
139-
object SortedIterableFactoryWithBuilder {
140-
class Delegate[CC[_]](delegate: SortedIterableFactoryWithBuilder[CC])
141-
extends SortedIterableFactory.Delegate[CC](delegate)
142-
with SortedIterableFactoryWithBuilder[CC] {
143-
def newBuilder[A: Ordering](): Builder[A, CC[A]] = delegate.newBuilder()
142+
override def newBuilder[A : Ordering](): Builder[A, CC[A]] = delegate.newBuilder[A]()
144143
}
145144
}
146145

147146
/** Factory methods for collections of kind `* −> * -> *` which require an implicit evidence value for the key type */
148147
trait SortedMapFactory[+CC[X, Y]] {
149-
150148
def empty[K : Ordering, V]: CC[K, V]
151-
152149
def sortedFromIterable[K : Ordering, V](it: Iterable[(K, V)]): CC[K, V]
153-
154150
def apply[K : Ordering, V](elems: (K, V)*): CC[K, V] =
155151
sortedFromIterable(elems.toStrawman)
152+
def newBuilder[K : Ordering, V](): Builder[(K, V), CC[K, V]] = new ArrayBuffer[(K, V)]().mapResult(sortedFromIterable[K, V] _)
156153
}
157154

158155
object SortedMapFactory {
159-
import scala.language.implicitConversions
160-
161-
implicit def toSpecific[K : Ordering, V, CC[_, _]](factory: SortedMapFactory[CC]): FromSpecificIterable[(K, V), CC[K, V]] =
156+
implicit def toSpecific[K : Ordering, V, CC[X, Y]](factory: SortedMapFactory[CC]): FromSpecificIterable[(K, V), CC[K, V]] =
162157
new FromSpecificIterable[(K, V), CC[K, V]] {
163-
def fromSpecificIterable(it: Iterable[(K, V)]): CC[K, V] = factory.sortedFromIterable(it)
158+
def fromSpecificIterable(it: Iterable[(K, V)]): CC[K, V] = factory.sortedFromIterable[K, V](it)
159+
def newBuilder: Builder[(K, V), CC[K, V]] = factory.newBuilder[K, V]()
164160
}
165161

166-
class Delegate[CC[_, _]](delegate: SortedMapFactory[CC]) extends SortedMapFactory[CC] {
167-
def empty[K: Ordering, V]: CC[K, V] = delegate.empty[K, V]
168-
def sortedFromIterable[K: Ordering, V](it: Iterable[(K, V)]): CC[K, V] = delegate.sortedFromIterable(it)
169-
}
170-
171-
}
172-
173-
trait SortedMapFactoryWithBuilder[+CC[_, _]] extends SortedMapFactory[CC] {
174-
def newBuilder[K : Ordering, V](): Builder[(K, V), CC[K, V]]
175-
}
176-
177-
object SortedMapFactoryWithBuilder {
178-
class Delegate[CC[_, _]](delegate: SortedMapFactoryWithBuilder[CC])
179-
extends SortedMapFactory.Delegate[CC](delegate)
180-
with SortedMapFactoryWithBuilder[CC] {
181-
def newBuilder[K: Ordering, V](): Builder[(K, V), CC[K, V]] = delegate.newBuilder()
162+
class Delegate[C[X, Y]](delegate: SortedMapFactory[C]) extends SortedMapFactory[C] {
163+
def sortedFromIterable[K : Ordering, V](it: Iterable[(K, V)]): C[K, V] = delegate.sortedFromIterable(it)
164+
def empty[K : Ordering, V]: C[K, V] = delegate.empty
165+
override def newBuilder[K : Ordering, V](): Builder[(K, V), C[K, V]] = delegate.newBuilder()
182166
}
183167
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ trait MapOps[K, +V, +CC[X, Y] <: Map[X, Y], +C <: Map[K, V]]
2121
/** Similar to fromIterable, but returns a Map collection type */
2222
protected[this] def mapFromIterable[K2, V2](it: Iterable[(K2, V2)]): CC[K2, V2]
2323

24+
def mapFactory: MapFactory[CC]
25+
2426
/** Optionally returns the value associated with a key.
2527
*
2628
* @param key the key value

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ trait SortedMap[K, +V]
1212

1313
trait SortedMapOps[K, +V, +CC[X, Y] <: SortedMap[X, Y] with SortedMapOps[X, Y, CC, _], +C <: SortedMap[K, V]]
1414
extends MapOps[K, V, Map, C]
15-
with SortedOps[K, C] {
15+
with SortedOps[K, C, SortedSet] {
16+
17+
def sortedIterableFactory = SortedSet
18+
19+
def sortedMapFactory: SortedMapFactory[CC]
1620

1721
protected[this] def sortedMapFromIterable[K2, V2](it: collection.Iterable[(K2, V2)])(implicit ordering: Ordering[K2]): CC[K2, V2]
1822

src/main/scala/strawman/collection/SortedOps.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ package strawman.collection
33
import scala.{Ordering, Option, Some}
44

55
/** Base trait for sorted collections */
6-
trait SortedOps[A, +C] {
6+
trait SortedOps[A, +C, +CC[_]] {
77

88
implicit def ordering: Ordering[A]
99

10+
def sortedIterableFactory: SortedIterableFactory[CC]
11+
1012
/** Returns the first key of the collection. */
1113
def firstKey: A
1214

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ trait SortedSet[A] extends Set[A] with SortedSetOps[A, SortedSet, SortedSet[A]]
99

1010
trait SortedSetOps[A, +CC[X], +C <: SortedSet[A]]
1111
extends SetOps[A, Set, C]
12-
with SortedOps[A, C] {
12+
with SortedOps[A, C, CC] {
1313

1414
protected[this] def sortedFromIterable[B: Ordering](it: Iterable[B]): CC[B]
1515

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ sealed abstract class BitSet
2828
def empty: BitSet = BitSet.empty
2929

3030
def iterableFactory = Set
31+
def sortedIterableFactory = SortedSet
3132

3233
protected[this] def fromSpecificIterable(coll: collection.Iterable[Int]): BitSet = BitSet.fromSpecificIterable(coll)
3334
protected[this] def sortedFromIterable[B : Ordering](it: collection.Iterable[B]): SortedSet[B] = SortedSet.sortedFromIterable(it)

src/main/scala/strawman/collection/immutable/HashMap.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ sealed trait HashMap[K, +V]
3737
import HashMap.{bufferSize, liftMerger, Merger, MergeFunction, nullToEmpty}
3838

3939
def iterableFactory = List
40+
def mapFactory = HashMap
4041

4142
protected[this] def fromSpecificIterable(coll: collection.Iterable[(K, V)]): HashMap[K, V] = HashMap.fromIterable(coll)
4243

src/main/scala/strawman/collection/immutable/List.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ case object Nil extends List[Nothing] {
5757
override def tail: Nothing = throw new UnsupportedOperationException("tail of empty list")
5858
}
5959

60-
object List extends IterableFactoryWithBuilder[List] {
60+
object List extends IterableFactory[List] {
6161

6262
def fromIterable[B](coll: collection.Iterable[B]): List[B] = coll match {
6363
case coll: List[B] => coll
6464
case _ => ListBuffer.fromIterable(coll).toList
6565
}
6666

67-
def newBuilder[A](): Builder[A, List[A]] = new GrowableBuilder(ListBuffer.empty[A]).mapResult(_.toList)
67+
override def newBuilder[A](): Builder[A, List[A]] = new ListBuffer[A].mapResult(_.toList)
6868

6969
def empty[A]: List[A] = Nil
7070
}

src/main/scala/strawman/collection/immutable/ListMap.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ sealed class ListMap[K, +V]
5050
with Serializable {
5151

5252
def iterableFactory = List
53+
def mapFactory = ListMap
5354

5455
protected[this] def mapFromIterable[K2, V2](it: collection.Iterable[(K2, V2)]): ListMap[K2,V2] = ListMap.fromIterable(it)
5556

src/main/scala/strawman/collection/immutable/TreeMap.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ final class TreeMap[K, +V] private (tree: RB.Tree[K, V])(implicit val ordering:
3737
def this()(implicit ordering: Ordering[K]) = this(null)(ordering)
3838

3939
def iterableFactory = List
40+
def mapFactory = Map
41+
def sortedMapFactory = TreeMap
4042

4143
protected[this] def fromSpecificIterable(coll: collection.Iterable[(K, V)]): TreeMap[K, V] =
4244
TreeMap.sortedFromIterable(coll)

src/main/scala/strawman/collection/immutable/TreeSet.scala

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ final class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: O
3636

3737
def iterableFactory = Set
3838

39+
def sortedIterableFactory = TreeSet
40+
3941
protected[this] def fromSpecificIterable(coll: strawman.collection.Iterable[A]): TreeSet[A] =
4042
TreeSet.sortedFromIterable(coll)
4143

@@ -108,7 +110,7 @@ final class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: O
108110
else newSet(RB.delete(tree, elem))
109111
}
110112

111-
object TreeSet extends SortedIterableFactoryWithBuilder[TreeSet] {
113+
object TreeSet extends SortedIterableFactory[TreeSet] {
112114

113115
def empty[A: Ordering]: TreeSet[A] = new TreeSet[A]
114116

@@ -118,9 +120,4 @@ object TreeSet extends SortedIterableFactoryWithBuilder[TreeSet] {
118120
case _ => empty[E] ++ it
119121
}
120122

121-
def newBuilder[A : Ordering](): Builder[A, TreeSet[A]] =
122-
new ImmutableBuilder[A, TreeSet[A]](empty) {
123-
def add(elem: A): this.type = { elems = elems + elem; this }
124-
}
125-
126123
}

src/main/scala/strawman/collection/mutable/ArrayBuffer.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ object ArrayBuffer extends IterableFactory[ArrayBuffer] {
134134
}
135135
else new ArrayBuffer[B] ++= coll
136136

137+
override def newBuilder[A](): Builder[A, ArrayBuffer[A]] = new ArrayBuffer[A]()
138+
137139
def empty[A]: ArrayBuffer[A] = new ArrayBuffer[A]()
138140
}
139141

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class BitSet(protected[collection] final var elems: Array[Long])
3737

3838
def iterableFactory = Set
3939

40+
def sortedIterableFactory = SortedSet
41+
4042
protected[this] def sortedFromIterable[B : Ordering](it: collection.Iterable[B]): collection.mutable.SortedSet[B] =
4143
collection.mutable.SortedSet.sortedFromIterable(it)
4244

0 commit comments

Comments
 (0)