summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/LowPriorityImplicits.scala13
-rw-r--r--src/library/scala/Predef.scala24
-rw-r--r--src/library/scala/Proxy.scala34
-rw-r--r--src/library/scala/math/Numeric.scala12
-rw-r--r--src/library/scala/runtime/RichBoolean.scala11
-rw-r--r--src/library/scala/runtime/RichByte.scala13
-rw-r--r--src/library/scala/runtime/RichChar.scala95
-rw-r--r--src/library/scala/runtime/RichDouble.scala54
-rw-r--r--src/library/scala/runtime/RichFloat.scala36
-rw-r--r--src/library/scala/runtime/RichInt.scala38
-rw-r--r--src/library/scala/runtime/RichLong.scala38
-rw-r--r--src/library/scala/runtime/RichShort.scala13
-rw-r--r--src/library/scala/runtime/ScalaNumberProxy.scala80
-rw-r--r--test/files/run/richWrapperEquals.scala10
14 files changed, 228 insertions, 243 deletions
diff --git a/src/library/scala/LowPriorityImplicits.scala b/src/library/scala/LowPriorityImplicits.scala
index 32bdf7e30d..1b9a65cdaf 100644
--- a/src/library/scala/LowPriorityImplicits.scala
+++ b/src/library/scala/LowPriorityImplicits.scala
@@ -21,6 +21,19 @@ import collection.generic.CanBuildFrom
* @since 2.8
*/
class LowPriorityImplicits {
+ /** We prefer the java.lang.* boxed types to these wrappers in
+ * any potential conflicts. Conflicts do exist because the wrappers
+ * need to implement ScalaNumber in order to have a symmetric equals
+ * method, but that implies implementing java.lang.Number as well.
+ */
+ implicit def byteWrapper(x: Byte) = new runtime.RichByte(x)
+ implicit def shortWrapper(x: Short) = new runtime.RichShort(x)
+ implicit def intWrapper(x: Int) = new runtime.RichInt(x)
+ implicit def charWrapper(c: Char) = new runtime.RichChar(c)
+ implicit def longWrapper(x: Long) = new runtime.RichLong(x)
+ implicit def floatWrapper(x: Float) = new runtime.RichFloat(x)
+ implicit def doubleWrapper(x: Double) = new runtime.RichDouble(x)
+ implicit def booleanWrapper(x: Boolean) = new runtime.RichBoolean(x)
implicit def genericWrapArray[T](xs: Array[T]): WrappedArray[T] =
if (xs ne null) WrappedArray.make(xs) else null
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index bd8f6b6822..2c60a8e8a8 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -199,19 +199,8 @@ object Predef extends LowPriorityImplicits {
// views --------------------------------------------------------------
- implicit def byteWrapper(x: Byte) = new runtime.RichByte(x)
- implicit def shortWrapper(x: Short) = new runtime.RichShort(x)
- implicit def intWrapper(x: Int) = new runtime.RichInt(x)
- implicit def charWrapper(c: Char) = new runtime.RichChar(c)
- implicit def longWrapper(x: Long) = new runtime.RichLong(x)
- implicit def floatWrapper(x: Float) = new runtime.RichFloat(x)
- implicit def doubleWrapper(x: Double) = new runtime.RichDouble(x)
- implicit def booleanWrapper(x: Boolean) = new runtime.RichBoolean(x)
-
implicit def exceptionWrapper(exc: Throwable) = new runtime.RichException(exc)
- // tuple zip views
-
implicit def zipped2ToTraversable[El1, El2](zz: Tuple2[_, _]#Zipped[_, El1, _, El2]): Traversable[(El1, El2)] =
new Traversable[(El1, El2)] {
def foreach[U](f: ((El1, El2)) => U): Unit = zz foreach Function.untupled(f)
@@ -285,6 +274,19 @@ object Predef extends LowPriorityImplicits {
implicit def double2Double(x: Double) = java.lang.Double.valueOf(x)
implicit def boolean2Boolean(x: Boolean) = java.lang.Boolean.valueOf(x)
+ // These next eight implicits exist solely to exclude AnyRef methods from the
+ // eight implicits above so that primitives are not coerced to AnyRefs. They
+ // only create such conflict for AnyRef methods, so the methods on the java.lang
+ // boxed types are unambiguously reachable.
+ implicit def byte2ByteConflict(x: Byte) = new AnyRef
+ implicit def short2ShortConflict(x: Short) = new AnyRef
+ implicit def char2CharacterConflict(x: Char) = new AnyRef
+ implicit def int2IntegerConflict(x: Int) = new AnyRef
+ implicit def long2LongConflict(x: Long) = new AnyRef
+ implicit def float2FloatConflict(x: Float) = new AnyRef
+ implicit def double2DoubleConflict(x: Double) = new AnyRef
+ implicit def boolean2BooleanConflict(x: Boolean) = new AnyRef
+
implicit def Byte2byte(x: java.lang.Byte): Byte = x.byteValue
implicit def Short2short(x: java.lang.Short): Short = x.shortValue
implicit def Character2char(x: java.lang.Character): Char = x.charValue
diff --git a/src/library/scala/Proxy.scala b/src/library/scala/Proxy.scala
index feac5904a5..b7bf8eeef3 100644
--- a/src/library/scala/Proxy.scala
+++ b/src/library/scala/Proxy.scala
@@ -6,24 +6,38 @@
** |/ **
\* */
-
-
package scala
-
/** This class implements a simple proxy that forwards all calls to
- * methods of class <code>Any</code> to another object <code>self</code>.
- * Please note that only those methods can be forwarded that are
- * overridable and public.
+ * the public, non-final methods defined in class "Any" to another
+ * object self. Those methods are:
+ *
+ * def hashCode(): Int
+ * def equals(other: Any): Boolean
+ * def toString(): String
+ *
+ * Note: forwarding methods in this way will most likely create
+ * an asymmetric equals method, which is not generally recommended.
*
* @author Matthias Zenger
* @version 1.0, 26/04/2004
*/
trait Proxy {
def self: Any
- override def hashCode: Int = self.##
- override def equals(that: Any): Boolean =
- if(that == null) false
- else that equals self
+
+ override def hashCode: Int = self.hashCode
+ override def equals(that: Any): Boolean = that match {
+ case null => false
+ case x: Equals => (x canEqual self) && (x equals self)
+ case x => (x equals self)
+ }
override def toString: String = self.toString
}
+
+object Proxy {
+ /** A proxy which exposes the type it is proxying for via a type parameter.
+ */
+ trait Typed[T] extends Proxy {
+ def self: T
+ }
+}
diff --git a/src/library/scala/math/Numeric.scala b/src/library/scala/math/Numeric.scala
index 673461132f..9cf2a15439 100644
--- a/src/library/scala/math/Numeric.scala
+++ b/src/library/scala/math/Numeric.scala
@@ -104,11 +104,10 @@ object Numeric {
}
implicit object LongIsIntegral extends LongIsIntegral with Ordering.LongOrdering
- trait FloatIsFractional extends Fractional[Float] {
+ trait FloatIsConflicted extends Numeric[Float] {
def plus(x: Float, y: Float): Float = x + y
def minus(x: Float, y: Float): Float = x - y
def times(x: Float, y: Float): Float = x * y
- def div(x: Float, y: Float): Float = x / y
def negate(x: Float): Float = -x
def fromInt(x: Int): Float = x
def toInt(x: Float): Int = x.toInt
@@ -116,7 +115,16 @@ object Numeric {
def toFloat(x: Float): Float = x
def toDouble(x: Float): Double = x
}
+ trait FloatIsFractional extends FloatIsConflicted with Fractional[Float] {
+ def div(x: Float, y: Float): Float = x / y
+ }
+ trait FloatAsIfIntegral extends FloatIsConflicted with Integral[Float] {
+ def quot(x: Float, y: Float): Float = (BigDecimal(x) / BigDecimal(y)).floatValue
+ def rem(x: Float, y: Float): Float = (BigDecimal(x) remainder BigDecimal(y)).floatValue
+ }
implicit object FloatIsFractional extends FloatIsFractional with Ordering.FloatOrdering
+ object FloatAsIfIntegral extends FloatAsIfIntegral with Ordering.FloatOrdering {
+ }
trait DoubleIsConflicted extends Numeric[Double] {
def plus(x: Double, y: Double): Double = x + y
diff --git a/src/library/scala/runtime/RichBoolean.scala b/src/library/scala/runtime/RichBoolean.scala
index bfff5dae94..289f287b19 100644
--- a/src/library/scala/runtime/RichBoolean.scala
+++ b/src/library/scala/runtime/RichBoolean.scala
@@ -10,13 +10,6 @@
package scala.runtime
-
-final class RichBoolean(x: Boolean) extends Proxy with Ordered[Boolean] {
-
- // Proxy.self
- def self: Any = x
-
- // Ordered[Boolean].compare
- def compare (y: Boolean): Int = if (x == y) 0 else if (x) 1 else -1
-
+final class RichBoolean(val self: Boolean) extends OrderedProxy[Boolean] {
+ protected val ord = Ordering[Boolean]
}
diff --git a/src/library/scala/runtime/RichByte.scala b/src/library/scala/runtime/RichByte.scala
index 52ec045217..fc3a75a0b8 100644
--- a/src/library/scala/runtime/RichByte.scala
+++ b/src/library/scala/runtime/RichByte.scala
@@ -6,17 +6,6 @@
** |/ **
\* */
-
-
package scala.runtime
-
-final class RichByte(x: Byte) extends Proxy with Ordered[Byte] {
-
- // Proxy.self
- def self: Any = x
-
- // Ordered[Byte].compare
- def compare (y: Byte): Int = if (x < y) -1 else if (x > y) 1 else 0
-
-}
+final class RichByte(val self: Byte) extends ScalaWholeNumberProxy[Byte] { }
diff --git a/src/library/scala/runtime/RichChar.scala b/src/library/scala/runtime/RichChar.scala
index b8324fa221..675af3aada 100644
--- a/src/library/scala/runtime/RichChar.scala
+++ b/src/library/scala/runtime/RichChar.scala
@@ -6,65 +6,39 @@
** |/ **
\* */
-
-
package scala.runtime
import java.lang.Character
-import collection.immutable.NumericRange
-
-/** <p>
- * For example, in the following code
- * </p>
- * <pre>
- * <b>object</b> test <b>extends</b> Application {
- * Console.println(<chr>'\40'</chr>.isWhitespace)
- * Console.println('\011'.isWhitespace)
- * Console.println('1'.asDigit == 1)
- * Console.println('A'.asDigit == 10)
- * }</pre>
- * <p>
- * the implicit conversions are performed using the predefined view
- * <a href="../Predef$object.html#charWrapper(scala.Char)"
- * target="contentFrame"><code>Predef.charWrapper</code></a>.
- * </p>
- */
-final class RichChar(x: Char) extends Proxy with Ordered[Char] {
-
- // Proxy.self
- def self: Any = x
-
- // Ordered[Char].compare
- def compare (y: Char): Int = if (x < y) -1 else if (x > y) 1 else 0
-
- def asDigit: Int = Character.digit(x, Character.MAX_RADIX)
- def isControl: Boolean = Character.isISOControl(x)
- def isDigit: Boolean = Character.isDigit(x)
- def isLetter: Boolean = Character.isLetter(x)
- def isLetterOrDigit: Boolean = Character.isLetterOrDigit(x)
- def isWhitespace: Boolean = Character.isWhitespace(x)
- def isSpaceChar: Boolean = Character.isSpaceChar(x)
- def isHighSurrogate: Boolean = Character.isHighSurrogate(x)
- def isLowSurrogate: Boolean = Character.isLowSurrogate(x)
- def isSurrogate: Boolean = isHighSurrogate || isLowSurrogate
- def isUnicodeIdentifierStart: Boolean = Character.isUnicodeIdentifierStart(x)
- def isUnicodeIdentifierPart: Boolean = Character.isUnicodeIdentifierPart(x)
- def isIdentifierIgnorable: Boolean = Character.isIdentifierIgnorable(x)
- def isMirrored: Boolean = Character.isMirrored(x)
-
- def isLower: Boolean = Character.isLowerCase(x)
- def isUpper: Boolean = Character.isUpperCase(x)
- def isTitleCase: Boolean = Character.isTitleCase(x)
-
- def toLower: Char = Character.toLowerCase(x)
- def toUpper: Char = Character.toUpperCase(x)
- def toTitleCase: Char = Character.toTitleCase(x)
-
- def getType: Int = Character.getType(x)
- def getNumericValue: Int = Character.getNumericValue(x)
- def getDirectionality: Byte = Character.getDirectionality(x)
- def reverseBytes: Char = Character.reverseBytes(x)
+final class RichChar(val self: Char) extends IntegralProxy[Char] {
+ def asDigit: Int = Character.digit(self, Character.MAX_RADIX)
+
+ def isControl: Boolean = Character.isISOControl(self)
+ def isDigit: Boolean = Character.isDigit(self)
+ def isLetter: Boolean = Character.isLetter(self)
+ def isLetterOrDigit: Boolean = Character.isLetterOrDigit(self)
+ def isWhitespace: Boolean = Character.isWhitespace(self)
+ def isSpaceChar: Boolean = Character.isSpaceChar(self)
+ def isHighSurrogate: Boolean = Character.isHighSurrogate(self)
+ def isLowSurrogate: Boolean = Character.isLowSurrogate(self)
+ def isSurrogate: Boolean = isHighSurrogate || isLowSurrogate
+ def isUnicodeIdentifierStart: Boolean = Character.isUnicodeIdentifierStart(self)
+ def isUnicodeIdentifierPart: Boolean = Character.isUnicodeIdentifierPart(self)
+ def isIdentifierIgnorable: Boolean = Character.isIdentifierIgnorable(self)
+ def isMirrored: Boolean = Character.isMirrored(self)
+
+ def isLower: Boolean = Character.isLowerCase(self)
+ def isUpper: Boolean = Character.isUpperCase(self)
+ def isTitleCase: Boolean = Character.isTitleCase(self)
+
+ def toLower: Char = Character.toLowerCase(self)
+ def toUpper: Char = Character.toUpperCase(self)
+ def toTitleCase: Char = Character.toTitleCase(self)
+
+ def getType: Int = Character.getType(self)
+ def getNumericValue: Int = Character.getNumericValue(self)
+ def getDirectionality: Byte = Character.getDirectionality(self)
+ def reverseBytes: Char = Character.reverseBytes(self)
// Java 5 Character methods not added:
//
@@ -81,15 +55,4 @@ final class RichChar(x: Char) extends Proxy with Ordered[Char] {
def isLowerCase: Boolean = isLower
@deprecated("Use ch.isUpper instead")
def isUpperCase: Boolean = isUpper
-
- /** Create a <code>[Char]</code> over the characters from 'x' to 'limit' - 1
- */
- def until(limit: Char): NumericRange[Char] =
- new NumericRange.Exclusive(x, limit, 1.toChar)
-
- /** Create a <code>IndexedSeqView[Char]</code> over the characters from 'x' to 'limit'
- */
- def to(limit: Char): NumericRange[Char] =
- new NumericRange.Inclusive(x, limit, 1.toChar)
-
}
diff --git a/src/library/scala/runtime/RichDouble.scala b/src/library/scala/runtime/RichDouble.scala
index 64976acb12..607bde1fb5 100644
--- a/src/library/scala/runtime/RichDouble.scala
+++ b/src/library/scala/runtime/RichDouble.scala
@@ -6,62 +6,34 @@
** |/ **
\* */
-
-
package scala.runtime
-import scala.collection.immutable.{Range, NumericRange}
-
-final class RichDouble(x: Double) extends Proxy with Ordered[Double] {
- // Proxy.self
- def self: Any = x
-
- def compare(y: Double): Int = java.lang.Double.compare(x, y)
-
- def min(y: Double): Double = math.min(x, y)
- def max(y: Double): Double = math.max(x, y)
- def abs: Double = math.abs(x)
+final class RichDouble(val self: Double) extends FractionalProxy[Double] {
+ protected val integralNum = Numeric.DoubleAsIfIntegral
- def round: Long = math.round(x)
- def ceil: Double = math.ceil(x)
- def floor: Double = math.floor(x)
-
- /** See <code>BigDecimal.until</code>. */
- def until(end: Double): Range.Partial[Double, NumericRange[Double]] =
- new Range.Partial(until(end, _))
-
- /** See <code>BigDecimal.until</code>. */
- def until(end: Double, step: Double): NumericRange[Double] =
- Range.Double(x, end, step)
-
- /** See <code>BigDecimal.to</code>. */
- def to(end: Double): Range.Partial[Double, NumericRange[Double]] =
- new Range.Partial(to(end, _))
-
- /** See <code>BigDecimal.to</code>. */
- def to(end: Double, step: Double): NumericRange[Double] =
- Range.Double.inclusive(x, end, step)
+ def round: Long = math.round(self)
+ def ceil: Double = math.ceil(self)
+ def floor: Double = math.floor(self)
/** Converts an angle measured in degrees to an approximately equivalent
* angle measured in radians.
*
* @param x an angle, in degrees
- * @return the measurement of the angle <code>x</code> in radians.
+ * @return the measurement of the angle x in radians.
*/
- def toRadians: Double = math.toRadians(x)
+ def toRadians: Double = math.toRadians(self)
/** Converts an angle measured in radians to an approximately equivalent
* angle measured in degrees
*
* @param x angle, in radians
- * @return the measurement of the angle <code>x</code> in degrees.
+ * @return the measurement of the angle x in degrees.
*/
- def toDegrees: Double = math.toDegrees(x)
+ def toDegrees: Double = math.toDegrees(self)
// isNaN is provided by the implicit conversion to java.lang.Double
- // def isNaN: Boolean = java.lang.Double.isNaN(x)
- def isInfinity: Boolean = java.lang.Double.isInfinite(x)
- def isPosInfinity: Boolean = isInfinity && x > 0.0
- def isNegInfinity: Boolean = isInfinity && x < 0.0
-
+ // def isNaN: Boolean = java.lang.Double.isNaN(self)
+ def isInfinity: Boolean = java.lang.Double.isInfinite(self)
+ def isPosInfinity: Boolean = isInfinity && self > 0.0
+ def isNegInfinity: Boolean = isInfinity && self < 0.0
}
diff --git a/src/library/scala/runtime/RichFloat.scala b/src/library/scala/runtime/RichFloat.scala
index e8e351bdaa..8a4ab13c19 100644
--- a/src/library/scala/runtime/RichFloat.scala
+++ b/src/library/scala/runtime/RichFloat.scala
@@ -6,27 +6,14 @@
** |/ **
\* */
-
-
package scala.runtime
+final class RichFloat(val self: Float) extends FractionalProxy[Float] {
+ protected val integralNum = Numeric.FloatAsIfIntegral
-final class RichFloat(x: Float) extends Proxy with Ordered[Float] {
-
- // Proxy.self
- def self: Any = x
-
- // Ordered[Float].compare
- //def compare(y: Float): Int = if (x < y) -1 else if (x > y) 1 else 0
- def compare(y: Float): Int = java.lang.Float.compare(x, y)
-
- def min(y: Float) = math.min(x, y)
- def max(y: Float) = math.max(x, y)
- def abs: Float = math.abs(x)
-
- def round: Int = math.round(x)
- def ceil: Float = math.ceil(x).toFloat
- def floor: Float = math.floor(x).toFloat
+ def round: Int = math.round(self)
+ def ceil: Float = math.ceil(self).toFloat
+ def floor: Float = math.floor(self).toFloat
/** Converts an angle measured in degrees to an approximately equivalent
* angle measured in radians.
@@ -34,7 +21,7 @@ final class RichFloat(x: Float) extends Proxy with Ordered[Float] {
* @param x an angle, in degrees
* @return the measurement of the angle <code>x</code> in radians.
*/
- def toRadians: Float = math.toRadians(x).toFloat
+ def toRadians: Float = math.toRadians(self).toFloat
/** Converts an angle measured in radians to an approximately equivalent
* angle measured in degrees.
@@ -42,12 +29,11 @@ final class RichFloat(x: Float) extends Proxy with Ordered[Float] {
* @param x angle, in radians
* @return the measurement of the angle <code>x</code> in degrees.
*/
- def toDegrees: Float = math.toDegrees(x).toFloat
+ def toDegrees: Float = math.toDegrees(self).toFloat
// isNaN is provided by the implicit conversion to java.lang.Float
- // def isNaN: Boolean = java.lang.Float.isNaN(x)
- def isInfinity: Boolean = java.lang.Float.isInfinite(x)
- def isPosInfinity: Boolean = isInfinity && x > 0.0f
- def isNegInfinity: Boolean = isInfinity && x < 0.0f
-
+ // def isNaN: Boolean = java.lang.Float.isNaN(self)
+ def isInfinity: Boolean = java.lang.Float.isInfinite(self)
+ def isPosInfinity: Boolean = isInfinity && self > 0.0f
+ def isNegInfinity: Boolean = isInfinity && self < 0.0f
}
diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala
index c5ed5df07c..8ba5685922 100644
--- a/src/library/scala/runtime/RichInt.scala
+++ b/src/library/scala/runtime/RichInt.scala
@@ -7,32 +7,28 @@
\* */
-
package scala.runtime
-import collection.immutable.Range
-
-
-final class RichInt(val start: Int) extends Proxy with Ordered[Int] {
-
- // Proxy
- def self: Any = start
+import scala.collection.immutable.Range
- // Ordered[Int]
- def compare(that: Int): Int = if (start < that) -1 else if (start > that) 1 else 0
+// Note that this does not implement IntegralProxy[Int] so that it can return
+// the Int-specific Range class from until/to.
+final class RichInt(val self: Int) extends ScalaNumberProxy[Int] with RangedProxy[Int] {
+ type ResultWithoutStep = Range
+ def isWhole() = true
- def until(end: Int): Range = Range(start, end)
- def until(end: Int, step: Int): Range = Range(start, end, step)
+ def until(end: Int): Range = Range(self, end)
+ def until(end: Int, step: Int): Range = Range(self, end, step)
- /** like <code>until</code>, but includes the last index */
- def to(end: Int): Range.Inclusive = Range.inclusive(start, end)
- def to(end: Int, step: Int): Range.Inclusive = Range.inclusive(start, end, step)
+ /** like `until`, but includes the last index */
+ def to(end: Int): Range.Inclusive = Range.inclusive(self, end)
+ def to(end: Int, step: Int): Range.Inclusive = Range.inclusive(self, end, step)
- def min(that: Int): Int = if (start < that) start else that
- def max(that: Int): Int = if (start > that) start else that
- def abs: Int = if (start < 0) -start else start
+ override def min(that: Int): Int = if (self < that) self else that
+ override def max(that: Int): Int = if (self > that) self else that
+ override def abs: Int = if (self < 0) -self else self
- def toBinaryString: String = java.lang.Integer.toBinaryString(start)
- def toHexString: String = java.lang.Integer.toHexString(start)
- def toOctalString: String = java.lang.Integer.toOctalString(start)
+ def toBinaryString: String = java.lang.Integer.toBinaryString(self)
+ def toHexString: String = java.lang.Integer.toHexString(self)
+ def toOctalString: String = java.lang.Integer.toOctalString(self)
}
diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala
index 82e2c77ef7..807929aa6d 100644
--- a/src/library/scala/runtime/RichLong.scala
+++ b/src/library/scala/runtime/RichLong.scala
@@ -6,40 +6,10 @@
** |/ **
\* */
-
-
package scala.runtime
-import scala.collection.immutable.{Range, NumericRange}
-
-final class RichLong(x: Long) extends Proxy with Ordered[Long] {
-
- // Proxy.self
- def self: Any = x
-
- // Ordered[Long].compare
- def compare(y: Long): Int = if (x < y) -1 else if (x > y) 1 else 0
-
- /** Create a NumericRange[Long] in range <code>[start;end)</code>
- * with the specified step, where start is the target Long.
- *
- * @param end the end value of the range (exclusive)
- * @param step the distance between elements (defaults to 1)
- * @return the range
- */
- def until(end: Long, step: Long = 1L): NumericRange.Exclusive[Long] = Range.Long(x, end, step)
-
- def until(end: Long): NumericRange.Exclusive[Long] = Range.Long(x, end, 1l)
-
- /** Like until, but inclusive of the end value.
- */
- def to(end: Long, step: Long = 1L): NumericRange.Inclusive[Long] = Range.Long.inclusive(x, end, step)
-
- def min(y: Long): Long = if (x < y) x else y
- def max(y: Long): Long = if (x > y) x else y
- def abs: Long = if (x < 0) -x else x
-
- def toBinaryString: String = java.lang.Long.toBinaryString(x)
- def toHexString: String = java.lang.Long.toHexString(x)
- def toOctalString: String = java.lang.Long.toOctalString(x)
+final class RichLong(val self: Long) extends IntegralProxy[Long] {
+ def toBinaryString: String = java.lang.Long.toBinaryString(self)
+ def toHexString: String = java.lang.Long.toHexString(self)
+ def toOctalString: String = java.lang.Long.toOctalString(self)
}
diff --git a/src/library/scala/runtime/RichShort.scala b/src/library/scala/runtime/RichShort.scala
index 0fa34b27c4..51214ac13e 100644
--- a/src/library/scala/runtime/RichShort.scala
+++ b/src/library/scala/runtime/RichShort.scala
@@ -6,17 +6,6 @@
** |/ **
\* */
-
-
package scala.runtime
-
-final class RichShort(start: Short) extends Proxy with Ordered[Short] {
-
- // Proxy.self
- def self: Any = start
-
- // Ordered[Short].compare
- def compare(that: Short): Int = if (start < that) -1 else if (start > that) 1 else 0
-
-}
+final class RichShort(val self: Short) extends ScalaWholeNumberProxy[Short] { }
diff --git a/src/library/scala/runtime/ScalaNumberProxy.scala b/src/library/scala/runtime/ScalaNumberProxy.scala
new file mode 100644
index 0000000000..42d65ba388
--- /dev/null
+++ b/src/library/scala/runtime/ScalaNumberProxy.scala
@@ -0,0 +1,80 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://www.scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.runtime
+
+import scala.collection.{ mutable, immutable }
+import math.ScalaNumericConversions
+import immutable.NumericRange
+import Proxy.Typed
+
+/** Base classes for the Rich* wrappers of the primitive types.
+ * As with all classes in scala.runtime.*, this is not a supported API.
+ *
+ * @author Paul Phillips
+ * @version 2.9
+ * @since 2.9
+ */
+abstract class ScalaNumberProxy[T: Numeric] extends ScalaNumericConversions with Typed[T] with OrderedProxy[T] {
+ private val num = implicitly[Numeric[T]]
+ protected val ord: Ordering[T] = num
+
+ def underlying() = self.asInstanceOf[AnyRef]
+ def doubleValue() = num.toDouble(self)
+ def floatValue() = num.toFloat(self)
+ def longValue() = num.toLong(self)
+ def intValue() = num.toInt(self)
+
+ def min(that: T): T = num.min(self, that)
+ def max(that: T): T = num.max(self, that)
+ def abs = num.abs(self)
+ def signum = num.signum(self)
+}
+abstract class ScalaWholeNumberProxy[T: Numeric] extends ScalaNumberProxy[T] {
+ def isWhole() = true
+}
+abstract class IntegralProxy[T : Integral] extends ScalaWholeNumberProxy[T] with RangedProxy[T] {
+ private lazy val num = implicitly[Integral[T]]
+ type ResultWithoutStep = NumericRange[T]
+
+ def until(end: T): NumericRange.Exclusive[T] = NumericRange(self, end, num.one)
+ def until(end: T, step: T): NumericRange.Exclusive[T] = NumericRange(self, end, step)
+ def to(end: T): NumericRange.Inclusive[T] = NumericRange.inclusive(self, end, num.one)
+ def to(end: T, step: T): NumericRange.Inclusive[T] = NumericRange.inclusive(self, end, step)
+}
+abstract class FractionalProxy[T : Fractional] extends ScalaNumberProxy[T] with RangedProxy[T] {
+ def isWhole() = false
+
+ /** In order to supply predictable ranges, we require an Integral[T] which provides
+ * us with discrete operations on the (otherwise fractional) T. See Numeric.DoubleAsIfIntegral
+ * for an example.
+ */
+ protected implicit def integralNum: Integral[T]
+ private lazy val num = implicitly[Fractional[T]]
+ type ResultWithoutStep = Range.Partial[T, NumericRange[T]]
+
+ def until(end: T): ResultWithoutStep = new Range.Partial(NumericRange(self, end, _))
+ def until(end: T, step: T): NumericRange.Exclusive[T] = NumericRange(self, end, step)
+ def to(end: T): ResultWithoutStep = new Range.Partial(NumericRange.inclusive(self, end, _))
+ def to(end: T, step: T): NumericRange.Inclusive[T] = NumericRange.inclusive(self, end, step)
+}
+
+trait OrderedProxy[T] extends Typed[T] with Ordered[T] {
+ protected def ord: Ordering[T]
+
+ def compare(y: T) = ord.compare(self, y)
+}
+trait RangedProxy[T] extends Typed[T] {
+ type ResultWithoutStep
+
+ def until(end: T): ResultWithoutStep
+ def until(end: T, step: T): immutable.IndexedSeq[T]
+ def to(end: T): ResultWithoutStep
+ def to(end: T, step: T): immutable.IndexedSeq[T]
+}
+
diff --git a/test/files/run/richWrapperEquals.scala b/test/files/run/richWrapperEquals.scala
new file mode 100644
index 0000000000..44beb133b3
--- /dev/null
+++ b/test/files/run/richWrapperEquals.scala
@@ -0,0 +1,10 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ assert(intWrapper(5) == 5)
+ assert(5 == intWrapper(5))
+ assert(5 == (5: java.lang.Integer))
+ assert((5: java.lang.Integer) == 5)
+ assert((5: java.lang.Integer) == intWrapper(5))
+ assert(intWrapper(5) == (5: java.lang.Integer))
+ }
+}