Created
May 25, 2010 00:17
-
-
Save paulp/412593 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifest.scala | |
index 3b05a58..73ddb01 100644 | |
--- a/src/library/scala/reflect/ClassManifest.scala | |
+++ b/src/library/scala/reflect/ClassManifest.scala | |
@@ -72,6 +72,10 @@ trait ClassManifest[T] extends OptManifest[T] with Equals { | |
def >:>(that: ClassManifest[_]): Boolean = | |
that <:< this | |
+ /** Tests for weak conformance. | |
+ */ | |
+ def weak_<:<(that: ClassManifest[_]): Boolean = this <:< that | |
+ | |
def canEqual(other: Any) = other match { | |
case _: ClassManifest[_] => true | |
case _ => false | |
diff --git a/src/library/scala/reflect/Manifest.scala b/src/library/scala/reflect/Manifest.scala | |
index a042b20..53ff0a0 100644 | |
--- a/src/library/scala/reflect/Manifest.scala | |
+++ b/src/library/scala/reflect/Manifest.scala | |
@@ -45,7 +45,16 @@ trait Manifest[T] extends ClassManifest[T] with Equals { | |
@serializable | |
trait AnyValManifest[T] extends Manifest[T] with Equals { | |
- import Manifest.{ Any, AnyVal } | |
+ import Manifest._ | |
+ | |
+ def weakIndex: Int | |
+ protected def weak_only_<:<(that: ClassManifest[_]) = that match { | |
+ case Char | Boolean | Unit => false | |
+ case x: AnyValManifest[_] => weakIndex < x.weakIndex | |
+ case _ => false | |
+ } | |
+ | |
+ override final def weak_<:<(that: ClassManifest[_]) = (this <:< that) || (this weak_only_<:< that) | |
override def <:<(that: ClassManifest[_]): Boolean = (that eq this) || (that eq Any) || (that eq AnyVal) | |
override def canEqual(other: Any) = other match { | |
case _: AnyValManifest[_] => true | |
@@ -65,8 +74,9 @@ trait AnyValManifest[T] extends Manifest[T] with Equals { | |
* will be implemented in a later version of this class. | |
* </p> | |
*/ | |
-object Manifest { | |
+object Manifest { | |
val Byte: AnyValManifest[Byte] = new (AnyValManifest[Byte] @serializable) { | |
+ val weakIndex = 0 | |
def erasure = java.lang.Byte.TYPE | |
override def toString = "Byte" | |
override def newArray(len: Int): Array[Byte] = new Array[Byte](len) | |
@@ -76,6 +86,7 @@ object Manifest { | |
} | |
val Short: AnyValManifest[Short] = new (AnyValManifest[Short] @serializable) { | |
+ val weakIndex = 1 | |
def erasure = java.lang.Short.TYPE | |
override def toString = "Short" | |
override def newArray(len: Int): Array[Short] = new Array[Short](len) | |
@@ -85,6 +96,11 @@ object Manifest { | |
} | |
val Char: AnyValManifest[Char] = new (AnyValManifest[Char] @serializable) { | |
+ val weakIndex = -1 | |
+ override protected def weak_only_<:<(that: ClassManifest[_]) = that match { | |
+ case Int | Long | Float | Double => true | |
+ case _ => false | |
+ } | |
def erasure = java.lang.Character.TYPE | |
override def toString = "Char" | |
override def newArray(len: Int): Array[Char] = new Array[Char](len) | |
@@ -94,6 +110,7 @@ object Manifest { | |
} | |
val Int: AnyValManifest[Int] = new (AnyValManifest[Int] @serializable) { | |
+ val weakIndex = 2 | |
def erasure = java.lang.Integer.TYPE | |
override def toString = "Int" | |
override def newArray(len: Int): Array[Int] = new Array[Int](len) | |
@@ -103,6 +120,7 @@ object Manifest { | |
} | |
val Long: AnyValManifest[Long] = new (AnyValManifest[Long] @serializable) { | |
+ val weakIndex = 3 | |
def erasure = java.lang.Long.TYPE | |
override def toString = "Long" | |
override def newArray(len: Int): Array[Long] = new Array[Long](len) | |
@@ -112,6 +130,7 @@ object Manifest { | |
} | |
val Float: AnyValManifest[Float] = new (AnyValManifest[Float] @serializable) { | |
+ val weakIndex = 4 | |
def erasure = java.lang.Float.TYPE | |
override def toString = "Float" | |
override def newArray(len: Int): Array[Float] = new Array[Float](len) | |
@@ -121,6 +140,7 @@ object Manifest { | |
} | |
val Double: AnyValManifest[Double] = new (AnyValManifest[Double] @serializable) { | |
+ val weakIndex = 5 | |
def erasure = java.lang.Double.TYPE | |
override def toString = "Double" | |
override def newArray(len: Int): Array[Double] = new Array[Double](len) | |
@@ -130,6 +150,8 @@ object Manifest { | |
} | |
val Boolean: AnyValManifest[Boolean] = new (AnyValManifest[Boolean] @serializable) { | |
+ val weakIndex = -1 | |
+ override protected def weak_only_<:<(that: ClassManifest[_]) = false | |
def erasure = java.lang.Boolean.TYPE | |
override def toString = "Boolean" | |
override def newArray(len: Int): Array[Boolean] = new Array[Boolean](len) | |
@@ -139,6 +161,8 @@ object Manifest { | |
} | |
val Unit: AnyValManifest[Unit] = new (AnyValManifest[Unit] @serializable) { | |
+ val weakIndex = -1 | |
+ override protected def weak_only_<:<(that: ClassManifest[_]) = false | |
def erasure = java.lang.Void.TYPE | |
override def toString = "Unit" | |
override def newArray(len: Int): Array[Unit] = new Array[Unit](len) | |
diff --git a/src/library/scala/reflect/WeakConformance.scala b/src/library/scala/reflect/WeakConformance.scala | |
new file mode 100644 | |
index 0000000..eb04838 | |
--- /dev/null | |
+++ b/src/library/scala/reflect/WeakConformance.scala | |
@@ -0,0 +1,138 @@ | |
+/* __ *\ | |
+** ________ ___ / / ___ Scala API ** | |
+** / __/ __// _ | / / / _ | (c) 2007-2010, LAMP/EPFL ** | |
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** | |
+** /____/\___/_/ |_/____/_/ | | ** | |
+** |/ ** | |
+\* */ | |
+ | |
+package scala.reflect | |
+ | |
+object WeakConformance { | |
+ import Manifest._ | |
+ def numericTypes: List[AnyValManifest[_]] = List(Byte, Char, Short, Int, Long, Float, Double) | |
+ | |
+ def foldManifests(xs: Traversable[Manifest[_]]): Manifest[_] = | |
+ xs.reduceLeft { (m1, m2) => | |
+ if (m1 weak_<:< m2) m2 | |
+ else if (m2 weak_<:< m1) m1 | |
+ else error(m1 + ", " + m2) | |
+ } | |
+ | |
+ def unify[A, B, C](a: A, b: B)(implicit ev: weak_unify[A, B, C]): (C, C) = (ev.aToC(a), ev.bToC(b)) | |
+ | |
+ implicit def weakSameSame[T]: weak_unify[T, T, T] = new weak_unify[T, T, T] { | |
+ def aToC(x: T): T = x | |
+ def bToC(x: T): T = x | |
+ } | |
+ | |
+ sealed abstract class weak_<:<[A <: AnyVal, B <: AnyVal] extends (A => B) | |
+ sealed abstract class weak_>:>[A <: AnyVal, B <: AnyVal] extends (B => A) | |
+ sealed abstract class weak_unify[A, B, C] { | |
+ def aToC(a: A): C | |
+ def bToC(b: B): C | |
+ } | |
+ | |
+ implicit val weakByteShort: weak_unify[Byte, Short, Short] = new weak_unify[Byte, Short, Short] { | |
+ def aToC(x: Byte): Short = x | |
+ def bToC(x: Short): Short = x | |
+ } | |
+ implicit val weakByteInt: weak_unify[Byte, Int, Int] = new weak_unify[Byte, Int, Int] { | |
+ def aToC(x: Byte): Int = x | |
+ def bToC(x: Int): Int = x | |
+ } | |
+ implicit val weakByteLong: weak_unify[Byte, Long, Long] = new weak_unify[Byte, Long, Long] { | |
+ def aToC(x: Byte): Long = x | |
+ def bToC(x: Long): Long = x | |
+ } | |
+ implicit val weakByteFloat: weak_unify[Byte, Float, Float] = new weak_unify[Byte, Float, Float] { | |
+ def aToC(x: Byte): Float = x | |
+ def bToC(x: Float): Float = x | |
+ } | |
+ implicit val weakByteDouble: weak_unify[Byte, Double, Double] = new weak_unify[Byte, Double, Double] { | |
+ def aToC(x: Byte): Double = x | |
+ def bToC(x: Double): Double = x | |
+ } | |
+ implicit val weakCharInt: weak_unify[Char, Int, Int] = new weak_unify[Char, Int, Int] { | |
+ def aToC(x: Char): Int = x | |
+ def bToC(x: Int): Int = x | |
+ } | |
+ implicit val weakCharLong: weak_unify[Char, Long, Long] = new weak_unify[Char, Long, Long] { | |
+ def aToC(x: Char): Long = x | |
+ def bToC(x: Long): Long = x | |
+ } | |
+ implicit val weakCharFloat: weak_unify[Char, Float, Float] = new weak_unify[Char, Float, Float] { | |
+ def aToC(x: Char): Float = x | |
+ def bToC(x: Float): Float = x | |
+ } | |
+ implicit val weakCharDouble: weak_unify[Char, Double, Double] = new weak_unify[Char, Double, Double] { | |
+ def aToC(x: Char): Double = x | |
+ def bToC(x: Double): Double = x | |
+ } | |
+ implicit val weakShortInt: weak_unify[Short, Int, Int] = new weak_unify[Short, Int, Int] { | |
+ def aToC(x: Short): Int = x | |
+ def bToC(x: Int): Int = x | |
+ } | |
+ implicit val weakShortLong: weak_unify[Short, Long, Long] = new weak_unify[Short, Long, Long] { | |
+ def aToC(x: Short): Long = x | |
+ def bToC(x: Long): Long = x | |
+ } | |
+ implicit val weakShortFloat: weak_unify[Short, Float, Float] = new weak_unify[Short, Float, Float] { | |
+ def aToC(x: Short): Float = x | |
+ def bToC(x: Float): Float = x | |
+ } | |
+ implicit val weakShortDouble: weak_unify[Short, Double, Double] = new weak_unify[Short, Double, Double] { | |
+ def aToC(x: Short): Double = x | |
+ def bToC(x: Double): Double = x | |
+ } | |
+ implicit val weakIntLong: weak_unify[Int, Long, Long] = new weak_unify[Int, Long, Long] { | |
+ def aToC(x: Int): Long = x | |
+ def bToC(x: Long): Long = x | |
+ } | |
+ implicit val weakIntFloat: weak_unify[Int, Float, Float] = new weak_unify[Int, Float, Float] { | |
+ def aToC(x: Int): Float = x | |
+ def bToC(x: Float): Float = x | |
+ } | |
+ implicit val weakIntDouble: weak_unify[Int, Double, Double] = new weak_unify[Int, Double, Double] { | |
+ def aToC(x: Int): Double = x | |
+ def bToC(x: Double): Double = x | |
+ } | |
+ implicit val weakLongFloat: weak_unify[Long, Float, Float] = new weak_unify[Long, Float, Float] { | |
+ def aToC(x: Long): Float = x | |
+ def bToC(x: Float): Float = x | |
+ } | |
+ implicit val weakLongDouble: weak_unify[Long, Double, Double] = new weak_unify[Long, Double, Double] { | |
+ def aToC(x: Long): Double = x | |
+ def bToC(x: Double): Double = x | |
+ } | |
+ implicit val weakFloatDouble: weak_unify[Float, Double, Double] = new weak_unify[Float, Double, Double] { | |
+ def aToC(x: Float): Double = x | |
+ def bToC(x: Double): Double = x | |
+ } | |
+ | |
+ def generateWeakUnify = { | |
+ for (m1 <- numericTypes ; m2 <- numericTypes) { | |
+ val conforms = m1 match { | |
+ case Char => List(Int, Long, Double, Float) contains m2 | |
+ case _ => m1.weakIndex < m2.weakIndex | |
+ } | |
+ | |
+ val template = | |
+ """|implicit val weak%s%s: %s = new %s { | |
+ | def aToC(x: %s): %s = x | |
+ | def bToC(x: %s): %s = x | |
+ |}""" | |
+ | |
+ val typeString = "weak_unify[%s, %s, %s]".format(m1, m2, m2) | |
+ | |
+ if (conforms) { | |
+ println(template.stripMargin.format( | |
+ m1, m2, | |
+ typeString, typeString, | |
+ m1, m2, | |
+ m2, m2 | |
+ )) | |
+ } | |
+ } | |
+ } | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment