From 252ebb328144c843266264ad40b59634685cb4cf Mon Sep 17 00:00:00 2001 From: Donna Malayeri Date: Fri, 27 Nov 2009 11:05:04 +0000 Subject: Closes #2540 and closes #2593. --- .../scala/tools/nsc/typechecker/Typers.scala | 21 +--------- src/library/scala/collection/Iterator.scala | 49 ++++++++++++++++++++-- 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 58146ffd80..59362e2874 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3898,26 +3898,7 @@ trait Typers { self: Analyzer => if (util.Statistics.enabled) selcnt += 1 var qual1 = checkDead(typedQualifier(qual, mode)) if (name.isTypeName) qual1 = checkStable(qual1) - - val tree1 = // temporarily use `filter' and an alternative for `withFilter' - if (name == nme.withFilter) - silent(_ => typedSelect(qual1, name)) match { - case result1: Tree => - result1 - case ex1: TypeError => - silent(_ => typed1(Select(qual1, nme.filter) setPos tree.pos, mode, pt)) match { - case result2: Tree => - unit.deprecationWarning( - tree.pos, "`withFilter' method does not yet exist on "+qual1.tpe.widen+ - ", using `filter' method instead") - result2 - case ex2: TypeError => - reportTypeError(tree.pos, ex1) - setError(tree) - } - } - else - typedSelect(qual1, name) + val tree1 = typedSelect(qual1, name) if (qual1.symbol == RootPackage) treeCopy.Ident(tree1, name) else tree1 diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index 8f49bbd0e4..b507426fb8 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -367,11 +367,52 @@ trait Iterator[+A] { self => def next() = if (hasNext) { hdDefined = false; hd } else empty.next() } + def withFilter(p: A => Boolean): WithFilter = new WithFilter(p) - /** !!! Temporary, awaiting more general implementation. - * ... better wait longer, this fails once flatMap gets in the mix. - */ - // def withFilter(p: A => Boolean) = this.toStream withFilter p + final class WithFilter private[Iterator] (p: A => Boolean) { + + def map[B](f: A => B): Iterator[B] = new Iterator[B] { + private var hd: A = _ + private var hdDefined: Boolean = false + + def hasNext: Boolean = hdDefined || { + do { + if (!self.hasNext) return false + hd = self.next() + } while (!p(hd)) + hdDefined = true + true + } + + def next() = if (hasNext) { hdDefined = false; f(hd) } else empty.next() + } + + def flatMap[B](f: A => Iterator[B]): Iterator[B] = new Iterator[B] { + private var cur: Iterator[B] = empty + + @tailrec + def hasNext: Boolean = cur.hasNext || { + var x = null.asInstanceOf[A] + do { + if (!self.hasNext) return false + x = self.next() + } while (!p(x)) + cur = f(x) + hasNext + } + + def next(): B = (if (hasNext) cur else empty).next() + } + + def foreach[U](f: A => U) { + while (self.hasNext) { + val x = self.next() + if (p(x)) f(x) + } + } + + def withFilter(q: A => Boolean): WithFilter = new WithFilter(x => p(x) && q(x)) + } /** Returns an iterator over all the elements of this iterator which * do not satisfy the predicate p. -- cgit v1.2.3