diff options
author | Paul Phillips <paulp@improving.org> | 2011-02-28 13:53:39 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-02-28 13:53:39 +0000 |
commit | ba236bdcdcf0816ffad8b4d17b90b69c80a80ac7 (patch) | |
tree | 487ae878c1374d6a0beee080e353041b9fc3ae2d | |
parent | e0aeabba88613ff53f8eb86104e444bea75c97c6 (diff) | |
download | scala-ba236bdcdcf0816ffad8b4d17b90b69c80a80ac7.tar.gz scala-ba236bdcdcf0816ffad8b4d17b90b69c80a80ac7.tar.bz2 scala-ba236bdcdcf0816ffad8b4d17b90b69c80a80ac7.zip |
A fix for ListBuffer's iterator not to blow up ...
A fix for ListBuffer's iterator not to blow up when values are changed
during iteration. No review.
-rw-r--r-- | src/library/scala/collection/mutable/ListBuffer.scala | 21 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/SeqLike.scala | 4 |
2 files changed, 18 insertions, 7 deletions
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala index 17db03fab7..ec33e6f9d9 100644 --- a/src/library/scala/collection/mutable/ListBuffer.scala +++ b/src/library/scala/collection/mutable/ListBuffer.scala @@ -308,14 +308,25 @@ final class ListBuffer[A] this } - override def iterator = new Iterator[A] { + override def iterator: Iterator[A] = new Iterator[A] { + // Have to be careful iterating over mutable structures. + // This used to have "(cursor ne last0)" as part of its hasNext + // condition, which means it can return true even when the iterator + // is exhausted. Inconsistent results are acceptable when one mutates + // a structure while iterating, but we should never return hasNext == true + // on exhausted iterators (thus creating exceptions) merely because + // values were changed in-place. var cursor: List[A] = null - def hasNext: Boolean = !start.isEmpty && (cursor ne last0) + var remaining = ListBuffer.this.length + + def hasNext: Boolean = remaining > 0 def next(): A = - if (!hasNext) { + if (remaining <= 0) throw new NoSuchElementException("next on empty Iterator") - } else { - if (cursor eq null) cursor = start else cursor = cursor.tail + else { + if (cursor eq null) cursor = start + else cursor = cursor.tail + remaining -= 1 cursor.head } } diff --git a/src/library/scala/collection/mutable/SeqLike.scala b/src/library/scala/collection/mutable/SeqLike.scala index 075bcf9e10..910dd1aab9 100644 --- a/src/library/scala/collection/mutable/SeqLike.scala +++ b/src/library/scala/collection/mutable/SeqLike.scala @@ -37,8 +37,8 @@ trait SeqLike[A, +This <: SeqLike[A, This] with Seq[A]] */ def transform(f: A => A): this.type = { var i = 0 - iterator foreach { el => - update(i, f(el)) + this foreach { el => + this(i) = f(el) i += 1 } this |