From 83d4a1b304b83fa97209c7e6db32ab82738d5e1e Mon Sep 17 00:00:00 2001 From: michelou Date: Wed, 22 Aug 2007 14:17:52 +0000 Subject: fixed method slice both in arrays and lists (se... fixed method slice both in arrays and lists (see run/slices.scala) --- src/library/scala/List.scala | 13 ++++++- src/library/scala/runtime/BoxedAnyArray.scala | 38 ++++++++++--------- src/library/scala/runtime/BoxedArray.scala | 9 +++++ src/library/scala/runtime/BoxedBooleanArray.scala | 14 +++---- src/library/scala/runtime/BoxedByteArray.scala | 14 +++---- src/library/scala/runtime/BoxedCharArray.scala | 14 +++---- src/library/scala/runtime/BoxedDoubleArray.scala | 14 +++---- src/library/scala/runtime/BoxedFloatArray.scala | 14 +++---- src/library/scala/runtime/BoxedIntArray.scala | 14 +++---- src/library/scala/runtime/BoxedLongArray.scala | 14 +++---- src/library/scala/runtime/BoxedObjectArray.scala | 14 +++---- src/library/scala/runtime/BoxedShortArray.scala | 14 +++---- test/files/run/slices.check | 36 ++++++++++++++++++ test/files/run/slices.scala | 46 +++++++++++++++++++++++ 14 files changed, 184 insertions(+), 84 deletions(-) create mode 100644 test/files/run/slices.check create mode 100644 test/files/run/slices.scala diff --git a/src/library/scala/List.scala b/src/library/scala/List.scala index c39051145c..a2e1045b25 100644 --- a/src/library/scala/List.scala +++ b/src/library/scala/List.scala @@ -554,8 +554,17 @@ sealed abstract class List[+A] extends Seq[A] { else b.toList } - - override def slice(from : Int, until : Int) : List[A] = drop(from).take(until - from) + /** Returns the list with elements belonging to the given index range. + * + * @param start the start position of the list slice. + * @param end the end position (exclusive) of the list slice. + * @return the list with elements belonging to the given index range. + */ + override def slice(start: Int, end: Int): List[A] = { + val s = start max 0 + val e = end min this.length + drop(s) take (e - s) + } /** Returns the list without its n first elements. * If this list has less than n elements, the empty list is returned. diff --git a/src/library/scala/runtime/BoxedAnyArray.scala b/src/library/scala/runtime/BoxedAnyArray.scala index 34cf4b3776..cbc967774b 100644 --- a/src/library/scala/runtime/BoxedAnyArray.scala +++ b/src/library/scala/runtime/BoxedAnyArray.scala @@ -18,6 +18,8 @@ import compat.Platform /** * Arrays created by new Array[T](length) where T * is a type variable. + * + * @author Martin Odersky */ @serializable final class BoxedAnyArray(val length: Int) extends BoxedArray { @@ -93,7 +95,7 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var i = 0 while (i < length) { newvalue(i) = Int.unbox(boxed(i)) - i = i + 1 + i += 1 } unboxed = newvalue } else if (elemClass eq classOf[Double]) { @@ -101,7 +103,7 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var i = 0 while (i < length) { newvalue(i) = Double.unbox(boxed(i)) - i = i + 1 + i += 1 } unboxed = newvalue; } else if (elemClass eq classOf[Float]) { @@ -109,7 +111,7 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var i = 0 while (i < length) { newvalue(i) = Float.unbox(boxed(i)) - i = i + 1 + i += 1 } unboxed = newvalue; } else if (elemClass eq classOf[Long]) { @@ -117,7 +119,7 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var i = 0 while (i < length) { newvalue(i) = Long.unbox(boxed(i)) - i = i + 1 + i += 1 } unboxed = newvalue; } else if (elemClass eq classOf[Char]) { @@ -125,7 +127,7 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var i = 0 while (i < length) { newvalue(i) = Char.unbox(boxed(i)) - i = i + 1 + i += 1 } unboxed = newvalue } else if (elemClass eq classOf[Byte]) { @@ -133,7 +135,7 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var i = 0 while (i < length) { newvalue(i) = Byte.unbox(boxed(i)) - i = i + 1 + i += 1 } unboxed = newvalue; } else if (elemClass eq classOf[Short]) { @@ -141,7 +143,7 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var i = 0 while (i < length) { newvalue(i) = Short.unbox(boxed(i)) - i = i + 1 + i += 1 } unboxed = newvalue; } else if (elemClass eq classOf[Boolean]) { @@ -149,15 +151,15 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var i = 0 while (i < length) { newvalue(i) = Boolean.unbox(boxed(i)) - i = i + 1 + i += 1 } unboxed = newvalue; } else if (elemClass == boxed.getClass().getComponentType()) { // todo: replace with ScalaRunTime.AnyRef.class unboxed = boxed } else { - unboxed = Platform.createArray(elemClass, length); - Platform.arraycopy(boxed, 0, unboxed, 0, length); + unboxed = Platform.createArray(elemClass, length) + Platform.arraycopy(boxed, 0, unboxed, 0, length) } boxed = null } @@ -219,12 +221,12 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { other } - override def copyFrom(src: AnyRef, from: Int, to: Int, len: Int): Unit = { + override def copyFrom(src: AnyRef, from: Int, to: Int, len: Int) { val src1 = adapt(src) Array.copy(src1, from, if (unboxed ne null) unboxed else boxed, to, len) } - override def copyTo(from: Int, dest: AnyRef, to: Int, len: Int): Unit = { + override def copyTo(from: Int, dest: AnyRef, to: Int, len: Int) { var dest1 = adapt(dest) Array.copy(if (unboxed ne null) unboxed else boxed, from, dest1, to, len) } @@ -240,23 +242,23 @@ final class BoxedAnyArray(val length: Int) extends BoxedArray { var len = 0 var i = 0 while (i < length) { - if (p(this(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(this(i))) { include(i) = true; len += 1 } + i += 1 } val result = new BoxedAnyArray(len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = this(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = this(i); len += 1 } + i += 1 } result } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = new BoxedAnyArray(len) - Array.copy(this, start, result, 0, len) + Array.copy(this, s, result, 0, len) result } diff --git a/src/library/scala/runtime/BoxedArray.scala b/src/library/scala/runtime/BoxedArray.scala index 6c65705ae0..aa5c9fe8c2 100644 --- a/src/library/scala/runtime/BoxedArray.scala +++ b/src/library/scala/runtime/BoxedArray.scala @@ -128,6 +128,15 @@ abstract class BoxedArray extends RandomAccessSeq.Mutable[Any] { override def slice(start: Int, end: Int): BoxedArray = throw new Error("internal: slice") + /** Calculate start position and length in source array to + * be passed to the array copy operation. + */ + protected def slice0(start: Int, end: Int): (Int, Int) = { + val s = start max 0 + val e = end min this.length + if (s > e) (0, 0) else (s, e - s) + } + override def take(n: Int) = slice(0, n) override def drop(n: Int) = slice(n, length) diff --git a/src/library/scala/runtime/BoxedBooleanArray.scala b/src/library/scala/runtime/BoxedBooleanArray.scala index 1f0567abad..cf0144214e 100644 --- a/src/library/scala/runtime/BoxedBooleanArray.scala +++ b/src/library/scala/runtime/BoxedBooleanArray.scala @@ -21,7 +21,7 @@ final class BoxedBooleanArray(val value: Array[Boolean]) extends BoxedArray { def apply(index: Int): Any = Boolean.box(value(index)) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = Boolean.unbox(elem.asInstanceOf[AnyRef]) } @@ -45,23 +45,23 @@ final class BoxedBooleanArray(val value: Array[Boolean]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = new Array[Boolean](len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedBooleanArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = new Array[Boolean](len) - Array.copy(value, start, result, 0, len) + Array.copy(value, s, result, 0, len) new BoxedBooleanArray(result) } } diff --git a/src/library/scala/runtime/BoxedByteArray.scala b/src/library/scala/runtime/BoxedByteArray.scala index 753dbaea04..481905b24b 100644 --- a/src/library/scala/runtime/BoxedByteArray.scala +++ b/src/library/scala/runtime/BoxedByteArray.scala @@ -21,7 +21,7 @@ final class BoxedByteArray(val value: Array[Byte]) extends BoxedArray { def apply(index: Int): Any = Byte.box(value(index)) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = Byte.unbox(elem.asInstanceOf[AnyRef]) } @@ -45,23 +45,23 @@ final class BoxedByteArray(val value: Array[Byte]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = new Array[Byte](len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedByteArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = new Array[Byte](len) - Array.copy(value, start, result, 0, len) + Array.copy(value, s, result, 0, len) new BoxedByteArray(result) } } diff --git a/src/library/scala/runtime/BoxedCharArray.scala b/src/library/scala/runtime/BoxedCharArray.scala index adb14dda51..47402d0819 100644 --- a/src/library/scala/runtime/BoxedCharArray.scala +++ b/src/library/scala/runtime/BoxedCharArray.scala @@ -21,7 +21,7 @@ final class BoxedCharArray(val value: Array[Char]) extends BoxedArray { def apply(index: Int): Any = Char.box(value(index)) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = Char.unbox(elem.asInstanceOf[AnyRef]) } @@ -46,23 +46,23 @@ final class BoxedCharArray(val value: Array[Char]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = new Array[Char](len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedCharArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = new Array[Char](len) - Array.copy(value, start, result, 0, len) + Array.copy(value, s, result, 0, len) new BoxedCharArray(result) } } diff --git a/src/library/scala/runtime/BoxedDoubleArray.scala b/src/library/scala/runtime/BoxedDoubleArray.scala index 9a4564e439..f96b9a5b67 100644 --- a/src/library/scala/runtime/BoxedDoubleArray.scala +++ b/src/library/scala/runtime/BoxedDoubleArray.scala @@ -21,7 +21,7 @@ final class BoxedDoubleArray(val value: Array[Double]) extends BoxedArray { def apply(index: Int): Any = Double.box(value(index)) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = Double.unbox(elem.asInstanceOf[AnyRef]) } @@ -45,23 +45,23 @@ final class BoxedDoubleArray(val value: Array[Double]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = new Array[Double](len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedDoubleArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = new Array[Double](len) - Array.copy(value, start, result, 0, len) + Array.copy(value, s, result, 0, len) new BoxedDoubleArray(result) } } diff --git a/src/library/scala/runtime/BoxedFloatArray.scala b/src/library/scala/runtime/BoxedFloatArray.scala index 1b8ccb3797..aa5c987d0f 100644 --- a/src/library/scala/runtime/BoxedFloatArray.scala +++ b/src/library/scala/runtime/BoxedFloatArray.scala @@ -21,7 +21,7 @@ final class BoxedFloatArray(val value: Array[Float]) extends BoxedArray { def apply(index: Int): Any = Float.box(value(index)) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = Float.unbox(elem.asInstanceOf[AnyRef]) } @@ -45,23 +45,23 @@ final class BoxedFloatArray(val value: Array[Float]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = new Array[Float](len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedFloatArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = new Array[Float](len) - Array.copy(value, start, result, 0, len) + Array.copy(value, s, result, 0, len) new BoxedFloatArray(result) } } diff --git a/src/library/scala/runtime/BoxedIntArray.scala b/src/library/scala/runtime/BoxedIntArray.scala index fc5e5b99bc..0fee3b675d 100644 --- a/src/library/scala/runtime/BoxedIntArray.scala +++ b/src/library/scala/runtime/BoxedIntArray.scala @@ -21,7 +21,7 @@ final class BoxedIntArray(val value: Array[Int]) extends BoxedArray { def apply(index: Int): Any = Int.box(value(index)) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = Int.unbox(elem.asInstanceOf[AnyRef]) } @@ -45,23 +45,21 @@ final class BoxedIntArray(val value: Array[Int]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = new Array[Int](len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedIntArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - var s = start max 0 - var e = end min value.length - var len = e - s + val (s, len) = slice0(start, end) val result = new Array[Int](len) Array.copy(value, s, result, 0, len) new BoxedIntArray(result) diff --git a/src/library/scala/runtime/BoxedLongArray.scala b/src/library/scala/runtime/BoxedLongArray.scala index 6accc84484..009aa72dc7 100644 --- a/src/library/scala/runtime/BoxedLongArray.scala +++ b/src/library/scala/runtime/BoxedLongArray.scala @@ -21,7 +21,7 @@ final class BoxedLongArray(val value: Array[Long]) extends BoxedArray { def apply(index: Int): Any = Long.box(value(index)) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = Long.unbox(elem.asInstanceOf[AnyRef]) } @@ -45,23 +45,23 @@ final class BoxedLongArray(val value: Array[Long]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = new Array[Long](len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedLongArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = new Array[Long](len) - Array.copy(value, start, result, 0, len) + Array.copy(value, s, result, 0, len) new BoxedLongArray(result) } } diff --git a/src/library/scala/runtime/BoxedObjectArray.scala b/src/library/scala/runtime/BoxedObjectArray.scala index 5c23e8257b..36decf6a4c 100644 --- a/src/library/scala/runtime/BoxedObjectArray.scala +++ b/src/library/scala/runtime/BoxedObjectArray.scala @@ -22,7 +22,7 @@ final class BoxedObjectArray(val value: Array[AnyRef]) extends BoxedArray { def apply(index: Int): Any = value(index) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = elem.asInstanceOf[AnyRef] } @@ -50,23 +50,23 @@ final class BoxedObjectArray(val value: Array[AnyRef]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = create(len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedObjectArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = create(len) - Array.copy(value, start, result, 0, len) + Array.copy(value, s, result, 0, len) new BoxedObjectArray(result) } } diff --git a/src/library/scala/runtime/BoxedShortArray.scala b/src/library/scala/runtime/BoxedShortArray.scala index 161b7b921b..f4c594978e 100644 --- a/src/library/scala/runtime/BoxedShortArray.scala +++ b/src/library/scala/runtime/BoxedShortArray.scala @@ -21,7 +21,7 @@ final class BoxedShortArray(val value: Array[Short]) extends BoxedArray { def apply(index: Int): Any = Short.box(value(index)) - def update(index: Int, elem: Any): Unit = { + def update(index: Int, elem: Any) { value(index) = Short.unbox(elem.asInstanceOf[AnyRef]) } @@ -45,23 +45,23 @@ final class BoxedShortArray(val value: Array[Short]) extends BoxedArray { var len = 0 var i = 0 while (i < value.length) { - if (p(value(i))) { include(i) = true; len = len + 1 } - i = i + 1 + if (p(value(i))) { include(i) = true; len += 1 } + i += 1 } val result = new Array[Short](len) len = 0 i = 0 while (len < result.length) { - if (include(i)) { result(len) = value(i); len = len + 1 } - i = i + 1 + if (include(i)) { result(len) = value(i); len += 1 } + i += 1 } new BoxedShortArray(result) } final override def slice(start: Int, end: Int): BoxedArray = { - val len = end - start + val (s, len) = slice0(start, end) val result = new Array[Short](len) - Array.copy(value, start, result, 0, len) + Array.copy(value, s, result, 0, len) new BoxedShortArray(result) } } diff --git a/test/files/run/slices.check b/test/files/run/slices.check new file mode 100644 index 0000000000..6840a029b7 --- /dev/null +++ b/test/files/run/slices.check @@ -0,0 +1,36 @@ +List(2) +List() +List(1) +List() +List(1, 2) + +List(1, 2, 3) +List(1, 2, 3) +List(1, 2) +List() +List() + +List(4) +List() +List() +List() +List() + +Array(2) +Array() +Array(1) +Array() +Array(1, 2) + +Array(1, 2, 3) +Array(1, 2, 3) +Array(1, 2) +Array() +Array() + +Array(4) +Array() +Array() +Array() +Array() + diff --git a/test/files/run/slices.scala b/test/files/run/slices.scala new file mode 100644 index 0000000000..14789d3edc --- /dev/null +++ b/test/files/run/slices.scala @@ -0,0 +1,46 @@ +object Test extends Application { + + // lists + println(List(1, 2, 3, 4).slice(1, 2)) + println(List(1, 2, 3, 4).slice(2, 1)) + println(List(1, 2, 3, 4).slice(-1, 1)) + println(List(1, 2, 3, 4).slice(1, -1)) + println(List(1, 2, 3, 4).slice(-2, 2)) + println + + println(List(1, 2, 3, 4) take 3) + println(List(1, 2, 3) take 3) + println(List(1, 2) take 3) + println((List(): List[Int]) take 3) + println(List[Nothing]() take 3) + println + + println(List(1, 2, 3, 4) drop 3) + println(List(1, 2, 3) drop 3) + println(List(1, 2) drop 3) + println((List(): List[Int]) drop 3) + println(List[Nothing]() drop 3) + println + + // arrays + println(Array(1, 2, 3, 4).slice(1, 2)) + println(Array(1, 2, 3, 4).slice(2, 1)) + println(Array(1, 2, 3, 4).slice(-1, 1)) + println(Array(1, 2, 3, 4).slice(1, -1)) + println(Array(1, 2, 3, 4).slice(-2, 2)) + println + + println(Array(1, 2, 3, 4) take 3) + println(Array(1, 2, 3) take 3) + println(Array(1, 2) take 3) + println((Array(): Array[Int]) take 3) + println(Array[Nothing]() take 3) // contrib #757 + println + + println(Array(1, 2, 3, 4) drop 3) + println(Array(1, 2, 3) drop 3) + println(Array(1, 2) drop 3) + println((Array(): Array[Int]) drop 3) + println(Array[Nothing]() drop 3) + println +} -- cgit v1.2.3