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:
parent
0f1992823c
commit
2ea962a689
|
@ -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.
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
abcdabcdabcd
|
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue