Skip to content

Commit 8a70a3d

Browse files
committed
[squash] non-anonymous Iterator
1 parent 6f211fb commit 8a70a3d

File tree

2 files changed

+34
-30
lines changed

2 files changed

+34
-30
lines changed

src/library/scala/collection/Iterable.scala

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -714,14 +714,6 @@ object IterableOps {
714714
object Iterable extends IterableFactory.Delegate[Iterable](immutable.Iterable) {
715715
implicit def toLazyZipOps[A, CC[X] <: Iterable[X]](that: CC[A]): LazyZipOps[A, CC[A]] = new LazyZipOps(that)
716716

717-
/** An `Iterable` that calls [[scala.collection.Iterator.unfold `Iterator.unfold`]]
718-
* to create `Iterator`s.
719-
*/
720-
private final class UnfoldIterable[A, S] private(initial: S)(f: S => Option[(A, S)])
721-
extends AbstractIterable[A] {
722-
override def iterator: Iterator[A] = Iterator.unfold(initial)(f)
723-
}
724-
725717
/**
726718
* @return an Iterable by using a function `f` producing elements of
727719
* type `A` and updating an internal state `S`.
@@ -731,7 +723,14 @@ object Iterable extends IterableFactory.Delegate[Iterable](immutable.Iterable) {
731723
* @tparam A Type of the elements
732724
* @tparam S Type of the internal state
733725
*/
734-
def unfold[A, S](init: S)(f: S => Option[(A, S)]): Iterable[A] = new UnfoldIterable[A, S](init)(f)
726+
def unfold[A, S](init: S)(f: S => Option[(A, S)]): Iterable[A] = new UnfoldIterable(init)(f)
727+
728+
/** An `Iterable` that calls [[scala.collection.Iterator.unfold `Iterator.unfold`]]
729+
* to create `Iterator`s.
730+
*/
731+
private final class UnfoldIterable[A, S](initial: S)(f: S => Option[(A, S)]) extends AbstractIterable[A] {
732+
override def iterator: Iterator[A] = Iterator.unfold(initial)(f)
733+
}
735734
}
736735

737736
/** Explicit instantiation of the `Iterable` trait to reduce class file size in subclasses. */

src/library/scala/collection/Iterator.scala

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -967,27 +967,7 @@ object Iterator extends IterableFactory[Iterator] {
967967
* @tparam A Type of the elements
968968
* @tparam S Type of the internal state
969969
*/
970-
def unfold[A, S](init: S)(f: S => Option[(A, S)]): Iterator[A] = new AbstractIterator[A] {
971-
private[this] var state: S = init
972-
private[this] var nextResult: Option[(A, S)] = null
973-
974-
override def hasNext: Boolean = {
975-
if (nextResult eq null) {
976-
nextResult = Objects.requireNonNull(f(state), "null during unfold")
977-
state = null.asInstanceOf[S] // allow GC
978-
}
979-
nextResult.isDefined
980-
}
981-
982-
override def next(): A = {
983-
if (hasNext) {
984-
val (value, newState) = nextResult.get
985-
state = newState
986-
nextResult = null
987-
value
988-
} else Iterator.empty.next()
989-
}
990-
}
970+
def unfold[A, S](init: S)(f: S => Option[(A, S)]): Iterator[A] = new UnfoldIterator(init)(f)
991971

992972
/** Creates an iterator to which other iterators can be appended efficiently.
993973
* Nested ConcatIterators are merged to avoid blowing the stack.
@@ -1108,6 +1088,31 @@ object Iterator extends IterableFactory[Iterator] {
11081088
}
11091089
}
11101090

1091+
/** `Iterator` which uses a function `f` to produce elements of
1092+
* type `A` and update an internal state `S`.
1093+
*/
1094+
private final class UnfoldIterator[A, S](init: S)(f: S => Option[(A, S)]) extends AbstractIterator[A] {
1095+
private[this] var state: S = init
1096+
private[this] var nextResult: Option[(A, S)] = null
1097+
1098+
override def hasNext: Boolean = {
1099+
if (nextResult eq null) {
1100+
nextResult = Objects.requireNonNull(f(state), "null during unfold")
1101+
state = null.asInstanceOf[S] // allow GC
1102+
}
1103+
nextResult.isDefined
1104+
}
1105+
1106+
override def next(): A = {
1107+
if (hasNext) {
1108+
val (value, newState) = nextResult.get
1109+
state = newState
1110+
nextResult = null
1111+
value
1112+
} else Iterator.empty.next()
1113+
}
1114+
}
1115+
11111116
// scalac generates a `readReplace` method to discard the deserialized state (see https://github.com/scala/bug/issues/10412).
11121117
// This prevents it from serializing it in the first place:
11131118
private[this] def writeObject(out: ObjectOutputStream): Unit = ()

0 commit comments

Comments
 (0)