|
12 | 12 |
|
13 | 13 | package scala.collection.compat
|
14 | 14 |
|
| 15 | +import scala.reflect.ClassTag |
15 | 16 | import scala.collection.generic.CanBuildFrom
|
16 |
| -import scala.collection.mutable.Builder |
17 | 17 | import scala.collection.{immutable => i, mutable => m}
|
18 | 18 |
|
| 19 | +/* builder optimized for a single ++= call, which returns identity on result if possible |
| 20 | + * and defers to the underlying builder if not. |
| 21 | + */ |
| 22 | +private final class IdentityPreservingBuilder[A, CC[X] <: TraversableOnce[X]](that: m.Builder[A, CC[A]])(implicit ct: ClassTag[CC[A]]) |
| 23 | + extends m.Builder[A, CC[A]] { |
| 24 | + |
| 25 | + //invariant: ruined => (collection == null) |
| 26 | + var collection: CC[A] = null.asInstanceOf[CC[A]] |
| 27 | + var ruined = false |
| 28 | + |
| 29 | + private[this] def ruin(): Unit = { |
| 30 | + if(collection != null) that ++= collection |
| 31 | + collection = null.asInstanceOf[CC[A]] |
| 32 | + ruined = true |
| 33 | + } |
| 34 | + |
| 35 | + override def ++=(elems: TraversableOnce[A]): this.type = |
| 36 | + elems match { |
| 37 | + case ct(ca) if collection == null && !ruined => { |
| 38 | + collection = ca |
| 39 | + this |
| 40 | + } |
| 41 | + case _ => { |
| 42 | + ruin() |
| 43 | + that ++= elems |
| 44 | + this |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + def +=(elem: A): this.type = { |
| 49 | + ruin() |
| 50 | + that += elem |
| 51 | + this |
| 52 | + } |
| 53 | + |
| 54 | + def clear(): Unit = { |
| 55 | + collection = null.asInstanceOf[CC[A]] |
| 56 | + if (ruined) that.clear() |
| 57 | + ruined = false |
| 58 | + } |
| 59 | + |
| 60 | + def result(): CC[A] = if(collection == null) that.result() else collection |
| 61 | +} |
| 62 | + |
19 | 63 | private[compat] object CompatImpl {
|
20 |
| - def simpleCBF[A, C](f: => Builder[A, C]): CanBuildFrom[Any, A, C] = new CanBuildFrom[Any, A, C] { |
21 |
| - def apply(from: Any): Builder[A, C] = apply() |
22 |
| - def apply(): Builder[A, C] = f |
| 64 | + def simpleCBF[A, C](f: => m.Builder[A, C]): CanBuildFrom[Any, A, C] = new CanBuildFrom[Any, A, C] { |
| 65 | + def apply(from: Any): m.Builder[A, C] = apply() |
| 66 | + def apply(): m.Builder[A, C] = f |
23 | 67 | }
|
24 | 68 |
|
25 | 69 | type ImmutableBitSetCC[X] = ({ type L[_] = i.BitSet })#L[X]
|
|
0 commit comments