diff options
author | Aleksandar Pokopec <aleksandar.prokopec@epfl.ch> | 2011-02-28 11:47:33 +0000 |
---|---|---|
committer | Aleksandar Pokopec <aleksandar.prokopec@epfl.ch> | 2011-02-28 11:47:33 +0000 |
commit | e0aeabba88613ff53f8eb86104e444bea75c97c6 (patch) | |
tree | 35e577dd1d8ec5b33f091384221fc4c20b76b84f | |
parent | 34d3f1cb95b1cc0fba242296026e546366c483d9 (diff) | |
download | scala-e0aeabba88613ff53f8eb86104e444bea75c97c6.tar.gz scala-e0aeabba88613ff53f8eb86104e444bea75c97c6.tar.bz2 scala-e0aeabba88613ff53f8eb86104e444bea75c97c6.zip |
Fixes and closes #4294.
No review.
-rw-r--r-- | src/library/scala/collection/immutable/Stream.scala | 20 | ||||
-rw-r--r-- | test/files/run/t4294.scala | 9 |
2 files changed, 29 insertions, 0 deletions
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 5988780943..771b945dec 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -174,6 +174,22 @@ self => else super.map(f)(bf) } + override final def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Stream[A], B, That]): That = { + if (!isStreamBuilder(bf)) super.collect(pf)(bf) + else { + // this implementation avoids: + // 1) stackoverflows (could be achieved with tailrec, too) + // 2) out of memory errors for big streams (`this` reference can be eliminated from the stack) + var rest: Stream[A] = this + while (rest.nonEmpty && !pf.isDefinedAt(rest.head)) rest = rest.tail + + // without the call to the companion object, a thunk is created for the tail of the new stream, + // and the closure of the thunk will reference `this` + if (rest.isEmpty) Stream.Empty.asInstanceOf[That] + else Stream.collectedTail(rest, pf, bf).asInstanceOf[That] + } + } + /** Applies the given function `f` to each element of * this stream, then concatenates the results. * @@ -673,6 +689,10 @@ object Stream extends SeqFactory[Stream] { new Stream.Cons(stream.head, stream.tail filter p) } + private[immutable] def collectedTail[A, B, That](stream: Stream[A], pf: PartialFunction[A, B], bf: CanBuildFrom[Stream[A], B, That]) = { + new Stream.Cons(stream.head, stream.tail.collect(pf)(bf).asInstanceOf[Stream[B]]) + } + /** A stream containing all elements of a given iterator, in the order they are produced. * @param it The iterator producing the stream's elements */ diff --git a/test/files/run/t4294.scala b/test/files/run/t4294.scala new file mode 100644 index 0000000000..588fa90f76 --- /dev/null +++ b/test/files/run/t4294.scala @@ -0,0 +1,9 @@ + + + + +object Test { + def main(args: Array[String]) { + (Stream.from(1).collect{case x if x > 5000000 => x}: Stream[Int]) + } +} |