This repository was archived by the owner on Sep 1, 2020. It is now read-only.
File tree Expand file tree Collapse file tree 2 files changed +22
-20
lines changed
src/library/scala/collection
test/junit/scala/collection Expand file tree Collapse file tree 2 files changed +22
-20
lines changed Original file line number Diff line number Diff line change @@ -580,29 +580,21 @@ trait Iterator[+A] extends TraversableOnce[A] {
580
580
def span (p : A => Boolean ): (Iterator [A ], Iterator [A ]) = {
581
581
val self = buffered
582
582
583
- /*
584
- * Giving a name to following iterator (as opposed to trailing) because
585
- * anonymous class is represented as a structural type that trailing
586
- * iterator is referring (the finish() method) and thus triggering
587
- * handling of structural calls. It's not what's intended here.
588
- */
583
+ // Must be a named class to avoid structural call to finish from trailing iterator
589
584
class Leading extends AbstractIterator [A ] {
590
- val lookahead = new mutable.Queue [A ]
591
- def advance () = {
592
- self.hasNext && p(self.head) && {
593
- lookahead += self.next
594
- true
595
- }
585
+ private val drained = new mutable.Queue [A ]
586
+ private var finished = false
587
+ def finish () : Unit = {
588
+ require( ! finished)
589
+ finished = true
590
+ while (selfish) drained += self.next
596
591
}
597
- def finish () = {
598
- while (advance()) ()
599
- }
600
- def hasNext = lookahead.nonEmpty || advance()
592
+ private def selfish = self.hasNext && p(self.head)
593
+ def hasNext = if (finished) drained.nonEmpty else selfish
601
594
def next () = {
602
- if (lookahead.isEmpty)
603
- advance()
604
-
605
- lookahead.dequeue()
595
+ if (finished) drained.dequeue()
596
+ else if (selfish) self.next()
597
+ else empty.next()
606
598
}
607
599
}
608
600
val leading = new Leading
Original file line number Diff line number Diff line change @@ -154,4 +154,14 @@ class IteratorTest {
154
154
results += (Stream from 1 ).toIterator.drop(10 ).toStream.drop(10 ).toIterator.next()
155
155
assertSameElements(List (1 ,1 ,21 ), results)
156
156
}
157
+ // SI-9332
158
+ @ Test def spanExhaustsLeadingIterator (): Unit = {
159
+ def it = Iterator .iterate(0 )(_ + 1 ).take(6 )
160
+ val (x, y) = it.span(_ != 1 )
161
+ val z = x.toList
162
+ assertEquals(1 , z.size)
163
+ assertFalse(x.hasNext)
164
+ assertEquals(1 , y.next)
165
+ assertFalse(x.hasNext) // was true, after advancing underlying iterator
166
+ }
157
167
}
You can’t perform that action at this time.
0 commit comments