summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/collection/Iterator.scala32
-rw-r--r--test/files/run/bug2552.check49
-rw-r--r--test/files/run/bug2552.scala34
3 files changed, 109 insertions, 6 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 751d084770..70462cb8d2 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -355,10 +355,19 @@ trait Iterator[+A] { self =>
def filter(p: A => Boolean): Iterator[A] = {
val self = buffered
new Iterator[A] {
- private def skip() = while (self.hasNext && !p(self.head)) self.next()
- def hasNext = { skip(); self.hasNext }
- def next() = { skip(); self.next() }
- }
+ var computedHasNext = false
+ private def skip() = {
+ while (self.hasNext && !p(self.head)) self.next()
+ computedHasNext = self.hasNext
+ }
+ def hasNext = { if (!computedHasNext) skip(); computedHasNext }
+ def next() = {
+ if (!computedHasNext)
+ skip()
+ computedHasNext = false
+ self.next()
+ }
+ }
}
/** !!! Temporary, awaiting more general implementation.
@@ -401,8 +410,19 @@ trait Iterator[+A] { self =>
def takeWhile(p: A => Boolean): Iterator[A] = {
val self = buffered
new Iterator[A] {
- def hasNext = { self.hasNext && p(self.head) }
- def next() = (if (hasNext) self else empty).next()
+ var computedHasNext = false
+
+ def hasNext = {
+ val result = computedHasNext || (self.hasNext && p(self.head))
+ computedHasNext = result
+ result
+ }
+
+ def next() = {
+ val result = (if (computedHasNext || hasNext) self else empty).next()
+ computedHasNext = false
+ result
+ }
}
}
diff --git a/test/files/run/bug2552.check b/test/files/run/bug2552.check
new file mode 100644
index 0000000000..774e360d13
--- /dev/null
+++ b/test/files/run/bug2552.check
@@ -0,0 +1,49 @@
+p(0)
+0
+p(1)
+1
+p(2)
+2
+p(3)
+3
+p(4)
+4
+p(5)
+5
+p(6)
+6
+p(7)
+7
+p(8)
+8
+p(9)
+9
+p(10)
+p(0)
+true
+true
+0
+p(1)
+true
+1
+p(2)
+false
+p(2)
+false
+p(0)
+true
+true
+0
+p(1)
+p(2)
+2
+p(3)
+p(4)
+4
+p(5)
+p(6)
+6
+p(7)
+p(8)
+8
+p(9)
diff --git a/test/files/run/bug2552.scala b/test/files/run/bug2552.scala
new file mode 100644
index 0000000000..911d98decc
--- /dev/null
+++ b/test/files/run/bug2552.scala
@@ -0,0 +1,34 @@
+object Test extends Application {
+ def testTakeWhile = {
+ val numbers = Iterator.range(0, 50)
+ val zeroTo9 = numbers.takeWhile(x => { println("p(" + x + ")"); x < 10 } )
+
+ zeroTo9.foreach(println _)
+
+ val zeroTo1 = Iterator.range(0, 20).takeWhile(x => { println("p(" + x + ")"); x < 2 } )
+
+ println(zeroTo1.hasNext)
+ println(zeroTo1.hasNext)
+ println(zeroTo1.next)
+ println(zeroTo1.hasNext)
+ println(zeroTo1.next)
+ println(zeroTo1.hasNext)
+ println(zeroTo1.hasNext)
+ }
+
+ def testFilter = {
+ val predicate = (x: Int) => { println("p(" + x + ")"); x % 2 == 0 }
+
+ val evens = Iterator.range(0, 10).filter(predicate)
+
+ println(evens.hasNext)
+ println(evens.hasNext)
+ println(evens.next)
+
+ evens.foreach(println _)
+ }
+
+ testTakeWhile
+ testFilter
+}
+