Skip to content

Commit d8351e9

Browse files
committed
Add test case
Iter2.scala fails with 6 errors, but succeeds once lubs and glbs do not try to unify under invariant type constructors.
1 parent cc942e6 commit d8351e9

File tree

1 file changed

+245
-0
lines changed

1 file changed

+245
-0
lines changed

tests/pos/Iter2.scala

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
package dotty1.collections
2+
package immutable
3+
4+
import annotation.unchecked.uncheckedVariance
5+
6+
object Iter2 {
7+
8+
trait Iterator[+A] extends IterableOnce[A] {
9+
def hasNext: Boolean
10+
def next: A
11+
def iterator = this
12+
def foreach(f: A => Unit): Unit = ???
13+
def map[B](f: A => B): Iterator[B] = ???
14+
def flatMap[B](f: A => IterableOnce[B]): Iterator[B] = ???
15+
def ++[B >: A](xs: IterableOnce[B]): Iterator[B] = ???
16+
def drop(n: Int): Iterator[A] = ???
17+
def indexWhere(p: A => Boolean): Int = {
18+
var i = 0
19+
while (hasNext) {
20+
if (p(next)) return i
21+
i += 1
22+
}
23+
-1
24+
}
25+
def zip[B](that: Iterator[B]): Iterator[(A, B)] = ???
26+
def copy: Iterator[A] = ???
27+
}
28+
/*
29+
trait View[+A] { self =>
30+
def iterator: Iterator[A]
31+
def foreach(f: A => Unit): Unit = iterator.foreach(f)
32+
def map[B](f: A => B): View[B] =
33+
new View[B] { def iterator = self.iterator.map(f) }
34+
def flatMap[B](f: A => IterableOnce[B]): View[B] =
35+
new View[B] { def iterator = self.iterator.flatMap(f) }
36+
def ++[B >: A](xs: IterableOnce[B]): View[B] =
37+
new View[B] { def iteratpr = self.iterator ++ xs }
38+
def drop(n: Int): View[A] =
39+
new View[A] { def iteratpr = self.iterator.drop(n) }
40+
def indexWhere(p: A => Boolean): Int = {
41+
var i = 0
42+
while (hasNext) {
43+
if (p(next)) return i
44+
i += 1
45+
}
46+
-1
47+
}
48+
def zip[B](that: Iterator[B]): Iterator[(A, B)] = ???
49+
}
50+
*/
51+
52+
trait IterableOnce[+A] {
53+
def iterator: Iterator[A]
54+
def buildIterator: Iterator[A] = iterator
55+
}
56+
57+
trait FromIterator[+C[X] <: Iterable[X]] {
58+
def fromIterator[B](it: Iterator[B]): C[B]
59+
}
60+
61+
trait Iterable[+IA] extends IterableOnce[IA] with FromIterator[Iterable] {
62+
def view: View[IA] = new View(iterator)
63+
}
64+
65+
trait Seq[+AA] extends Iterable[AA] with FromIterator[Seq] {
66+
def apply(i: Int): AA
67+
def length: Int
68+
}
69+
70+
sealed trait List[+A] extends Seq[A] with FromIterator[List] {
71+
def isEmpty: Boolean
72+
def head: A
73+
def tail: List[A]
74+
def iterator = new ListIterator[A](this)
75+
def fromIterator[B](it: Iterator[B]): List[B] = it match {
76+
case ListIterator(xs) => xs
77+
case _ => if (it.hasNext) Cons(it.next, fromIterator(it)) else Nil
78+
}
79+
def apply(i: Int): A = {
80+
require(!isEmpty)
81+
if (i == 0) head else tail.apply(i - 1)
82+
}
83+
def length: Int =
84+
if (isEmpty) 0 else 1 + tail.length
85+
}
86+
87+
class View[+A](it: Iterator[A]) extends Iterable[A] with FromIterator[View] {
88+
def iterator: Iterator[A] = it.copy
89+
def fromIterator[B](it: Iterator[B]): View[B] = new View(it)
90+
}
91+
92+
case class Cons[+A](x: A, xs: List[A]) extends List[A] {
93+
def isEmpty = false
94+
def head = x
95+
def tail = xs
96+
}
97+
98+
case object Nil extends List[Nothing] {
99+
def isEmpty = true
100+
def head = ???
101+
def tail = ???
102+
}
103+
104+
class ArrayBuffer[A] private (initElems: Array[AnyRef], initLen: Int) extends Seq[A] with FromIterator[ArrayBuffer] {
105+
def this() = this(new Array[AnyRef](16), 0)
106+
def this(it: ArrayIterator[A]) = this(it.elems, it.len)
107+
private var elems: Array[AnyRef] = initElems
108+
private var len = 0
109+
def iterator =
110+
elems.iterator.take(len).asInstanceOf[Iterator[A]]
111+
override def buildIterator =
112+
new ArrayIterator(elems, len).asInstanceOf[Iterator[A]]
113+
def fromIterator[B](it: Iterator[B]): ArrayBuffer[B] =
114+
new ArrayBuffer(ArrayIterator.fromIterator(it))
115+
def apply(i: Int) = elems(i).asInstanceOf[A]
116+
def length = len
117+
}
118+
/*
119+
class SeqView[A](itf: () => Iterator) extends Seq[A] with FromIterator[SeqView] {
120+
def iterator = it
121+
def buildIterator = it
122+
def fromIterator[B](it: Iterator[B]) = it match {
123+
case ViewIterator(itf) => SeqView(itf)
124+
}
125+
}
126+
*/
127+
implicit class IterableTransforms[A, C[X] <: Iterable[X]](val c: Iterable[A] with FromIterator[C]) extends AnyVal {
128+
def map[B](f: A => B): C[B] = c.fromIterator(c.buildIterator.map(f))
129+
def flatMap[B](f: A => IterableOnce[B]): C[B] = c.fromIterator(c.buildIterator.flatMap(f(_).buildIterator))
130+
def ++[B >: A](xs: IterableOnce[B]): C[B] = c.fromIterator(c.buildIterator ++ xs.buildIterator)
131+
def drop(n: Int): C[A] = c.fromIterator(c.buildIterator.drop(n))
132+
def head: A = c.iterator.next
133+
def zip[B](xs: IterableOnce[B]): C[(A, B)] = c.fromIterator(c.iterator.zip(xs.iterator))
134+
}
135+
136+
implicit class SeqTransforms[SA, C[X] <: Seq[X]](val c: Seq[SA] with FromIterator[C]) extends AnyVal {
137+
def reverse: C[SA] = {
138+
val elems = new Array[AnyRef](c.length)
139+
var i = elems.length
140+
val it = c.iterator
141+
while (it.hasNext) {
142+
i -= 1
143+
elems(i) = it.next.asInstanceOf[AnyRef]
144+
}
145+
val xzz = c.fromIterator(ArrayIterator[SA](elems, c.length))
146+
xzz
147+
}
148+
def indexWhere(p: SA => Boolean): Int = c.iterator.indexWhere(p)
149+
}
150+
/*
151+
case class ViewIterator[+A](itf: () => Iterator) extends Iterator[A] {
152+
153+
def hasNext = it.hasNext
154+
def next
155+
def map(f: A => B): ViewIterator[B] = ViewIterator(() => it().map(f))
156+
def
157+
}
158+
*/
159+
case class ListIterator[+A](xs: List[A]) extends Iterator[A] {
160+
private[this] var current: List[A] = xs
161+
def hasNext = !current.isEmpty
162+
def next = { val res = current.head; current = current.tail; res }
163+
}
164+
165+
case class ArrayIterator[+A](elems: Array[AnyRef], len: Int) extends Iterator[A] {
166+
import ArrayIterator._
167+
168+
private def elem(i: Int) = elems(i).asInstanceOf[A]
169+
170+
private var cur = 0
171+
172+
def hasNext = cur < len
173+
def next = { val res = elem(cur); cur += 1; res }
174+
175+
override def foreach(f: A => Unit): Unit =
176+
for (i <- 0 until len) f(elem(i))
177+
178+
override def map[B](f: A => B): ArrayIterator[B] = {
179+
var mapped = elems
180+
for (i <- 0 until len) {
181+
val x = elem(i)
182+
val y = widen(f(x))
183+
if (widen(x) ne y) {
184+
if (mapped eq elems) mapped = new Array[AnyRef](len)
185+
mapped(i) = y
186+
}
187+
}
188+
if (mapped eq elems) this.asInstanceOf[ArrayIterator[B]]
189+
else new ArrayIterator(mapped, len)
190+
}
191+
192+
override def flatMap[B](f: A => IterableOnce[B]): ArrayIterator[B] =
193+
flatten(map(f(_).buildIterator))
194+
195+
override def ++[B >: A](that: IterableOnce[B]): ArrayIterator[B] = {
196+
val thatIterator @ ArrayIterator(elems2, len2) = fromIterator(that.iterator)
197+
if (len == 0) thatIterator
198+
else if (len2 == 0) this
199+
else {
200+
val resLen = len + len2
201+
val resElems = new Array[AnyRef](resLen)
202+
Array.copy(elems, 0, resElems, 0, len)
203+
Array.copy(elems2, 0, resElems, len, len2)
204+
new ArrayIterator(resElems, resLen)
205+
}
206+
}
207+
}
208+
209+
object ArrayIterator {
210+
private def widen(x: Any): AnyRef = x.asInstanceOf[AnyRef]
211+
212+
def fromIterator[A](it: Iterator[A]): ArrayIterator[A] = it match {
213+
case it: ArrayIterator[A] => it
214+
case _ =>
215+
var elems = new Array[AnyRef](32)
216+
var len = 0
217+
def ensureCapacity() = {
218+
while (len > elems.length) {
219+
val newElems = new Array[AnyRef](elems.length * 2)
220+
Array.copy(elems, 0, newElems, 0, elems.length)
221+
elems = newElems
222+
}
223+
}
224+
while (it.hasNext) {
225+
len += 1
226+
ensureCapacity()
227+
elems(len - 1) = widen(it.next)
228+
}
229+
ArrayIterator(elems, len)
230+
}
231+
232+
def flatten[A](its: ArrayIterator[Iterator[A]]): ArrayIterator[A] = {
233+
var arrayIts = its.map(fromIterator)
234+
var totalLen = 0
235+
arrayIts.foreach(totalLen += _.len)
236+
val allElems = new Array[AnyRef](totalLen)
237+
var j = 0
238+
arrayIts.foreach { it =>
239+
Array.copy(it.elems, 0, allElems, j, it.len)
240+
j += it.len
241+
}
242+
new ArrayIterator(allElems, totalLen)
243+
}
244+
}
245+
}

0 commit comments

Comments
 (0)