diff options
author | Rex Kerr <ichoran@gmail.com> | 2014-05-29 08:04:14 -0700 |
---|---|---|
committer | Rex Kerr <ichoran@gmail.com> | 2014-08-24 13:41:45 -0700 |
commit | 3d64deeb687452cb7e8e53b5a172e7bc7c50bf1b (patch) | |
tree | fac47d36d7d63ca867b33834180d8d5d4556354f /src/library/scala/collection/SeqViewLike.scala | |
parent | d4b5c7b95de88d3890be654e06da812c6eb607f5 (diff) | |
download | scala-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.scala | 23 |
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) |