diff options
author | Martin Odersky <odersky@gmail.com> | 2012-02-15 15:33:09 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2012-02-15 15:36:32 +0100 |
commit | 280192f2c5e92f9f8fb3238f1b4bfdf2566e6fdf (patch) | |
tree | 0d2ed2836614f967f4cdc6e341197c05b09e2e43 | |
parent | cd6426a8c501eda2105196fc5a254d8f0dd77633 (diff) | |
download | scala-280192f2c5e92f9f8fb3238f1b4bfdf2566e6fdf.tar.gz scala-280192f2c5e92f9f8fb3238f1b4bfdf2566e6fdf.tar.bz2 scala-280192f2c5e92f9f8fb3238f1b4bfdf2566e6fdf.zip |
New scheme for "Rows" of value classes.
-rw-r--r-- | src/library/scala/Boxed.scala | 18 | ||||
-rw-r--r-- | src/library/scala/collection/generic/RowFactory.scala | 49 | ||||
-rw-r--r-- | test/files/run/Meter.scala | 40 |
3 files changed, 79 insertions, 28 deletions
diff --git a/src/library/scala/Boxed.scala b/src/library/scala/Boxed.scala new file mode 100644 index 0000000000..6055b3f436 --- /dev/null +++ b/src/library/scala/Boxed.scala @@ -0,0 +1,18 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2011, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +/** A trait that can be implemented by user-defined value classes + */ +trait Boxed[Unboxed] extends Any { + + /** The underlying value wrapped by the value class */ + def unbox: Unboxed +} + diff --git a/src/library/scala/collection/generic/RowFactory.scala b/src/library/scala/collection/generic/RowFactory.scala new file mode 100644 index 0000000000..c1559c9397 --- /dev/null +++ b/src/library/scala/collection/generic/RowFactory.scala @@ -0,0 +1,49 @@ +package scala.collection +package generic + +import mutable.{Builder, ArrayBuffer} +import scala.specialized + +/** A factory class for rows -- flat arrays of value classes that use the unboxed representation + * of the element type. + * + */ +abstract class RowFactory[@specialized Unboxed: ClassManifest, Boxed <: scala.Boxed[Unboxed]] extends (Unboxed => Boxed) { box => + + /** Convert to boxed representation + */ + def apply(x: Unboxed): Boxed + + class Row(elems: Array[Unboxed]) extends mutable.IndexedSeq[Boxed] with mutable.IndexedSeqLike[Boxed, Row] { + + override protected[this] def newBuilder: Builder[Boxed, Row] = Row.newBuilder + + def apply(idx: Int): Boxed = box(elems(idx)) + + def update(idx: Int, elem: Boxed): Unit = elems(idx) = elem.unbox + + def length = elems.length + + override def foreach[U](f: Boxed => U): Unit = elems foreach (elem => f(box(elem))) + + } + + object Row { + def fromSeq(elems: Seq[Boxed]): Row = { + val xs: Array[Unboxed] = new Array[Unboxed](elems.length) + var i = 0 + for (elem <- elems) { xs(i) = elem.unbox; i += 1 } + new Row(xs) + } + + def apply(elems: Boxed*) = fromSeq(elems) + + def newBuilder: Builder[Boxed, Row] = new ArrayBuffer mapResult fromSeq + + implicit def canBuildFrom: CanBuildFrom[Row, Boxed, Row] = + new CanBuildFrom[Row, Boxed, Row] { + def apply(): Builder[Boxed, Row] = newBuilder + def apply(from: Row): Builder[Boxed, Row] = newBuilder + } + } +} diff --git a/test/files/run/Meter.scala b/test/files/run/Meter.scala index da99f81722..15d35054a2 100644 --- a/test/files/run/Meter.scala +++ b/test/files/run/Meter.scala @@ -1,33 +1,17 @@ -class Meter(val underlying: Double) extends AnyVal with Printable { +import collection.generic.RowFactory + +class Meter(val unbox: Double) extends AnyVal with Boxed[Double] with Printable { def + (other: Meter): Meter = - new Meter(this.underlying + other.underlying) - def / (other: Meter): Double = this.underlying / other.underlying - def / (factor: Double): Meter = new Meter(this.underlying / factor) - def < (other: Meter): Boolean = this.underlying < other.underlying - override def toString: String = underlying.toString+"m" + new Meter(this.unbox + other.unbox) + def / (other: Meter): Double = this.unbox / other.unbox + def / (factor: Double): Meter = new Meter(this.unbox / factor) + def < (other: Meter): Boolean = this.unbox < other.unbox + override def toString: String = unbox.toString+"m" } -object Meter extends (Double => Meter) { - +object Meter extends RowFactory[Double, Meter] { def apply(x: Double): Meter = new Meter(x) - - class FlatArray(underlying: Array[Double]) { - def length = underlying.length - def apply(i: Int): Meter = new Meter(underlying(i)) - def update(i: Int, m: Meter) = underlying(i) = m.underlying - override def toString = underlying.toList map Meter mkString ("Meter.FlatArray(", ", ", ")") - } - - object FlatArray { - - def apply(xs: Meter*) = { - val elems = Array.ofDim[Double](xs.length) - for (i <- 0 until xs.length) - elems(i) = xs(i).asInstanceOf[Double] - new FlatArray(elems) - } - } - } + trait Printable extends Any { def print: Unit = Console.print(this) } object Test extends App { @@ -71,9 +55,9 @@ object Test extends App { } { println("testing wrapped arrays") - val arr = Meter.FlatArray(x, y + x) + val arr = Meter.Row(x, y + x) println(arr) - def foo(x: Meter.FlatArray) { + def foo(x: Meter.Row) { for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) } } val m = arr(0) |