summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-02-15 15:33:09 +0100
committerMartin Odersky <odersky@gmail.com>2012-02-15 15:36:32 +0100
commit280192f2c5e92f9f8fb3238f1b4bfdf2566e6fdf (patch)
tree0d2ed2836614f967f4cdc6e341197c05b09e2e43
parentcd6426a8c501eda2105196fc5a254d8f0dd77633 (diff)
downloadscala-280192f2c5e92f9f8fb3238f1b4bfdf2566e6fdf.tar.gz
scala-280192f2c5e92f9f8fb3238f1b4bfdf2566e6fdf.tar.bz2
scala-280192f2c5e92f9f8fb3238f1b4bfdf2566e6fdf.zip
New scheme for "Rows" of value classes.
-rw-r--r--src/library/scala/Boxed.scala18
-rw-r--r--src/library/scala/collection/generic/RowFactory.scala49
-rw-r--r--test/files/run/Meter.scala40
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)