diff options
author | Martin Odersky <odersky@gmail.com> | 2009-09-21 12:50:04 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-09-21 12:50:04 +0000 |
commit | d5b02c8652d7edbdfb0b5a02570d370d3bad299f (patch) | |
tree | f57063402f8a83cd3f7caf437afedbdb279be400 /src/library | |
parent | ced5ee337f45d0209ec3e7c69a6e04e956257ec0 (diff) | |
download | scala-d5b02c8652d7edbdfb0b5a02570d370d3bad299f.tar.gz scala-d5b02c8652d7edbdfb0b5a02570d370d3bad299f.tar.bz2 scala-d5b02c8652d7edbdfb0b5a02570d370d3bad299f.zip |
new arrays are done.
Diffstat (limited to 'src/library')
22 files changed, 513 insertions, 623 deletions
diff --git a/src/library/scala/Array.scala b/src/library/scala/Array.scala index bb711be10f..afd6f7bb9b 100644 --- a/src/library/scala/Array.scala +++ b/src/library/scala/Array.scala @@ -13,39 +13,52 @@ package scala import scala.collection.generic._ import scala.collection.Traversable -import scala.collection.mutable.{Vector, ArrayBuilder} +import scala.collection.mutable.{Vector, ArrayBuilder, GenericArray} import compat.Platform.arraycopy import scala.reflect.ClassManifest +import scala.runtime.ScalaRunTime.{array_apply, array_update} + +/** A class containing a fall back builder for arrays where the element type + * does not have a class manifest. In that case a generic array is built. + */ +class FallbackArrayBuilding { + + /** A builder factory that generates a generic array. + * Called instead of Array.newBuilder if the element type of an array + * does not have a class manifest. Note that fallbackBuilder fcatory + * needs an implicit parameter (otherwise it would not be dominated in implicit search + * by Array.builderFactory). We make sure that that implicit search is always + * succesfull. + */ + implicit def fallbackBuilderFactory[T](implicit m: DummyImplicit): BuilderFactory[T, GenericArray[T], Array[_]] = + new BuilderFactory[T, GenericArray[T], Array[_]] { + def apply(from: Array[_]) = GenericArray.newBuilder[T] + } +} /** This object contains utility methods operating on arrays. * * @author Martin Odersky * @version 1.0 */ -object Array { +object Array extends FallbackArrayBuilding { import runtime.BoxedArray; import scala.runtime.ScalaRunTime.boxArray; - implicit def builderFactory[A]/* !!!(implicit m: ClassManifest[A])*/: BuilderFactory[A, Array[A], Array[_]] = - new BuilderFactory[A, Array[A], Array[_]] { def apply(from: Array[_]) = newBuilder[A](null) } - - def newBuilder[A](implicit m: ClassManifest[A]): Builder[A, Array[A]] = - new ArrayBuilder[A](m).asInstanceOf[Builder[A, Array[A]]] // the cast is safe, because the erasure of Array[A] is BoxedArray[A] + implicit def builderFactory[T](implicit m: ClassManifest[T]): BuilderFactory[T, Array[T], Array[_]] = + new BuilderFactory[T, Array[T], Array[_]] { def apply(from: Array[_]) = ArrayBuilder.make[T]()(m) } - private def slowcopy( - src : AnyRef, - srcPos : Int, - dest : AnyRef, - destPos : Int, - length : Int) { + def newBuilder[T](implicit m: ClassManifest[T]): ArrayBuilder[T] = ArrayBuilder.make[T]()(m) - val srcArray = boxArray(src).asInstanceOf[BoxedArray[AnyRef]] - val destArray = boxArray(dest).asInstanceOf[BoxedArray[AnyRef]] - - var i = 0; + private def slowcopy(src : AnyRef, + srcPos : Int, + dest : AnyRef, + destPos : Int, + length : Int) { + var i = 0 while (i < length) { - destArray(destPos + i) = srcArray(srcPos + i) + array_update(dest, i, array_apply(src, i)) i += 1 } } @@ -70,102 +83,115 @@ object Array { } /** Returns array of length 0 */ - def empty[A: ClassManifest]: Array[A] = new Array[A](0) + def empty[T: ClassManifest]: Array[T] = new Array[T](0) /** Create an array with given elements. * * @param xs the elements to put in the array * @return the array containing elements xs. */ - def apply[A: ClassManifest](xs: A*): Array[A] = { - val array = new Array[A](xs.length) + def apply[T: ClassManifest](xs: T*): Array[T] = { + val array = new Array[T](xs.length) var i = 0 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Boolean*): Array[Boolean] = { - val array = new Array[Boolean](xs.length) - var i = 0 + def apply(x: Boolean, xs: Boolean*): Array[Boolean] = { + val array = new Array[Boolean](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Byte*): Array[Byte] = { - val array = new Array[Byte](xs.length) - var i = 0 + def apply(x: Byte, xs: Byte*): Array[Byte] = { + val array = new Array[Byte](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Short*): Array[Short] = { - val array = new Array[Short](xs.length) - var i = 0 + def apply(x: Short, xs: Short*): Array[Short] = { + val array = new Array[Short](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Char*): Array[Char] = { - val array = new Array[Char](xs.length) - var i = 0 + def apply(x: Char, xs: Char*): Array[Char] = { + val array = new Array[Char](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Int*): Array[Int] = { - val array = new Array[Int](xs.length) - var i = 0 + def apply(x: Int, xs: Int*): Array[Int] = { + val array = new Array[Int](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Long*): Array[Long] = { - val array = new Array[Long](xs.length) - var i = 0 + def apply(x: Long, xs: Long*): Array[Long] = { + val array = new Array[Long](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Float*): Array[Float] = { - val array = new Array[Float](xs.length) - var i = 0 + def apply(x: Float, xs: Float*): Array[Float] = { + val array = new Array[Float](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Double*): Array[Double] = { - val array = new Array[Double](xs.length) - var i = 0 + def apply(x: Double, xs: Double*): Array[Double] = { + val array = new Array[Double](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } - def apply(xs: Unit*): Array[Unit] = { - val array = new Array[Unit](xs.length) - var i = 0 + def apply(x: Unit, xs: Unit*): Array[Unit] = { + val array = new Array[Unit](xs.length + 1) + array(0) = x + var i = 1 for (x <- xs.iterator) { array(i) = x; i += 1 } array } /** Create array with given dimensions */ - def ofDim[A: ClassManifest](n1: Int): Array[A] = - new Array[A](n1) - def ofDim[A: ClassManifest](n1: Int, n2: Int): Array[Array[A]] = - tabulate(n1)(_ => ofDim[A](n2)) - def ofDim[A: ClassManifest](n1: Int, n2: Int, n3: Int): Array[Array[Array[A]]] = - tabulate(n1)(_ => ofDim[A](n2, n3)) - def ofDim[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[A]]]] = - tabulate(n1)(_ => ofDim[A](n2, n3, n4)) - def ofDim[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[A]]]]] = - tabulate(n1)(_ => ofDim[A](n2, n3, n4, n5)) + def ofDim[T: ClassManifest](n1: Int): Array[T] = + new Array[T](n1) + def ofDim[T: ClassManifest](n1: Int, n2: Int): Array[Array[T]] = { + val arr: Array[Array[T]] = (new Array[Array[T]](n1): Array[Array[T]]) + for (i <- 0 until n1) arr(i) = new Array[T](n2) + arr + // tabulate(n1)(_ => ofDim[T](n2)) + } + def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = + tabulate(n1)(_ => ofDim[T](n2, n3)) + def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = + tabulate(n1)(_ => ofDim[T](n2, n3, n4)) + def ofDim[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = + tabulate(n1)(_ => ofDim[T](n2, n3, n4, n5)) /** Concatenate all argument sequences into a single array. * * @param xs the given argument sequences * @return the array created from the concatenated arguments */ - def concat[A: ClassManifest](xss: Traversable[A]*): Array[A] = { - val b = newBuilder[A] + def concat[T: ClassManifest](xss: Array[T]*): Array[T] = { + val b = newBuilder[T] b.sizeHint(xss.map(_.size).sum) for (xs <- xss) b ++= xs b.result @@ -177,8 +203,8 @@ object Array { * @param n the number of elements returned * @param elem the element computation */ - def fill[A: ClassManifest](n: Int)(elem: => A): Array[A] = { - val b = newBuilder[A] + def fill[T: ClassManifest](n: Int)(elem: => T): Array[T] = { + val b = newBuilder[T] var i = 0 while (i < n) { b += elem @@ -194,7 +220,7 @@ object Array { * @param n2 the number of elements in the 2nd dimension * @param elem the element computation */ - def fill[A: ClassManifest](n1: Int, n2: Int)(elem: => A): Array[Array[A]] = + def fill[T: ClassManifest](n1: Int, n2: Int)(elem: => T): Array[Array[T]] = tabulate(n1)(_ => fill(n2)(elem)) /** A three-dimensional array that contains the results of some element @@ -205,7 +231,7 @@ object Array { * @param n3 the number of elements in the 3nd dimension * @param elem the element computation */ - def fill[A: ClassManifest](n1: Int, n2: Int, n3: Int)(elem: => A): Array[Array[Array[A]]] = + def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int)(elem: => T): Array[Array[Array[T]]] = tabulate(n1)(_ => fill(n2, n3)(elem)) /** A four-dimensional array that contains the results of some element @@ -217,7 +243,7 @@ object Array { * @param n4 the number of elements in the 4th dimension * @param elem the element computation */ - def fill[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => A): Array[Array[Array[Array[A]]]] = + def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): Array[Array[Array[Array[T]]]] = tabulate(n1)(_ => fill(n2, n3, n4)(elem)) /** A five-dimensional array that contains the results of some element @@ -230,7 +256,7 @@ object Array { * @param n5 the number of elements in the 5th dimension * @param elem the element computation */ - def fill[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => A): Array[Array[Array[Array[Array[A]]]]] = + def fill[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): Array[Array[Array[Array[Array[T]]]]] = tabulate(n1)(_ => fill(n2, n3, n4, n5)(elem)) /** An array containing values of a given function over a range of integer @@ -240,8 +266,8 @@ object Array { * @param f The function computing element values * @return A traversable consisting of elements `f(0), ..., f(n -1)` */ - def tabulate[A: ClassManifest](n: Int)(f: Int => A): Array[A] = { - val b = newBuilder[A] + def tabulate[T: ClassManifest](n: Int)(f: Int => T): Array[T] = { + val b = newBuilder[T] var i = 0 while (i < n) { b += f(i) @@ -257,7 +283,7 @@ object Array { * @param n2 the number of elements in the 2nd dimension * @param f The function computing element values */ - def tabulate[A: ClassManifest](n1: Int, n2: Int)(f: (Int, Int) => A): Array[Array[A]] = + def tabulate[T: ClassManifest](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]] = tabulate(n1)(i1 => tabulate(n2)(f(i1, _))) /** A three-dimensional array containing values of a given function over @@ -268,7 +294,7 @@ object Array { * @param n3 the number of elements in the 3nd dimension * @param f The function computing element values */ - def tabulate[A: ClassManifest](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => A): Array[Array[Array[A]]] = + def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): Array[Array[Array[T]]] = tabulate(n1)(i1 => tabulate(n2, n3)(f(i1, _, _))) /** A four-dimensional array containing values of a given function over @@ -280,7 +306,7 @@ object Array { * @param n4 the number of elements in the 4th dimension * @param f The function computing element values */ - def tabulate[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => A): Array[Array[Array[Array[A]]]] = + def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): Array[Array[Array[Array[T]]]] = tabulate(n1)(i1 => tabulate(n2, n3, n4)(f(i1, _, _, _))) /** A five-dimensional array containing values of a given function over @@ -293,7 +319,7 @@ object Array { * @param n5 the number of elements in the 5th dimension * @param f The function computing element values */ - def tabulate[A: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => A): Array[Array[Array[Array[Array[A]]]]] = + def tabulate[T: ClassManifest](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): Array[Array[Array[Array[Array[T]]]]] = tabulate(n1)(i1 => tabulate(n2, n3, n4, n5)(f(i1, _, _, _, _))) /** An array containing a sequence of increasing integers in a range. @@ -330,8 +356,8 @@ object Array { * @param f the function that's repeatedly applied * @return the array returning `len` values in the sequence `start, f(start), f(f(start)), ...` */ - def iterate[A: ClassManifest](start: A, len: Int)(f: A => A): Array[A] = { - val b = newBuilder[A] + def iterate[T: ClassManifest](start: T, len: Int)(f: T => T): Array[T] = { + val b = newBuilder[T] var acc = start var i = 0 while (i < len) { @@ -347,7 +373,10 @@ object Array { * @param x the selector value * @return sequence wrapped in an option, if this is a Sequence, otherwise none */ - def unapplySeq[A](x: Array[A]): Some[Array[A]] = Some(x) + def unapplySeq[T](x: Array[T]): Option[Vector[T]] = + if (x == null) None else Some(x.toVector) + // !!! the null check should to be necessary, but without it 2241 fails. Seems to be a bug + // in pattern matcher. /** Create an array containing several copies of an element. * @@ -356,8 +385,8 @@ object Array { * @return an array composed of n elements all equal to elem */ @deprecated("use `Array.fill' instead") - def make[A: ClassManifest](n: Int, elem: A): Array[A] = { - val a = new Array[A](n) + def make[T: ClassManifest](n: Int, elem: T): Array[T] = { + val a = new Array[T](n) var i = 0 while (i < n) { a(i) = elem @@ -370,8 +399,8 @@ object Array { * over given range <code>[0..n)</code> */ @deprecated("use `Array.tabulate' instead") - def fromFunction[A: ClassManifest](f: Int => A)(n: Int): Array[A] = { - val a = new Array[A](n) + def fromFunction[T: ClassManifest](f: Int => T)(n: Int): Array[T] = { + val a = new Array[T](n) var i = 0 while (i < n) { a(i) = f(i) @@ -384,28 +413,28 @@ object Array { * over given range <code>[0..n1, 0..n2)</code> */ @deprecated("use `Array.tabulate' instead") - def fromFunction[A: ClassManifest](f: (Int, Int) => A)(n1: Int, n2: Int): Array[Array[A]] = + def fromFunction[T: ClassManifest](f: (Int, Int) => T)(n1: Int, n2: Int): Array[Array[T]] = fromFunction(i => fromFunction(f(i, _))(n2))(n1) /** Create an array containing the values of a given function <code>f</code> * over given range <code>[0..n1, 0..n2, 0..n3)</code> */ @deprecated("use `Array.tabulate' instead") - def fromFunction[A: ClassManifest](f: (Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int): Array[Array[Array[A]]] = + def fromFunction[T: ClassManifest](f: (Int, Int, Int) => T)(n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]] = fromFunction(i => fromFunction(f(i, _, _))(n2, n3))(n1) /** Create an array containing the values of a given function <code>f</code> * over given range <code>[0..n1, 0..n2, 0..n3, 0..n4)</code> */ @deprecated("use `Array.tabulate' instead") - def fromFunction[A: ClassManifest](f: (Int, Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[A]]]] = + def fromFunction[T: ClassManifest](f: (Int, Int, Int, Int) => T)(n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]] = fromFunction(i => fromFunction(f(i, _, _, _))(n2, n3, n4))(n1) /** Create an array containing the values of a given function <code>f</code> * over given range <code>[0..n1, 0..n2, 0..n3, 0..n4, 0..n5)</code> */ @deprecated("use `Array.tabulate' instead") - def fromFunction[A: ClassManifest](f: (Int, Int, Int, Int, Int) => A)(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[A]]]]] = + def fromFunction[T: ClassManifest](f: (Int, Int, Int, Int, Int) => T)(n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]] = fromFunction(i => fromFunction(f(i, _, _, _, _))(n2, n3, n4, n5))(n1) } @@ -415,11 +444,7 @@ object Array { * @author Martin Odersky * @version 1.0 */ -final class Array[A](_length: Int) extends Vector[A] - with TraversableClass[A, Array] - with VectorTemplate[A, Array[A]] { - - override def companion: Companion[Array] = throw new Error() +final class Array[T](_length: Int) { /** Multidimensional array creation */ @deprecated("use `Array.ofDim' instead") @@ -494,7 +519,7 @@ final class Array[A](_length: Int) extends Vector[A] * @throws ArrayIndexOutOfBoundsException if <code>i < 0</code> or * <code>length <= i</code> */ - def apply(i: Int): A = throw new Error() + def apply(i: Int): T = throw new Error() /** <p> * Update the element at given index. @@ -513,74 +538,5 @@ final class Array[A](_length: Int) extends Vector[A] * @throws ArrayIndexOutOfBoundsException if <code>i < 0</code> or * <code>length <= i</code> */ - override def update(i: Int, x: A) { throw new Error() } - - /** Creates a possible nested vector which consists of all the elements - * of this array. If the elements are arrays themselves, the `deep' transformation - * is applied recursively to them. The stringPrefix of the vector is - * "Array", hence the vector prints like an array with all its - * elements shown, and the same recursively for any subarrays. - * - * Example: Array(Array(1, 2), Array(3, 4)).deep.toString - * prints: Array(Array(1, 2), Array(3, 4)) - */ - def deep: Vector[Any] = throw new Error() - - /** - * @return a deep string representation of this array. - */ - @deprecated("use deep.toString instead") - def deepToString(): String = throw new Error() - - /** <p> - * Returns a string representation of this array object. The resulting string - * begins with the string <code>start</code> and is finished by the string - * <code>end</code>. Inside, the string representations of elements (w.r.t. - * the method <code>deepToString()</code>) are separated by the string - * <code>sep</code>. For example: - * </p> - * <p> - * <code>Array(Array(1, 2), Array(3)).deepMkString("[", "; ", "]") = "[[1; 2]; [3]]"</code> - * </p> - * - * @param start starting string. - * @param sep separator string. - * @param end ending string. - * @return a string representation of this array object. - */ - @deprecated("use deep.mkString instead") - def deepMkString(start: String, sep: String, end: String): String = - throw new Error() - - /** Returns a string representation of this array object. The string - * representations of elements (w.r.t. the method <code>deepToString()</code>) - * are separated by the string <code>sep</code>. - * - * @param sep separator string. - * @return a string representation of this array object. - */ - @deprecated("use deep.mkString instead") - def deepMkString(sep: String): String = throw new Error() - - /** <p> - * Returns <code>true</code> if the two specified arrays are - * <em>deeply equal</em> to one another. - * </p> - * <p> - * Two array references are considered deeply equal if both are null, - * or if they refer to arrays that contain the same number of elements - * and all corresponding pairs of elements in the two arrays are deeply - * equal. - * </p> - * <p> - * See also method <code>deepEquals</code> in the Java class - * <a href="http://java.sun.com/javase/6/docs/api/java/util/Arrays.html" - * target="_top">java.utils.Arrays</a> - * </p> - * - * @param that the second - * @return <code>true</code> iff both arrays are deeply equal. - */ - @deprecated("use array1.deep.equals(array2.deep) instead") - def deepEquals(that: Any): Boolean = throw new Error() + def update(i: Int, x: T) { throw new Error() } } diff --git a/src/library/scala/LowPriorityImplicits.scala b/src/library/scala/LowPriorityImplicits.scala index ea12c07d63..58796b4ddc 100644 --- a/src/library/scala/LowPriorityImplicits.scala +++ b/src/library/scala/LowPriorityImplicits.scala @@ -20,20 +20,10 @@ import collection.immutable.WrappedString */ class LowPriorityImplicits { - implicit def genericWapArray[T](xs: Array[T]): WrappedArray[T] = (xs: AnyRef) match { // !!! drop the AnyRef and get unreachable code errors! - case x: Array[AnyRef] => wrapArray[AnyRef](x).asInstanceOf[WrappedArray[T]] - case x: Array[Int] => wrapArray(x).asInstanceOf[WrappedArray[T]] - case x: Array[Double] => wrapArray(x).asInstanceOf[WrappedArray[T]] - case x: Array[Long] => wrapArray(x).asInstanceOf[WrappedArray[T]] - case x: Array[Float] => wrapArray(x).asInstanceOf[WrappedArray[T]] - case x: Array[Char] => wrapArray(x).asInstanceOf[WrappedArray[T]] - case x: Array[Byte] => wrapArray(x).asInstanceOf[WrappedArray[T]] - case x: Array[Short] => wrapArray(x).asInstanceOf[WrappedArray[T]] - case x: Array[Boolean] => wrapArray(x).asInstanceOf[WrappedArray[T]] - case x: Array[Unit] => wrapArray(x).asInstanceOf[WrappedArray[T]] - } - - implicit def wrapArray[T <: AnyRef](xs: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](xs.asInstanceOf[Array[AnyRef]]) + implicit def genericWrapArray[T](xs: Array[T]): WrappedArray[T] = + WrappedArray.make(xs) + + implicit def wrapArray[T <: AnyRef](xs: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](xs) implicit def wrapArray(xs: Array[Int]): WrappedArray[Int] = new WrappedArray.ofInt(xs) implicit def wrapArray(xs: Array[Double]): WrappedArray[Double] = new WrappedArray.ofDouble(xs) implicit def wrapArray(xs: Array[Long]): WrappedArray[Long] = new WrappedArray.ofLong(xs) diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala index 1412fbc924..3ab86869d1 100644 --- a/src/library/scala/Predef.scala +++ b/src/library/scala/Predef.scala @@ -12,7 +12,7 @@ package scala import collection.immutable.StringOps -import collection.mutable.{StringBuilder, ArrayOps} +import collection.mutable.ArrayOps import collection.generic.BuilderFactory /** The <code>Predef</code> object provides definitions that are @@ -67,7 +67,7 @@ object Predef extends LowPriorityImplicits { private val P = scala.`package` // to force scala package object to be seen. private val L = scala.collection.immutable.List // to force Nil, :: to be seen. - private val S = StringBuilder // to force StringBuilder to be seen. + private val S = scala.collection.mutable.StringBuilder // to force StringBuilder to be seen. val $scope = scala.xml.TopScope @@ -81,7 +81,7 @@ object Predef extends LowPriorityImplicits { type Manifest[T] = scala.reflect.Manifest[T] type ClassManifest[T] = scala.reflect.ClassManifest[T] - def evidence[T](implicit e: T) = e + def implicitly[T](implicit e: T) = e def manifest[T](implicit m: Manifest[T]) = m def classManifest[T](implicit m: ClassManifest[T]) = m @@ -89,6 +89,8 @@ object Predef extends LowPriorityImplicits { // @see `conforms` for the implicit version implicit def identity[A](x: A): A = x + def currentThread = java.lang.Thread.currentThread() + // errors and asserts ------------------------------------------------- def error(message: String): Nothing = throw new RuntimeException(message) @@ -214,7 +216,7 @@ object Predef extends LowPriorityImplicits { implicit def unaugmentString(x: StringOps): String = x.repr implicit def stringBuilderFactory: BuilderFactory[Char, String, String] = - new BuilderFactory[Char, String, String] { def apply(from: String) = new StringBuilder } + new BuilderFactory[Char, String, String] { def apply(from: String) = new scala.collection.mutable.StringBuilder } implicit def any2stringadd(x: Any) = new runtime.StringAdd(x) @@ -229,9 +231,10 @@ object Predef extends LowPriorityImplicits { case x: Array[Short] => arrayOps(x).asInstanceOf[ArrayOps[T]] case x: Array[Boolean] => arrayOps(x).asInstanceOf[ArrayOps[T]] case x: Array[Unit] => arrayOps(x).asInstanceOf[ArrayOps[T]] + case null => null } - implicit def arrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs.asInstanceOf[Array[AnyRef]]) + implicit def arrayOps[T <: AnyRef](xs: Array[T]): ArrayOps[T] = new ArrayOps.ofRef[T](xs) implicit def arrayOps(xs: Array[Int]): ArrayOps[Int] = new ArrayOps.ofInt(xs) implicit def arrayOps(xs: Array[Double]): ArrayOps[Double] = new ArrayOps.ofDouble(xs) implicit def arrayOps(xs: Array[Long]): ArrayOps[Long] = new ArrayOps.ofLong(xs) @@ -294,6 +297,13 @@ object Predef extends LowPriorityImplicits { override def toString: String = xs.mkString("") } + implicit def arrayToCharSequence(xs: Array[Char]): CharSequence = new CharSequence { + def length: Int = xs.length + def charAt(index: Int): Char = xs(index) + def subSequence(start: Int, end: Int): CharSequence = arrayToCharSequence(xs.slice(start, end)) + override def toString: String = xs.mkString("") + } + // used, for example, in the encoding of generalized constraints // we need a new type constructor `<:<` and evidence `conforms`, as // reusing `Function2` and `identity` leads to ambiguities (any2stringadd is inferred) @@ -302,5 +312,16 @@ object Predef extends LowPriorityImplicits { sealed abstract class <:<[-From, +To] //extends (From => To) implicit def conforms[A]: A <:< A = new (A <:< A) {def convert(x: A) = x} - def currentThread = java.lang.Thread.currentThread() + /** A type for which there is aways an implicit value. + * @see fallbackBuilderFactory in Array.scala + */ + class DummyImplicit + + object DummyImplicit { + + /** An implicit value yielding a DummyImplicit. + * @see fallbackBuilderFactory in Array.scala + */ + implicit def dummyImplicit: DummyImplicit = new DummyImplicit + } } diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala index b8888c3aef..be4f7a6e9d 100644 --- a/src/library/scala/collection/immutable/PagedSeq.scala +++ b/src/library/scala/collection/immutable/PagedSeq.scala @@ -21,7 +21,7 @@ object PagedSeq { final val UndeterminedEnd = Math.MAX_INT /** Constructs a character sequence from a character iterator */ - def fromIterator[T](source: Iterator[T]): PagedSeq[T] = + def fromIterator[T: ClassManifest](source: Iterator[T]): PagedSeq[T] = new PagedSeq[T]((data: Array[T], start: Int, len: Int) => { var i = 0 while (i < len && source.hasNext) { @@ -32,7 +32,7 @@ object PagedSeq { }) /** Constructs a character sequence from a character iterable */ - def fromIterable[T](source: Iterable[T]): PagedSeq[T] = + def fromIterable[T: ClassManifest](source: Iterable[T]): PagedSeq[T] = fromIterator(source.iterator) /** Constructs a character sequence from a string iterator */ @@ -107,7 +107,7 @@ import PagedSeq._ * * @author Martin Odersky */ -class PagedSeq[T] protected( +class PagedSeq[T: ClassManifest] protected( more: (Array[T], Int, Int) => Int, first1: Page[T], start: Int, @@ -191,7 +191,7 @@ extends collection.Vector[T] /** Page containing up to PageSize characters of the input sequence. */ -private class Page[T](val num: Int) { +private class Page[T: ClassManifest](val num: Int) { private final val PageSize = 4096 diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala index 5813c86607..cad2ae2700 100644 --- a/src/library/scala/collection/immutable/StringLike.scala +++ b/src/library/scala/collection/immutable/StringLike.scala @@ -228,7 +228,7 @@ self => * @throws java.lang.IllegalArgumentException */ def format(args : Any*) : String = - java.lang.String.format(toString, args.asInstanceOf[Seq[AnyRef]].toArray: _*) + java.lang.String.format(toString, args.asInstanceOf[Seq[AnyRef]]: _*) /** <p> * Like format(args*) but takes an initial Locale parameter @@ -245,6 +245,6 @@ self => * @throws java.lang.IllegalArgumentException */ def format(l: java.util.Locale, args: Any*): String = - java.lang.String.format(l, toString, args.asInstanceOf[Seq[AnyRef]].toArray: _*) + java.lang.String.format(l, toString, args.asInstanceOf[Seq[AnyRef]]: _*) } diff --git a/src/library/scala/collection/mutable/ArrayBuffer.scala b/src/library/scala/collection/mutable/ArrayBuffer.scala index 55a4870748..d47a7cec9e 100644 --- a/src/library/scala/collection/mutable/ArrayBuffer.scala +++ b/src/library/scala/collection/mutable/ArrayBuffer.scala @@ -40,9 +40,11 @@ class ArrayBuffer[A](override protected val initialSize: Int) def clear() { reduceToSize(0) } override def sizeHint(len: Int) { - val newarray = new Array[AnyRef](len min 1) - Array.copy(array, 0, newarray, 0, size0) - array = newarray + if (len > size && len >= 1) { + val newarray = new Array[AnyRef](len min 1) + Array.copy(array, 0, newarray, 0, size0) + array = newarray + } } /** Appends a single element to this buffer and returns diff --git a/src/library/scala/collection/mutable/ArrayBuilder.scala b/src/library/scala/collection/mutable/ArrayBuilder.scala index 10f6b1ba10..bf5c34694b 100755 --- a/src/library/scala/collection/mutable/ArrayBuilder.scala +++ b/src/library/scala/collection/mutable/ArrayBuilder.scala @@ -16,70 +16,21 @@ import scala.reflect.ClassManifest import scala.runtime.BoxedArray /** A builder class for arrays */ -class ArrayBuilder[A](manifest: ClassManifest[A]) extends Builder[A, BoxedArray[A]] { - - private var elems: BoxedArray[A] = _ - private var capacity: Int = 0 - private var size: Int = 0 - - private def mkArray(size: Int): BoxedArray[A] = { - if (false && manifest != null) { // !!! - val newelems = manifest.newArray(size) - if (this.size > 0) Array.copy(elems.value, 0, newelems.value, 0, this.size) - newelems - } else { // !!! - val newelems = new scala.runtime.BoxedAnyArray[A](size) - if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) - newelems - } - } - - private def resize(size: Int) { - elems = mkArray(size) - capacity = size - } - - override def sizeHint(size: Int) { - if (capacity < size) resize(size) - } - - private def ensureSize(size: Int) { - if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 - while (newsize < size) newsize *= 2 - resize(newsize) - } - } - - def +=(elem: A): this.type = { - ensureSize(size + 1) - elems(size) = elem - size += 1 - this - } - - def clear() { - size = 0 - } - - def result() = { - if (capacity != 0 && capacity == size) elems - else mkArray(size) - } - - // todo: add ++= -} +abstract class ArrayBuilder[T] extends Builder[T, Array[T]] object ArrayBuilder { - class ofRef[T <: AnyRef] extends Builder[T, Array[AnyRef]] { + def make[T: ClassManifest](): ArrayBuilder[T] = + implicitly[ClassManifest[T]].newArrayBuilder() + + class ofRef[T <: AnyRef : ClassManifest] extends ArrayBuilder[T] { - private var elems: Array[AnyRef] = _ + private var elems: Array[T] = _ private var capacity: Int = 0 private var size: Int = 0 - private def mkArray(size: Int): Array[AnyRef] = { - val newelems = new Array[AnyRef](size) + private def mkArray(size: Int): Array[T] = { + val newelems = new Array[T](size) if (this.size > 0) Array.copy(elems, 0, newelems, 0, this.size) newelems } @@ -94,8 +45,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -111,7 +63,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[T]): this.type = (xs: AnyRef) match { case xs: WrappedArray.ofRef[_] => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -128,7 +80,7 @@ object ArrayBuilder { } } - class ofByte extends Builder[Byte, Array[Byte]] { + class ofByte extends ArrayBuilder[Byte] { private var elems: Array[Byte] = _ private var capacity: Int = 0 @@ -150,8 +102,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -167,7 +120,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Byte]): this.type = xs match { case xs: WrappedArray.ofByte => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -184,7 +137,7 @@ object ArrayBuilder { } } - class ofShort extends Builder[Short, Array[Short]] { + class ofShort extends ArrayBuilder[Short] { private var elems: Array[Short] = _ private var capacity: Int = 0 @@ -206,8 +159,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -223,7 +177,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Short]): this.type = xs match { case xs: WrappedArray.ofShort => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -240,7 +194,7 @@ object ArrayBuilder { } } - class ofChar extends Builder[Char, Array[Char]] { + class ofChar extends ArrayBuilder[Char] { private var elems: Array[Char] = _ private var capacity: Int = 0 @@ -262,8 +216,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -279,7 +234,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Char]): this.type = xs match { case xs: WrappedArray.ofChar => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -296,7 +251,7 @@ object ArrayBuilder { } } - class ofInt extends Builder[Int, Array[Int]] { + class ofInt extends ArrayBuilder[Int] { private var elems: Array[Int] = _ private var capacity: Int = 0 @@ -318,8 +273,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -335,7 +291,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Int]): this.type = xs match { case xs: WrappedArray.ofInt => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -352,7 +308,7 @@ object ArrayBuilder { } } - class ofLong extends Builder[Long, Array[Long]] { + class ofLong extends ArrayBuilder[Long] { private var elems: Array[Long] = _ private var capacity: Int = 0 @@ -374,8 +330,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -391,7 +348,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Long]): this.type = xs match { case xs: WrappedArray.ofLong => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -408,7 +365,7 @@ object ArrayBuilder { } } - class ofFloat extends Builder[Float, Array[Float]] { + class ofFloat extends ArrayBuilder[Float] { private var elems: Array[Float] = _ private var capacity: Int = 0 @@ -430,8 +387,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -447,7 +405,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Float]): this.type = xs match { case xs: WrappedArray.ofFloat => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -464,7 +422,7 @@ object ArrayBuilder { } } - class ofDouble extends Builder[Double, Array[Double]] { + class ofDouble extends ArrayBuilder[Double] { private var elems: Array[Double] = _ private var capacity: Int = 0 @@ -486,8 +444,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -503,7 +462,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Double]): this.type = xs match { case xs: WrappedArray.ofDouble => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -520,7 +479,7 @@ object ArrayBuilder { } } - class ofBoolean extends Builder[Boolean, Array[Boolean]] { + class ofBoolean extends ArrayBuilder[Boolean] { private var elems: Array[Boolean] = _ private var capacity: Int = 0 @@ -542,8 +501,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -559,7 +519,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Boolean]): this.type = xs match { case xs: WrappedArray.ofBoolean => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => @@ -576,7 +536,7 @@ object ArrayBuilder { } } - class ofUnit extends Builder[Unit, Array[Unit]] { + class ofUnit extends ArrayBuilder[Unit] { private var elems: Array[Unit] = _ private var capacity: Int = 0 @@ -598,8 +558,9 @@ object ArrayBuilder { } private def ensureSize(size: Int) { + if (capacity == 0) resize(16) if (capacity < size) { - var newsize = if (capacity == 0) 16 else capacity * 2 + var newsize = capacity * 2 while (newsize < size) newsize *= 2 resize(newsize) } @@ -615,7 +576,7 @@ object ArrayBuilder { override def ++=(xs: scala.collection.Traversable[Unit]): this.type = xs match { case xs: WrappedArray.ofUnit => ensureSize(this.size + xs.length) - Array.copy(elems, this.size, xs.array, 0, xs.length) + Array.copy(xs.array, 0, elems, this.size, xs.length) size += xs.length this case _ => diff --git a/src/library/scala/collection/mutable/ArrayLike.scala b/src/library/scala/collection/mutable/ArrayLike.scala new file mode 100644 index 0000000000..939c8b3ccb --- /dev/null +++ b/src/library/scala/collection/mutable/ArrayLike.scala @@ -0,0 +1,56 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: MutableVectorTemplate.scala 18387 2009-07-24 15:28:37Z odersky $ + + +package scala.collection +package mutable +import generic._ + +/** A subtrait of collection.Vector which represents sequences + * that can be mutated. + */ +trait ArrayLike[A, +Repr] extends VectorLike[A, Repr] { self => + + /** Creates a possible nested vector which consists of all the elements + * of this array. If the elements are arrays themselves, the `deep' transformation + * is applied recursively to them. The stringPrefix of the vector is + * "Array", hence the vector prints like an array with all its + * elements shown, and the same recursively for any subarrays. + * + * Example: Array(Array(1, 2), Array(3, 4)).deep.toString + * prints: Array(Array(1, 2), Array(3, 4)) + */ + def deep: scala.collection.Vector[Any] = new collection.Vector[Any] { + def length = self.length + def apply(idx: Int): Any = self.apply(idx) match { + case x: AnyRef if x.getClass.isArray => WrappedArray.make(x).deep + case x => x + } + override def stringPrefix = "Array" + } + + @deprecated("use deep.toString instead") + final def deepToString() = + deep.toString + + @deprecated("use deep.mkString instead") + final def deepMkString(start: String, sep: String, end: String): String = + deep.mkString(start, sep, end) + + @deprecated("use deep.mkString instead") + final def deepMkString(sep: String): String = + deepMkString("", sep, "") + + @deprecated("use array1.deep.equals(array2.deep) instead") + final def deepEquals(that: Any): Boolean = that match { + case x: AnyRef if x.getClass.isArray => deep.equals(WrappedArray.make(x).deep) + case _ => false + } +} diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index 6a85d7cd02..b5c0d0e458 100755 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -12,24 +12,61 @@ package scala.collection package mutable -abstract class ArrayOps[T] extends VectorLike[T, AnyRef /*!!!Array[T]!!!*/] { -} +import generic.Builder + +import scala.reflect.ClassManifest + +abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] { + + private def rowBuilder[U]: Builder[U, Array[U]] = + Array.newBuilder( + ClassManifest.fromClass( + repr.getClass.getComponentType.getComponentType.asInstanceOf[Predef.Class[U]])) + /** Flattens a two-dimensional array by concatenating all its rows + * into a single array + */ + def flatten[U](implicit asArray: T => /*<:<!!!*/ Array[U]): Array[U] = { + val b = rowBuilder[U] + for (xs <- this) + b ++= asArray(xs) + b.result + } + + /** Transposes a two dimensional array + */ + def transpose[U](implicit asArray: T => Array[U]): Array[Array[U]] = { + val bs = asArray(head) map (_ => rowBuilder[U]) + for (xs <- this) { + var i = 0 + for (x <- asArray(xs)) { + bs(i) += x + i += 1 + } + } + val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder( + ClassManifest.fromClass( + repr.getClass.getComponentType.asInstanceOf[Predef.Class[Array[U]]])) + for (b <- bs) bb += b.result + bb.result + } +} object ArrayOps { - class ofRef[T <: AnyRef](override val repr: Array[AnyRef]) extends ArrayOps[T] with VectorLike[T, Array[AnyRef]] { + class ofRef[T <: AnyRef](override val repr: Array[T]) extends ArrayOps[T] with ArrayLike[T, Array[T]] { override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr) - override protected[this] def toCollection(repr: Array[AnyRef]): WrappedArray[T] = new WrappedArray.ofRef[T](repr) - override protected[this] def newBuilder = new ArrayBuilder.ofRef[T] + override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr) + override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()( + ClassManifest.classType[T](repr.getClass.getComponentType)) def length: Int = repr.length - def apply(index: Int): T = repr(index).asInstanceOf[T] - def update(index: Int, elem: T) { repr(index) = elem.asInstanceOf[AnyRef] } + def apply(index: Int): T = repr(index) + def update(index: Int, elem: T) { repr(index) = elem } } - class ofByte(override val repr: Array[Byte]) extends ArrayOps[Byte] with VectorLike[Byte, Array[Byte]] { + class ofByte(override val repr: Array[Byte]) extends ArrayOps[Byte] with ArrayLike[Byte, Array[Byte]] { override protected[this] def thisCollection: WrappedArray[Byte] = new WrappedArray.ofByte(repr) override protected[this] def toCollection(repr: Array[Byte]): WrappedArray[Byte] = new WrappedArray.ofByte(repr) @@ -40,7 +77,7 @@ object ArrayOps { def update(index: Int, elem: Byte) { repr(index) = elem } } - class ofShort(override val repr: Array[Short]) extends ArrayOps[Short] with VectorLike[Short, Array[Short]] { + class ofShort(override val repr: Array[Short]) extends ArrayOps[Short] with ArrayLike[Short, Array[Short]] { override protected[this] def thisCollection: WrappedArray[Short] = new WrappedArray.ofShort(repr) override protected[this] def toCollection(repr: Array[Short]): WrappedArray[Short] = new WrappedArray.ofShort(repr) @@ -51,7 +88,7 @@ object ArrayOps { def update(index: Int, elem: Short) { repr(index) = elem } } - class ofChar(override val repr: Array[Char]) extends ArrayOps[Char] with VectorLike[Char, Array[Char]] { + class ofChar(override val repr: Array[Char]) extends ArrayOps[Char] with ArrayLike[Char, Array[Char]] { override protected[this] def thisCollection: WrappedArray[Char] = new WrappedArray.ofChar(repr) override protected[this] def toCollection(repr: Array[Char]): WrappedArray[Char] = new WrappedArray.ofChar(repr) @@ -62,7 +99,7 @@ object ArrayOps { def update(index: Int, elem: Char) { repr(index) = elem } } - class ofInt(override val repr: Array[Int]) extends ArrayOps[Int] with VectorLike[Int, Array[Int]] { + class ofInt(override val repr: Array[Int]) extends ArrayOps[Int] with ArrayLike[Int, Array[Int]] { override protected[this] def thisCollection: WrappedArray[Int] = new WrappedArray.ofInt(repr) override protected[this] def toCollection(repr: Array[Int]): WrappedArray[Int] = new WrappedArray.ofInt(repr) @@ -73,7 +110,7 @@ object ArrayOps { def update(index: Int, elem: Int) { repr(index) = elem } } - class ofLong(override val repr: Array[Long]) extends ArrayOps[Long] with VectorLike[Long, Array[Long]] { + class ofLong(override val repr: Array[Long]) extends ArrayOps[Long] with ArrayLike[Long, Array[Long]] { override protected[this] def thisCollection: WrappedArray[Long] = new WrappedArray.ofLong(repr) override protected[this] def toCollection(repr: Array[Long]): WrappedArray[Long] = new WrappedArray.ofLong(repr) @@ -84,7 +121,7 @@ object ArrayOps { def update(index: Int, elem: Long) { repr(index) = elem } } - class ofFloat(override val repr: Array[Float]) extends ArrayOps[Float] with VectorLike[Float, Array[Float]] { + class ofFloat(override val repr: Array[Float]) extends ArrayOps[Float] with ArrayLike[Float, Array[Float]] { override protected[this] def thisCollection: WrappedArray[Float] = new WrappedArray.ofFloat(repr) override protected[this] def toCollection(repr: Array[Float]): WrappedArray[Float] = new WrappedArray.ofFloat(repr) @@ -95,7 +132,7 @@ object ArrayOps { def update(index: Int, elem: Float) { repr(index) = elem } } - class ofDouble(override val repr: Array[Double]) extends ArrayOps[Double] with VectorLike[Double, Array[Double]] { + class ofDouble(override val repr: Array[Double]) extends ArrayOps[Double] with ArrayLike[Double, Array[Double]] { override protected[this] def thisCollection: WrappedArray[Double] = new WrappedArray.ofDouble(repr) override protected[this] def toCollection(repr: Array[Double]): WrappedArray[Double] = new WrappedArray.ofDouble(repr) @@ -106,7 +143,7 @@ object ArrayOps { def update(index: Int, elem: Double) { repr(index) = elem } } - class ofBoolean(override val repr: Array[Boolean]) extends ArrayOps[Boolean] with VectorLike[Boolean, Array[Boolean]] { + class ofBoolean(override val repr: Array[Boolean]) extends ArrayOps[Boolean] with ArrayLike[Boolean, Array[Boolean]] { override protected[this] def thisCollection: WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr) override protected[this] def toCollection(repr: Array[Boolean]): WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr) @@ -117,7 +154,7 @@ object ArrayOps { def update(index: Int, elem: Boolean) { repr(index) = elem } } - class ofUnit(override val repr: Array[Unit]) extends ArrayOps[Unit] with VectorLike[Unit, Array[Unit]] { + class ofUnit(override val repr: Array[Unit]) extends ArrayOps[Unit] with ArrayLike[Unit, Array[Unit]] { override protected[this] def thisCollection: WrappedArray[Unit] = new WrappedArray.ofUnit(repr) override protected[this] def toCollection(repr: Array[Unit]): WrappedArray[Unit] = new WrappedArray.ofUnit(repr) diff --git a/src/library/scala/collection/mutable/StringBuilder.scala b/src/library/scala/collection/mutable/StringBuilder.scala index 6f7ecc8c70..a5eab238e5 100644 --- a/src/library/scala/collection/mutable/StringBuilder.scala +++ b/src/library/scala/collection/mutable/StringBuilder.scala @@ -716,7 +716,7 @@ final class StringBuilder(initCapacity: Int, private val initValue: String) * substring, <code>-1</code> is returned. * @throws NullPointerException if <code>str</code> is <code>null</code>. */ - def indexOf(str: String): Int = indexOfSeq(str.toArray) + def indexOf(str: String): Int = indexOf(str, 0) /** <p> * Returns the index within this string of the first occurrence of the @@ -735,7 +735,7 @@ final class StringBuilder(initCapacity: Int, private val initValue: String) * @return the index within this string of the first occurrence * of the specified substring, starting at the specified index. */ - def indexOf(str: String, fromIndex: Int): Int = indexOfSeq(str.toArray, fromIndex) + def indexOf(str: String, fromIndex: Int): Int = indexOfSeq(str.toVector, fromIndex) /** <p> * Returns the index within this string of the rightmost occurrence @@ -757,7 +757,7 @@ final class StringBuilder(initCapacity: Int, private val initValue: String) * a substring, <code>-1</code> is returned. * @throws NullPointerException if <code>str</code> is <code>null</code>. */ - def lastIndexOf(str: String): Int = lastIndexOfSeq(str.toArray, count) + def lastIndexOf(str: String): Int = lastIndexOf(str, count) /** <p> * Returns the index within this string of the last occurrence of the @@ -776,7 +776,7 @@ final class StringBuilder(initCapacity: Int, private val initValue: String) * @return the index within this sequence of the last occurrence * of the specified substring. */ - def lastIndexOf(str: String, fromIndex: Int): Int = lastIndexOfSeq(str.toArray, fromIndex) + def lastIndexOf(str: String, fromIndex: Int): Int = lastIndexOfSeq(str.toVector, fromIndex) /** <p> * Causes this character sequence to be replaced by the reverse of the diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 020843aabc..46b9d3fa4a 100755 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -21,185 +21,134 @@ import collection.generic._ * @author Martin Odersky, Stephane Micheloud * @version 1.0 */ -abstract class WrappedArray[A] extends Vector[A] with VectorLike[A, WrappedArray[A]] with Proxy { self => +abstract class WrappedArray[T] extends Vector[T] with ArrayLike[T, WrappedArray[T]] { - override protected[this] def thisCollection: WrappedArray[A] = this - override protected[this] def toCollection(repr: WrappedArray[A]): WrappedArray[A] = repr + override protected[this] def thisCollection: WrappedArray[T] = this + override protected[this] def toCollection(repr: WrappedArray[T]): WrappedArray[T] = repr /** The manifest of the element type */ - def elemManifest: ClassManifest[A] + def elemManifest: ClassManifest[T] /** The length of the array */ def length: Int /** The element at given index */ - def apply(index: Int): A + def apply(index: Int): T /** Update element at given index */ - def update(index: Int, elem: A): Unit + def update(index: Int, elem: T): Unit /** The underlying array */ - def array: AnyRef + def array: Array[T] - /** The original of a proxy represented by a wrapped array */ - override def self = repr + override def stringPrefix = "Array" /** Creates new builder for this collection ==> move to subclasses */ - override protected[this] def newBuilder: Builder[A, WrappedArray[A]] = - new WrappedArrayBuilder[A](elemManifest) + override protected[this] def newBuilder: Builder[T, WrappedArray[T]] = + new WrappedArrayBuilder[T](elemManifest) } object WrappedArray { - @serializable - final class ofRef[T](val array: Array[AnyRef]) extends WrappedArray[T] { + def make[T](x: AnyRef): WrappedArray[T] = x match { + case x: Array[AnyRef] => wrapArray[AnyRef](x).asInstanceOf[WrappedArray[T]] + case x: Array[Int] => wrapArray(x).asInstanceOf[WrappedArray[T]] + case x: Array[Double] => wrapArray(x).asInstanceOf[WrappedArray[T]] + case x: Array[Long] => wrapArray(x).asInstanceOf[WrappedArray[T]] + case x: Array[Float] => wrapArray(x).asInstanceOf[WrappedArray[T]] + case x: Array[Char] => wrapArray(x).asInstanceOf[WrappedArray[T]] + case x: Array[Byte] => wrapArray(x).asInstanceOf[WrappedArray[T]] + case x: Array[Short] => wrapArray(x).asInstanceOf[WrappedArray[T]] + case x: Array[Boolean] => wrapArray(x).asInstanceOf[WrappedArray[T]] + case x: Array[Unit] => wrapArray(x).asInstanceOf[WrappedArray[T]] + } - lazy val elemManifest = ClassManifest.classType[T](array.getClass.getComponentType) + implicit def builderFactory[T](implicit m: ClassManifest[T]): BuilderFactory[T, WrappedArray[T], WrappedArray[_]] = + new BuilderFactory[T, WrappedArray[T], WrappedArray[_]] { + def apply(from: WrappedArray[_]): Builder[T, WrappedArray[T]] = + ArrayBuilder.make[T]()(m) mapResult WrappedArray.make[T] + } - def length: Int = array.length + def newBuilder[A]: Builder[A, Vector[A]] = new ArrayBuffer + @serializable + final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] { + lazy val elemManifest = ClassManifest.classType[T](array.getClass.getComponentType) + def length: Int = array.length def apply(index: Int): T = array(index).asInstanceOf[T] - - def update(index: Int, elem: T) { - array(index) = elem.asInstanceOf[AnyRef] - } - - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: T) { array(index) = elem } } @serializable final class ofByte(val array: Array[Byte]) extends WrappedArray[Byte] { - def elemManifest = ClassManifest.Byte - def length: Int = array.length - def apply(index: Int): Byte = array(index) - - def update(index: Int, elem: Byte) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Byte) { array(index) = elem } } @serializable final class ofShort(val array: Array[Short]) extends WrappedArray[Short] { - def elemManifest = ClassManifest.Short - def length: Int = array.length - def apply(index: Int): Short = array(index) - - def update(index: Int, elem: Short) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Short) { array(index) = elem } } @serializable final class ofChar(val array: Array[Char]) extends WrappedArray[Char] { - def elemManifest = ClassManifest.Char - def length: Int = array.length - def apply(index: Int): Char = array(index) - - def update(index: Int, elem: Char) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Char) { array(index) = elem } } @serializable final class ofInt(val array: Array[Int]) extends WrappedArray[Int] { - def elemManifest = ClassManifest.Int - def length: Int = array.length - def apply(index: Int): Int = array(index) - - def update(index: Int, elem: Int) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Int) { array(index) = elem } } @serializable final class ofLong(val array: Array[Long]) extends WrappedArray[Long] { - def elemManifest = ClassManifest.Long - def length: Int = array.length - def apply(index: Int): Long = array(index) - - def update(index: Int, elem: Long) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Long) { array(index) = elem } } @serializable final class ofFloat(val array: Array[Float]) extends WrappedArray[Float] { - def elemManifest = ClassManifest.Float - def length: Int = array.length - def apply(index: Int): Float = array(index) - - def update(index: Int, elem: Float) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Float) { array(index) = elem } } @serializable final class ofDouble(val array: Array[Double]) extends WrappedArray[Double] { - def elemManifest = ClassManifest.Double - def length: Int = array.length - def apply(index: Int): Double = array(index) - - def update(index: Int, elem: Double) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Double) { array(index) = elem } } @serializable final class ofBoolean(val array: Array[Boolean]) extends WrappedArray[Boolean] { - def elemManifest = ClassManifest.Boolean - def length: Int = array.length - def apply(index: Int): Boolean = array(index) - - def update(index: Int, elem: Boolean) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Boolean) { array(index) = elem } } @serializable final class ofUnit(val array: Array[Unit]) extends WrappedArray[Unit] { - def elemManifest = ClassManifest.Unit - def length: Int = array.length - def apply(index: Int): Unit = array(index) - - def update(index: Int, elem: Unit) { - array(index) = elem - } - def unbox(elemClass: Class[_]): AnyRef = array + def update(index: Int, elem: Unit) { array(index) = elem } } } diff --git a/src/library/scala/io/BytePickle.scala b/src/library/scala/io/BytePickle.scala index b468ba4b52..558a299399 100644 --- a/src/library/scala/io/BytePickle.scala +++ b/src/library/scala/io/BytePickle.scala @@ -65,8 +65,8 @@ object BytePickle { def refDef: PU[RefDef] = new PU[RefDef] { def appP(b: RefDef, s: Array[Byte]): Array[Byte] = b match { - case Ref() => Array.concat(s, (List[Byte](0)).toArray) - case Def() => Array.concat(s, (List[Byte](1)).toArray) + case Ref() => Array.concat(s, Array[Byte](0)) + case Def() => Array.concat(s, Array[Byte](1)) }; def appU(s: Array[Byte]): (RefDef, Array[Byte]) = if (s(0) == 0) (Ref(), s.slice(1, s.length)) @@ -229,7 +229,7 @@ object BytePickle { sequ(j, pa, (x: a) => lift(i(x))) def appendByte(a: Array[Byte], b: Int): Array[Byte] = - Array.concat(a, (List[Byte](b.asInstanceOf[Byte])).toArray) + Array.concat(a, Array(b.toByte)) def nat2Bytes(x: Int): Array[Byte] = { val buf = new ArrayBuffer[Byte] @@ -266,7 +266,7 @@ object BytePickle { def byte: SPU[Byte] = new SPU[Byte] { def appP(b: Byte, s: PicklerState): PicklerState = - new PicklerState(Array.concat(s.stream, (List[Byte](b)).toArray), s.dict); + new PicklerState(Array.concat(s.stream, Array(b)), s.dict) def appU(s: UnPicklerState): (Byte, UnPicklerState) = (s.stream(0), new UnPicklerState(s.stream.slice(1, s.stream.length), s.dict)); } diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala index 68183580ce..4dc9631710 100644 --- a/src/library/scala/reflect/ClassManifest.scala +++ b/src/library/scala/reflect/ClassManifest.scala @@ -13,7 +13,7 @@ package scala.reflect import scala.runtime._ import scala.collection.immutable.Nil -import scala.collection.mutable.{WrappedArray} +import scala.collection.mutable.{WrappedArray, ArrayBuilder} /** <p> * A <code>ClassManifest[T]</code> is an opaque descriptor for type <code>T</code>. @@ -72,24 +72,50 @@ trait ClassManifest[T] extends OptManifest[T] { case _ => false } - def newArray(len: Int): BoxedArray[T] = { - // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests - new BoxedObjectArray(java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[AnyRef]]) - .asInstanceOf[BoxedArray[T]] - } + protected def arrayClass: Predef.Class[Array[T]] = + java.lang.reflect.Array.newInstance(erasure, 0).getClass + .asInstanceOf[Predef.Class[Array[T]]] - def newArray1(len: Int): Array[T] = + def arrayManifest: ClassManifest[Array[T]] = + ClassManifest.classType[Array[T]](arrayClass) + + def newArray(len: Int): Array[T] = java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[T]] + def newArray2(len: Int): Array[Array[T]] = + java.lang.reflect.Array.newInstance( + java.lang.reflect.Array.newInstance(erasure, 0).getClass, len) + .asInstanceOf[Array[Array[T]]] + + def newArray3(len: Int): Array[Array[Array[T]]] = + java.lang.reflect.Array.newInstance( + java.lang.reflect.Array.newInstance(erasure, 0, 0).getClass, len) + .asInstanceOf[Array[Array[Array[T]]]] + + def newArray4(len: Int): Array[Array[Array[Array[T]]]] = + java.lang.reflect.Array.newInstance( + java.lang.reflect.Array.newInstance(erasure, 0, 0, 0).getClass, len) + .asInstanceOf[Array[Array[Array[Array[T]]]]] + + def newArray5(len: Int): Array[Array[Array[Array[Array[T]]]]] = + java.lang.reflect.Array.newInstance( + java.lang.reflect.Array.newInstance(erasure, 0, 0, 0, 0).getClass, len) + .asInstanceOf[Array[Array[Array[Array[Array[T]]]]]] + def newWrappedArray(len: Int): WrappedArray[T] = // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests - new WrappedArray.ofRef(java.lang.reflect.Array.newInstance(erasure, len).asInstanceOf[Array[AnyRef]]) - .asInstanceOf[WrappedArray[T]] + new WrappedArray.ofRef[T with AnyRef](newArray(len).asInstanceOf[Array[T with AnyRef]]).asInstanceOf[WrappedArray[T]] - def typeArguments: List[OptManifest[_]] = List() + def newArrayBuilder(): ArrayBuilder[T] = + // it's safe to assume T <: AnyRef here because the method is overridden for all value type manifests + new ArrayBuilder.ofRef[T with AnyRef]()(this.asInstanceOf[ClassManifest[T with AnyRef]]).asInstanceOf[ArrayBuilder[T]] - protected def argString = if (typeArguments.isEmpty) "" else typeArguments.mkString("[", ", ", "]") + def typeArguments: List[OptManifest[_]] = List() + protected def argString = + if (typeArguments.nonEmpty) typeArguments.mkString("[", ", ", "]") + else if (erasure.isArray) "["+ClassManifest.fromClass(erasure.getComponentType)+"]" + else "" } /** <p> @@ -114,10 +140,24 @@ object ClassManifest { val Boolean = Manifest.Boolean val Unit = Manifest.Unit val Any = Manifest.Any + val Object = Manifest.Object val AnyVal = Manifest.AnyVal val Nothing = Manifest.Nothing val Null = Manifest.Null + def fromClass[T](clazz: Predef.Class[T]): ClassManifest[T] = clazz match { + case java.lang.Byte.TYPE => Byte.asInstanceOf[ClassManifest[T]] + case java.lang.Short.TYPE => Short.asInstanceOf[ClassManifest[T]] + case java.lang.Character.TYPE => Char.asInstanceOf[ClassManifest[T]] + case java.lang.Integer.TYPE => Int.asInstanceOf[ClassManifest[T]] + case java.lang.Long.TYPE => Long.asInstanceOf[ClassManifest[T]] + case java.lang.Float.TYPE => Float.asInstanceOf[ClassManifest[T]] + case java.lang.Double.TYPE => Double.asInstanceOf[ClassManifest[T]] + case java.lang.Boolean.TYPE => Boolean.asInstanceOf[ClassManifest[T]] + case java.lang.Void.TYPE => Unit.asInstanceOf[ClassManifest[T]] + case _ => classType[T with AnyRef](clazz).asInstanceOf[ClassManifest[T]] + } + def singleType[T](value: Any): Manifest[T] = Manifest.singleType(value) /** ClassManifest for the class type `clazz', where `clazz' is @@ -127,32 +167,37 @@ object ClassManifest { * pass varargs as arrays into this, we get an infinitely recursive call * to boxArray. (Besides, having a separate case is more efficient) */ - def classType[T](clazz: Predef.Class[_]): ClassManifest[T] = + def classType[T <: AnyRef](clazz: Predef.Class[_]): ClassManifest[T] = new ClassTypeManifest[T](None, clazz, Nil) /** ClassManifest for the class type `clazz[args]', where `clazz' is * a top-level or static class and `args` are its type arguments */ - def classType[T](clazz: Predef.Class[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = + def classType[T <: AnyRef](clazz: Predef.Class[_], arg1: OptManifest[_], args: OptManifest[_]*): ClassManifest[T] = new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) /** ClassManifest for the class type `clazz[args]', where `clazz' is * a class with non-package prefix type `prefix` and type arguments `args`. */ - def classType[T](prefix: OptManifest[_], clazz: Predef.Class[_], args: OptManifest[_]*): ClassManifest[T] = + def classType[T <: AnyRef](prefix: OptManifest[_], clazz: Predef.Class[_], args: OptManifest[_]*): ClassManifest[T] = new ClassTypeManifest[T](Some(prefix), clazz, args.toList) /** Manifest for the class type `clazz[args]', where `clazz' is * a top-level or static class. */ @serializable - private class ClassTypeManifest[T](prefix: Option[OptManifest[_]], - val erasure: Predef.Class[_], - override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T] { + private class ClassTypeManifest[T <: AnyRef](prefix: Option[OptManifest[_]], + val erasure: Predef.Class[_], + override val typeArguments: List[OptManifest[_]]) extends ClassManifest[T] { override def toString = (if (prefix.isEmpty) "" else prefix.get.toString+"#") + (if (erasure.isArray) "Array" else erasure.getName) + argString } + def arrayType[T](arg: OptManifest[_]): ClassManifest[Array[T]] = arg match { + case NoManifest => Object.asInstanceOf[ClassManifest[Array[T]]] + case m: ClassManifest[_] => m.asInstanceOf[ClassManifest[T]].arrayManifest + } + /** ClassManifest for the abstract type `prefix # name'. `upperBound' is not * strictly necessary as it could be obtained by reflection. It was * added so that erasure can be calculated without reflection. */ diff --git a/src/library/scala/reflect/FullManifest.scala b/src/library/scala/reflect/FullManifest.scala deleted file mode 100644 index ea71aedf71..0000000000 --- a/src/library/scala/reflect/FullManifest.scala +++ /dev/null @@ -1,147 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2007-2009, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -// $Id: Manifest.scala 18506 2009-08-18 17:24:36Z odersky $ - - -package scala.reflect - -import scala.runtime._ - -/** <p> - * A <code>Manifest[T]</code> is an opaque descriptor for type <code>T</code>. - * Currently, its only use is to give access to the erasure of the type as a - * <code>Class</code> instance. - * </p> - * <p> - * <b>BE AWARE</b>: The different type-relation operators are all forwarded - * to the erased type as an approximation of the final semantics where - * these operators should be on the unerased type. - * </p> - */ -@serializable -trait FullManifest[T] extends Manifest[T] { - override def typeArguments: List[FullManifest[_]] = List() -} - -/** <p> - * This object is used by the compiler and <b>should not be used in client - * code</b>. The object <code>Manifest</code> defines factory methods for - * manifests. - * </p> - * <p> - * <b>BE AWARE</b>: The factory for refinement types is missing and - * will be implemented in a later version of this class. - * </p> - */ -object FullManifest { - - val Byte = new (FullManifest[Byte] @serializable) { - def erasure = java.lang.Byte.TYPE - override def toString = "Byte" - override def newArray(len: Int): BoxedArray[Byte] = new BoxedByteArray(new Array[Byte](len)) - } - - val Short = new (FullManifest[Short] @serializable) { - def erasure = java.lang.Short.TYPE - override def toString = "Short" - override def newArray(len: Int): BoxedArray[Short] = new BoxedShortArray(new Array[Short](len)) - } - - val Char = new (FullManifest[Char] @serializable) { - def erasure = java.lang.Character.TYPE - override def toString = "Char" - override def newArray(len: Int): BoxedArray[Char] = new BoxedCharArray(new Array[Char](len)) - } - - val Int = new (FullManifest[Int] @serializable) { - def erasure = java.lang.Integer.TYPE - override def toString = "Int" - override def newArray(len: Int): BoxedArray[Int] = new BoxedIntArray(new Array[Int](len)) - } - - val Long = new (FullManifest[Long] @serializable) { - def erasure = java.lang.Long.TYPE - override def toString = "Long" - override def newArray(len: Int): BoxedArray[Long] = new BoxedLongArray(new Array[Long](len)) - } - - val Float = new (FullManifest[Float] @serializable) { - def erasure = java.lang.Float.TYPE - override def toString = "Float" - override def newArray(len: Int): BoxedArray[Float] = new BoxedFloatArray(new Array[Float](len)) - } - - val Double = new (FullManifest[Double] @serializable) { - def erasure = java.lang.Double.TYPE - override def toString = "Double" - override def newArray(len: Int): BoxedArray[Double] = new BoxedDoubleArray(new Array[Double](len)) - } - - val Boolean = new (FullManifest[Boolean] @serializable) { - def erasure = java.lang.Boolean.TYPE - override def toString = "Boolean" - override def newArray(len: Int): BoxedArray[Boolean] = new BoxedBooleanArray(new Array[Boolean](len)) - } - - val Unit = new (FullManifest[Unit] @serializable) { - def erasure = java.lang.Void.TYPE - override def toString = "Unit" - override def newArray(len: Int): BoxedArray[Unit] = new BoxedUnitArray(new Array[Unit](len)) - } - - /** Manifest for the singleton type `value.type'. */ - def singleType[T](value: Any): FullManifest[T] = - new (FullManifest[T] @serializable) { - lazy val erasure = - value match { - case anyRefValue: AnyRef => anyRefValue.getClass - case anyValue => error("There is no singleton type for AnyVal values") - } - override lazy val toString = value.toString + ".type" - } - - /** Manifest for the class type `clazz', where `clazz' is - * a top-level or static class. */ - def classType[T](clazz: Predef.Class[T], args: FullManifest[_]*): FullManifest[T] = - classType(None, clazz, args: _*) - - /** Manifest for the class type `clazz[args]', where `clazz' is - * a top-level or static class. */ - def classType[T](prefix: FullManifest[_], clazz: Predef.Class[_], args: FullManifest[_]*): FullManifest[T] = - classType(Some(prefix), clazz, args: _*) - - /** Manifest for the class type `clazz[args]', where `clazz' is - * a top-level or static class. */ - def classType[T](prefix: Option[FullManifest[_]], clazz: Predef.Class[_], args: FullManifest[_]*): FullManifest[T] = - new (FullManifest[T] @serializable) { - def erasure = clazz - override val typeArguments = args.toList - override def toString = - (if (prefix.isEmpty) "" else prefix.get.toString+"#") + - (if (erasure.isArray) "Array" else erasure.getName) + - argString - } - - /** Manifest for the abstract type `prefix # name'. `upperBound' is not - * strictly necessary as it could be obtained by reflection. It was - * added so that erasure can be calculated without reflection. */ - def abstractType[T](prefix: FullManifest[_], name: String, upperBound: FullManifest[_], args: FullManifest[_]*): FullManifest[T] = - new (FullManifest[T] @serializable) { - def erasure = upperBound.erasure - override val typeArguments = args.toList - override def toString = prefix.toString+"#"+name+argString - } - - /** Manifest for the intersection type `parents_0 with ... with parents_n'. */ - def intersectionType[T](parents: FullManifest[_]*): FullManifest[T] = - new (FullManifest[T] @serializable) { - def erasure = parents.head.erasure - override def toString = parents.mkString(" with ") - } -} diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala index bf1ff5cfaf..f0c5183e6a 100644 --- a/src/library/scala/reflect/Manifest.scala +++ b/src/library/scala/reflect/Manifest.scala @@ -28,6 +28,9 @@ import scala.collection.mutable._ @serializable trait Manifest[T] extends ClassManifest[T] { override def typeArguments: List[Manifest[_]] = List() + + override def arrayManifest: Manifest[Array[T]] = + Manifest.classType[Array[T]](arrayClass) } /** <ps> @@ -45,64 +48,73 @@ object Manifest { val Byte = new (Manifest[Byte] @serializable) { def erasure = java.lang.Byte.TYPE override def toString = "Byte" - override def newArray(len: Int): BoxedArray[Byte] = new BoxedByteArray(new Array[Byte](len)) + override def newArray(len: Int): Array[Byte] = new Array[Byte](len) override def newWrappedArray(len: Int): WrappedArray[Byte] = new WrappedArray.ofByte(new Array[Byte](len)) + override def newArrayBuilder(): ArrayBuilder[Byte] = new ArrayBuilder.ofByte() } val Short = new (Manifest[Short] @serializable) { def erasure = java.lang.Short.TYPE override def toString = "Short" - override def newArray(len: Int): BoxedArray[Short] = new BoxedShortArray(new Array[Short](len)) + override def newArray(len: Int): Array[Short] = new Array[Short](len) override def newWrappedArray(len: Int): WrappedArray[Short] = new WrappedArray.ofShort(new Array[Short](len)) + override def newArrayBuilder(): ArrayBuilder[Short] = new ArrayBuilder.ofShort() } val Char = new (Manifest[Char] @serializable) { def erasure = java.lang.Character.TYPE override def toString = "Char" - override def newArray(len: Int): BoxedArray[Char] = new BoxedCharArray(new Array[Char](len)) + override def newArray(len: Int): Array[Char] = new Array[Char](len) override def newWrappedArray(len: Int): WrappedArray[Char] = new WrappedArray.ofChar(new Array[Char](len)) + override def newArrayBuilder(): ArrayBuilder[Char] = new ArrayBuilder.ofChar() } val Int = new (Manifest[Int] @serializable) { def erasure = java.lang.Integer.TYPE override def toString = "Int" - override def newArray(len: Int): BoxedArray[Int] = new BoxedIntArray(new Array[Int](len)) + override def newArray(len: Int): Array[Int] = new Array[Int](len) override def newWrappedArray(len: Int): WrappedArray[Int] = new WrappedArray.ofInt(new Array[Int](len)) + override def newArrayBuilder(): ArrayBuilder[Int] = new ArrayBuilder.ofInt() } val Long = new (Manifest[Long] @serializable) { def erasure = java.lang.Long.TYPE override def toString = "Long" - override def newArray(len: Int): BoxedArray[Long] = new BoxedLongArray(new Array[Long](len)) + override def newArray(len: Int): Array[Long] = new Array[Long](len) override def newWrappedArray(len: Int): WrappedArray[Long] = new WrappedArray.ofLong(new Array[Long](len)) + override def newArrayBuilder(): ArrayBuilder[Long] = new ArrayBuilder.ofLong() } val Float = new (Manifest[Float] @serializable) { def erasure = java.lang.Float.TYPE override def toString = "Float" - override def newArray(len: Int): BoxedArray[Float] = new BoxedFloatArray(new Array[Float](len)) + override def newArray(len: Int): Array[Float] = new Array[Float](len) override def newWrappedArray(len: Int): WrappedArray[Float] = new WrappedArray.ofFloat(new Array[Float](len)) + override def newArrayBuilder(): ArrayBuilder[Float] = new ArrayBuilder.ofFloat() } val Double = new (Manifest[Double] @serializable) { def erasure = java.lang.Double.TYPE override def toString = "Double" - override def newArray(len: Int): BoxedArray[Double] = new BoxedDoubleArray(new Array[Double](len)) + override def newArray(len: Int): Array[Double] = new Array[Double](len) override def newWrappedArray(len: Int): WrappedArray[Double] = new WrappedArray.ofDouble(new Array[Double](len)) + override def newArrayBuilder(): ArrayBuilder[Double] = new ArrayBuilder.ofDouble() } val Boolean = new (Manifest[Boolean] @serializable) { def erasure = java.lang.Boolean.TYPE override def toString = "Boolean" - override def newArray(len: Int): BoxedArray[Boolean] = new BoxedBooleanArray(new Array[Boolean](len)) + override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) override def newWrappedArray(len: Int): WrappedArray[Boolean] = new WrappedArray.ofBoolean(new Array[Boolean](len)) + override def newArrayBuilder(): ArrayBuilder[Boolean] = new ArrayBuilder.ofBoolean() } val Unit = new (Manifest[Unit] @serializable) { def erasure = java.lang.Void.TYPE override def toString = "Unit" - override def newArray(len: Int): BoxedArray[Unit] = new BoxedUnitArray(new Array[Unit](len)) + override def newArray(len: Int): Array[Unit] = new Array[Unit](len) override def newWrappedArray(len: Int): WrappedArray[Unit] = new WrappedArray.ofUnit(new Array[Unit](len)) + override def newArrayBuilder(): ArrayBuilder[Unit] = new ArrayBuilder.ofUnit() } val Any: Manifest[Any] = new ClassTypeManifest[Any](None, classOf[java.lang.Object], List()) { @@ -110,6 +122,11 @@ object Manifest { // todo: re-implement <:< } + val Object: Manifest[Object] = new ClassTypeManifest[Object](None, classOf[java.lang.Object], List()) { + override def toString = "Object" + // todo: re-implement <:< + } + val AnyVal: Manifest[AnyVal] = new ClassTypeManifest[AnyVal](None, classOf[java.lang.Object], List()) { override def toString = "AnyVal" // todo: re-implement <:< @@ -136,32 +153,29 @@ object Manifest { override lazy val toString = value.toString + ".type" } - /** Manifest for the class type <code>clazz[args]</code>, where <code>clazz</code> - * is a top-level or static class. - * @note This no-prefix, no-arguments case is separate because we - * it's called from ScalaRunTime.boxArray itself. If we - * pass varargs as arrays into this, we get an infinitely recursive call - * to boxArray. (Besides, having a separate case is more efficient) - */ + /** Manifest for the class type `clazz[args]', where `clazz' is + * a top-level or static class. + * @note This no-prefix, no-arguments case is separate because we + * it's called from ScalaRunTime.boxArray itself. If we + * pass varargs as arrays into this, we get an infinitely recursive call + * to boxArray. (Besides, having a separate case is more efficient) + */ def classType[T](clazz: Predef.Class[_]): Manifest[T] = new ClassTypeManifest[T](None, clazz, Nil) - /** Manifest for the class type <code>clazz</code>, where <code>clazz</code> - * is a top-level or static class and <code>args</code> are its type arguments. - */ + /** Manifest for the class type `clazz', where `clazz' is + * a top-level or static class and args are its type arguments. */ def classType[T](clazz: Predef.Class[T], arg1: Manifest[_], args: Manifest[_]*): Manifest[T] = new ClassTypeManifest[T](None, clazz, arg1 :: args.toList) - /** Manifest for the class type <code>clazz[args]</code>, where <code>clazz</code> - * is a class with non-package prefix type <code>prefix</code> and type - * arguments <code>args</code>. - */ + /** Manifest for the class type `clazz[args]', where `clazz' is + * a class with non-package prefix type `prefix` and type arguments `args`. + */ def classType[T](prefix: Manifest[_], clazz: Predef.Class[_], args: Manifest[_]*): Manifest[T] = new ClassTypeManifest[T](Some(prefix), clazz, args.toList) - /** Manifest for the class type <code>clazz[args]</code>, where `clazz' is - * a top-level or static class. - */ + /** Manifest for the class type `clazz[args]', where `clazz' is + * a top-level or static class. */ @serializable private class ClassTypeManifest[T](prefix: Option[Manifest[_]], val erasure: Predef.Class[_], @@ -172,11 +186,12 @@ object Manifest { argString } - /** Manifest for the abstract type <code>prefix # name</code>. - * <code>upperBound</code> is not strictly necessary as it could be obtained - * by reflection. It was added so that erasure can be calculated without - * reflection. - */ + def arrayType[T](arg: Manifest[_]): Manifest[Array[T]] = + arg.asInstanceOf[Manifest[T]].arrayManifest + + /** Manifest for the abstract type `prefix # name'. `upperBound' is not + * strictly necessary as it could be obtained by reflection. It was + * added so that erasure can be calculated without reflection. */ def abstractType[T](prefix: Manifest[_], name: String, upperBound: Manifest[_], args: Manifest[_]*): Manifest[T] = new (Manifest[T] @serializable) { def erasure = upperBound.erasure diff --git a/src/library/scala/reflect/RichClass.scala b/src/library/scala/reflect/RichClass.scala index 5d58d12377..7d690f360d 100644 --- a/src/library/scala/reflect/RichClass.scala +++ b/src/library/scala/reflect/RichClass.scala @@ -10,9 +10,9 @@ package scala.reflect -import annotation.experimental -import util.control.Exception._ -import util.ScalaClassLoader._ +import scala.annotation.experimental +import scala.util.control.Exception._ +import scala.util.ScalaClassLoader._ import java.lang.{ Class => JClass } import java.lang.reflect. { Constructor => JConstructor } diff --git a/src/library/scala/runtime/BoxedArray.scala b/src/library/scala/runtime/BoxedArray.scala index c626f685d3..3e815d16a4 100644 --- a/src/library/scala/runtime/BoxedArray.scala +++ b/src/library/scala/runtime/BoxedArray.scala @@ -25,6 +25,10 @@ import collection.Sequence */ abstract class BoxedArray[A] extends Vector[A] with VectorTemplate[A, BoxedArray[A]] with Boxed { self => + val ex = new Error("trying to create a BoxedArray") + ex.printStackTrace() + throw ex + /** The manifest of the element type */ def elemManifest: ClassManifest[A] @@ -40,8 +44,7 @@ abstract class BoxedArray[A] extends Vector[A] with VectorTemplate[A, BoxedArray /** Creates new builder for this collection ==> move to subclasses */ override protected[this] def newBuilder: Builder[A, BoxedArray[A]] = - if (elemManifest != null) new ArrayBuilder[A](elemManifest) - else genericBuilder[A] + genericBuilder[A] // !!! todo: remove override def genericBuilder[B]: Builder[B, BoxedArray[B]] = new ArrayBuffer[B].mapResult { diff --git a/src/library/scala/runtime/RichString.scala b/src/library/scala/runtime/RichString.scala index 1be546a902..3c643131cc 100644 --- a/src/library/scala/runtime/RichString.scala +++ b/src/library/scala/runtime/RichString.scala @@ -232,7 +232,7 @@ class RichString(val self: String) extends Proxy with Vector[Char] with VectorTe * @throws java.lang.IllegalArgumentException */ def format(args : Any*) : String = - java.lang.String.format(self, args.asInstanceOf[Seq[AnyRef]].toArray: _*) + java.lang.String.format(self, args.asInstanceOf[Seq[AnyRef]]: _*) /** <p> * Like format(args*) but takes an initial Locale parameter @@ -249,6 +249,6 @@ class RichString(val self: String) extends Proxy with Vector[Char] with VectorTe * @throws java.lang.IllegalArgumentException */ def format(l: java.util.Locale, args: Any*): String = - java.lang.String.format(l, self, args.asInstanceOf[Seq[AnyRef]].toArray: _*) + java.lang.String.format(l, self, args.asInstanceOf[Seq[AnyRef]]: _*) } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 707433d241..158e83b582 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -19,16 +19,20 @@ import scala.collection.mutable._ */ object ScalaRunTime { - def isArray(x: AnyRef): Boolean = x != null && (x.getClass.isArray || x.isInstanceOf[BoxedArray[_]]) + def isArray(x: AnyRef): Boolean = // !!! remove once newarrays + x != null && (x.getClass.isArray || x.isInstanceOf[BoxedArray[_]]) + + def isArray(x: AnyRef, atLevel: Int): Boolean = + x != null && isArrayClass(x.getClass, atLevel) + + private def isArrayClass(clazz: Class[_], atLevel: Int): Boolean = + clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) + def isValueClass(clazz: Class[_]) = clazz.isPrimitive() - // todo: [for Gilles] replace with boxArray - def forceBoxedArray[A <: Any](xs: Seq[A]): Array[A] = { - val array = new Array[A](xs.length) - var i = 0 - for (x <- xs.iterator) { array(i) = x; i += 1 } - array - } + // todo: remove? + def forceBoxedArray[A <: Any](xs: Seq[A]): Array[A] = + throw new Error(" not implemented: forceBoxedArray") /** Retrieve generic array element */ def array_apply(xs: AnyRef, idx: Int): Any = java.lang.reflect.Array.get(xs, idx) @@ -39,6 +43,18 @@ object ScalaRunTime { /** Get generic array length */ def array_length(xs: AnyRef): Int = java.lang.reflect.Array.getLength(xs) + /** Convert a numeric value array to an object array. + * Needed to deal with vararg arguments of primtive types that are passed + * to a generic Java vararg parameter T ... + */ + def toObjectArray(src: AnyRef): Array[Object] = { + val length = array_length(src) + val dest = new Array[Object](length) + for (i <- 0 until length) + array_update(dest, i, array_apply(src, i)) + dest + } + def toArray[T](xs: scala.collection.Sequence[T]) = { val arr = new Array[AnyRef](xs.length) var i = 0 @@ -46,23 +62,6 @@ object ScalaRunTime { arr } - /** Convert arrays to sequences, leave sequences as they are - * !!! see duplication wrt - */ - def toSequence[T](xs: AnyRef): Sequence[T] = xs match { - case ts: Sequence[T] => ts.asInstanceOf[Sequence[T]] - case null => null - case x: Array[AnyRef] => new WrappedArray.ofRef(x).asInstanceOf[Array[T]] - case x: Array[Int] => new WrappedArray.ofInt(x).asInstanceOf[Array[T]] - case x: Array[Double] => new WrappedArray.ofDouble(x).asInstanceOf[Array[T]] - case x: Array[Long] => new WrappedArray.ofLong(x).asInstanceOf[Array[T]] - case x: Array[Float] => new WrappedArray.ofFloat(x).asInstanceOf[Array[T]] - case x: Array[Char] => new WrappedArray.ofChar(x).asInstanceOf[Array[T]] - case x: Array[Byte] => new WrappedArray.ofByte(x).asInstanceOf[Array[T]] - case x: Array[Short] => new WrappedArray.ofShort(x).asInstanceOf[Array[T]] - case x: Array[Boolean] => new WrappedArray.ofBoolean(x).asInstanceOf[Array[T]] - } - def checkInitialized[T <: AnyRef](x: T): T = if (x == null) throw new UninitializedError else x @@ -191,7 +190,10 @@ object ScalaRunTime { */ def stringOf(arg : Any): String = arg match { case null => "null" - case (arg : AnyRef) if isArray(arg) => boxArray(arg).deepToString + case arg: AnyRef if isArray(arg) => + val d: collection.Vector[Any] = WrappedArray.make(arg).deep + d.toString + case arg: WrappedArray[_] => arg.deep.toString case arg => arg.toString } } diff --git a/src/library/scala/util/ClassLoader.scala b/src/library/scala/util/ClassLoader.scala index 6458b0900c..56ed6c70c2 100644 --- a/src/library/scala/util/ClassLoader.scala +++ b/src/library/scala/util/ClassLoader.scala @@ -51,7 +51,7 @@ trait ScalaClassLoader extends JavaClassLoader if (!Modifier.isStatic(method.getModifiers)) throw new NoSuchMethodException(objectName + ".main is not static") - asContext(method.invoke(null, Array(arguments.toArray): _*)) + asContext(method.invoke(null, Array(arguments.toArray).toSequence: _*)) // !!! todo: remove toSequence once newarrays starr is in } } @@ -89,4 +89,4 @@ object ScalaClassLoader { search(getContextLoader()) } -}
\ No newline at end of file +} diff --git a/src/library/scala/xml/Utility.scala b/src/library/scala/xml/Utility.scala index 68d68ee4aa..39e594eb05 100644 --- a/src/library/scala/xml/Utility.scala +++ b/src/library/scala/xml/Utility.scala @@ -292,7 +292,7 @@ object Utility extends AnyRef with parsing.TokenTests def getName(s: String, index: Int): String = { if (index >= s.length) null else (s drop index) match { - case Seq(x, xs @ _*) if isNameStart(x) => (Array(x) ++ (xs takeWhile isNameChar)).mkString + case Seq(x, xs @ _*) if isNameStart(x) => x.toString + (xs takeWhile isNameChar).mkString case _ => "" } } diff --git a/src/library/scala/xml/transform/BasicTransformer.scala b/src/library/scala/xml/transform/BasicTransformer.scala index a79c32a5f0..6b01871397 100644 --- a/src/library/scala/xml/transform/BasicTransformer.scala +++ b/src/library/scala/xml/transform/BasicTransformer.scala @@ -31,7 +31,7 @@ abstract class BasicTransformer extends Function1[Node,Node] * to NodeBuffer. */ def transform(it: Iterator[Node], nb: NodeBuffer): Seq[Node] = - it.foldLeft(nb)(_ ++= transform(_)) toArray + it.foldLeft(nb)(_ ++= transform(_)).toSequence /** Call transform(Node) to each node in ns, yield ns if nothing changes, * otherwise a new sequence of concatenated results. |