From 0661398cebda25f3a775e1b2e356125859e2b37c Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Wed, 14 Jul 2010 08:00:03 +0000 Subject: Moved the burden of forgivingness for string sl... Moved the burden of forgivingness for string slices into StringOps where it belongs. Review by odersky. --- .../scala/collection/IndexedSeqOptimized.scala | 8 ++++---- .../scala/collection/immutable/StringOps.scala | 12 ++++++++++-- test/files/run/slice-strings.scala | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+), 6 deletions(-) create mode 100644 test/files/run/slice-strings.scala diff --git a/src/library/scala/collection/IndexedSeqOptimized.scala b/src/library/scala/collection/IndexedSeqOptimized.scala index 59b68aaaa6..6360de33f1 100755 --- a/src/library/scala/collection/IndexedSeqOptimized.scala +++ b/src/library/scala/collection/IndexedSeqOptimized.scala @@ -139,16 +139,16 @@ trait IndexedSeqOptimized[+A, +Repr] extends IndexedSeqLike[A, Repr] { self => def init: Repr = if (length > 0) slice(0, length - 1) else super.init override /*TraversableLike*/ - def take(n: Int): Repr = if (n < length) slice(0, n) else slice(0, length) + def take(n: Int): Repr = slice(0, n) override /*TraversableLike*/ - def drop(n: Int): Repr = if (n < length) slice(n, length) else newBuilder.result + def drop(n: Int): Repr = slice(n, length) override /*IterableLike*/ - def takeRight(n: Int): Repr = if (n < length) slice(length - n, length) else slice(0, length) + def takeRight(n: Int): Repr = slice(length - n, length) override /*IterableLike*/ - def dropRight(n: Int): Repr = if (n < length) slice(0, length - n) else newBuilder.result + def dropRight(n: Int): Repr = slice(0, length - n) override /*TraversableLike*/ def splitAt(n: Int): (Repr, Repr) = (take(n), drop(n)) diff --git a/src/library/scala/collection/immutable/StringOps.scala b/src/library/scala/collection/immutable/StringOps.scala index 8a27a4ad4b..0d8f5f6b83 100644 --- a/src/library/scala/collection/immutable/StringOps.scala +++ b/src/library/scala/collection/immutable/StringOps.scala @@ -36,8 +36,16 @@ final class StringOps(override val repr: String) extends StringLike[String] { /** Creates a string builder buffer as builder for this class */ override protected[this] def newBuilder = new StringBuilder - override def slice(from: Int, until: Int): String = - repr.substring(from max 0, until min repr.length) + override def slice(from: Int, until: Int): String = { + /** Slice must be forgiving on all out of bounds indices and + * substring is not. + */ + val start = from max 0 + val end = until min repr.length + + if (start >= end) "" + else repr.substring(start, end) + } override def toString = repr } diff --git a/test/files/run/slice-strings.scala b/test/files/run/slice-strings.scala new file mode 100644 index 0000000000..129314387a --- /dev/null +++ b/test/files/run/slice-strings.scala @@ -0,0 +1,19 @@ +object Test { + def cmp(x1: String) = { + val x2 = x1.toList + + -10 to 10 foreach { i => + assert(x1.take(i) == x2.take(i).mkString) + assert(x1.drop(i) == x2.drop(i).mkString) + assert(x1.takeRight(i) == x2.takeRight(i).mkString) + assert(x1.dropRight(i) == x2.dropRight(i).mkString) + } + for (idx1 <- -3 to 3 ; idx2 <- -3 to 3) { + assert(x1.slice(idx1, idx2) == x2.slice(idx1, idx2).mkString) + } + } + + def main(args: Array[String]): Unit = { + cmp("abcde") + } +} -- cgit v1.2.3