diff options
author | Som Snytt <som.snytt@gmail.com> | 2014-11-14 11:16:06 -0800 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2014-12-06 21:29:51 -0800 |
commit | 6ba7068b9f0389812bb03eae88c31035ad73c1aa (patch) | |
tree | 6047a08b293e779d9d839b628bb19e2e2a632cc2 /src | |
parent | a1ee57da54eff4fe372e304fb5695941a70211c6 (diff) | |
download | scala-6ba7068b9f0389812bb03eae88c31035ad73c1aa.tar.gz scala-6ba7068b9f0389812bb03eae88c31035ad73c1aa.tar.bz2 scala-6ba7068b9f0389812bb03eae88c31035ad73c1aa.zip |
SI-8976 MutableList.tail.iterator.size is length
The previous behavior was to iterate over the mutated
list of arbitrary length. The previous iteration of
the iterator would also iterate the terminal element
of the list without halting.
This is fixed by capping the length of iterator.
That is OK because mutating the list by adding to it during
iteration is not recommended.
For good measure, the exhausted iterator does not hold
a reference to any remaining tail.
A test is added that will no doubt be superseded by the QCC tests.
(Quasi-Comprehensive Collections.)
The test just checks that the extra tail is not strongly
reachable from the iterator. If the garbage collector happens
to kick in and determine that the object is weakly reachable,
then the check terminates early.
Diffstat (limited to 'src')
-rw-r--r-- | src/library/scala/collection/mutable/MutableList.scala | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/library/scala/collection/mutable/MutableList.scala b/src/library/scala/collection/mutable/MutableList.scala index b852a4747b..646023f469 100644 --- a/src/library/scala/collection/mutable/MutableList.scala +++ b/src/library/scala/collection/mutable/MutableList.scala @@ -13,7 +13,6 @@ package mutable import generic._ import immutable.{List, Nil} -// !!! todo: convert to LinkedListBuffer? /** * This class is used internally to represent mutable lists. It is the * basis for the implementation of the class `Queue`. @@ -113,9 +112,21 @@ extends AbstractSeq[A] } } - /** Returns an iterator over all elements of this list. + /** Returns an iterator over up to `length` elements of this list. */ - override def iterator: Iterator[A] = first0.iterator + override def iterator: Iterator[A] = if (isEmpty) Iterator.empty else + new AbstractIterator[A] { + var elems = first0 + var count = len + def hasNext = count > 0 && elems.nonEmpty + def next() = { + if (!hasNext) throw new NoSuchElementException + count = count - 1 + val e = elems.elem + elems = if (count == 0) null else elems.next + e + } + } override def last = { if (isEmpty) throw new NoSuchElementException("MutableList.empty.last") |