summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@typesafe.com>2015-05-28 12:16:15 +0200
committerLukas Rytz <lukas.rytz@typesafe.com>2015-05-28 12:16:15 +0200
commit3ae3e9f086f88054102aa3b88bc18350d85edd1f (patch)
tree22d00b34f0cc48c2e11663b0d005859295403457 /src
parentb0a511f579013357aed47a4e51287175214da29a (diff)
parent5ebb7bb3bfc0e5152a707e693379d5ac5b5d9355 (diff)
downloadscala-3ae3e9f086f88054102aa3b88bc18350d85edd1f.tar.gz
scala-3ae3e9f086f88054102aa3b88bc18350d85edd1f.tar.bz2
scala-3ae3e9f086f88054102aa3b88bc18350d85edd1f.zip
Merge pull request #4530 from som-snytt/issue/9332
SI-9332 Iterator.span exhausts leading iterator
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/Iterator.scala32
1 files changed, 12 insertions, 20 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 0783beac0f..c9037eb3e3 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -580,29 +580,21 @@ trait Iterator[+A] extends TraversableOnce[A] {
def span(p: A => Boolean): (Iterator[A], Iterator[A]) = {
val self = buffered
- /*
- * Giving a name to following iterator (as opposed to trailing) because
- * anonymous class is represented as a structural type that trailing
- * iterator is referring (the finish() method) and thus triggering
- * handling of structural calls. It's not what's intended here.
- */
+ // Must be a named class to avoid structural call to finish from trailing iterator
class Leading extends AbstractIterator[A] {
- val lookahead = new mutable.Queue[A]
- def advance() = {
- self.hasNext && p(self.head) && {
- lookahead += self.next
- true
- }
+ private val drained = new mutable.Queue[A]
+ private var finished = false
+ def finish(): Unit = {
+ require(!finished)
+ finished = true
+ while (selfish) drained += self.next
}
- def finish() = {
- while (advance()) ()
- }
- def hasNext = lookahead.nonEmpty || advance()
+ private def selfish = self.hasNext && p(self.head)
+ def hasNext = if (finished) drained.nonEmpty else selfish
def next() = {
- if (lookahead.isEmpty)
- advance()
-
- lookahead.dequeue()
+ if (finished) drained.dequeue()
+ else if (selfish) self.next()
+ else empty.next()
}
}
val leading = new Leading