summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/SeqViewLike.scala
diff options
context:
space:
mode:
authorRex Kerr <ichoran@gmail.com>2014-05-29 08:04:14 -0700
committerRex Kerr <ichoran@gmail.com>2014-08-24 13:41:45 -0700
commit3d64deeb687452cb7e8e53b5a172e7bc7c50bf1b (patch)
treefac47d36d7d63ca867b33834180d8d5d4556354f /src/library/scala/collection/SeqViewLike.scala
parentd4b5c7b95de88d3890be654e06da812c6eb607f5 (diff)
downloadscala-3d64deeb687452cb7e8e53b5a172e7bc7c50bf1b.tar.gz
scala-3d64deeb687452cb7e8e53b5a172e7bc7c50bf1b.tar.bz2
scala-3d64deeb687452cb7e8e53b5a172e7bc7c50bf1b.zip
SI-8474 Inconsistent behavior of patch method
Changed Iterator to be consistent with other collections. Also fixed SeqViewLike to validate/constrain inputs. No specific tests; quasi-comprehensive collection tests will cover this later.
Diffstat (limited to 'src/library/scala/collection/SeqViewLike.scala')
-rw-r--r--src/library/scala/collection/SeqViewLike.scala23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala
index 5e31ac4a53..e719f19c78 100644
--- a/src/library/scala/collection/SeqViewLike.scala
+++ b/src/library/scala/collection/SeqViewLike.scala
@@ -154,17 +154,27 @@ trait SeqViewLike[+A,
}
}
+ // Note--for this to work, must ensure 0 <= from and 0 <= replaced
+ // Must also take care to allow patching inside an infinite stream
+ // (patching in an infinite stream is not okay)
trait Patched[B >: A] extends Transformed[B] {
protected[this] val from: Int
protected[this] val patch: GenSeq[B]
protected[this] val replaced: Int
private lazy val plen = patch.length
override def iterator: Iterator[B] = self.iterator patch (from, patch.iterator, replaced)
- def length: Int = self.length + plen - replaced
- def apply(idx: Int): B =
- if (idx < from) self.apply(idx)
- else if (idx < from + plen) patch.apply(idx - from)
+ def length: Int = {
+ val len = self.length
+ val pre = math.min(from, len)
+ val post = math.max(0, len - pre - replaced)
+ pre + plen + post
+ }
+ def apply(idx: Int): B = {
+ val actualFrom = if (self.lengthCompare(from) < 0) self.length else from
+ if (idx < actualFrom) self.apply(idx)
+ else if (idx < actualFrom + plen) patch.apply(idx - actualFrom)
else self.apply(idx - plen + replaced)
+ }
final override protected[this] def viewIdentifier = "P"
}
@@ -210,7 +220,10 @@ trait SeqViewLike[+A,
override def reverse: This = newReversed.asInstanceOf[This]
override def patch[B >: A, That](from: Int, patch: GenSeq[B], replaced: Int)(implicit bf: CanBuildFrom[This, B, That]): That = {
- newPatched(from, patch, replaced).asInstanceOf[That]
+ // Be careful to not evaluate the entire sequence! Patch should work (slowly, perhaps) on infinite streams.
+ val nonNegFrom = math.max(0,from)
+ val nonNegRep = math.max(0,replaced)
+ newPatched(nonNegFrom, patch, nonNegRep).asInstanceOf[That]
// was: val b = bf(repr)
// if (b.isInstanceOf[NoBuilder[_]]) newPatched(from, patch, replaced).asInstanceOf[That]
// else super.patch[B, That](from, patch, replaced)(bf)