Modernized DRMacIver's languishing array patch and added test

cases to exercise primitive to any array conversion.  This fixes
bugs #1300 and #1301.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@17667 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
extempore 2009-05-07 15:43:48 +00:00
parent 0f1992823c
commit 2ea962a689
3 changed files with 36 additions and 44 deletions

View File

@ -21,6 +21,24 @@ import compat.Platform.arraycopy
* @version 1.0
*/
object Array {
import runtime.BoxedArray;
import scala.runtime.ScalaRunTime.boxArray;
private def slowcopy(
src : AnyRef,
srcPos : Int,
dest : AnyRef,
destPos : Int,
length : Int) {
val srcArray = boxArray(src).asInstanceOf[BoxedArray[AnyRef]]
val destArray = boxArray(dest).asInstanceOf[BoxedArray[AnyRef]]
var i = 0;
while(i < length) {
destArray(destPos + i) = srcArray(srcPos + i)
i += 1
}
}
/** Copy one array to another.
* Equivalent to
@ -34,50 +52,11 @@ object Array {
* @param length ...
*/
def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int) {
src match {
case xs: runtime.BoxedArray[_] =>
xs.copyTo(srcPos, dest, destPos, length)
case _ =>
dest match {
case xs: runtime.BoxedArray[_] =>
xs.copyFrom(src, srcPos, destPos, length)
case _ =>
def fillDest[T](da: Array[T], sa: Int=>T) {
var d = destPos
for (s <- srcPos to srcPos+length-1) {
da(d) = sa(s); d += 1
}
}
if (dest.isInstanceOf[Array[Any]]) {
def fill(sa: Int=>Any) = fillDest(dest.asInstanceOf[Array[Any]], sa)
src match {
case sa:Array[Int] => fill(s=>Int.box(sa(s)))
case sa:Array[Long] => fill(s=>Long.box(sa(s)))
case sa:Array[Char] => fill(s=>Char.box(sa(s)))
case sa:Array[Boolean] => fill(s=>Boolean.box(sa(s)))
case sa:Array[Byte] => fill(s=>Byte.box(sa(s)))
case sa:Array[Short] => fill(s=>Short.box(sa(s)))
case sa:Array[Double] => fill(s=>Double.box(sa(s)))
case sa:Array[Float] => fill(s=>Float.box(sa(s)))
case _ => arraycopy(src, srcPos, dest, destPos, length)
}
} else if (dest.isInstanceOf[Array[AnyVal]]) {
def fill(sa: Int=>AnyVal) = fillDest(dest.asInstanceOf[Array[AnyVal]], sa)
src match {
case sa:Array[Int] => fill(sa(_))
case sa:Array[Long] => fill(sa(_))
case sa:Array[Char] => fill(sa(_))
case sa:Array[Boolean] => fill(sa(_))
case sa:Array[Byte] => fill(sa(_))
case sa:Array[Short] => fill(sa(_))
case sa:Array[Double] => fill(sa(_))
case sa:Array[Float] => fill(sa(_))
case _ => arraycopy(src, srcPos, dest, destPos, length)
}
} else
arraycopy(src, srcPos, dest, destPos, length)
}
}
val srcClass = src.getClass
if (srcClass.isArray && dest.getClass.isAssignableFrom(srcClass))
arraycopy(src, srcPos, dest, destPos, length)
else
slowcopy(src, srcPos, dest, destPos, length)
}
/** Concatenate all argument sequences into a single array.

View File

@ -0,0 +1 @@
abcdabcdabcd

View File

@ -0,0 +1,12 @@
object Test extends Application
{
val a1 = Array(0,1,2,3).toArray[Any]
val a2 = Array('a','b','c','d').toArray[Any]
val a3 = Array("e","f","g","h").toArray[Any]
Array.copy(a3, 0, a1, 0, 4)
Array.copy(a2, 0, a3, 0, 4)
Array.copy(a2, 0, a1, 0, 4)
println(a1.mkString + a2.mkString + a3.mkString)
}