aboutsummaryrefslogtreecommitdiff
path: root/tests/run/colltest5
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-04-17 16:42:40 +0200
committerMartin Odersky <odersky@gmail.com>2016-04-17 16:42:40 +0200
commitb8472d8c6e6c9a267088817eb8e05577e5eda60b (patch)
treeb98790c277e83fac25995a6cc3fcc75dbf4290b0 /tests/run/colltest5
parent8cb73c0f5ca8bd809d0b9d7549951678f2240a61 (diff)
downloaddotty-b8472d8c6e6c9a267088817eb8e05577e5eda60b.tar.gz
dotty-b8472d8c6e6c9a267088817eb8e05577e5eda60b.tar.bz2
dotty-b8472d8c6e6c9a267088817eb8e05577e5eda60b.zip
Updates of strawman
Bring strawman-4 and strawman-5 to feature-parity. Test also strawman-4.
Diffstat (limited to 'tests/run/colltest5')
-rw-r--r--tests/run/colltest5/CollectionStrawMan5_1.scala94
-rw-r--r--tests/run/colltest5/CollectionTests_2.scala4
2 files changed, 52 insertions, 46 deletions
diff --git a/tests/run/colltest5/CollectionStrawMan5_1.scala b/tests/run/colltest5/CollectionStrawMan5_1.scala
index aa127cb7e..1a89d9659 100644
--- a/tests/run/colltest5/CollectionStrawMan5_1.scala
+++ b/tests/run/colltest5/CollectionStrawMan5_1.scala
@@ -3,6 +3,7 @@ package strawman.collections
import Predef.{augmentString => _, wrapString => _, _}
import scala.reflect.ClassTag
import annotation.unchecked.uncheckedVariance
+import annotation.tailrec
/** A strawman architecture for new collections. It contains some
* example collection classes and methods with the intent to expose
@@ -32,30 +33,8 @@ object CollectionStrawMan5 {
def apply[A](xs: A*): C[A] = fromIterable(View.Elems(xs: _*))
}
- /** Base trait for Iterable operations */
- trait IterableLike[+A, +C[X] <: Iterable[X]]
- extends FromIterable[C]
- with IterableOps[A]
- with IterableMonoTransforms[A @uncheckedVariance, C[A @uncheckedVariance]]
- with IterablePolyTransforms[A @uncheckedVariance, C] {
- protected def fromLikeIterable(coll: Iterable[A @uncheckedVariance]): C[A @uncheckedVariance] = fromIterable(coll)
- }
-
- /** Base trait for Seq operations */
- trait SeqLike[+A, +C[X] <: Seq[X]] extends IterableLike[A, C] {
- def reverse: C[A @uncheckedVariance] = {
- var xs: List[A] = Nil
- var it = iterator
- while (it.hasNext) xs = new Cons(it.next, xs)
- fromLikeIterable(xs)
- }
- }
-
/** Base trait for generic collections */
trait Iterable[+A] extends IterableOnce[A] with IterableLike[A, Iterable] {
- override def iterator: Iterator[A]
- override def fromIterable[B](it: Iterable[B]): Iterable[B]
-
protected def coll: Iterable[A] = this
def knownLength: Int = -1
}
@@ -64,9 +43,9 @@ object CollectionStrawMan5 {
trait Seq[+A] extends Iterable[A] with SeqLike[A, Seq] {
def apply(i: Int): A
def length: Int
- override def iterator: Iterator[A]
}
+ /** Base trait for strict collections */
trait Buildable[+A, +To <: Iterable[A]] extends Iterable[A] {
protected[this] def newBuilder: Builder[A, To]
override def partition(p: A => Boolean): (To, To) = {
@@ -74,8 +53,11 @@ object CollectionStrawMan5 {
iterator.foreach(x => (if (p(x)) l else r) += x)
(l.result, r.result)
}
+ // one might also override other transforms here to avoid generating
+ // iterators if it helps efficiency.
}
+ /** Base trait for collection builders */
trait Builder[-A, +To] {
def +=(x: A): this.type
def result: To
@@ -88,6 +70,29 @@ object CollectionStrawMan5 {
/* ------------ Operations ----------------------------------- */
+ /** Base trait for Iterable operations
+ *
+ * VarianceNote
+ * ============
+ *
+ * We require that for all child classes of Iterable the variance of
+ * the child class and the variance of the `C` parameter passed to `IterableLike`
+ * are the same. We cannot express this since we lack variance polymorphism. That's
+ * why we have to resort at some places to write `C[A @uncheckedVariance]`.
+ *
+ */
+ trait IterableLike[+A, +C[X] <: Iterable[X]]
+ extends FromIterable[C]
+ with IterableOps[A]
+ with IterableMonoTransforms[A, C[A @uncheckedVariance]] // sound bcs of VarianceNote
+ with IterablePolyTransforms[A, C] {
+ protected[this] def fromLikeIterable(coll: Iterable[A]): C[A] = fromIterable(coll)
+ }
+
+ /** Base trait for Seq operations */
+ trait SeqLike[+A, +C[X] <: Seq[X]]
+ extends IterableLike[A, C] with SeqMonoTransforms[A, C[A @uncheckedVariance]] // sound bcs of VarianceNote
+
trait IterableOps[+A] extends Any {
def iterator: Iterator[A]
def foreach(f: A => Unit): Unit = iterator.foreach(f)
@@ -99,16 +104,19 @@ object CollectionStrawMan5 {
def view: View[A] = View.fromIterator(iterator)
}
- trait IterableMonoTransforms[A, +Repr] extends Any {
+ trait IterableMonoTransforms[+A, +Repr] extends Any {
protected def coll: Iterable[A]
- protected def fromLikeIterable(coll: Iterable[A]): Repr
+ protected[this] def fromLikeIterable(coll: Iterable[A]): Repr
def filter(p: A => Boolean): Repr = fromLikeIterable(View.Filter(coll, p))
def partition(p: A => Boolean): (Repr, Repr) = {
val pn = View.Partition(coll, p)
(fromLikeIterable(pn.left), fromLikeIterable(pn.right))
}
def drop(n: Int): Repr = fromLikeIterable(View.Drop(coll, n))
- def to[C[X] <: Iterable[X]](fi: FromIterable[C]): C[A] = fi.fromIterable(coll)
+ def to[C[X] <: Iterable[X]](fi: FromIterable[C]): C[A @uncheckedVariance] =
+ // variance seems sound because `to` could just as well have been added
+ // as a decorator. We should investigate this further to be sure.
+ fi.fromIterable(coll)
}
trait IterablePolyTransforms[+A, +C[A]] extends Any {
@@ -118,9 +126,10 @@ object CollectionStrawMan5 {
def flatMap[B](f: A => IterableOnce[B]): C[B] = fromIterable(View.FlatMap(coll, f))
def ++[B >: A](xs: IterableOnce[B]): C[B] = fromIterable(View.Concat(coll, xs))
def zip[B](xs: IterableOnce[B]): C[(A @uncheckedVariance, B)] = fromIterable(View.Zip(coll, xs))
+ // sound bcs of VarianceNote
}
- trait SeqMonoTransforms[A, +Repr] extends Any with IterableMonoTransforms[A, Repr] {
+ trait SeqMonoTransforms[+A, +Repr] extends Any with IterableMonoTransforms[A, Repr] {
def reverse: Repr = {
var xs: List[A] = Nil
var it = coll.iterator
@@ -156,10 +165,12 @@ object CollectionStrawMan5 {
case xs: List[B] => this ++: xs
case _ => super.++(xs)
}
- override def reverse = super.reverse
+ @tailrec final override def drop(n: Int) =
+ if (n > 0) tail.drop(n - 1) else this
}
- case class Cons[+A](x: A, private[collections] var next: List[A @uncheckedVariance]) extends List[A] {
+ case class Cons[+A](x: A, private[collections] var next: List[A @uncheckedVariance]) // sound because `next` is used only locally
+ extends List[A] {
override def isEmpty = false
override def head = x
def tail = next
@@ -182,11 +193,7 @@ object CollectionStrawMan5 {
class ListBuffer[A] extends Seq[A] with SeqLike[A, ListBuffer] with Builder[A, List[A]] {
private var first, last: List[A] = Nil
private var aliased = false
- def iterator = new Iterator[A] {
- var current: List[A] = first
- def hasNext = ???
- def next = ???
- }
+ def iterator = first.iterator
def fromIterable[B](coll: Iterable[B]) = ListBuffer.fromIterable(coll)
def apply(i: Int) = first.apply(i)
def length = first.length
@@ -211,6 +218,12 @@ object CollectionStrawMan5 {
last = last1
this
}
+ override def toString: String =
+ if (first.isEmpty) "ListBuffer()"
+ else {
+ val b = new StringBuilder("ListBuffer(").append(first.head)
+ first.tail.foldLeft(b)(_.append(", ").append(_)).append(")").toString
+ }
}
object ListBuffer extends IterableFactory[ListBuffer] {
@@ -297,12 +310,12 @@ object CollectionStrawMan5 {
def fromIterable[B](coll: Iterable[B]): List[B] = List.fromIterable(coll)
def map(f: Char => Char): String = {
val sb = new StringBuilder
- for (ch <- StringOps(s)) sb.append(f(ch))
+ for (ch <- s) sb.append(f(ch))
sb.toString
}
def flatMap(f: Char => String): String = {
val sb = new StringBuilder
- for (ch <- StringOps(s)) sb.append(f(ch))
+ for (ch <- s) sb.append(f(ch))
sb.toString
}
def ++(xs: IterableOnce[Char]): String = {
@@ -399,15 +412,6 @@ object CollectionStrawMan5 {
-1
}
}
- case class Reverse[A](underlying: Iterable[A]) extends View[A] {
- def iterator = {
- var xs: List[A] = Nil
- val it = underlying.iterator
- while (it.hasNext) xs = Cons(it.next(), xs)
- xs.iterator
- }
- override def knownLength = underlying.knownLength
- }
}
/* ---------- Iterators ---------------------------------------------------*/
diff --git a/tests/run/colltest5/CollectionTests_2.scala b/tests/run/colltest5/CollectionTests_2.scala
index cdff2e260..0961180ed 100644
--- a/tests/run/colltest5/CollectionTests_2.scala
+++ b/tests/run/colltest5/CollectionTests_2.scala
@@ -124,7 +124,7 @@ object Test {
val ys9: Seq[Int] = xs9
val xs9a = xs.map(_.toUpper) // !!! need a language change to make this work without the : Char
val ys9a: String = xs9a
- val xs10 = xs.flatMap(x => s"$x,$x")
+ val xs10 = xs.flatMap((x: Char) => s"$x,$x")
val ys10: String = xs10
val xs11 = xs ++ xs
val ys11: String = xs11
@@ -161,9 +161,11 @@ object Test {
def main(args: Array[String]) = {
val ints = Cons(1, Cons(2, Cons(3, Nil)))
val intsBuf = ints.to(ArrayBuffer)
+ val intsListBuf = ints.to(ListBuffer)
val intsView = ints.view
seqOps(ints)
seqOps(intsBuf)
+ seqOps(intsListBuf)
viewOps(intsView)
stringOps("abc")
}