11package strawman
22package collection
33
4- import strawman .collection .mutable .Builder
4+ import scala .language .implicitConversions
5+
6+ import strawman .collection .mutable .{ArrayBuffer , Builder }
57
68import scala .{Any , Int , Nothing , Ordering }
79import 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 */
1970trait 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
3178object 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
5892trait 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
79107object 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 */
109124trait 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
120132object 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 */
148147trait 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
158155object 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}
0 commit comments