Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,40 @@ import scala.collection.generic.CanBuildFrom
import scala.collection.mutable.Builder
import scala.collection.{immutable => i, mutable => m}

/* builder optimized for a single ++= call, which returns identity on result if possible
* and defers to the underlying builder if not.
*/
private final class IdentityPreservingSeqBuilder[A, C <: Seq[A]](that: Builder[A, C])
extends Builder[A, Seq[A]] {
var collection: Seq[A] = null
var ruined = false

final override def ++=(elems: TraversableOnce[A]): this.type =
if(!ruined && collection == null && elems.isInstanceOf[Seq[_]]) {
collection = elems.asInstanceOf[Seq[A]]
this
}
else {
ruined = true
if (collection != null) that ++= collection
that ++= elems
collection = null
this
}

final def +=(elem: A): this.type = {
collection = null
ruined = true
that += elem
this
}
final def clear(): Unit = {
collection = null
if (ruined) that.clear()
}
final def result(): Seq[A] = if(ruined) that.result() else if (collection eq null) Nil else collection
}

private[compat] object CompatImpl {
def simpleCBF[A, C](f: => Builder[A, C]): CanBuildFrom[Any, A, C] = new CanBuildFrom[Any, A, C] {
def apply(from: Any): Builder[A, C] = apply()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ private[compat] trait PackageShared {
}

implicit def genericCompanionToCBF[A, CC[X] <: GenTraversable[X]](
fact: GenericCompanion[CC]): CanBuildFrom[Any, A, CC[A]] =
simpleCBF(fact.newBuilder[A])
fact: GenericCompanion[CC]): CanBuildFrom[Any, A, CC[A]] = {
val builder = if (fact == Seq) new IdentityPreservingSeqBuilder[A, Seq[A]](Seq.newBuilder[A]).asInstanceOf[m.Builder[A, CC[A]]]
else fact.newBuilder[A]
simpleCBF(builder)
}

implicit def sortedSetCompanionToCBF[A: Ordering,
CC[X] <: c.SortedSet[X] with c.SortedSetLike[X, CC[X]]](
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ class CollectionTest {
//val mT: Map[Int, String] = m
assertEquals(Map(1 -> "a", 2 -> "b"), m)
assertTrue(m.isInstanceOf[Map[_, _]])

// Stream.to(Seq) doesn't evaluate the stream
val strm = 1 #:: {throw new Exception("not lazy")} #:: Stream.empty[Int]
val strmsq: Seq[Int] = strm.to(Seq)
}

@Test
Expand Down