From 3045b84c8c36d25a3936a114e77a2ae1488ec313 Mon Sep 17 00:00:00 2001 From: Donna Malayeri Date: Mon, 23 Nov 2009 15:16:25 +0000 Subject: Closed #2552. --- src/library/scala/collection/Iterator.scala | 32 +++++++++++++++---- test/files/run/bug2552.check | 49 +++++++++++++++++++++++++++++ test/files/run/bug2552.scala | 34 ++++++++++++++++++++ 3 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 test/files/run/bug2552.check create mode 100644 test/files/run/bug2552.scala 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 +} + -- cgit v1.2.3