Skip to content

Commit 144d86e

Browse files
authored
Merge pull request scala#8 from julienrf/factory
Add scala.collection.Factory
2 parents 2fca3b3 + 7d28d9d commit 144d86e

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package scala.collection
2+
3+
import scala.collection.generic.CanBuildFrom
4+
5+
/**
6+
* A factory that builds a collection of type `C` with elements of type `A`.
7+
*
8+
* @tparam A Type of elements (e.g. `Int`, `Boolean`, etc.)
9+
* @tparam C Type of collection (e.g. `List[Int]`, `TreeMap[Int, String]`, etc.)
10+
*/
11+
trait Factory[-A, +C] extends Any {
12+
13+
/**
14+
* @return A collection of type `C` containing the same elements
15+
* as the source collection `it`.
16+
* @param it Source collection
17+
*/
18+
def fromSpecific(it: TraversableOnce[A]): C
19+
20+
/** Get a Builder for the collection. For non-strict collection types this will use an intermediate buffer.
21+
* Building collections with `fromSpecific` is preferred because it can be lazy for lazy collections. */
22+
def newBuilder(): mutable.Builder[A, C]
23+
}
24+
25+
object Factory {
26+
27+
implicit def fromCanBuildFrom[A, C](implicit cbf: CanBuildFrom[Nothing, A, C]): Factory[A, C] =
28+
new Factory[A, C] {
29+
def fromSpecific(it: TraversableOnce[A]): C = (cbf() ++= it).result()
30+
def newBuilder(): mutable.Builder[A, C] = cbf()
31+
}
32+
33+
implicit def fromCanBuildFromConversion[X, A, C](x: X)(implicit toCanBuildFrom: X => CanBuildFrom[Nothing, A, C]): Factory[A, C] =
34+
fromCanBuildFrom(toCanBuildFrom(x))
35+
36+
}

src/main/scala-2.12/collection/compat/package.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ package object compat {
2323
implicit def sortedMapFactoryToCBF[K : Ordering, V, CC[A, B] <: SortedMap[A, B] with SortedMapLike[A, B, CC[A, B]]](fact: SortedMapFactory[CC]): CanBuildFrom[Any, (K, V), CC[K, V]] =
2424
simpleCBF(fact.newBuilder[K, V])
2525

26+
implicit def bitSetFactoryToCBF(fact: BitSetFactory[BitSet]): CanBuildFrom[Any, Int, BitSet] =
27+
simpleCBF(fact.newBuilder)
28+
2629
implicit def immutableBitSetFactoryToCBF(fact: BitSetFactory[immutable.BitSet]): CanBuildFrom[Any, Int, ImmutableBitSetCC[Int]] =
2730
simpleCBF(fact.newBuilder)
2831

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package collection
2+
3+
import org.junit.{Assert, Test}
4+
5+
import scala.collection.{BitSet, Factory, Iterable, immutable, mutable}
6+
import scala.collection.compat._
7+
8+
class FactoryTest {
9+
10+
implicitly[Factory[Char, String]]
11+
implicitly[Factory[Char, Array[Char]]]
12+
implicitly[Factory[Int, BitSet]]
13+
implicitly[Factory[Int, mutable.BitSet]]
14+
implicitly[Factory[Int, immutable.BitSet]]
15+
16+
BitSet: Factory[Int, BitSet]
17+
Iterable: Factory[Int, Iterable[Int]]
18+
immutable.TreeSet: Factory[Int, immutable.TreeSet[Int]]
19+
Map: Factory[(Int, String), Map[Int, String]]
20+
immutable.TreeMap: Factory[(Int, String), immutable.TreeMap[Int, String]]
21+
22+
@Test
23+
def streamFactoryPreservesLaziness(): Unit = {
24+
val factory = implicitly[Factory[Int, Stream[Int]]]
25+
var counter = 0
26+
val source = Stream.continually { counter += 1; 1 }
27+
val result = factory.fromSpecific(source)
28+
Assert.assertEquals(1, counter) // One element has been evaluated because Stream is not lazy in its head
29+
}
30+
31+
}

0 commit comments

Comments
 (0)