summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2014-08-26 17:38:19 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2014-08-27 08:55:51 +0200
commit9276a1205f74fdec74206209712831913e93f359 (patch)
tree88b968bc84906bbfb75dbca60320449edc4fb050 /src
parent5e0880fe05fb65a8757721be7e5be6a3259c19a8 (diff)
downloadscala-9276a1205f74fdec74206209712831913e93f359.tar.gz
scala-9276a1205f74fdec74206209712831913e93f359.tar.bz2
scala-9276a1205f74fdec74206209712831913e93f359.zip
SI-8627 make Stream.filterNot non-eager
The obvious fix, overriding `filterNot` in Stream, is not binary compatible, see https://github.com/scala/scala/pull/3925 Instead, this makes `filterImpl` in TaversableLike private[scala], which allows overriding it in Stream. The corresponding mima-failures can be whitelisted, as the changes are only to private[scala]. In 2.12.x we can remove the override of `filter` in Stream, but in 2.11.x this is not binary compatible. Eventually we'd also like to make filter / filterNot in TraversableLike final, but that's not source compatible, so it cannot be done in 2.12.x.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/TraversableLike.scala2
-rw-r--r--src/library/scala/collection/immutable/Stream.scala24
2 files changed, 14 insertions, 12 deletions
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index d3a7db6968..a8731a51b1 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -253,7 +253,7 @@ trait TraversableLike[+A, +Repr] extends Any
b.result
}
- private def filterImpl(p: A => Boolean, isFlipped: Boolean): Repr = {
+ private[scala] def filterImpl(p: A => Boolean, isFlipped: Boolean): Repr = {
val b = newBuilder
for (x <- this)
if (p(x) != isFlipped) b += x
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index d3ff5e8abf..f43f864e86 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -468,6 +468,16 @@ self =>
)
else super.flatMap(f)(bf)
+ override private[scala] def filterImpl(p: A => Boolean, isFlipped: Boolean): Stream[A] = {
+ // optimization: drop leading prefix of elems for which f returns false
+ // var rest = this dropWhile (!p(_)) - forget DRY principle - GC can't collect otherwise
+ var rest = this
+ while (!rest.isEmpty && p(rest.head) == isFlipped) rest = rest.tail
+ // private utility func to avoid `this` on stack (would be needed for the lazy arg)
+ if (rest.nonEmpty) Stream.filteredTail(rest, p, isFlipped)
+ else Stream.Empty
+ }
+
/** Returns all the elements of this `Stream` that satisfy the predicate `p`
* in a new `Stream` - i.e. it is still a lazy data structure. The order of
* the elements is preserved
@@ -481,15 +491,7 @@ self =>
* // produces
* }}}
*/
- override def filter(p: A => Boolean): Stream[A] = {
- // optimization: drop leading prefix of elems for which f returns false
- // var rest = this dropWhile (!p(_)) - forget DRY principle - GC can't collect otherwise
- var rest = this
- while (!rest.isEmpty && !p(rest.head)) rest = rest.tail
- // private utility func to avoid `this` on stack (would be needed for the lazy arg)
- if (rest.nonEmpty) Stream.filteredTail(rest, p)
- else Stream.Empty
- }
+ override def filter(p: A => Boolean): Stream[A] = filterImpl(p, isFlipped = false) // This override is only left in 2.11 because of binary compatibility, see PR #3925
override final def withFilter(p: A => Boolean): StreamWithFilter = new StreamWithFilter(p)
@@ -1187,8 +1189,8 @@ object Stream extends SeqFactory[Stream] {
else cons(start, range(start + step, end, step))
}
- private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean) = {
- cons(stream.head, stream.tail filter p)
+ private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean, isFlipped: Boolean) = {
+ cons(stream.head, stream.tail.filterImpl(p, isFlipped))
}
private[immutable] def collectedTail[A, B, That](head: B, stream: Stream[A], pf: PartialFunction[A, B], bf: CanBuildFrom[Stream[A], B, That]) = {