1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
package a {
abstract class BoxingConversions[Boxed, Unboxed] {
def box(x: Unboxed): Boxed
def unbox(x: Boxed): Unboxed
}
class Meter(val underlying: Double) extends AnyVal with _root_.b.Printable {
def + (other: Meter): Meter =
new Meter(this.underlying + other.underlying)
def / (other: Meter)(implicit dummy: Meter.MeterArg = null): Double = this.underlying / other.underlying
def / (factor: Double): Meter = new Meter(this.underlying / factor)
def < (other: Meter): Boolean = this.underlying < other.underlying
def toFoot: Foot = new Foot(this.underlying * 0.3048)
override def print = { Console.print(">>>"); super.print; proprint }
override def toString: String = underlying.toString+"m"
}
object Meter extends (Double => Meter) {
private[a] trait MeterArg
def apply(x: Double): Meter = new Meter(x)
implicit val boxings = new BoxingConversions[Meter, Double] {
def box(x: Double) = new Meter(x)
def unbox(m: Meter) = m.underlying
}
}
class Foot(val unbox: Double) extends AnyVal {
def + (other: Foot): Foot =
new Foot(this.unbox + other.unbox)
override def toString = unbox.toString+"ft"
}
object Foot {
implicit val boxings = new BoxingConversions[Foot, Double] {
def box(x: Double) = new Foot(x)
def unbox(m: Foot) = m.unbox
}
}
}
package b {
trait Printable extends Any {
def print: Unit = Console.print(this)
protected def proprint = Console.print("<<<")
}
}
import a._
import _root_.b._
object Test extends App {
{
val x: Meter = new Meter(1)
val a: Object = x.asInstanceOf[Object]
val y: Meter = a.asInstanceOf[Meter]
val u: Double = 1
val b: Object = u.asInstanceOf[Object]
val v: Double = b.asInstanceOf[Double]
}
val x = new Meter(1)
val y = x
println((x + x) / x)
println((x + x) / 0.5)
println((x < x).toString)
println("x.isInstanceOf[Meter]: "+x.isInstanceOf[Meter])
println("x.hashCode: "+x.hashCode)
println("x == 1: "+(x == 1))
println("x == y: "+(x == y))
assert(x.hashCode == (1.0).hashCode)
val a: Any = x
val b: Any = y
println("a == b: "+(a == b))
{ println("testing native arrays")
val arr = Array(x, y + x)
println(arr.deep)
def foo[T <: Printable](x: Array[T]) {
for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) }
}
val m = arr(0)
println(m)
foo(arr)
}
//
// { println("testing wrapped arrays")
// import collection.mutable.FlatArray
// val arr = FlatArray(x, y + x)
// println(arr)
// def foo(x: FlatArray[Meter]) {
// for (i <- 0 until x.length) { x(i).print; println(" "+x(i)) }
// }
// val m = arr(0)
// println(m)
// foo(arr)
// val ys: Seq[Meter] = arr map (_ + new Meter(1))
// println(ys)
// val zs = arr map (_ / Meter(1))
// println(zs)
// val fs = arr map (_.toFoot)
// println(fs)
// }
}
|