From 17f712ec18b4f6f4fac43f146b66c749ed68caa7 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 23 Dec 2009 17:57:36 +0000 Subject: Created team of private[collection] abstract cl... Created team of private[collection] abstract classes and traits in scala.collection.views. Factored boilerplate and base Transformed traits out of *ViewLike classes. Executive summary and motivation: 4812029 Dec 23 09:47 scala-library.jar // before 4604150 Dec 23 09:24 scala-library.jar // after Direct size savings of 4.5%. Review by odersky. --- .../scala/collection/IndexedSeqViewLike.scala | 70 +++-------- .../scala/collection/IterableViewLike.scala | 28 +---- src/library/scala/collection/SeqViewLike.scala | 26 +---- .../scala/collection/TraversableViewLike.scala | 23 ++-- .../scala/collection/mutable/IndexedSeqView.scala | 5 +- .../scala/collection/views/Transformed.scala | 128 +++++++++++++++++++++ 6 files changed, 163 insertions(+), 117 deletions(-) create mode 100644 src/library/scala/collection/views/Transformed.scala (limited to 'src') diff --git a/src/library/scala/collection/IndexedSeqViewLike.scala b/src/library/scala/collection/IndexedSeqViewLike.scala index b27383424f..06fa6c8953 100644 --- a/src/library/scala/collection/IndexedSeqViewLike.scala +++ b/src/library/scala/collection/IndexedSeqViewLike.scala @@ -24,47 +24,24 @@ import TraversableView.NoBuilder trait IndexedSeqViewLike[+A, +Coll, +This <: IndexedSeqView[A, Coll] with IndexedSeqViewLike[A, Coll, This]] - extends IndexedSeq[A] with IndexedSeqLike[A, This] with SeqView[A, Coll] with SeqViewLike[A, Coll, This] + extends IndexedSeq[A] + with IndexedSeqLike[A, This] + with SeqView[A, Coll] + with SeqViewLike[A, Coll, This] + with views.IndexedSeqTransformations[A, Coll, This] { self => - trait Transformed[+B] extends IndexedSeqView[B, Coll] with super.Transformed[B] + trait Transformed[+B] extends views.IndexedSeqLike[B, Coll] with super.Transformed[B] - trait Sliced extends Transformed[A] with super.Sliced { - /** Override to use IndexedSeq's foreach; todo: see whether this is really faster */ - override def foreach[U](f: A => U) = super[Transformed].foreach(f) - } - - trait Mapped[B] extends Transformed[B] with super.Mapped[B] { - override def foreach[U](f: B => U) = super[Transformed].foreach(f) - } - - trait FlatMapped[B] extends Transformed[B] with super.FlatMapped[B] { - override def foreach[U](f: B => U) = super[Transformed].foreach(f) - } - - trait Appended[B >: A] extends Transformed[B] with super.Appended[B] { - override def foreach[U](f: B => U) = super[Transformed].foreach(f) - } - - trait Filtered extends Transformed[A] with super.Filtered { - override def foreach[U](f: A => U) = super[Transformed].foreach(f) - } - - trait TakenWhile extends Transformed[A] with super.TakenWhile { - override def foreach[U](f: A => U) = super[Transformed].foreach(f) - } - - trait DroppedWhile extends Transformed[A] with super.DroppedWhile { - override def foreach[U](f: A => U) = super[Transformed].foreach(f) - } - - trait Reversed extends Transformed[A] with super.Reversed { - override def foreach[U](f: A => U) = super[Transformed].foreach(f) - } - - trait Patched[B >: A] extends Transformed[B] with super.Patched[B] { - override def foreach[U](f: B => U) = super[Transformed].foreach(f) - } + trait Sliced extends Transformed[A] with super.Sliced + trait Mapped[B] extends Transformed[B] with super.Mapped[B] + trait FlatMapped[B] extends Transformed[B] with super.FlatMapped[B] + trait Appended[B >: A] extends Transformed[B] with super.Appended[B] + trait Filtered extends Transformed[A] with super.Filtered + trait TakenWhile extends Transformed[A] with super.TakenWhile + trait DroppedWhile extends Transformed[A] with super.DroppedWhile + trait Reversed extends Transformed[A] with super.Reversed + trait Patched[B >: A] extends Transformed[B] with super.Patched[B] trait Zipped[B] extends Transformed[(A, B)] { protected[this] val other: Iterable[B] @@ -88,22 +65,5 @@ trait IndexedSeqViewLike[+A, } override def stringPrefix = self.stringPrefix+"Z" } - - /** Boilerplate method, to override in each subclass - * This method could be eliminated if Scala had virtual classes - */ - protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } - protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } - protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } - protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } - protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } - protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } - protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p } - protected override def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { val other = that } - protected override def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new ZippedAll[A1, B] { val other = that; val thisElem = _thisElem; val thatElem = _thatElem } - protected override def newReversed: Transformed[A] = new Reversed { } - protected override def newPatched[B >: A](_from: Int, _patch: Seq[B], _replaced: Int): Transformed[B] = new Patched[B] { - val from = _from; val patch = _patch; val replaced = _replaced - } override def stringPrefix = "IndexedSeqView" } diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala index 27323294c4..831a244352 100644 --- a/src/library/scala/collection/IterableViewLike.scala +++ b/src/library/scala/collection/IterableViewLike.scala @@ -24,10 +24,14 @@ import TraversableView.NoBuilder trait IterableViewLike[+A, +Coll, +This <: IterableView[A, Coll] with IterableViewLike[A, Coll, This]] -extends Iterable[A] with IterableLike[A, This] with TraversableView[A, Coll] with TraversableViewLike[A, Coll, This] + extends Iterable[A] + with IterableLike[A, This] + with TraversableView[A, Coll] + with TraversableViewLike[A, Coll, This] + with views.IterableTransformations[A, Coll, This] { self => - trait Transformed[+B] extends IterableView[B, Coll] with super.Transformed[B] + trait Transformed[+B] extends views.IterableLike[B, Coll] with super.Transformed[B] trait Sliced extends Transformed[A] with super.Sliced { override def iterator = self.iterator slice (from, until) @@ -84,25 +88,5 @@ extends Iterable[A] with IterableLike[A, This] with TraversableView[A, Coll] wit override def zipAll[B, A1 >: A, That](that: Iterable[B], thisElem: A1, thatElem: B)(implicit bf: CanBuildFrom[This, (A1, B), That]): That = newZippedAll(that, thisElem, thatElem).asInstanceOf[That] - protected def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { - val other = that - } - protected def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new ZippedAll[A1, B] { - val other: Iterable[B] = that - val thisElem = _thisElem - val thatElem = _thatElem - } - - /** Boilerplate method, to override in each subclass - * This method could be eliminated if Scala had virtual classes - */ - protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } - protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } - protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } - protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } - protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } - protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } - protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p } - override def stringPrefix = "IterableView" } diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala index 1a8cd20013..6f677616e7 100644 --- a/src/library/scala/collection/SeqViewLike.scala +++ b/src/library/scala/collection/SeqViewLike.scala @@ -23,13 +23,14 @@ import TraversableView.NoBuilder trait SeqViewLike[+A, +Coll, +This <: SeqView[A, Coll] with SeqViewLike[A, Coll, This]] - extends Seq[A] with SeqLike[A, This] with IterableView[A, Coll] with IterableViewLike[A, Coll, This] + extends Seq[A] + with SeqLike[A, This] + with IterableView[A, Coll] + with IterableViewLike[A, Coll, This] + with views.SeqTransformations[A, Coll, This] { self => - trait Transformed[+B] extends SeqView[B, Coll] with super.Transformed[B] { - override def length: Int - override def apply(idx: Int): B - } + trait Transformed[+B] extends views.SeqLike[B, Coll] with super.Transformed[B] trait Sliced extends Transformed[A] with super.Sliced { override def length = ((until min self.length) - from) max 0 @@ -143,21 +144,6 @@ trait SeqViewLike[+A, override def stringPrefix = self.stringPrefix+"P" } - /** Boilerplate method, to override in each subclass - * This method could be eliminated if Scala had virtual classes - */ - protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } - protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } - protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } - protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } - protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } - protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } - protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p } - protected override def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { val other = that } - protected override def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new ZippedAll[A1, B] { val other = that; val thisElem = _thisElem; val thatElem = _thatElem } - protected def newReversed: Transformed[A] = new Reversed { } - protected def newPatched[B >: A](_from: Int, _patch: Seq[B], _replaced: Int): Transformed[B] = new Patched[B] { val from = _from; val patch = _patch; val replaced = _replaced } - override def reverse: This = newReversed.asInstanceOf[This] override def patch[B >: A, That](from: Int, patch: Seq[B], replaced: Int)(implicit bf: CanBuildFrom[This, B, That]): That = { diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index 84c33296db..7f4d0ebd71 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -33,7 +33,9 @@ import TraversableView.NoBuilder trait TraversableViewLike[+A, +Coll, +This <: TraversableView[A, Coll] with TraversableViewLike[A, Coll, This]] - extends Traversable[A] with TraversableLike[A, This] { + extends Traversable[A] + with TraversableLike[A, This] + with views.TraversableTransformations[A, Coll, This] { self => override protected[this] def newBuilder: Builder[A, This] = @@ -41,16 +43,16 @@ self => protected def underlying: Coll + trait Transformed[+B] extends views.TraversableLike[B, Coll] { + lazy val underlying = self.underlying + } + def force[B >: A, That](implicit bf: CanBuildFrom[Coll, B, That]) = { val b = bf(underlying) b ++= this b.result() } - trait Transformed[+B] extends TraversableView[B, Coll] { - lazy val underlying = self.underlying - } - /** pre: from >= 0 */ trait Sliced extends Transformed[A] { @@ -131,17 +133,6 @@ self => override def stringPrefix = self.stringPrefix+"D" } - /** Boilerplate method, to override in each subclass - * This method could be eliminated if Scala had virtual classes - */ - protected def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } - protected def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } - protected def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } - protected def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } - protected def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } - protected def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } - protected def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p } - override def ++[B >: A, That](that: Traversable[B])(implicit bf: CanBuildFrom[This, B, That]): That = { newAppended(that).asInstanceOf[That] // was: if (bf.isInstanceOf[ByPassCanBuildFrom]) newAppended(that).asInstanceOf[That] diff --git a/src/library/scala/collection/mutable/IndexedSeqView.scala b/src/library/scala/collection/mutable/IndexedSeqView.scala index e864845455..db1735b543 100644 --- a/src/library/scala/collection/mutable/IndexedSeqView.scala +++ b/src/library/scala/collection/mutable/IndexedSeqView.scala @@ -13,7 +13,6 @@ package scala.collection package mutable import generic._ - import TraversableView.NoBuilder /** A non-strict view of a mutable IndexedSeq. @@ -30,9 +29,7 @@ self => def update(idx: Int, elem: A) - trait Transformed[B] extends IndexedSeqView[B, Coll] with super.Transformed[B] { - def update(idx: Int, elem: B) - } + trait Transformed[B] extends views.MutableIndexedSeq[B, Coll] with IndexedSeqView[B, Coll] with super.Transformed[B] trait Sliced extends Transformed[A] with super.Sliced { override def update(idx: Int, elem: A) = diff --git a/src/library/scala/collection/views/Transformed.scala b/src/library/scala/collection/views/Transformed.scala new file mode 100644 index 0000000000..189ca127c8 --- /dev/null +++ b/src/library/scala/collection/views/Transformed.scala @@ -0,0 +1,128 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2010, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.collection +package views + +import generic.CanBuildFrom + +/** These classes act as accumulators for the majority of methods in the + * collections hierarchy. By creating abstract classes rather than using + * the traits exclusively, we avoid creating forwarders in dozens of distinct + * anonymous classes and reduce the size of scala-library.jar by over 200K. + */ +private[collection] trait Transformed +private[collection] abstract class TraversableLike[+B, +Coll] extends TraversableView[B, Coll] with Transformed { + override def foreach[C](f: B => C): Unit +} +private[collection] abstract class IterableLike[+B, +Coll] extends TraversableLike[B, Coll] with IterableView[B, Coll] { + override def iterator: Iterator[B] +} +private[collection] abstract class SeqLike[+B, +Coll] extends IterableLike[B, Coll] with SeqView[B, Coll] { + override def length: Int + override def apply(idx: Int): B +} +private[collection] abstract class IndexedSeqLike[+B, +Coll] extends SeqLike[B, Coll] with IndexedSeqView[B, Coll] { + /** Override to use IndexedSeq's foreach; todo: see whether this is really faster */ + override def foreach[U](f: B => U) = super[IndexedSeqView].foreach(f) +} +private[collection] abstract class MutableIndexedSeq[B, +Coll] extends IndexedSeqLike[B, Coll] { + def update(idx: Int, elem: B) +} + +/** The boilerplate in the following traits factored out of the *ViewLike classes + * to reduce noise. It exists only to specialize the return type of each method. + * It would be unnecessary if scala had virtual classes because the inner classes + * of subtraits would subclass the parent trait inner classes, and the same method + * would then suffice for both. + */ +private[collection] trait TraversableTransformations[+A, +Coll, +This <: TraversableView[A, Coll] with TraversableViewLike[A, Coll, This]] { + self: TraversableViewLike[A, Coll, This] => + + /** Boilerplate methods, to override in each subclass. */ + protected def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } + protected def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } + protected def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } + protected def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } + protected def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } + protected def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } + protected def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p } +} + +private[collection] trait IterableTransformations[+A, +Coll, +This <: IterableView[A, Coll] with IterableViewLike[A, Coll, This]] + extends TraversableTransformations[A, Coll, This] +{ + self: IterableViewLike[A, Coll, This] => + + /** Inherited from TraversableView */ + protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } + protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } + protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } + protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } + protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } + protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } + protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p } + + /** IterableView boilerplate contribution */ + protected def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { + val other = that + } + protected def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = new ZippedAll[A1, B] { + val other: Iterable[B] = that + val thisElem = _thisElem + val thatElem = _thatElem + } +} + +private[collection] trait SeqTransformations[+A, +Coll, +This <: SeqView[A, Coll] with SeqViewLike[A, Coll, This]] + extends IterableTransformations[A, Coll, This] +{ + self: SeqViewLike[A, Coll, This] => + + /** Inherited from IterableView */ + protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } + protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } + protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } + protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } + protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } + protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } + protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p } + protected override def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { val other = that } + protected override def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = + new ZippedAll[A1, B] { val other = that; val thisElem = _thisElem; val thatElem = _thatElem } + + /** SeqView boilerplate contribution */ + protected def newReversed: Transformed[A] = new Reversed { } + protected def newPatched[B >: A](_from: Int, _patch: Seq[B], _replaced: Int): Transformed[B] = + new Patched[B] { val from = _from; val patch = _patch; val replaced = _replaced } +} + +private[collection] trait IndexedSeqTransformations[+A, +Coll, +This <: IndexedSeqView[A, Coll] with IndexedSeqViewLike[A, Coll, This]] + extends SeqTransformations[A, Coll, This] +{ + self: IndexedSeqViewLike[A, Coll, This] => + + /** Inherited from SeqView */ + protected override def newAppended[B >: A](that: Traversable[B]): Transformed[B] = new Appended[B] { val rest = that } + protected override def newMapped[B](f: A => B): Transformed[B] = new Mapped[B] { val mapping = f } + protected override def newFlatMapped[B](f: A => Traversable[B]): Transformed[B] = new FlatMapped[B] { val mapping = f } + protected override def newFiltered(p: A => Boolean): Transformed[A] = new Filtered { val pred = p } + protected override def newSliced(_from: Int, _until: Int): Transformed[A] = new Sliced { val from = _from; val until = _until } + protected override def newDroppedWhile(p: A => Boolean): Transformed[A] = new DroppedWhile { val pred = p } + protected override def newTakenWhile(p: A => Boolean): Transformed[A] = new TakenWhile { val pred = p } + + protected override def newZipped[B](that: Iterable[B]): Transformed[(A, B)] = new Zipped[B] { val other = that } + protected override def newZippedAll[A1 >: A, B](that: Iterable[B], _thisElem: A1, _thatElem: B): Transformed[(A1, B)] = + new ZippedAll[A1, B] { val other = that; val thisElem = _thisElem; val thatElem = _thatElem } + protected override def newReversed: Transformed[A] = new Reversed { } + protected override def newPatched[B >: A](_from: Int, _patch: Seq[B], _replaced: Int): Transformed[B] = + new Patched[B] { val from = _from; val patch = _patch; val replaced = _replaced } +} -- cgit v1.2.3