summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@typesafe.com>2015-02-18 12:46:21 -0800
committerAdriaan Moors <adriaan.moors@typesafe.com>2015-02-18 12:46:21 -0800
commitbff86367607a713288a939639a654802349d1067 (patch)
tree228d886551855645d8490b7c13feca02e305db8e
parent788f38871ca52bc22967dca22355f6a1affb4e06 (diff)
downloadscala-bff86367607a713288a939639a654802349d1067.tar.gz
scala-bff86367607a713288a939639a654802349d1067.tar.bz2
scala-bff86367607a713288a939639a654802349d1067.zip
Use if/then/else to avoid box(unbox(_))
-rw-r--r--src/library/scala/reflect/ClassTag.scala29
-rw-r--r--test/junit/scala/reflect/ClassTag.scala29
2 files changed, 43 insertions, 15 deletions
diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala
index b9b4772870..9dd96183da 100644
--- a/src/library/scala/reflect/ClassTag.scala
+++ b/src/library/scala/reflect/ClassTag.scala
@@ -69,21 +69,20 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial
* `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)`
* is uncheckable, but we have an instance of `ClassTag[T]`.
*/
- def unapply(x: Any): Option[T] = x match {
- case null => None
- case x: Byte => unapplyImpl(x, classOf[Byte]) // erases to: if (x instanceof Byte) unapplyImpl(BoxesRunTime.boxToByte(BoxesRunTime.unboxToByte(x)), Byte.TYPE)
- case x: Short => unapplyImpl(x, classOf[Short])
- case x: Char => unapplyImpl(x, classOf[Char])
- case x: Int => unapplyImpl(x, classOf[Int])
- case x: Long => unapplyImpl(x, classOf[Long])
- case x: Float => unapplyImpl(x, classOf[Float])
- case x: Double => unapplyImpl(x, classOf[Double])
- case x: Boolean => unapplyImpl(x, classOf[Boolean])
- case x: Unit => unapplyImpl(x, classOf[Unit])
- // TODO: move this next case up and remove the redundant check in unapplyImpl?
- case _ if runtimeClass isInstance x => Some(x.asInstanceOf[T])
- case _ => None
- }
+ def unapply(x: Any): Option[T] =
+ if (null != x && (
+ (runtimeClass.isInstance(x))
+ || (x.isInstanceOf[Byte] && runtimeClass.isAssignableFrom(classOf[Byte]))
+ || (x.isInstanceOf[Short] && runtimeClass.isAssignableFrom(classOf[Short]))
+ || (x.isInstanceOf[Char] && runtimeClass.isAssignableFrom(classOf[Char]))
+ || (x.isInstanceOf[Int] && runtimeClass.isAssignableFrom(classOf[Int]))
+ || (x.isInstanceOf[Long] && runtimeClass.isAssignableFrom(classOf[Long]))
+ || (x.isInstanceOf[Float] && runtimeClass.isAssignableFrom(classOf[Float]))
+ || (x.isInstanceOf[Double] && runtimeClass.isAssignableFrom(classOf[Double]))
+ || (x.isInstanceOf[Boolean] && runtimeClass.isAssignableFrom(classOf[Boolean]))
+ || (x.isInstanceOf[Unit] && runtimeClass.isAssignableFrom(classOf[Unit])))
+ ) Some(x.asInstanceOf[T])
+ else None
// TODO: deprecate overloads in 2.12.0, remove in 2.13.0
def unapply(x: Byte) : Option[T] = unapplyImpl(x, classOf[Byte])
diff --git a/test/junit/scala/reflect/ClassTag.scala b/test/junit/scala/reflect/ClassTag.scala
new file mode 100644
index 0000000000..90cc981fc1
--- /dev/null
+++ b/test/junit/scala/reflect/ClassTag.scala
@@ -0,0 +1,29 @@
+package scala.reflect
+
+import org.junit.Test
+import org.junit.Assert._
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+import scala.tools.testing.AssertUtil._
+
+class Misc
+
+@RunWith(classOf[JUnit4])
+class ClassTagTest {
+ def checkNotString[A: ClassTag](a: Any) = a match { case x: String => false case x: A => true case _ => false }
+ def checkNotInt[A: ClassTag](a: Any) = a match { case x: Int => false case x: A => true case _ => false }
+ def checkNotLong[A: ClassTag](a: Any) = a match { case x: Long => false case x: A => true case _ => false }
+
+ @Test def checkMisc = assertTrue(checkNotString[Misc](new Misc))
+ @Test def checkString = assertTrue(checkNotInt[String] ("woele"))
+ @Test def checkByte = assertTrue(checkNotInt[Byte] (0.toByte))
+ @Test def checkShort = assertTrue(checkNotInt[Short] (0.toShort))
+ @Test def checkChar = assertTrue(checkNotInt[Char] (0.toChar))
+ @Test def checkInt = assertTrue(checkNotLong[Int] (0.toInt))
+ @Test def checkLong = assertTrue(checkNotInt[Long] (0.toLong))
+ @Test def checkFloat = assertTrue(checkNotInt[Float] (0.toFloat))
+ @Test def checkDouble = assertTrue(checkNotInt[Double] (0.toDouble))
+ @Test def checkBoolean = assertTrue(checkNotInt[Boolean](false))
+ @Test def checkUnit = assertTrue(checkNotInt[Unit] ({}))
+} \ No newline at end of file