summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksandar Pokopec <aleksandar.prokopec@epfl.ch>2011-02-28 11:47:33 +0000
committerAleksandar Pokopec <aleksandar.prokopec@epfl.ch>2011-02-28 11:47:33 +0000
commite0aeabba88613ff53f8eb86104e444bea75c97c6 (patch)
tree35e577dd1d8ec5b33f091384221fc4c20b76b84f
parent34d3f1cb95b1cc0fba242296026e546366c483d9 (diff)
downloadscala-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.scala20
-rw-r--r--test/files/run/t4294.scala9
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])
+ }
+}