/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id: BoxedArray.scala 18589 2009-08-27 14:45:35Z odersky $ package scala.runtime import Predef._ import scala.reflect.ClassManifest import collection.mutable.{Vector, ArrayBuilder, ArrayBuffer} import collection.generic._ import collection.Sequence /** * <p>A class representing <code>Array[T]</code></p> * * @author Martin Odersky, Stephane Micheloud * @version 1.0 */ abstract class BoxedArray[A] extends Vector[A] with VectorTemplate[A, BoxedArray[A]] with Boxed { self => /** The manifest of the element type */ def elemManifest: ClassManifest[A] /** The length of the array */ def length: Int /** The element at given index */ def apply(index: Int): A /** Update element at given index */ def update(index: Int, elem: A): Unit /** 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] // !!! todo: remove override def genericBuilder[B]: Builder[B, BoxedArray[B]] = new ArrayBuffer[B].mapResult { _.toArray(null).asInstanceOf[BoxedArray[B]] } /** Convert to Java array. * @param elemTag Either one of the tags ".N" where N is the name of a primitive type * (@see ScalaRunTime), or a full class name. */ def unbox(elemClass: Class[_]): AnyRef /** The underlying array value */ def value: AnyRef def copyFrom(src: AnyRef, from: Int, to: Int, len: Int): Unit = Array.copy(src, from, value, to, len) def copyTo(from: Int, dest: AnyRef, to: Int, len: Int): Unit = { Array.copy(value, from, dest, to, len) } override def toArray[B >: A](implicit m: ClassManifest[B]): Array[B] = { if ((elemManifest ne null) && (elemManifest.erasure eq m.erasure)) this.asInstanceOf[Array[B]] else super.toArray[B] } /* override def equals(other: Any) = (value eq other) || other.isInstanceOf[BoxedArray[_]] && (value == other.asInstanceOf[BoxedArray[_]].value) override def hashCode(): Int = value.hashCode() */ /** Fills the given array <code>xs</code> with the elements of * this sequence starting at position <code>start</code>. * * @param xs the array to fill. * @param start starting index. * @pre the array must be large enough to hold all elements. */ override def copyToArray[B](xs: Array[B], start: Int, len: Int): Unit = copyTo(0, xs, start, len) /** 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: collection.Vector[Any] = new collection.Vector[Any] { def length = self.length def apply(idx: Int): Any = self.apply(idx) match { case elem: AnyRef if ScalaRunTime.isArray(elem) => ScalaRunTime.boxArray(elem).deep case elem => elem } override def stringPrefix = "Array" } @deprecated("use deep.toString instead") final def deepToString() = deepMkString(stringPrefix + "(", ", ", ")") @deprecated("use deep.mkString instead") final def deepMkString(start: String, sep: String, end: String): String = { def _deepToString(x: Any) = x match { case a: AnyRef if ScalaRunTime.isArray(a) => ScalaRunTime.boxArray(a).deepMkString(start, sep, end) case _ => ScalaRunTime.stringOf(x) } val buf = new StringBuilder() buf.append(start) val iter = this.iterator if (iter.hasNext) buf.append(_deepToString(iter.next)) while (iter.hasNext) { buf.append(sep); buf.append(_deepToString(iter.next)) } buf.append(end) buf.toString } @deprecated("use deep.mkString instead") final def deepMkString(sep: String): String = this.deepMkString("", sep, "") @deprecated("use array1.deep.equals(array2.deep) instead") final def deepEquals(that: Any): Boolean = { def _deepEquals(x1: Any, x2: Any) = (x1, x2) match { case (a1: BoxedArray[_], a2: BoxedArray[_]) => _sameElements(a1, a2) case (a1: AnyRef, a2: AnyRef) if ScalaRunTime.isArray(a1) && ScalaRunTime.isArray(a2) => _sameElements(ScalaRunTime.boxArray(a1), ScalaRunTime.boxArray(a2)) case _ => x1.equals(x2) } def _sameElements(a1: BoxedArray[_], a2: BoxedArray[_]): Boolean = { val it1 = a1.iterator val it2 = a2.iterator var res = true while (res && it1.hasNext && it2.hasNext) res = _deepEquals(it1.next, it2.next) !it1.hasNext && !it2.hasNext && res } that match { case a: BoxedArray[_] => _sameElements(this, a) case a: AnyRef if ScalaRunTime.isArray(a) => _sameElements(this, ScalaRunTime.boxArray(a)) case _ => false } } override final def stringPrefix: String = "Array" }