diff options
74 files changed, 301 insertions, 189 deletions
diff --git a/src/library/scala/collection/BitSetLike.scala b/src/library/scala/collection/BitSetLike.scala index 447af9405a..b96e8f6a91 100644 --- a/src/library/scala/collection/BitSetLike.scala +++ b/src/library/scala/collection/BitSetLike.scala @@ -58,7 +58,7 @@ trait BitSetLike[+This <: BitSetLike[This] with Set[Int]] extends SetLike[Int, T s } - def iterator = new Iterator[Int] { + def iterator: Iterator[Int] = new AbstractIterator[Int] { private var current = 0 private val end = nwords * WordLength def hasNext: Boolean = { diff --git a/src/library/scala/collection/IndexedSeqLike.scala b/src/library/scala/collection/IndexedSeqLike.scala index 96e9ca2dbb..b743174260 100644 --- a/src/library/scala/collection/IndexedSeqLike.scala +++ b/src/library/scala/collection/IndexedSeqLike.scala @@ -51,7 +51,7 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { */ // pre: start >= 0, end <= self.length @SerialVersionUID(1756321872811029277L) - protected class Elements(start: Int, end: Int) extends BufferedIterator[A] with Serializable { + protected class Elements(start: Int, end: Int) extends AbstractIterator[A] with BufferedIterator[A] with Serializable { private def initialSize = if (end <= start) 0 else end - start private var index = start private def available = (end - index) max 0 diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala index d5991eb9df..e2541f2a66 100755 --- a/src/library/scala/collection/IndexedSeqOptimized.scala +++ b/src/library/scala/collection/IndexedSeqOptimized.scala @@ -219,7 +219,7 @@ trait IndexedSeqOptimized[+A, +Repr] extends IndexedSeqLike[A, Repr] { self => } override /*SeqLike*/ - def reverseIterator: Iterator[A] = new Iterator[A] { + def reverseIterator: Iterator[A] = new AbstractIterator[A] { private var i = self.length def hasNext: Boolean = 0 < i def next(): A = diff --git a/src/library/scala/collection/Iterable.scala b/src/library/scala/collection/Iterable.scala index 0717861c26..50558d5a9f 100644 --- a/src/library/scala/collection/Iterable.scala +++ b/src/library/scala/collection/Iterable.scala @@ -49,3 +49,6 @@ object Iterable extends TraversableFactory[Iterable] { def newBuilder[A]: Builder[A, Iterable[A]] = immutable.Iterable.newBuilder[A] } + +/** Explicit instantiation of the `Iterable` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractIterable[+T] extends AbstractTraversable[T] with Iterable[T] diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala index df4710b1be..ce2daf08d4 100644 --- a/src/library/scala/collection/IterableViewLike.scala +++ b/src/library/scala/collection/IterableViewLike.scala @@ -42,6 +42,9 @@ trait IterableViewLike[+A, override def toString = viewToString } + /** Explicit instantiation of the `Transformed` trait to reduce class file size in subclasses. */ + private[collection] abstract class AbstractTransformed[+B] extends super[TraversableViewLike].Transformed[B] with Transformed[B] + trait EmptyView extends Transformed[Nothing] with super[TraversableViewLike].EmptyView with super[GenIterableViewLike].EmptyView trait Forced[B] extends super[TraversableViewLike].Forced[B] with super[GenIterableViewLike].Forced[B] with Transformed[B] @@ -69,20 +72,20 @@ trait IterableViewLike[+A, /** Boilerplate method, to override in each subclass * This method could be eliminated if Scala had virtual classes */ - protected def newZipped[B](that: GenIterable[B]): Transformed[(A, B)] = new { val other = that } with Zipped[B] + protected def newZipped[B](that: GenIterable[B]): Transformed[(A, B)] = new { val other = that } with AbstractTransformed[(A, B)] with Zipped[B] protected def newZippedAll[A1 >: A, B](that: GenIterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new { val other: GenIterable[B] = that val thisElem = _thisElem val thatElem = _thatElem - } with ZippedAll[A1, B] - protected override def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with Forced[B] - protected override def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with Appended[B] - protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with Mapped[B] - protected override def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with FlatMapped[B] - protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with Filtered - protected override def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with Sliced - protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with DroppedWhile - protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with TakenWhile + } with AbstractTransformed[(A1, B)] with ZippedAll[A1, B] + protected override def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B] + protected override def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B] + protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B] + protected override def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B] + protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered + protected override def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with AbstractTransformed[A] with Sliced + protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with DroppedWhile + protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with TakenWhile // After adding take and drop overrides to IterableLike, these overrides (which do nothing // but duplicate the implementation in TraversableViewLike) had to be added to prevent the diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 73e2c17398..b56a83043d 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -22,7 +22,7 @@ import immutable.Stream object Iterator { /** The iterator which produces no values. */ - val empty = new Iterator[Nothing] { + val empty: Iterator[Nothing] = new AbstractIterator[Nothing] { def hasNext: Boolean = false def next(): Nothing = throw new NoSuchElementException("next on empty iterator") } @@ -34,7 +34,7 @@ object Iterator { * @return An iterator which produces `elem` on the first call to `next`, * and which has no further elements. */ - def single[A](elem: A) = new Iterator[A] { + def single[A](elem: A): Iterator[A] = new AbstractIterator[A] { private var hasnext = true def hasNext: Boolean = hasnext def next(): A = @@ -56,7 +56,7 @@ object Iterator { * @param elem the element computation * @return An iterator that produces the results of `n` evaluations of `elem`. */ - def fill[A](len: Int)(elem: => A) = new Iterator[A] { + def fill[A](len: Int)(elem: => A): Iterator[A] = new AbstractIterator[A] { private var i = 0 def hasNext: Boolean = i < len def next(): A = @@ -70,7 +70,7 @@ object Iterator { * @param f The function computing element values * @return An iterator that produces the values `f(0), ..., f(n -1)`. */ - def tabulate[A](end: Int)(f: Int => A) = new Iterator[A] { + def tabulate[A](end: Int)(f: Int => A): Iterator[A] = new AbstractIterator[A] { private var i = 0 def hasNext: Boolean = i < end def next(): A = @@ -93,7 +93,7 @@ object Iterator { * @param step the increment value of the iterator (must be positive or negative) * @return the iterator producing values `start, start + step, ...` up to, but excluding `end` */ - def range(start: Int, end: Int, step: Int) = new Iterator[Int] { + def range(start: Int, end: Int, step: Int): Iterator[Int] = new AbstractIterator[Int] { if (step == 0) throw new IllegalArgumentException("zero step") private var i = start def hasNext: Boolean = (step <= 0 || i < end) && (step >= 0 || i > end) @@ -108,7 +108,7 @@ object Iterator { * @param f the function that's repeatedly applied * @return the iterator producing the infinite sequence of values `start, f(start), f(f(start)), ...` */ - def iterate[T](start: T)(f: T => T): Iterator[T] = new Iterator[T] { + def iterate[T](start: T)(f: T => T): Iterator[T] = new AbstractIterator[T] { private[this] var first = true private[this] var acc = start def hasNext: Boolean = true @@ -133,7 +133,7 @@ object Iterator { * @param step the increment between successive values * @return the iterator producing the infinite sequence of values `start, start + 1 * step, start + 2 * step, ...` */ - def from(start: Int, step: Int): Iterator[Int] = new Iterator[Int] { + def from(start: Int, step: Int): Iterator[Int] = new AbstractIterator[Int] { private var i = start def hasNext: Boolean = true def next(): Int = { val result = i; i += step; result } @@ -145,7 +145,7 @@ object Iterator { * @param elem the element computation. * @return the iterator containing an infinite number of results of evaluating `elem`. */ - def continually[A](elem: => A): Iterator[A] = new Iterator[A] { + def continually[A](elem: => A): Iterator[A] = new AbstractIterator[A] { def hasNext = true def next = elem } @@ -291,7 +291,7 @@ trait Iterator[+A] extends TraversableOnce[A] { toDrop -= 1 } - new Iterator[A] { + new AbstractIterator[A] { private var remaining = until - lo def hasNext = remaining > 0 && self.hasNext def next(): A = @@ -311,7 +311,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * iterator by applying the function `f` to it. * @note Reuse: $consumesAndProducesIterator */ - def map[B](f: A => B): Iterator[B] = new Iterator[B] { + def map[B](f: A => B): Iterator[B] = new AbstractIterator[B] { def hasNext = self.hasNext def next() = f(self.next()) } @@ -324,7 +324,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * @note Reuse: $consumesTwoAndProducesOneIterator * @usecase def ++(that: => Iterator[A]): Iterator[A] */ - def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new Iterator[B] { + def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new AbstractIterator[B] { // optimize a little bit to prevent n log n behavior. private var cur : Iterator[B] = self // since that is by-name, make sure it's only referenced once - @@ -349,7 +349,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * `f` to each value produced by this iterator and concatenating the results. * @note Reuse: $consumesAndProducesIterator */ - def flatMap[B](f: A => GenTraversableOnce[B]): Iterator[B] = new Iterator[B] { + def flatMap[B](f: A => GenTraversableOnce[B]): Iterator[B] = new AbstractIterator[B] { private var cur: Iterator[B] = empty def hasNext: Boolean = cur.hasNext || self.hasNext && { cur = f(self.next).toIterator; hasNext } @@ -363,7 +363,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * @return an iterator which produces those values of this iterator which satisfy the predicate `p`. * @note Reuse: $consumesAndProducesIterator */ - def filter(p: A => Boolean): Iterator[A] = new Iterator[A] { + def filter(p: A => Boolean): Iterator[A] = new AbstractIterator[A] { private var hd: A = _ private var hdDefined: Boolean = false @@ -416,7 +416,7 @@ trait Iterator[+A] extends TraversableOnce[A] { ) def collect[B](pf: PartialFunction[A, B]): Iterator[B] = { val self = buffered - new Iterator[B] { + new AbstractIterator[B] { private def skip() = while (self.hasNext && !pf.isDefinedAt(self.head)) self.next() def hasNext = { skip(); self.hasNext } def next() = { skip(); pf(self.next()) } @@ -435,7 +435,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * @return iterator with intermediate results * @note Reuse: $consumesAndProducesIterator */ - def scanLeft[B](z: B)(op: (B, A) => B): Iterator[B] = new Iterator[B] { + def scanLeft[B](z: B)(op: (B, A) => B): Iterator[B] = new AbstractIterator[B] { var hasNext = true var elem = z def next() = if (hasNext) { @@ -471,7 +471,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * the predicate `p`. * @note Reuse: $consumesAndProducesIterator */ - def takeWhile(p: A => Boolean): Iterator[A] = new Iterator[A] { + def takeWhile(p: A => Boolean): Iterator[A] = new AbstractIterator[A] { private var hd: A = _ private var hdDefined: Boolean = false private var tail: Iterator[A] = self @@ -496,7 +496,7 @@ trait Iterator[+A] extends TraversableOnce[A] { */ def partition(p: A => Boolean): (Iterator[A], Iterator[A]) = { val self = buffered - class PartitionIterator(p: A => Boolean) extends Iterator[A] { + class PartitionIterator(p: A => Boolean) extends AbstractIterator[A] { var other: PartitionIterator = _ val lookahead = new mutable.Queue[A] def skip() = @@ -530,7 +530,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * iterator is referring (the finish() method) and thus triggering * handling of structural calls. It's not what's intended here. */ - class Leading extends Iterator[A] { + class Leading extends AbstractIterator[A] { private var isDone = false val lookahead = new mutable.Queue[A] def advance() = { @@ -552,7 +552,7 @@ trait Iterator[+A] extends TraversableOnce[A] { } } val leading = new Leading - val trailing = new Iterator[A] { + val trailing = new AbstractIterator[A] { private lazy val it = { leading.finish() self @@ -574,7 +574,7 @@ trait Iterator[+A] extends TraversableOnce[A] { */ def dropWhile(p: A => Boolean): Iterator[A] = { val self = buffered - new Iterator[A] { + new AbstractIterator[A] { var dropped = false private def skip() = if (!dropped) { @@ -599,7 +599,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * iterator and `that`. * @note Reuse: $consumesTwoAndProducesOneIterator */ - def zip[B](that: Iterator[B]) = new Iterator[(A, B)] { + def zip[B](that: Iterator[B]): Iterator[(A, B)] = new AbstractIterator[(A, B)] { def hasNext = self.hasNext && that.hasNext def next = (self.next, that.next) } @@ -614,7 +614,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * @note Reuse: $consumesAndProducesIterator * @usecase def padTo(len: Int, elem: A): Iterator[A] */ - def padTo[A1 >: A](len: Int, elem: A1) = new Iterator[A1] { + def padTo[A1 >: A](len: Int, elem: A1): Iterator[A1] = new AbstractIterator[A1] { private var count = 0 def hasNext = self.hasNext || count < len def next = { @@ -632,7 +632,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * corresponding elements of this iterator and their indices. * @note Reuse: $consumesAndProducesIterator */ - def zipWithIndex = new Iterator[(A, Int)] { + def zipWithIndex: Iterator[(A, Int)] = new AbstractIterator[(A, Int)] { var idx = 0 def hasNext = self.hasNext def next = { @@ -663,7 +663,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * @note Reuse: $consumesTwoAndProducesOneIterator * @usecase def zipAll[B](that: Iterator[B], thisElem: A, thatElem: B): Iterator[(A, B)] */ - def zipAll[B, A1 >: A, B1 >: B](that: Iterator[B], thisElem: A1, thatElem: B1) = new Iterator[(A1, B1)] { + def zipAll[B, A1 >: A, B1 >: B](that: Iterator[B], thisElem: A1, thatElem: B1): Iterator[(A1, B1)] = new AbstractIterator[(A1, B1)] { def hasNext = self.hasNext || that.hasNext def next(): (A1, B1) = if (self.hasNext) { @@ -794,7 +794,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * @return a buffered iterator producing the same values as this iterator. * @note Reuse: $consumesAndProducesIterator */ - def buffered = new BufferedIterator[A] { + def buffered: BufferedIterator[A] = new AbstractIterator[A] with BufferedIterator[A] { private var hd: A = _ private var hdDefined: Boolean = false @@ -822,7 +822,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * * Typical uses can be achieved via methods `grouped` and `sliding`. */ - class GroupedIterator[B >: A](self: Iterator[A], size: Int, step: Int) extends Iterator[Seq[B]] { + class GroupedIterator[B >: A](self: Iterator[A], size: Int, step: Int) extends AbstractIterator[Seq[B]] { require(size >= 1 && step >= 1, "size=%d and step=%d, but both must be positive".format(size, step)) private[this] var buffer: ArrayBuffer[B] = ArrayBuffer() // the buffer @@ -1004,7 +1004,7 @@ trait Iterator[+A] extends TraversableOnce[A] { def duplicate: (Iterator[A], Iterator[A]) = { val gap = new scala.collection.mutable.Queue[A] var ahead: Iterator[A] = null - class Partner extends Iterator[A] { + class Partner extends AbstractIterator[A] { def hasNext: Boolean = self.synchronized { (this ne ahead) && !gap.isEmpty || self.hasNext } @@ -1035,7 +1035,7 @@ trait Iterator[+A] extends TraversableOnce[A] { * @param replaced The number of values in the original iterator that are replaced by the patch. * @note Reuse: $consumesTwoAndProducesOneIterator */ - def patch[B >: A](from: Int, patchElems: Iterator[B], replaced: Int) = new Iterator[B] { + def patch[B >: A](from: Int, patchElems: Iterator[B], replaced: Int): Iterator[B] = new AbstractIterator[B] { private var origElems = self private var i = 0 def hasNext: Boolean = @@ -1107,3 +1107,6 @@ trait Iterator[+A] extends TraversableOnce[A] { */ override def toString = (if (hasNext) "non-empty" else "empty")+" iterator" } + +/** Explicit instantiation of the `Iterator` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractIterator[+T] extends Iterator[T] diff --git a/src/library/scala/collection/JavaConversions.scala b/src/library/scala/collection/JavaConversions.scala index f929086062..d911a16d02 100644 --- a/src/library/scala/collection/JavaConversions.scala +++ b/src/library/scala/collection/JavaConversions.scala @@ -524,12 +524,12 @@ object JavaConversions { def asJava = new IteratorWrapper(underlying) } - case class JIteratorWrapper[A](underlying: ju.Iterator[A]) extends Iterator[A] { + case class JIteratorWrapper[A](underlying: ju.Iterator[A]) extends AbstractIterator[A] with Iterator[A] { def hasNext = underlying.hasNext def next() = underlying.next } - case class JEnumerationWrapper[A](underlying: ju.Enumeration[A]) extends Iterator[A] { + case class JEnumerationWrapper[A](underlying: ju.Enumeration[A]) extends AbstractIterator[A] with Iterator[A] { def hasNext = underlying.hasMoreElements def next() = underlying.nextElement } @@ -538,12 +538,12 @@ object JavaConversions { extends ju.AbstractCollection[A] with IterableWrapperTrait[A] { } - case class JIterableWrapper[A](underlying: jl.Iterable[A]) extends Iterable[A] { + case class JIterableWrapper[A](underlying: jl.Iterable[A]) extends AbstractIterable[A] with Iterable[A] { def iterator = underlying.iterator def newBuilder[B] = new mutable.ArrayBuffer[B] } - case class JCollectionWrapper[A](underlying: ju.Collection[A]) extends Iterable[A] { + case class JCollectionWrapper[A](underlying: ju.Collection[A]) extends AbstractIterable[A] with Iterable[A] { def iterator = underlying.iterator override def size = underlying.size override def isEmpty = underlying.isEmpty @@ -572,7 +572,7 @@ object JavaConversions { override def remove(i: Int) = underlying remove i } - case class JListWrapper[A](val underlying: ju.List[A]) extends mutable.Buffer[A] { + case class JListWrapper[A](val underlying: ju.List[A]) extends mutable.AbstractBuffer[A] with mutable.Buffer[A] { def length = underlying.size override def isEmpty = underlying.isEmpty override def iterator: Iterator[A] = underlying.iterator @@ -625,7 +625,10 @@ object JavaConversions { } case class JSetWrapper[A](underlying: ju.Set[A]) - extends mutable.Set[A] with mutable.SetLike[A, JSetWrapper[A]] { + extends mutable.AbstractSet[A] + with mutable.Set[A] + with mutable.SetLike[A, JSetWrapper[A]] { + override def size = underlying.size def iterator = underlying.iterator @@ -746,7 +749,7 @@ object JavaConversions { if (r != null) Some(r) else None } - def iterator = new Iterator[(A, B)] { + def iterator: Iterator[(A, B)] = new AbstractIterator[(A, B)] { val ui = underlying.entrySet.iterator def hasNext = ui.hasNext def next() = { val e = ui.next(); (e.getKey, e.getValue) } @@ -758,7 +761,10 @@ object JavaConversions { } case class JMapWrapper[A, B](val underlying : ju.Map[A, B]) - extends JMapWrapperLike[A, B, JMapWrapper[A, B]] { + extends mutable.AbstractMap[A, B] + with mutable.Map[A, B] + with JMapWrapperLike[A, B, JMapWrapper[A, B]] { + override def empty = JMapWrapper(new ju.HashMap[A, B]) } @@ -786,7 +792,11 @@ object JavaConversions { } case class JConcurrentMapWrapper[A, B](val underlying: juc.ConcurrentMap[A, B]) - extends JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] with mutable.ConcurrentMap[A, B] { + extends mutable.AbstractMap[A, B] + with mutable.Map[A, B] + with JMapWrapperLike[A, B, JConcurrentMapWrapper[A, B]] + with mutable.ConcurrentMap[A, B] { + override def get(k: A) = { val v = underlying get k if (v != null) Some(v) @@ -840,7 +850,8 @@ object JavaConversions { } case class JDictionaryWrapper[A, B](underlying: ju.Dictionary[A, B]) - extends mutable.Map[A, B] { + extends mutable.AbstractMap[A, B] + with mutable.Map[A, B] { override def size: Int = underlying.size @@ -870,7 +881,10 @@ object JavaConversions { } case class JPropertiesWrapper(underlying: ju.Properties) - extends mutable.Map[String, String] with mutable.MapLike[String, String, JPropertiesWrapper] { + extends mutable.AbstractMap[String, String] + with mutable.Map[String, String] + with mutable.MapLike[String, String, JPropertiesWrapper] { + override def size = underlying.size def get(k: String) = { @@ -893,7 +907,7 @@ object JavaConversions { if (r != null) Some(r.asInstanceOf[String]) else None } - def iterator = new Iterator[(String, String)] { + def iterator: Iterator[(String, String)] = new AbstractIterator[(String, String)] { val ui = underlying.entrySet.iterator def hasNext = ui.hasNext def next() = { diff --git a/src/library/scala/collection/LinearSeqLike.scala b/src/library/scala/collection/LinearSeqLike.scala index decb281a5f..1b3fa9b26e 100644 --- a/src/library/scala/collection/LinearSeqLike.scala +++ b/src/library/scala/collection/LinearSeqLike.scala @@ -47,7 +47,7 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr override protected[this] def toCollection(repr: Repr): LinearSeq[A] = repr.asInstanceOf[LinearSeq[A]] override /*IterableLike*/ - def iterator: Iterator[A] = new Iterator[A] { + def iterator: Iterator[A] = new AbstractIterator[A] { var these = self def hasNext: Boolean = !these.isEmpty def next(): A = diff --git a/src/library/scala/collection/Map.scala b/src/library/scala/collection/Map.scala index 71b2e7fb1e..a72bb13b5d 100644 --- a/src/library/scala/collection/Map.scala +++ b/src/library/scala/collection/Map.scala @@ -48,10 +48,13 @@ object Map extends MapFactory[Map] { /** An abstract shell used by { mutable, immutable }.Map but not by collection.Map * because of variance issues. */ - abstract class WithDefault[A, +B](underlying: Map[A, B], d: A => B) extends Map[A, B] { + abstract class WithDefault[A, +B](underlying: Map[A, B], d: A => B) extends AbstractMap[A, B] with Map[A, B] { override def size = underlying.size def get(key: A) = underlying.get(key) // removed in 2.9: orElse Some(default(key)) def iterator = underlying.iterator override def default(key: A): B = d(key) } } + +/** Explicit instantiation of the `Map` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractMap[A, +B] extends AbstractIterable[(A, B)] with Map[A, B] diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala index 5b4ac20329..3485fe1be6 100644 --- a/src/library/scala/collection/MapLike.scala +++ b/src/library/scala/collection/MapLike.scala @@ -159,7 +159,7 @@ self => /** The implementation class of the set returned by `keySet`. */ - protected class DefaultKeySet extends Set[A] { + protected class DefaultKeySet extends AbstractSet[A] { def contains(key : A) = self.contains(key) def iterator = keysIterator def + (elem: A): Set[A] = (Set[A]() ++ this + elem).asInstanceOf[Set[A]] // !!! concrete overrides abstract problem @@ -172,7 +172,7 @@ self => * * @return an iterator over all keys. */ - def keysIterator: Iterator[A] = new Iterator[A] { + def keysIterator: Iterator[A] = new AbstractIterator[A] { val iter = self.iterator def hasNext = iter.hasNext def next() = iter.next._1 @@ -194,7 +194,7 @@ self => /** The implementation class of the iterable returned by `values`. */ - protected class DefaultValuesIterable extends Iterable[B] { + protected class DefaultValuesIterable extends AbstractIterable[B] { def iterator = valuesIterator override def size = self.size override def foreach[C](f: B => C) = self.valuesIterator foreach f @@ -204,7 +204,7 @@ self => * * @return an iterator over all values that are associated with some key in this map. */ - def valuesIterator: Iterator[B] = new Iterator[B] { + def valuesIterator: Iterator[B] = new AbstractIterator[B] { val iter = self.iterator def hasNext = iter.hasNext def next() = iter.next._2 @@ -226,7 +226,7 @@ self => * @return an immutable map consisting only of those key value pairs of this map where the key satisfies * the predicate `p`. The resulting map wraps the original map without copying any elements. */ - def filterKeys(p: A => Boolean): Map[A, B] = new DefaultMap[A, B] { + def filterKeys(p: A => Boolean): Map[A, B] = new AbstractMap[A, B] with DefaultMap[A, B] { override def foreach[C](f: ((A, B)) => C): Unit = for (kv <- self) if (p(kv._1)) f(kv) def iterator = self.iterator.filter(kv => p(kv._1)) override def contains(key: A) = self.contains(key) && p(key) @@ -238,7 +238,7 @@ self => * @return a map view which maps every key of this map * to `f(this(key))`. The resulting map wraps the original map without copying any elements. */ - def mapValues[C](f: B => C): Map[A, C] = new DefaultMap[A, C] { + def mapValues[C](f: B => C): Map[A, C] = new AbstractMap[A, C] with DefaultMap[A, C] { override def foreach[D](g: ((A, C)) => D): Unit = for ((k, v) <- self) g((k, f(v))) def iterator = for ((k, v) <- self.iterator) yield (k, f(v)) override def size = self.size diff --git a/src/library/scala/collection/Seq.scala b/src/library/scala/collection/Seq.scala index 7bbbae9b0f..3be3ca0204 100644 --- a/src/library/scala/collection/Seq.scala +++ b/src/library/scala/collection/Seq.scala @@ -41,3 +41,5 @@ object Seq extends SeqFactory[Seq] { def newBuilder[A]: Builder[A, Seq[A]] = immutable.Seq.newBuilder[A] } +/** Explicit instantiation of the `Seq` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractSeq[+T] extends AbstractIterable[T] with Seq[T] diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index a0b595803b..8a4f2ff31a 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -143,7 +143,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] with GenSeqLike[A, Repr] if (n < 0 || n > size) Iterator.empty else new CombinationsItr(n) - private class PermutationsItr extends Iterator[Repr] { + private class PermutationsItr extends AbstractIterator[Repr] { private[this] val (elms, idxs) = init() private var _hasNext = true @@ -190,7 +190,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] with GenSeqLike[A, Repr] } } - private class CombinationsItr(n: Int) extends Iterator[Repr] { + private class CombinationsItr(n: Int) extends AbstractIterator[Repr] { // generating all nums such that: // (1) nums(0) + .. + nums(length-1) = n // (2) 0 <= nums(i) <= cnts(i), where 0 <= i <= cnts.length-1 @@ -690,18 +690,18 @@ object SeqLike { case iso: IndexedSeq[_] => // Already optimized for indexing--use original (or custom view of original) if (forward && n0==0 && n1==W.length) iso.asInstanceOf[IndexedSeq[B]] - else if (forward) new IndexedSeq[B] { + else if (forward) new AbstractSeq[B] with IndexedSeq[B] { val length = n1 - n0 def apply(x: Int) = iso(n0 + x).asInstanceOf[B] } - else new IndexedSeq[B] { + else new AbstractSeq[B] with IndexedSeq[B] { def length = n1 - n0 def apply(x: Int) = iso(n1 - 1 - x).asInstanceOf[B] } case _ => // W is probably bad at indexing. Pack in array (in correct orientation) // Would be marginally faster to special-case each direction - new IndexedSeq[B] { + new AbstractSeq[B] with IndexedSeq[B] { private[this] val Warr = new Array[AnyRef](n1-n0) private[this] val delta = if (forward) 1 else -1 private[this] val done = if (forward) n1-n0 else -1 diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala index 6e8afdd04f..a32cad08e5 100644 --- a/src/library/scala/collection/SeqViewLike.scala +++ b/src/library/scala/collection/SeqViewLike.scala @@ -40,6 +40,9 @@ trait SeqViewLike[+A, override def toString = viewToString } + /** Explicit instantiation of the `Transformed` trait to reduce class file size in subclasses. */ + private[collection] abstract class AbstractTransformed[+B] extends super[IterableViewLike].AbstractTransformed[B] with Transformed[B] + trait EmptyView extends Transformed[Nothing] with super[IterableViewLike].EmptyView with super[GenSeqViewLike].EmptyView trait Forced[B] extends super[IterableViewLike].Forced[B] with super[GenSeqViewLike].Forced[B] with Transformed[B] @@ -71,27 +74,27 @@ trait SeqViewLike[+A, /** Boilerplate method, to override in each subclass * This method could be eliminated if Scala had virtual classes */ - protected override def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with Forced[B] - protected override def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with Appended[B] - protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with Mapped[B] - protected override def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with FlatMapped[B] - protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with Filtered - protected override def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with Sliced - protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with DroppedWhile - protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with TakenWhile - protected override def newZipped[B](that: GenIterable[B]): Transformed[(A, B)] = new { val other = that } with Zipped[B] + protected override def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B] + protected override def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B] + protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B] + protected override def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B] + protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered + protected override def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with AbstractTransformed[A] with Sliced + protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with DroppedWhile + protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with TakenWhile + protected override def newZipped[B](that: GenIterable[B]): Transformed[(A, B)] = new { val other = that } with AbstractTransformed[(A, B)] with Zipped[B] protected override def newZippedAll[A1 >: A, B](that: GenIterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new { val other = that val thisElem = _thisElem val thatElem = _thatElem - } with ZippedAll[A1, B] - protected def newReversed: Transformed[A] = new Reversed { } + } with AbstractTransformed[(A1, B)] with ZippedAll[A1, B] + protected def newReversed: Transformed[A] = new AbstractTransformed[A] with Reversed protected def newPatched[B >: A](_from: Int, _patch: GenSeq[B], _replaced: Int): Transformed[B] = new { val from = _from val patch = _patch val replaced = _replaced - } with Patched[B] - protected def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with Prepended[B] + } with AbstractTransformed[B] with Patched[B] + protected def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with AbstractTransformed[B] with Prepended[B] // see comment in IterableViewLike. protected override def newTaken(n: Int): Transformed[A] = newSliced(SliceInterval(0, n)) diff --git a/src/library/scala/collection/Set.scala b/src/library/scala/collection/Set.scala index 7241d7fb3a..bdfbcd9c74 100644 --- a/src/library/scala/collection/Set.scala +++ b/src/library/scala/collection/Set.scala @@ -44,3 +44,6 @@ object Set extends SetFactory[Set] { override def empty[A]: Set[A] = immutable.Set.empty[A] implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Set[A]] = setCanBuildFrom[A] } + +/** Explicit instantiation of the `Set` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractSet[A] extends AbstractIterable[A] with Set[A] diff --git a/src/library/scala/collection/SetLike.scala b/src/library/scala/collection/SetLike.scala index c657e6b243..b4695363de 100644 --- a/src/library/scala/collection/SetLike.scala +++ b/src/library/scala/collection/SetLike.scala @@ -181,7 +181,7 @@ self => * * @return the iterator. */ - def subsets: Iterator[This] = new Iterator[This] { + def subsets: Iterator[This] = new AbstractIterator[This] { private val elms = self.toIndexedSeq private var len = 0 private var itr: Iterator[This] = Iterator.empty @@ -207,7 +207,7 @@ self => * @author Eastsun * @date 2010.12.6 */ - private class SubsetsItr(elms: IndexedSeq[A], len: Int) extends Iterator[This] { + private class SubsetsItr(elms: IndexedSeq[A], len: Int) extends AbstractIterator[This] { private val idxs = Array.range(0, len+1) private var _hasNext = true idxs(len) = elms.size diff --git a/src/library/scala/collection/Traversable.scala b/src/library/scala/collection/Traversable.scala index 3f550adeed..014586b3af 100644 --- a/src/library/scala/collection/Traversable.scala +++ b/src/library/scala/collection/Traversable.scala @@ -108,3 +108,5 @@ object Traversable extends TraversableFactory[Traversable] { self => def newBuilder[A]: Builder[A, Traversable[A]] = immutable.Traversable.newBuilder[A] } +/** Explicit instantiation of the `Traversable` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractTraversable[+T] extends Traversable[T] diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index 4f125b4090..908c4c808d 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -383,7 +383,7 @@ object TraversableOnce { } class FlattenOps[A](travs: TraversableOnce[TraversableOnce[A]]) { - def flatten: Iterator[A] = new Iterator[A] { + def flatten: Iterator[A] = new AbstractIterator[A] { val its = travs.toIterator private var it: Iterator[A] = Iterator.empty def hasNext: Boolean = it.hasNext || its.hasNext && { it = its.next.toIterator; hasNext } diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index 03286fef67..8c67d841bc 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -107,6 +107,9 @@ trait TraversableViewLike[+A, override def toString = viewToString } + /** Explicit instantiation of the `Transformed` trait to reduce class file size in subclasses. */ + private[collection] abstract class AbstractTransformed[+B] extends Transformed[B] + trait EmptyView extends Transformed[Nothing] with super.EmptyView /** A fall back which forces everything into a vector and then applies an operation @@ -155,14 +158,14 @@ trait TraversableViewLike[+A, /** Boilerplate method, to override in each subclass * This method could be eliminated if Scala had virtual classes */ - protected def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with Forced[B] - protected def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with Appended[B] - protected def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with Mapped[B] - protected def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with FlatMapped[B] - protected def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with Filtered - protected def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with Sliced - protected def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with DroppedWhile - protected def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with TakenWhile + protected def newForced[B](xs: => GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B] + protected def newAppended[B >: A](that: GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B] + protected def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B] + protected def newFlatMapped[B](f: A => GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B] + protected def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered + protected def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with AbstractTransformed[A] with Sliced + protected def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with DroppedWhile + protected def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with TakenWhile protected def newTaken(n: Int): Transformed[A] = newSliced(SliceInterval(0, n)) protected def newDropped(n: Int): Transformed[A] = newSliced(SliceInterval(n, Int.MaxValue)) diff --git a/src/library/scala/collection/immutable/BitSet.scala b/src/library/scala/collection/immutable/BitSet.scala index bc82c4c133..36aa087dd0 100644 --- a/src/library/scala/collection/immutable/BitSet.scala +++ b/src/library/scala/collection/immutable/BitSet.scala @@ -21,7 +21,8 @@ import mutable.{ Builder, SetBuilder } * @define coll immutable bitset */ @SerialVersionUID(1611436763290191562L) -abstract class BitSet extends Set[Int] +abstract class BitSet extends scala.collection.AbstractSet[Int] + with Set[Int] with scala.collection.BitSet with BitSetLike[BitSet] with Serializable { diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index f4e9c91733..79ee067d63 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -31,7 +31,8 @@ import parallel.immutable.ParHashMap * @define willNotTerminateInf */ @SerialVersionUID(2L) -class HashMap[A, +B] extends Map[A,B] +class HashMap[A, +B] extends AbstractMap[A, B] + with Map[A, B] with MapLike[A, B, HashMap[A, B]] with Serializable with CustomParallelizable[(A, B), ParHashMap[A, B]] diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index 579edc66cc..8cb19d4f31 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -30,7 +30,8 @@ import collection.parallel.immutable.ParHashSet * @define coll immutable hash set */ @SerialVersionUID(2L) -class HashSet[A] extends Set[A] +class HashSet[A] extends AbstractSet[A] + with Set[A] with GenericSetTemplate[A, HashSet] with SetLike[A, HashSet[A]] with CustomParallelizable[A, ParHashSet[A]] diff --git a/src/library/scala/collection/immutable/IndexedSeq.scala b/src/library/scala/collection/immutable/IndexedSeq.scala index 2b06c950fa..35b93860a3 100644 --- a/src/library/scala/collection/immutable/IndexedSeq.scala +++ b/src/library/scala/collection/immutable/IndexedSeq.scala @@ -31,7 +31,7 @@ trait IndexedSeq[+A] extends Seq[A] * @define Coll IndexedSeq */ object IndexedSeq extends SeqFactory[IndexedSeq] { - class Impl[A](buf: ArrayBuffer[A]) extends IndexedSeq[A] with Serializable { + class Impl[A](buf: ArrayBuffer[A]) extends AbstractSeq[A] with IndexedSeq[A] with Serializable { def length = buf.length def apply(idx: Int) = buf.apply(idx) } diff --git a/src/library/scala/collection/immutable/IntMap.scala b/src/library/scala/collection/immutable/IntMap.scala index cb1065d786..dd6b066878 100644 --- a/src/library/scala/collection/immutable/IntMap.scala +++ b/src/library/scala/collection/immutable/IntMap.scala @@ -83,7 +83,7 @@ object IntMap { import IntMap._ // Iterator over a non-empty IntMap. -private[immutable] abstract class IntMapIterator[V, T](it : IntMap[V]) extends Iterator[T]{ +private[immutable] abstract class IntMapIterator[V, T](it : IntMap[V]) extends AbstractIterator[T] { // Basically this uses a simple stack to emulate conversion over the tree. However // because we know that Ints are at least 32 bits we can have at most 32 IntMap.Bins and @@ -155,7 +155,11 @@ import IntMap._ * @define mayNotTerminateInf * @define willNotTerminateInf */ -sealed abstract class IntMap[+T] extends Map[Int, T] with MapLike[Int, T, IntMap[T]] { +sealed abstract class IntMap[+T] +extends AbstractMap[Int, T] + with Map[Int, T] + with MapLike[Int, T, IntMap[T]] { + override def empty: IntMap[T] = IntMap.Nil; override def toList = { diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index fb7808bc41..d5e5f2aee0 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -74,7 +74,8 @@ import annotation.tailrec * @define mayNotTerminateInf * @define willNotTerminateInf */ -sealed abstract class List[+A] extends LinearSeq[A] +sealed abstract class List[+A] extends AbstractSeq[A] + with LinearSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqOptimized[A, List[A]] { diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index 0933ef7c58..3b7da3259e 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -45,7 +45,11 @@ object ListMap extends ImmutableMapFactory[ListMap] { * @define willNotTerminateInf */ @SerialVersionUID(301002838095710379L) -class ListMap[A, +B] extends Map[A, B] with MapLike[A, B, ListMap[A, B]] with Serializable { +class ListMap[A, +B] +extends AbstractMap[A, B] + with Map[A, B] + with MapLike[A, B, ListMap[A, B]] + with Serializable { override def empty = ListMap.empty @@ -112,7 +116,7 @@ class ListMap[A, +B] extends Map[A, B] with MapLike[A, B, ListMap[A, B]] with Se /** Returns an iterator over key-value pairs. */ def iterator: Iterator[(A,B)] = - new Iterator[(A,B)] { + new AbstractIterator[(A,B)] { var self: ListMap[A,B] = ListMap.this def hasNext = !self.isEmpty def next(): (A,B) = diff --git a/src/library/scala/collection/immutable/ListSet.scala b/src/library/scala/collection/immutable/ListSet.scala index 22e614dd75..47e3245117 100644 --- a/src/library/scala/collection/immutable/ListSet.scala +++ b/src/library/scala/collection/immutable/ListSet.scala @@ -63,7 +63,8 @@ object ListSet extends ImmutableSetFactory[ListSet] { * @define mayNotTerminateInf * @define willNotTerminateInf */ -class ListSet[A] extends Set[A] +class ListSet[A] extends AbstractSet[A] + with Set[A] with GenericSetTemplate[A, ListSet] with SetLike[A, ListSet[A]] with Serializable{ self => @@ -112,7 +113,7 @@ class ListSet[A] extends Set[A] * @throws Predef.NoSuchElementException * @return the new iterator */ - def iterator: Iterator[A] = new Iterator[A] { + def iterator: Iterator[A] = new AbstractIterator[A] { var that: ListSet[A] = self def hasNext = that.nonEmpty def next: A = diff --git a/src/library/scala/collection/immutable/LongMap.scala b/src/library/scala/collection/immutable/LongMap.scala index 6c951a6ff2..963ddac762 100644 --- a/src/library/scala/collection/immutable/LongMap.scala +++ b/src/library/scala/collection/immutable/LongMap.scala @@ -79,7 +79,7 @@ object LongMap { import LongMap._ // Iterator over a non-empty LongMap. -private[immutable] abstract class LongMapIterator[V, T](it : LongMap[V]) extends Iterator[T]{ +private[immutable] abstract class LongMapIterator[V, T](it : LongMap[V]) extends AbstractIterator[T] { // Basically this uses a simple stack to emulate conversion over the tree. However // because we know that Longs are only 64 bits we can have at most 64 LongMap.Bins and @@ -152,7 +152,11 @@ import LongMap._; * @define mayNotTerminateInf * @define willNotTerminateInf */ -sealed abstract class LongMap[+T] extends Map[Long, T] with MapLike[Long, T, LongMap[T]] { +sealed abstract class LongMap[+T] +extends AbstractMap[Long, T] + with Map[Long, T] + with MapLike[Long, T, LongMap[T]] { + override def empty: LongMap[T] = LongMap.Nil; override def toList = { diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala index 82cf050f43..45cf088dd9 100644 --- a/src/library/scala/collection/immutable/Map.scala +++ b/src/library/scala/collection/immutable/Map.scala @@ -84,7 +84,7 @@ object Map extends ImmutableMapFactory[Map] { override def withDefaultValue[B1 >: B](d: B1): immutable.Map[A, B1] = new WithDefault[A, B1](underlying, x => d) } - private object EmptyMap extends Map[Any, Nothing] with Serializable { + private object EmptyMap extends AbstractMap[Any, Nothing] with Map[Any, Nothing] with Serializable { override def size: Int = 0 def get(key: Any): Option[Nothing] = None def iterator: Iterator[(Any, Nothing)] = Iterator.empty @@ -93,7 +93,7 @@ object Map extends ImmutableMapFactory[Map] { def - (key: Any): Map[Any, Nothing] = this } - class Map1[A, +B](key1: A, value1: B) extends Map[A, B] with Serializable { + class Map1[A, +B](key1: A, value1: B) extends AbstractMap[A, B] with Map[A, B] with Serializable { override def size = 1 def get(key: A): Option[B] = if (key == key1) Some(value1) else None @@ -109,7 +109,7 @@ object Map extends ImmutableMapFactory[Map] { } } - class Map2[A, +B](key1: A, value1: B, key2: A, value2: B) extends Map[A, B] with Serializable { + class Map2[A, +B](key1: A, value1: B, key2: A, value2: B) extends AbstractMap[A, B] with Map[A, B] with Serializable { override def size = 2 def get(key: A): Option[B] = if (key == key1) Some(value1) @@ -130,7 +130,7 @@ object Map extends ImmutableMapFactory[Map] { } } - class Map3[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B) extends Map[A, B] with Serializable { + class Map3[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B) extends AbstractMap[A, B] with Map[A, B] with Serializable { override def size = 3 def get(key: A): Option[B] = if (key == key1) Some(value1) @@ -154,7 +154,7 @@ object Map extends ImmutableMapFactory[Map] { } } - class Map4[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B, key4: A, value4: B) extends Map[A, B] with Serializable { + class Map4[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B, key4: A, value4: B) extends AbstractMap[A, B] with Map[A, B] with Serializable { override def size = 4 def get(key: A): Option[B] = if (key == key1) Some(value1) @@ -182,3 +182,5 @@ object Map extends ImmutableMapFactory[Map] { } } +/** Explicit instantiation of the `Map` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractMap[A, +B] extends scala.collection.AbstractMap[A, B] with Map[A, B] diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala index beea72d676..80da1ab010 100644 --- a/src/library/scala/collection/immutable/MapLike.scala +++ b/src/library/scala/collection/immutable/MapLike.scala @@ -93,7 +93,7 @@ trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]] * @return an immutable map consisting only of those key value pairs of this map where the key satisfies * the predicate `p`. The resulting map wraps the original map without copying any elements. */ - override def filterKeys(p: A => Boolean): Map[A, B] = new DefaultMap[A, B] { + override def filterKeys(p: A => Boolean): Map[A, B] = new AbstractMap[A, B] with DefaultMap[A, B] { override def foreach[C](f: ((A, B)) => C): Unit = for (kv <- self) if (p(kv._1)) f(kv) def iterator = self.iterator.filter(kv => p(kv._1)) override def contains(key: A) = self.contains(key) && p(key) @@ -105,7 +105,7 @@ trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]] * @return a map view which maps every key of this map * to `f(this(key))`. The resulting map wraps the original map without copying any elements. */ - override def mapValues[C](f: B => C): Map[A, C] = new DefaultMap[A, C] { + override def mapValues[C](f: B => C): Map[A, C] = new AbstractMap[A, C] with DefaultMap[A, C] { override def foreach[D](g: ((A, C)) => D): Unit = for ((k, v) <- self) g((k, f(v))) def iterator = for ((k, v) <- self.iterator) yield (k, f(v)) override def size = self.size diff --git a/src/library/scala/collection/immutable/NumericRange.scala b/src/library/scala/collection/immutable/NumericRange.scala index e70db13251..65bd9ab6f2 100644 --- a/src/library/scala/collection/immutable/NumericRange.scala +++ b/src/library/scala/collection/immutable/NumericRange.scala @@ -42,7 +42,7 @@ import generic._ abstract class NumericRange[T] (val start: T, val end: T, val step: T, val isInclusive: Boolean) (implicit num: Integral[T]) -extends IndexedSeq[T] with Serializable { +extends AbstractSeq[T] with IndexedSeq[T] with Serializable { /** Note that NumericRange must be invariant so that constructs * such as "1L to 10 by 5" do not infer the range type as AnyVal. */ diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala index 8e14d9885d..97c7c789f8 100644 --- a/src/library/scala/collection/immutable/PagedSeq.scala +++ b/src/library/scala/collection/immutable/PagedSeq.scala @@ -129,7 +129,8 @@ class PagedSeq[T: ClassManifest] protected( first1: Page[T], start: Int, end: Int) -extends scala.collection.IndexedSeq[T] +extends scala.collection.AbstractSeq[T] + with scala.collection.IndexedSeq[T] { def this(more: (Array[T], Int, Int) => Int) = this(more, new Page[T](0), 0, UndeterminedEnd) diff --git a/src/library/scala/collection/immutable/Queue.scala b/src/library/scala/collection/immutable/Queue.scala index c1db8b4851..6e73eef101 100644 --- a/src/library/scala/collection/immutable/Queue.scala +++ b/src/library/scala/collection/immutable/Queue.scala @@ -35,7 +35,8 @@ import annotation.tailrec @SerialVersionUID(-7622936493364270175L) class Queue[+A] protected(protected val in: List[A], protected val out: List[A]) - extends LinearSeq[A] + extends AbstractSeq[A] + with LinearSeq[A] with GenericTraversableTemplate[A, Queue] with LinearSeqLike[A, Queue[A]] with Serializable { diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 804c67527a..47ce2f0341 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -41,7 +41,8 @@ import annotation.bridge */ @SerialVersionUID(7618862778670199309L) class Range(val start: Int, val end: Int, val step: Int) -extends IndexedSeq[Int] +extends collection.AbstractSeq[Int] + with IndexedSeq[Int] with collection.CustomParallelizable[Int, ParRange] with Serializable { diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala index 89be64b1d2..fe3ce8fd0b 100644 --- a/src/library/scala/collection/immutable/Set.scala +++ b/src/library/scala/collection/immutable/Set.scala @@ -49,7 +49,7 @@ object Set extends ImmutableSetFactory[Set] { private val hashSeed = "Set".hashCode /** An optimized representation for immutable empty sets */ - private object EmptySet extends Set[Any] with Serializable { + private object EmptySet extends AbstractSet[Any] with Set[Any] with Serializable { override def size: Int = 0 def contains(elem: Any): Boolean = false def + (elem: Any): Set[Any] = new Set1(elem) @@ -60,7 +60,7 @@ object Set extends ImmutableSetFactory[Set] { /** An optimized representation for immutable sets of size 1 */ @SerialVersionUID(1233385750652442003L) - class Set1[A] private[collection] (elem1: A) extends Set[A] with Serializable { + class Set1[A] private[collection] (elem1: A) extends AbstractSet[A] with Set[A] with Serializable { override def size: Int = 1 def contains(elem: A): Boolean = elem == elem1 @@ -79,7 +79,7 @@ object Set extends ImmutableSetFactory[Set] { /** An optimized representation for immutable sets of size 2 */ @SerialVersionUID(-6443011234944830092L) - class Set2[A] private[collection] (elem1: A, elem2: A) extends Set[A] with Serializable { + class Set2[A] private[collection] (elem1: A, elem2: A) extends AbstractSet[A] with Set[A] with Serializable { override def size: Int = 2 def contains(elem: A): Boolean = elem == elem1 || elem == elem2 @@ -99,7 +99,7 @@ object Set extends ImmutableSetFactory[Set] { /** An optimized representation for immutable sets of size 3 */ @SerialVersionUID(-3590273538119220064L) - class Set3[A] private[collection] (elem1: A, elem2: A, elem3: A) extends Set[A] with Serializable { + class Set3[A] private[collection] (elem1: A, elem2: A, elem3: A) extends AbstractSet[A] with Set[A] with Serializable { override def size: Int = 3 def contains(elem: A): Boolean = elem == elem1 || elem == elem2 || elem == elem3 @@ -120,7 +120,7 @@ object Set extends ImmutableSetFactory[Set] { /** An optimized representation for immutable sets of size 4 */ @SerialVersionUID(-3622399588156184395L) - class Set4[A] private[collection] (elem1: A, elem2: A, elem3: A, elem4: A) extends Set[A] with Serializable { + class Set4[A] private[collection] (elem1: A, elem2: A, elem3: A, elem4: A) extends AbstractSet[A] with Set[A] with Serializable { override def size: Int = 4 def contains(elem: A): Boolean = elem == elem1 || elem == elem2 || elem == elem3 || elem == elem4 diff --git a/src/library/scala/collection/immutable/SetProxy.scala b/src/library/scala/collection/immutable/SetProxy.scala index 9c1e2f0b4d..3c098061f0 100644 --- a/src/library/scala/collection/immutable/SetProxy.scala +++ b/src/library/scala/collection/immutable/SetProxy.scala @@ -24,7 +24,7 @@ package immutable trait SetProxy[A] extends Set[A] with SetProxyLike[A, Set[A]] { override def repr = this private def newProxy[B >: A](newSelf: Set[B]): SetProxy[B] = - new SetProxy[B] { val self = newSelf } + new AbstractSet[B] with SetProxy[B] { val self = newSelf } override def empty = newProxy(self.empty) override def + (elem: A) = newProxy(self + elem) diff --git a/src/library/scala/collection/immutable/Stack.scala b/src/library/scala/collection/immutable/Stack.scala index 238b3e414f..d65300ecb7 100644 --- a/src/library/scala/collection/immutable/Stack.scala +++ b/src/library/scala/collection/immutable/Stack.scala @@ -43,7 +43,8 @@ object Stack extends SeqFactory[Stack] { */ @SerialVersionUID(1976480595012942526L) class Stack[+A] protected (protected val elems: List[A]) - extends LinearSeq[A] + extends AbstractSeq[A] + with LinearSeq[A] with GenericTraversableTemplate[A, Stack] with LinearSeqOptimized[A, Stack[A]] with Serializable { diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 7fa973e82f..7bae387ad2 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -178,7 +178,8 @@ import Stream.cons * @define orderDependent * @define orderDependentFold */ -abstract class Stream[+A] extends LinearSeq[A] +abstract class Stream[+A] extends AbstractSeq[A] + with LinearSeq[A] with GenericTraversableTemplate[A, Stream] with LinearSeqOptimized[A, Stream[A]] { self => @@ -925,7 +926,7 @@ self => /** A specialized, extra-lazy implementation of a stream iterator, so it can * iterate as lazily as it traverses the tail. */ -final class StreamIterator[+A](self: Stream[A]) extends Iterator[A] { +final class StreamIterator[+A](self: Stream[A]) extends AbstractIterator[A] with Iterator[A] { // A call-by-need cell. class LazyCell(st: => Stream[A]) { lazy val v = st diff --git a/src/library/scala/collection/immutable/StreamViewLike.scala b/src/library/scala/collection/immutable/StreamViewLike.scala index 7c44c1e019..3fd92aaff9 100644 --- a/src/library/scala/collection/immutable/StreamViewLike.scala +++ b/src/library/scala/collection/immutable/StreamViewLike.scala @@ -18,11 +18,14 @@ extends SeqView[A, Coll] override def toString = viewToString } - trait EmptyView extends Transformed[Nothing] with super.EmptyView { } + /** Explicit instantiation of the `Transformed` trait to reduce class file size in subclasses. */ + private[collection] abstract class AbstractTransformed[+B] extends super.AbstractTransformed[B] with Transformed[B] - trait Forced[B] extends super.Forced[B] with Transformed[B] { } + trait EmptyView extends Transformed[Nothing] with super.EmptyView - trait Sliced extends super.Sliced with Transformed[A] { } + trait Forced[B] extends super.Forced[B] with Transformed[B] + + trait Sliced extends super.Sliced with Transformed[A] trait Mapped[B] extends super.Mapped[B] with Transformed[B] @@ -47,23 +50,23 @@ extends SeqView[A, Coll] trait Prepended[B >: A] extends super.Prepended[B] with Transformed[B] /** boilerplate */ - protected override def newForced[B](xs: => collection.GenSeq[B]): Transformed[B] = new { val forced = xs } with Forced[B] - protected override def newAppended[B >: A](that: collection.GenTraversable[B]): Transformed[B] = new { val rest = that } with Appended[B] - protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with Mapped[B] - protected override def newFlatMapped[B](f: A => collection.GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with FlatMapped[B] - protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with Filtered - protected override def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with Sliced - protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with DroppedWhile - protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with TakenWhile - protected override def newZipped[B](that: collection.GenIterable[B]): Transformed[(A, B)] = new { val other = that } with Zipped[B] + protected override def newForced[B](xs: => collection.GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B] + protected override def newAppended[B >: A](that: collection.GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B] + protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B] + protected override def newFlatMapped[B](f: A => collection.GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B] + protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered + protected override def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with AbstractTransformed[A] with Sliced + protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with DroppedWhile + protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with TakenWhile + protected override def newZipped[B](that: collection.GenIterable[B]): Transformed[(A, B)] = new { val other = that } with AbstractTransformed[(A, B)] with Zipped[B] protected override def newZippedAll[A1 >: A, B](that: collection.GenIterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = { - new { val other = that; val thisElem = _thisElem; val thatElem = _thatElem } with ZippedAll[A1, B] + new { val other = that; val thisElem = _thisElem; val thatElem = _thatElem } with AbstractTransformed[(A1, B)] with ZippedAll[A1, B] } protected override def newReversed: Transformed[A] = new Reversed { } protected override def newPatched[B >: A](_from: Int, _patch: collection.GenSeq[B], _replaced: Int): Transformed[B] = { - new { val from = _from; val patch = _patch; val replaced = _replaced } with Patched[B] + new { val from = _from; val patch = _patch; val replaced = _replaced } with AbstractTransformed[B] with Patched[B] } - protected override def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with Prepended[B] + protected override def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with AbstractTransformed[B] with Prepended[B] override def stringPrefix = "StreamView" } diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index 42ac5bb23b..9b52c8805c 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -106,7 +106,7 @@ self => * - `LF` - line feed (`0x0A` hex) * - `FF` - form feed (`0x0C` hex) */ - def linesWithSeparators: Iterator[String] = new Iterator[String] { + def linesWithSeparators: Iterator[String] = new AbstractIterator[String] { val str = self.toString private val len = str.length private var index = 0 diff --git a/src/library/scala/collection/immutable/TrieIterator.scala b/src/library/scala/collection/immutable/TrieIterator.scala index 7c36ed14ce..c77334b732 100644 --- a/src/library/scala/collection/immutable/TrieIterator.scala +++ b/src/library/scala/collection/immutable/TrieIterator.scala @@ -17,7 +17,7 @@ import scala.annotation.tailrec /** Abandons any pretense of type safety for speed. You can't say I * didn't try: see r23934. */ -private[collection] abstract class TrieIterator[+T](elems: Array[Iterable[T]]) extends Iterator[T] { +private[collection] abstract class TrieIterator[+T](elems: Array[Iterable[T]]) extends AbstractIterator[T] { outer => private[immutable] def getElem(x: AnyRef): T @@ -216,4 +216,4 @@ private[collection] abstract class TrieIterator[+T](elems: Array[Iterable[T]]) e } } } -}
\ No newline at end of file +} diff --git a/src/library/scala/collection/immutable/Vector.scala b/src/library/scala/collection/immutable/Vector.scala index 5c8046fa58..ab12300097 100644 --- a/src/library/scala/collection/immutable/Vector.scala +++ b/src/library/scala/collection/immutable/Vector.scala @@ -52,7 +52,8 @@ object Vector extends SeqFactory[Vector] { * @define willNotTerminateInf */ final class Vector[+A](private[collection] val startIndex: Int, private[collection] val endIndex: Int, focus: Int) -extends IndexedSeq[A] +extends AbstractSeq[A] + with IndexedSeq[A] with GenericTraversableTemplate[A, Vector] with IndexedSeqLike[A, Vector[A]] with VectorPointer[A @uncheckedVariance] @@ -90,7 +91,7 @@ override def companion: GenericCompanion[Vector] = Vector // can still be improved override /*SeqLike*/ - def reverseIterator: Iterator[A] = new Iterator[A] { + def reverseIterator: Iterator[A] = new AbstractIterator[A] { private var i = self.length def hasNext: Boolean = 0 < i def next(): A = @@ -636,7 +637,10 @@ override def companion: GenericCompanion[Vector] = Vector } -class VectorIterator[+A](_startIndex: Int, _endIndex: Int) extends Iterator[A] with VectorPointer[A @uncheckedVariance] { +class VectorIterator[+A](_startIndex: Int, _endIndex: Int) +extends AbstractIterator[A] + with Iterator[A] + with VectorPointer[A @uncheckedVariance] { private var blockIndex: Int = _startIndex & ~31 private var lo: Int = _startIndex & 31 diff --git a/src/library/scala/collection/immutable/WrappedString.scala b/src/library/scala/collection/immutable/WrappedString.scala index b6fd98fd0e..de8aeea7e1 100644 --- a/src/library/scala/collection/immutable/WrappedString.scala +++ b/src/library/scala/collection/immutable/WrappedString.scala @@ -28,7 +28,7 @@ import mutable.{Builder, StringBuilder} * @define Coll WrappedString * @define coll wrapped string */ -class WrappedString(val self: String) extends IndexedSeq[Char] with StringLike[WrappedString] { +class WrappedString(val self: String) extends AbstractSeq[Char] with IndexedSeq[Char] with StringLike[WrappedString] { override protected[this] def thisCollection: WrappedString = this override protected[this] def toCollection(repr: WrappedString): WrappedString = repr diff --git a/src/library/scala/collection/mutable/ArrayBuffer.scala b/src/library/scala/collection/mutable/ArrayBuffer.scala index 31a6f1f160..ea56eee395 100644 --- a/src/library/scala/collection/mutable/ArrayBuffer.scala +++ b/src/library/scala/collection/mutable/ArrayBuffer.scala @@ -42,7 +42,8 @@ import parallel.mutable.ParArray */ @SerialVersionUID(1529165946227428979L) class ArrayBuffer[A](override protected val initialSize: Int) - extends Buffer[A] + extends AbstractBuffer[A] + with Buffer[A] with GenericTraversableTemplate[A, ArrayBuffer] with BufferLike[A, ArrayBuffer[A]] with IndexedSeqOptimized[A, ArrayBuffer[A]] diff --git a/src/library/scala/collection/mutable/ArrayLike.scala b/src/library/scala/collection/mutable/ArrayLike.scala index 62f2620498..23d36252d2 100644 --- a/src/library/scala/collection/mutable/ArrayLike.scala +++ b/src/library/scala/collection/mutable/ArrayLike.scala @@ -38,7 +38,7 @@ trait ArrayLike[A, +Repr] extends IndexedSeqOptimized[A, Repr] { self => * * @return An possibly nested indexed sequence of consisting of all the elements of the array. */ - def deep: scala.collection.IndexedSeq[Any] = new scala.collection.IndexedSeq[Any] { + def deep: scala.collection.IndexedSeq[Any] = new scala.collection.AbstractSeq[Any] with scala.collection.IndexedSeq[Any] { def length = self.length def apply(idx: Int): Any = self.apply(idx) match { case x: AnyRef if x.getClass.isArray => WrappedArray.make(x).deep diff --git a/src/library/scala/collection/mutable/ArraySeq.scala b/src/library/scala/collection/mutable/ArraySeq.scala index 0d6aac3549..414d80b462 100644 --- a/src/library/scala/collection/mutable/ArraySeq.scala +++ b/src/library/scala/collection/mutable/ArraySeq.scala @@ -41,7 +41,8 @@ import parallel.mutable.ParArray */ @SerialVersionUID(1530165946227428979L) class ArraySeq[A](override val length: Int) -extends IndexedSeq[A] +extends AbstractSeq[A] + with IndexedSeq[A] with GenericTraversableTemplate[A, ArraySeq] with IndexedSeqOptimized[A, ArraySeq[A]] with CustomParallelizable[A, ParArray[A]] diff --git a/src/library/scala/collection/mutable/ArrayStack.scala b/src/library/scala/collection/mutable/ArrayStack.scala index d33ca03fbe..c46955477b 100644 --- a/src/library/scala/collection/mutable/ArrayStack.scala +++ b/src/library/scala/collection/mutable/ArrayStack.scala @@ -59,7 +59,8 @@ object ArrayStack extends SeqFactory[ArrayStack] { @cloneable @SerialVersionUID(8565219180626620510L) class ArrayStack[T] private(private var table : Array[AnyRef], private var index : Int) -extends Seq[T] +extends AbstractSeq[T] + with Seq[T] with SeqLike[T, ArrayStack[T]] with GenericTraversableTemplate[T, ArrayStack] with Cloneable[ArrayStack[T]] @@ -219,7 +220,7 @@ extends Seq[T] /** Creates and iterator over the stack in LIFO order. * @return an iterator over the elements of the stack. */ - def iterator: Iterator[T] = new Iterator[T] { + def iterator: Iterator[T] = new AbstractIterator[T] { var currentIndex = index def hasNext = currentIndex > 0 def next() = { diff --git a/src/library/scala/collection/mutable/BitSet.scala b/src/library/scala/collection/mutable/BitSet.scala index a547e8a17e..0cff9f970f 100644 --- a/src/library/scala/collection/mutable/BitSet.scala +++ b/src/library/scala/collection/mutable/BitSet.scala @@ -33,7 +33,8 @@ import BitSetLike.{LogWL, updateArray} * @define willNotTerminateInf */ @SerialVersionUID(8483111450368547763L) -class BitSet(protected var elems: Array[Long]) extends Set[Int] +class BitSet(protected var elems: Array[Long]) extends AbstractSet[Int] + with Set[Int] with scala.collection.BitSet with BitSetLike[BitSet] with SetLike[Int, BitSet] diff --git a/src/library/scala/collection/mutable/Buffer.scala b/src/library/scala/collection/mutable/Buffer.scala index 4ced60c44d..7326d5ec5b 100644 --- a/src/library/scala/collection/mutable/Buffer.scala +++ b/src/library/scala/collection/mutable/Buffer.scala @@ -44,3 +44,5 @@ object Buffer extends SeqFactory[Buffer] { def newBuilder[A]: Builder[A, Buffer[A]] = new ArrayBuffer } +/** Explicit instantiation of the `Buffer` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractBuffer[A] extends AbstractSeq[A] with Buffer[A] diff --git a/src/library/scala/collection/mutable/DoubleLinkedList.scala b/src/library/scala/collection/mutable/DoubleLinkedList.scala index 24c2306e30..dd111b3800 100644 --- a/src/library/scala/collection/mutable/DoubleLinkedList.scala +++ b/src/library/scala/collection/mutable/DoubleLinkedList.scala @@ -38,7 +38,8 @@ import generic._ * @define willNotTerminateInf */ @SerialVersionUID(-8144992287952814767L) -class DoubleLinkedList[A]() extends LinearSeq[A] +class DoubleLinkedList[A]() extends AbstractSeq[A] + with LinearSeq[A] with GenericTraversableTemplate[A, DoubleLinkedList] with DoubleLinkedListLike[A, DoubleLinkedList[A]] with Serializable { diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala index 0b8ca66c55..0740d97e09 100644 --- a/src/library/scala/collection/mutable/FlatHashTable.scala +++ b/src/library/scala/collection/mutable/FlatHashTable.scala @@ -169,7 +169,7 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] { None } - def iterator = new Iterator[A] { + def iterator: Iterator[A] = new AbstractIterator[A] { private var i = 0 def hasNext: Boolean = { while (i < table.length && (null == table(i))) i += 1 diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala index 98ece514f7..c86ee39256 100644 --- a/src/library/scala/collection/mutable/HashMap.scala +++ b/src/library/scala/collection/mutable/HashMap.scala @@ -35,7 +35,8 @@ import scala.collection.parallel.mutable.ParHashMap */ @SerialVersionUID(1L) class HashMap[A, B] private[collection] (contents: HashTable.Contents[A, DefaultEntry[A, B]]) -extends Map[A, B] +extends AbstractMap[A, B] + with Map[A, B] with MapLike[A, B, HashMap[A, B]] with HashTable[A, DefaultEntry[A, B]] with CustomParallelizable[(A, B), ParHashMap[A, B]] @@ -105,14 +106,14 @@ extends Map[A, B] } /* Override to avoid tuple allocation */ - override def keysIterator: Iterator[A] = new Iterator[A] { + override def keysIterator: Iterator[A] = new AbstractIterator[A] { val iter = entriesIterator def hasNext = iter.hasNext def next() = iter.next.key } /* Override to avoid tuple allocation */ - override def valuesIterator: Iterator[B] = new Iterator[B] { + override def valuesIterator: Iterator[B] = new AbstractIterator[B] { val iter = entriesIterator def hasNext = iter.hasNext def next() = iter.next.value diff --git a/src/library/scala/collection/mutable/HashSet.scala b/src/library/scala/collection/mutable/HashSet.scala index 853becbf43..6a6964609c 100644 --- a/src/library/scala/collection/mutable/HashSet.scala +++ b/src/library/scala/collection/mutable/HashSet.scala @@ -37,7 +37,8 @@ import collection.parallel.mutable.ParHashSet */ @SerialVersionUID(1L) class HashSet[A] private[collection] (contents: FlatHashTable.Contents[A]) -extends Set[A] +extends AbstractSet[A] + with Set[A] with GenericSetTemplate[A, HashSet] with SetLike[A, HashSet[A]] with FlatHashTable[A] diff --git a/src/library/scala/collection/mutable/HashTable.scala b/src/library/scala/collection/mutable/HashTable.scala index ffde88575a..cdf1b78f29 100644 --- a/src/library/scala/collection/mutable/HashTable.scala +++ b/src/library/scala/collection/mutable/HashTable.scala @@ -162,7 +162,7 @@ trait HashTable[A, Entry >: Null <: HashEntry[A, Entry]] extends HashTable.HashU /** An iterator returning all entries. */ - protected def entriesIterator: Iterator[Entry] = new Iterator[Entry] { + protected def entriesIterator: Iterator[Entry] = new AbstractIterator[Entry] { val iterTable = table var idx = lastPopulatedIndex var es = iterTable(idx) diff --git a/src/library/scala/collection/mutable/History.scala b/src/library/scala/collection/mutable/History.scala index bc61a6189e..0c3b762bd9 100644 --- a/src/library/scala/collection/mutable/History.scala +++ b/src/library/scala/collection/mutable/History.scala @@ -25,7 +25,7 @@ package mutable * @tparam Pub Type of publishers. */ @SerialVersionUID(5219213543849892588L) -class History[Evt, Pub] extends Subscriber[Evt, Pub] with Iterable[(Pub, Evt)] with Serializable +class History[Evt, Pub] extends AbstractIterable[(Pub, Evt)] with Subscriber[Evt, Pub] with Serializable { protected val log: Queue[(Pub, Evt)] = new Queue val maxHistory: Int = 1000 diff --git a/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala b/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala index c2fca46a8b..32fca1117c 100644 --- a/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala +++ b/src/library/scala/collection/mutable/ImmutableMapAdaptor.scala @@ -25,7 +25,9 @@ import annotation.migration * @since 1 */ class ImmutableMapAdaptor[A, B](protected var imap: immutable.Map[A, B]) -extends Map[A, B] with Serializable +extends AbstractMap[A, B] + with Map[A, B] + with Serializable { override def size: Int = imap.size diff --git a/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala b/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala index c44b77a9c4..f98a3ef1ed 100644 --- a/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala +++ b/src/library/scala/collection/mutable/ImmutableSetAdaptor.scala @@ -22,7 +22,10 @@ package mutable * @version 1.0, 21/07/2003 * @since 1 */ -class ImmutableSetAdaptor[A](protected var set: immutable.Set[A]) extends Set[A] with Serializable { +class ImmutableSetAdaptor[A](protected var set: immutable.Set[A]) +extends AbstractSet[A] + with Set[A] + with Serializable { override def size: Int = set.size diff --git a/src/library/scala/collection/mutable/IndexedSeqView.scala b/src/library/scala/collection/mutable/IndexedSeqView.scala index f13a6bb70a..593af92255 100644 --- a/src/library/scala/collection/mutable/IndexedSeqView.scala +++ b/src/library/scala/collection/mutable/IndexedSeqView.scala @@ -41,6 +41,9 @@ self => override def toString = viewToString } + /** Explicit instantiation of the `Transformed` trait to reduce class file size in subclasses. */ + private[collection] abstract class AbstractTransformed[B] extends super.AbstractTransformed[B] with Transformed[B] + // pre: until <= self.length trait Sliced extends super.Sliced with Transformed[A] { override def length = endpoints.width @@ -72,11 +75,11 @@ self => /** Boilerplate method, to override in each subclass * This method could be eliminated if Scala had virtual classes */ - protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with Filtered - protected override def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with Sliced - protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with DroppedWhile - protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with TakenWhile - protected override def newReversed: Transformed[A] = new Reversed { } + protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered + protected override def newSliced(_endpoints: SliceInterval): Transformed[A] = new { val endpoints = _endpoints } with AbstractTransformed[A] with Sliced + protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with DroppedWhile + protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with TakenWhile + protected override def newReversed: Transformed[A] = new AbstractTransformed[A] with Reversed private implicit def asThis(xs: Transformed[A]): This = xs.asInstanceOf[This] diff --git a/src/library/scala/collection/mutable/Iterable.scala b/src/library/scala/collection/mutable/Iterable.scala index f20179a2d9..54fe11f98c 100644 --- a/src/library/scala/collection/mutable/Iterable.scala +++ b/src/library/scala/collection/mutable/Iterable.scala @@ -36,3 +36,5 @@ object Iterable extends TraversableFactory[Iterable] { def newBuilder[A]: Builder[A, Iterable[A]] = new ArrayBuffer } +/** Explicit instantiation of the `Iterable` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractIterable[A] extends scala.collection.AbstractIterable[A] with Iterable[A] diff --git a/src/library/scala/collection/mutable/LinkedHashMap.scala b/src/library/scala/collection/mutable/LinkedHashMap.scala index 31f539cc09..e4090637ec 100644 --- a/src/library/scala/collection/mutable/LinkedHashMap.scala +++ b/src/library/scala/collection/mutable/LinkedHashMap.scala @@ -45,7 +45,8 @@ object LinkedHashMap extends MutableMapFactory[LinkedHashMap] { * @define orderDependentFold */ @SerialVersionUID(1L) -class LinkedHashMap[A, B] extends Map[A, B] +class LinkedHashMap[A, B] extends AbstractMap[A, B] + with Map[A, B] with MapLike[A, B, LinkedHashMap[A, B]] with HashTable[A, LinkedEntry[A, B]] with Serializable { @@ -99,7 +100,7 @@ class LinkedHashMap[A, B] extends Map[A, B] def += (kv: (A, B)): this.type = { put(kv._1, kv._2); this } def -=(key: A): this.type = { remove(key); this } - def iterator: Iterator[(A, B)] = new Iterator[(A, B)] { + def iterator: Iterator[(A, B)] = new AbstractIterator[(A, B)] { private var cur = firstEntry def hasNext = cur ne null def next = @@ -107,7 +108,7 @@ class LinkedHashMap[A, B] extends Map[A, B] else Iterator.empty.next } - override def keysIterator: Iterator[A] = new Iterator[A] { + override def keysIterator: Iterator[A] = new AbstractIterator[A] { private var cur = firstEntry def hasNext = cur ne null def next = @@ -115,7 +116,7 @@ class LinkedHashMap[A, B] extends Map[A, B] else Iterator.empty.next } - override def valuesIterator: Iterator[B] = new Iterator[B] { + override def valuesIterator: Iterator[B] = new AbstractIterator[B] { private var cur = firstEntry def hasNext = cur ne null def next = diff --git a/src/library/scala/collection/mutable/LinkedHashSet.scala b/src/library/scala/collection/mutable/LinkedHashSet.scala index 7a1e695f32..f6d4915fef 100644 --- a/src/library/scala/collection/mutable/LinkedHashSet.scala +++ b/src/library/scala/collection/mutable/LinkedHashSet.scala @@ -39,7 +39,8 @@ import generic._ * @define orderDependentFold */ @SerialVersionUID(1L) -class LinkedHashSet[A] extends Set[A] +class LinkedHashSet[A] extends AbstractSet[A] + with Set[A] with GenericSetTemplate[A, LinkedHashSet] with SetLike[A, LinkedHashSet[A]] with FlatHashTable[A] diff --git a/src/library/scala/collection/mutable/LinkedList.scala b/src/library/scala/collection/mutable/LinkedList.scala index 6c4372cbb4..65391f5884 100644 --- a/src/library/scala/collection/mutable/LinkedList.scala +++ b/src/library/scala/collection/mutable/LinkedList.scala @@ -73,7 +73,8 @@ import generic._ * }}} */ @SerialVersionUID(-7308240733518833071L) -class LinkedList[A]() extends LinearSeq[A] +class LinkedList[A]() extends AbstractSeq[A] + with LinearSeq[A] with GenericTraversableTemplate[A, LinkedList] with LinkedListLike[A, LinkedList[A]] with Serializable { diff --git a/src/library/scala/collection/mutable/LinkedListLike.scala b/src/library/scala/collection/mutable/LinkedListLike.scala index 0f977c0a17..ebec31ca98 100644 --- a/src/library/scala/collection/mutable/LinkedListLike.scala +++ b/src/library/scala/collection/mutable/LinkedListLike.scala @@ -163,7 +163,7 @@ trait LinkedListLike[A, This <: Seq[A] with LinkedListLike[A, This]] extends Seq else None } - override def iterator: Iterator[A] = new Iterator[A] { + override def iterator: Iterator[A] = new AbstractIterator[A] { var elems = self def hasNext = elems.nonEmpty def next = { diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala index b55cad8fbb..233544c4ca 100644 --- a/src/library/scala/collection/mutable/ListBuffer.scala +++ b/src/library/scala/collection/mutable/ListBuffer.scala @@ -40,7 +40,8 @@ import immutable.{List, Nil, ::} */ @SerialVersionUID(3419063961353022661L) final class ListBuffer[A] - extends Buffer[A] + extends AbstractBuffer[A] + with Buffer[A] with GenericTraversableTemplate[A, ListBuffer] with BufferLike[A, ListBuffer[A]] with Builder[A, List[A]] @@ -316,7 +317,7 @@ final class ListBuffer[A] this } - override def iterator: Iterator[A] = new Iterator[A] { + override def iterator: Iterator[A] = new AbstractIterator[A] { // Have to be careful iterating over mutable structures. // This used to have "(cursor ne last0)" as part of its hasNext // condition, which means it can return true even when the iterator diff --git a/src/library/scala/collection/mutable/ListMap.scala b/src/library/scala/collection/mutable/ListMap.scala index c02593fdf3..d8d60d1c9a 100644 --- a/src/library/scala/collection/mutable/ListMap.scala +++ b/src/library/scala/collection/mutable/ListMap.scala @@ -34,8 +34,11 @@ import generic._ * @define orderDependent * @define orderDependentFold */ -class ListMap[A, B] extends Map[A, B] with MapLike[A, B, ListMap[A, B]] with Serializable { - +class ListMap[A, B] +extends AbstractMap[A, B] + with Map[A, B] + with MapLike[A, B, ListMap[A, B]] + with Serializable { override def empty = ListMap.empty[A, B] diff --git a/src/library/scala/collection/mutable/Map.scala b/src/library/scala/collection/mutable/Map.scala index 561dcc9399..0d40a1c70d 100644 --- a/src/library/scala/collection/mutable/Map.scala +++ b/src/library/scala/collection/mutable/Map.scala @@ -86,3 +86,6 @@ object Map extends MutableMapFactory[Map] { override def withDefaultValue(d: B): mutable.Map[A, B] = new WithDefault[A, B](underlying, x => d) } } + +/** Explicit instantiation of the `Map` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractMap[A, B] extends scala.collection.AbstractMap[A, B] with Map[A, B] diff --git a/src/library/scala/collection/mutable/MutableList.scala b/src/library/scala/collection/mutable/MutableList.scala index b7eab5c2a9..20910e48f4 100644 --- a/src/library/scala/collection/mutable/MutableList.scala +++ b/src/library/scala/collection/mutable/MutableList.scala @@ -26,7 +26,8 @@ import immutable.{List, Nil} */ @SerialVersionUID(5938451523372603072L) class MutableList[A] -extends LinearSeq[A] +extends AbstractSeq[A] + with LinearSeq[A] with LinearSeqOptimized[A, MutableList[A]] with GenericTraversableTemplate[A, MutableList] with Builder[A, MutableList[A]] diff --git a/src/library/scala/collection/mutable/OpenHashMap.scala b/src/library/scala/collection/mutable/OpenHashMap.scala index a9bd0b0b1c..87e5c061fa 100644 --- a/src/library/scala/collection/mutable/OpenHashMap.scala +++ b/src/library/scala/collection/mutable/OpenHashMap.scala @@ -48,7 +48,8 @@ object OpenHashMap { * @define willNotTerminateInf */ class OpenHashMap[Key, Value](initialSize : Int) -extends Map[Key, Value] +extends AbstractMap[Key, Value] + with Map[Key, Value] with MapLike[Key, Value, OpenHashMap[Key, Value]] { import OpenHashMap.OpenEntry @@ -175,7 +176,7 @@ extends Map[Key, Value] * * @return the iterator */ - def iterator = new Iterator[(Key, Value)]{ + def iterator: Iterator[(Key, Value)] = new AbstractIterator[(Key, Value)] { var index = 0 val initialModCount = modCount diff --git a/src/library/scala/collection/mutable/PriorityQueue.scala b/src/library/scala/collection/mutable/PriorityQueue.scala index 469d2de495..23a68c1d3e 100644 --- a/src/library/scala/collection/mutable/PriorityQueue.scala +++ b/src/library/scala/collection/mutable/PriorityQueue.scala @@ -34,7 +34,8 @@ import annotation.{migration, bridge} */ @cloneable class PriorityQueue[A](implicit val ord: Ordering[A]) - extends Iterable[A] + extends AbstractIterable[A] + with Iterable[A] with GenericOrderedTraversableTemplate[A, PriorityQueue] with IterableLike[A, PriorityQueue[A]] with Growable[A] @@ -43,7 +44,7 @@ class PriorityQueue[A](implicit val ord: Ordering[A]) { import ord._ - private final class ResizableArrayAccess[A] extends ResizableArray[A] { + private final class ResizableArrayAccess[A] extends AbstractSeq[A] with ResizableArray[A] { @inline def p_size0 = size0 @inline def p_size0_=(s: Int) = size0 = s @inline def p_array = array @@ -169,7 +170,7 @@ class PriorityQueue[A](implicit val ord: Ordering[A]) * * @return an iterator over all elements sorted in descending order. */ - override def iterator: Iterator[A] = new Iterator[A] { + override def iterator: Iterator[A] = new AbstractIterator[A] { private var i = 1 def hasNext: Boolean = i < resarr.p_size0 def next(): A = { @@ -201,7 +202,7 @@ class PriorityQueue[A](implicit val ord: Ordering[A]) revq } - def reverseIterator = new Iterator[A] { + def reverseIterator: Iterator[A] = new AbstractIterator[A] { private var i = resarr.p_size0 - 1 def hasNext: Boolean = i >= 1 def next(): A = { diff --git a/src/library/scala/collection/mutable/Seq.scala b/src/library/scala/collection/mutable/Seq.scala index d876824ec2..89b930e36f 100644 --- a/src/library/scala/collection/mutable/Seq.scala +++ b/src/library/scala/collection/mutable/Seq.scala @@ -42,3 +42,6 @@ object Seq extends SeqFactory[Seq] { implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]] def newBuilder[A]: Builder[A, Seq[A]] = new ArrayBuffer } + +/** Explicit instantiation of the `Seq` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractSeq[A] extends scala.collection.AbstractSeq[A] with Seq[A] diff --git a/src/library/scala/collection/mutable/Set.scala b/src/library/scala/collection/mutable/Set.scala index 30fc3682fd..744768e8dd 100644 --- a/src/library/scala/collection/mutable/Set.scala +++ b/src/library/scala/collection/mutable/Set.scala @@ -41,3 +41,5 @@ object Set extends MutableSetFactory[Set] { override def empty[A]: Set[A] = HashSet.empty[A] } +/** Explicit instantiation of the `Set` trait to reduce class file size in subclasses. */ +private[scala] abstract class AbstractSet[A] extends AbstractIterable[A] with Set[A] diff --git a/src/library/scala/collection/mutable/Stack.scala b/src/library/scala/collection/mutable/Stack.scala index bd180fc0b4..c795609b67 100644 --- a/src/library/scala/collection/mutable/Stack.scala +++ b/src/library/scala/collection/mutable/Stack.scala @@ -53,7 +53,8 @@ object Stack extends SeqFactory[Stack] { */ @cloneable class Stack[A] private (var elems: List[A]) -extends Seq[A] +extends AbstractSeq[A] + with Seq[A] with SeqLike[A, Stack[A]] with GenericTraversableTemplate[A, Stack] with Cloneable[Stack[A]] diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala index 2cfab4713c..6fb4b839ef 100644 --- a/src/library/scala/collection/mutable/StringBuilder.scala +++ b/src/library/scala/collection/mutable/StringBuilder.scala @@ -24,7 +24,8 @@ import immutable.StringLike */ @SerialVersionUID(0 - 8525408645367278351L) final class StringBuilder(private val underlying: JavaStringBuilder) - extends java.lang.CharSequence + extends AbstractSeq[Char] + with java.lang.CharSequence with IndexedSeq[Char] with StringLike[StringBuilder] with Builder[Char, String] diff --git a/src/library/scala/collection/mutable/UnrolledBuffer.scala b/src/library/scala/collection/mutable/UnrolledBuffer.scala index d4185b736d..09e6088782 100644 --- a/src/library/scala/collection/mutable/UnrolledBuffer.scala +++ b/src/library/scala/collection/mutable/UnrolledBuffer.scala @@ -8,6 +8,7 @@ package scala.collection.mutable +import collection.AbstractIterator import collection.Iterator import collection.generic._ import annotation.tailrec @@ -41,7 +42,8 @@ import annotation.tailrec */ @SerialVersionUID(1L) class UnrolledBuffer[T](implicit val manifest: ClassManifest[T]) -extends collection.mutable.Buffer[T] +extends collection.mutable.AbstractBuffer[T] + with collection.mutable.Buffer[T] with collection.mutable.BufferLike[T, UnrolledBuffer[T]] with GenericClassManifestTraversableTemplate[T, UnrolledBuffer] with collection.mutable.Builder[T, UnrolledBuffer[T]] @@ -102,7 +104,7 @@ extends collection.mutable.Buffer[T] sz = 0 } - def iterator = new Iterator[T] { + def iterator: Iterator[T] = new AbstractIterator[T] { var pos: Int = -1 var node: Unrolled[T] = headptr scan() diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 21e62306e7..4287bac249 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -31,7 +31,8 @@ import scala.collection.parallel.mutable.ParArray * @define willNotTerminateInf */ abstract class WrappedArray[T] -extends IndexedSeq[T] +extends AbstractSeq[T] + with IndexedSeq[T] with ArrayLike[T, WrappedArray[T]] with CustomParallelizable[T, ParArray[T]] { |