summaryrefslogtreecommitdiff
path: root/src/library/scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-06-24 15:19:09 +0000
committerPaul Phillips <paulp@improving.org>2009-06-24 15:19:09 +0000
commit1c9870541fb22ac032edaa0be0103cc1aa2c99b4 (patch)
tree881d38aa5dfba0542295e7e56e642a77cd3852b6 /src/library/scala
parent6ab1f0b7710af132401848bc25da9101a364093b (diff)
downloadscala-1c9870541fb22ac032edaa0be0103cc1aa2c99b4.tar.gz
scala-1c9870541fb22ac032edaa0be0103cc1aa2c99b4.tar.bz2
scala-1c9870541fb22ac032edaa0be0103cc1aa2c99b4.zip
More work and documentation for GenericRanges, ...
More work and documentation for GenericRanges, plus minor findbugs noticed issues.
Diffstat (limited to 'src/library/scala')
-rw-r--r--src/library/scala/BigDecimal.scala24
-rw-r--r--src/library/scala/BigInt.scala21
-rwxr-xr-xsrc/library/scala/Numeric.scala2
-rw-r--r--src/library/scala/Range.scala80
-rw-r--r--src/library/scala/collection/immutable/PagedSeq.scala11
-rw-r--r--src/library/scala/collection/mutable/ArrayStack.scala1
-rw-r--r--src/library/scala/runtime/RichChar.scala2
-rw-r--r--src/library/scala/runtime/RichDouble.scala21
-rw-r--r--src/library/scala/runtime/RichInt.scala7
-rw-r--r--src/library/scala/runtime/RichLong.scala23
-rw-r--r--src/library/scala/util/control/Exception.scala8
-rw-r--r--src/library/scala/xml/Group.scala4
-rw-r--r--src/library/scala/xml/NamespaceBinding.scala4
13 files changed, 136 insertions, 72 deletions
diff --git a/src/library/scala/BigDecimal.scala b/src/library/scala/BigDecimal.scala
index b4d4732951..020a58edc9 100644
--- a/src/library/scala/BigDecimal.scala
+++ b/src/library/scala/BigDecimal.scala
@@ -345,10 +345,30 @@ extends java.lang.Number
def intValueExact: Int = bigDecimal.intValueExact
def longValueExact: Long = bigDecimal.longValueExact
- /** See <code>Iterator.range</code>. */
+ /** Creates a partially constructed GenericRange[BigDecimal] in range
+ * <code>[start;end)</code>, where start is the target BigDecimal. The step
+ * must be supplied via the "by" method of the returned object in order
+ * to receive the fully constructed range. For example:
+ * <pre>
+ * val partial = BigDecimal(1.0) to 2.0 // not usable yet
+ * val range = partial by 0.01 // now a GenericRange
+ * val range2 = BigDecimal(0) to 1.0 by 0.01 // all at once of course is fine too
+ * </pre>
+ *
+ * @param end the end value of the range (exclusive)
+ * @return the partially constructed GenericRange
+ */
+ def until(end: BigDecimal): Range.Partial[BigDecimal, GenericRange.Exclusive[BigDecimal]] =
+ new Range.Partial(until(end, _))
+
+ /** Same as the one-argument <code>until</code>, but creates the range immediately. */
def until(end: BigDecimal, step: BigDecimal) = Range.BigDecimal(this, end, step)
- /** like <code>until</code>, but includes the last index */
+ /** Like <code>until</code>, but inclusive of the end value. */
+ def to(end: BigDecimal): Range.Partial[BigDecimal, GenericRange.Inclusive[BigDecimal]] =
+ new Range.Partial(to(end, _))
+
+ /** Like <code>until</code>, but inclusive of the end value. */
def to(end: BigDecimal, step: BigDecimal) = Range.BigDecimal.inclusive(this, end, step)
/** Converts this <code>BigDecimal</code> to a scala.BigInt.
diff --git a/src/library/scala/BigInt.scala b/src/library/scala/BigInt.scala
index 6ec02d0100..9e54e9bee2 100644
--- a/src/library/scala/BigInt.scala
+++ b/src/library/scala/BigInt.scala
@@ -338,17 +338,18 @@ class BigInt(val bigInteger: BigInteger) extends jl.Number
*/
def doubleValue = this.bigInteger.doubleValue
- /** See <code>Iterator.range</code>. */
- def until(end: BigInt) = Range.BigInt(this, end, BigInt(1))
-
- /** See <code>Iterator.range</code>. */
- def until(end: BigInt, step: BigInt) = Range.BigInt(this, end, step)
-
- /** like <code>until</code>, but includes the last index */
- def to(end: BigInt) = Range.BigInt.inclusive(this, end, BigInt(1))
+ /** Create a GenericRange[BigInt] in range <code>[start;end)</code>
+ * with the specified step, where start is the target BigInt.
+ *
+ * @param end the end value of the range (exclusive)
+ * @param step the distance between elements (defaults to 1)
+ * @return the range
+ */
+ def until(end: BigInt, step: BigInt = BigInt(1)) = Range.BigInt(this, end, step)
- /** like <code>until</code>, but includes the last index */
- def to(end: BigInt, step: BigInt) = Range.BigInt.inclusive(this, end, step)
+ /** Like until, but inclusive of the end value.
+ */
+ def to(end: BigInt, step: BigInt = BigInt(1)) = Range.BigInt.inclusive(this, end, step)
/** Returns the decimal String representation of this BigInt.
*/
diff --git a/src/library/scala/Numeric.scala b/src/library/scala/Numeric.scala
index a9fc0c08f8..5cdbb32a68 100755
--- a/src/library/scala/Numeric.scala
+++ b/src/library/scala/Numeric.scala
@@ -74,7 +74,7 @@ object Numeric {
}
implicit object DoubleIsFractional extends DoubleIsFractional with Ordering.DoubleOrdering
- trait BigDecimalIsConflicted {
+ trait BigDecimalIsConflicted extends Numeric[BigDecimal] {
def plus(x: BigDecimal, y: BigDecimal): BigDecimal = x + y
def minus(x: BigDecimal, y: BigDecimal): BigDecimal = x - y
def times(x: BigDecimal, y: BigDecimal): BigDecimal = x * y
diff --git a/src/library/scala/Range.scala b/src/library/scala/Range.scala
index d7ee1d7a38..992a6a2e1b 100644
--- a/src/library/scala/Range.scala
+++ b/src/library/scala/Range.scala
@@ -10,6 +10,7 @@
package scala
+import annotation.experimental
import collection.immutable.Vector
import collection.generic.VectorView
import util.control.Exception.catching
@@ -21,9 +22,9 @@ import util.Hashable
* It must be supplied with an Integral implementation of the
* range type.
*
- * Factories for likely types include Range.BigInt and Range.Long.
- * Range.Int exists for completeness, but the Int-based scala.Range
- * should be more performant.
+ * Factories for likely types include Range.BigInt, Range.Long,
+ * and Range.BigDecimal. Range.Int exists for completeness, but
+ * the Int-based scala.Range should be more performant.
* </p><pre>
* <b>val</b> r1 = new Range(0, 100, 1)
* <b>val</b> veryBig = Math.MAX_INT.toLong + 1
@@ -34,6 +35,7 @@ import util.Hashable
* @author Paul Phillips
* @version 2.8
*/
+@experimental
abstract class GenericRange[T]
(val start: T, val end: T, val step: T, val isInclusive: Boolean = false)
(implicit num: Integral[T])
@@ -53,9 +55,17 @@ extends VectorView[T, Vector[T]] with RangeToString[T] with Hashable {
/** Create a new range with the start and end values of this range and
* a new <code>step</code>.
*/
- def by(step: T): GenericRange[T] =
- if (isInclusive) GenericRange.inclusive(start, end, step)
- else GenericRange(start, end, step)
+ def by(newStep: T): GenericRange[T] = copy(start, end, newStep)
+
+ /** Create a copy of this range.
+ */
+ def copy(start: T, end: T, step: T): GenericRange[T]
+
+ /** Shift or multiply the entire range by some constant.
+ */
+ def -(shift: T) = this + negate(shift)
+ def +(shift: T) = copy(this.start + shift, this.end + shift, step)
+ def *(mult: T) = copy(this.start * mult, this.end * mult, step * mult)
override def foreach[U](f: T => U) {
var i = start
@@ -132,21 +142,23 @@ private[scala] trait RangeToString[T] extends VectorView[T, Vector[T]] {
}
-object GenericRange {
+object GenericRange
+{
class Inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T])
extends GenericRange(start, end, step, true) {
- def exclusive: Exclusive[T] = new Exclusive(start, end, step)
+ def exclusive: Exclusive[T] = GenericRange(start, end, step)
+ def copy(start: T, end: T, step: T): Inclusive[T] = GenericRange.inclusive(start, end, step)
}
class Exclusive[T](start: T, end: T, step: T)(implicit num: Integral[T])
extends GenericRange(start, end, step, false) {
- def inclusive: Inclusive[T] = new Inclusive(start, end, step)
+ def inclusive: Inclusive[T] = GenericRange.inclusive(start, end, step)
+ def copy(start: T, end: T, step: T): Exclusive[T] = GenericRange(start, end, step)
}
- def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]) =
+ def apply[T](start: T, end: T, step: T)(implicit num: Integral[T]): Exclusive[T] =
new Exclusive(start, end, step)
-
- def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]) =
+ def inclusive[T](start: T, end: T, step: T)(implicit num: Integral[T]): Inclusive[T] =
new Inclusive(start, end, step)
}
@@ -210,6 +222,12 @@ extends VectorView[Int, Vector[Int]] with RangeToString[Int]
else start >= x && x > end
def inclusive = Range.inclusive(start, end, step)
+ // XXX right now (1 to 10).toList == (1 to 10) but their hashCodes are unequal.
+ override def equals(other: Any) = other match {
+ case x: Range => start == x.start && end == x.end && step == x.step
+ case _ => super.equals(other)
+ }
+ override def hashCode = start + end + step
}
object Range {
@@ -219,33 +237,45 @@ object Range {
override def by(step: Int): Range = new Inclusive(start, end0, step)
}
+ // The standard / Int-specific Range.
def apply(start: Int, end: Int, step: Int) =
new Range(start, end, step)
-
def inclusive(start: Int, end: Int, step: Int): Range =
new Range.Inclusive(start, end, step)
+ // BigInt and Long are straightforward generic ranges.
object BigInt {
def apply(start: BigInt, end: BigInt, step: BigInt) = GenericRange(start, end, step)
def inclusive(start: BigInt, end: BigInt, step: BigInt) = GenericRange.inclusive(start, end, step)
}
- // The BigDecimal and Double ranges will throw an exception if they cannot
- // step exactly as requested.
- object BigDecimal {
- def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) =
- GenericRange(start, end, step)(Numeric.BigDecimalAsIfIntegral)
- def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) =
- GenericRange.inclusive(start, end, step)(Numeric.BigDecimalAsIfIntegral)
- }
object Long {
def apply(start: Long, end: Long, step: Long) = GenericRange(start, end, step)
def inclusive(start: Long, end: Long, step: Long) = GenericRange.inclusive(start, end, step)
}
+
+ // BigDecimal uses an alternative implementation of Numeric in which
+ // it pretends to be Integral[T] instead of Fractional[T]. See Numeric for
+ // details. The intention is for it to throw an exception anytime
+ // imprecision or surprises might result from anything, although this may
+ // not yet be fully implemented.
+ object BigDecimal {
+ implicit val bigDecAsIntegral = scala.Numeric.BigDecimalAsIfIntegral
+
+ def apply(start: BigDecimal, end: BigDecimal, step: BigDecimal) =
+ GenericRange(start, end, step)
+ def inclusive(start: BigDecimal, end: BigDecimal, step: BigDecimal) =
+ GenericRange.inclusive(start, end, step)
+ }
+ // Double re-uses BigDecimal's range.
object Double {
- def apply(start: Double, end: Double, step: Double) =
- BigDecimal(scala.BigDecimal(start), scala.BigDecimal(end), scala.BigDecimal(step))
- def inclusive(start: Double, end: Double, step: Double) =
- BigDecimal.inclusive(scala.BigDecimal(start), scala.BigDecimal(end), scala.BigDecimal(step))
+ def apply(start: Double, end: Double, step: Double) = scala.BigDecimal(start) until end by step
+ def inclusive(start: Double, end: Double, step: Double) = scala.BigDecimal(start) to end by step
+ }
+
+ // As there is no appealing default step size for not-really-integral ranges,
+ // we offer a partially constructed object.
+ class Partial[T, U](f: T => U) {
+ def by(x: T): U = f(x)
}
// Illustrating genericity with Int Range, which should have the same behavior
diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala
index fe34195238..3b839fe678 100644
--- a/src/library/scala/collection/immutable/PagedSeq.scala
+++ b/src/library/scala/collection/immutable/PagedSeq.scala
@@ -14,7 +14,6 @@ package scala.collection.immutable
import java.io._
import util.matching.Regex
-
/** The PagedSeq object defines a lazy implementations of
* a random access sequence.
*/
@@ -108,9 +107,13 @@ import PagedSeq._
*
* @author Martin Odersky
*/
-class PagedSeq[T] protected (more: (Array[T], Int, Int) => Int,
- first1: Page[T], start: Int, end: Int) extends RandomAccessSeq[T] {
-
+class PagedSeq[T] protected(
+ more: (Array[T], Int, Int) => Int,
+ first1: Page[T],
+ start: Int,
+ end: Int)
+extends collection.Vector[T]
+{
/** A paged sequence is constructed from a method that produces more characters when asked.
* The producer method is analogous to the read method in java.io.Reader.
* It takes three parameters: an array of characters, a start index, and an end index.
diff --git a/src/library/scala/collection/mutable/ArrayStack.scala b/src/library/scala/collection/mutable/ArrayStack.scala
index b0090da156..bc3e8eea0d 100644
--- a/src/library/scala/collection/mutable/ArrayStack.scala
+++ b/src/library/scala/collection/mutable/ArrayStack.scala
@@ -31,6 +31,7 @@ private object Utils{
*
* @author David MacIver
*/
+@cloneable
class ArrayStack[T] private(private var table : Array[AnyRef],
private var index : Int) extends Iterable[T]{
def this() = this(new Array[AnyRef](1), 0);
diff --git a/src/library/scala/runtime/RichChar.scala b/src/library/scala/runtime/RichChar.scala
index 943e5516f5..cbc8f88ab0 100644
--- a/src/library/scala/runtime/RichChar.scala
+++ b/src/library/scala/runtime/RichChar.scala
@@ -67,7 +67,7 @@ final class RichChar(x: Char) extends Proxy with Ordered[Char] {
}
}
- /** Create a <code>RandomAccessSeq.Projection[Char]</code> over the characters from 'x' to 'y'
+ /** Create a <code>VectorView[Char]</code> over the characters from 'x' to 'y'
*/
def to(y: Char): VectorView[Char, Vector[Char]] = until((y + 1).toChar)
diff --git a/src/library/scala/runtime/RichDouble.scala b/src/library/scala/runtime/RichDouble.scala
index 5c20745f60..c9e25e4edf 100644
--- a/src/library/scala/runtime/RichDouble.scala
+++ b/src/library/scala/runtime/RichDouble.scala
@@ -13,12 +13,9 @@ package scala.runtime
final class RichDouble(x: Double) extends Proxy with Ordered[Double] {
-
// Proxy.self
def self: Any = x
- // Ordered[Double].compare
- //def compare(y: Double): Int = if (x < y) -1 else if (x > y) 1 else 0
def compare(y: Double): Int = java.lang.Double.compare(x, y)
def min(y: Double): Double = Math.min(x, y)
@@ -29,11 +26,21 @@ final class RichDouble(x: Double) extends Proxy with Ordered[Double] {
def ceil: Double = Math.ceil(x)
def floor: Double = Math.floor(x)
- /** See <code>Iterator.range</code>. */
- def until(end: Double, step: Double) = Range.Double(x, end, step)
+ /** See <code>BigDecimal.until</code>. */
+ def until(end: Double): Range.Partial[Double, GenericRange.Exclusive[BigDecimal]] =
+ new Range.Partial(until(end, _))
+
+ /** See <code>BigDecimal.until</code>. */
+ def until(end: Double, step: Double): GenericRange.Exclusive[BigDecimal] =
+ BigDecimal(x).until(end, step)
+
+ /** See <code>BigDecimal.to</code>. */
+ def to(end: Double): Range.Partial[Double, GenericRange.Inclusive[BigDecimal]] =
+ new Range.Partial(to(end, _))
- /** like <code>until</code>, but includes the last index */
- def to(end: Double, step: Double) = Range.Double.inclusive(x, end, step)
+ /** See <code>BigDecimal.to</code>. */
+ def to(end: Double, step: Double): GenericRange.Inclusive[BigDecimal] =
+ BigDecimal(x).to(end, step)
/** Converts an angle measured in degrees to an approximately equivalent
* angle measured in radians.
diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala
index bb01e0de35..921416d28a 100644
--- a/src/library/scala/runtime/RichInt.scala
+++ b/src/library/scala/runtime/RichInt.scala
@@ -21,13 +21,10 @@ final class RichInt(val start: Int) extends Proxy with Ordered[Int] {
def compare(that: Int): Int = if (start < that) -1 else if (start > that) 1 else 0
/** See <code>Iterator.range</code>. */
- def until(end: Int): Range = new Range(start, end, 1)
-
- /** See <code>Iterator.range</code>. */
- def until(end: Int, step: Int): Range = new Range(start, end, step)
+ def until(end: Int, step: Int = 1): Range = new Range(start, end, step)
/** like <code>until</code>, but includes the last index */
- def to(end: Int) = Range.inclusive(start, end, 1)
+ def to(end: Int, step: Int = 1): Range = Range.inclusive(start, end, step)
def min(that: Int): Int = if (start < that) start else that
def max(that: Int): Int = if (start > that) start else that
diff --git a/src/library/scala/runtime/RichLong.scala b/src/library/scala/runtime/RichLong.scala
index 5eddaf0ec3..7eac1e0cab 100644
--- a/src/library/scala/runtime/RichLong.scala
+++ b/src/library/scala/runtime/RichLong.scala
@@ -20,17 +20,18 @@ final class RichLong(x: Long) extends Proxy with Ordered[Long] {
// Ordered[Long].compare
def compare(y: Long): Int = if (x < y) -1 else if (x > y) 1 else 0
- /** See <code>Iterator.range</code>. */
- def until(end: Long) = Range.Long(x, end, 1L)
-
- /** See <code>Iterator.range</code>. */
- def until(end: Long, step: Long) = Range.Long(x, end, step)
-
- /** like <code>until</code>, but includes the last index */
- def to(end: Long) = Range.Long.inclusive(x, end, 1L)
-
- /** like <code>until</code>, but includes the last index */
- def to(end: Long, step: Long) = Range.Long.inclusive(x, end, step)
+ /** Create a GenericRange[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): GenericRange.Exclusive[Long] = Range.Long(x, end, step)
+
+ /** Like until, but inclusive of the end value.
+ */
+ def to(end: Long, step: Long = 1L): GenericRange.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
diff --git a/src/library/scala/util/control/Exception.scala b/src/library/scala/util/control/Exception.scala
index 769be2fef8..3b0590ca37 100644
--- a/src/library/scala/util/control/Exception.scala
+++ b/src/library/scala/util/control/Exception.scala
@@ -167,8 +167,12 @@ object Exception
* an exception handler function as an argument to "by". Example:
* handling(ex1, ex2) by (_.printStackTrace)
*/
- def handling[T](exceptions: Class[_]*) = new {
- def by(f: (Throwable) => T): Catch[T] = catching(exceptions: _*) withApply f
+ class By[T,R](f: T => R) {
+ def by(x: T): R = f(x)
+ }
+ def handling[T](exceptions: Class[_]*) = {
+ def fun(f: Throwable => T) = catching(exceptions: _*) withApply f
+ new By[Throwable => T, Catch[T]](fun _)
}
/** Returns a Catch object with no catch logic and the argument as Finally. */
diff --git a/src/library/scala/xml/Group.scala b/src/library/scala/xml/Group.scala
index 9e18ecb5f0..7e4b983ec6 100644
--- a/src/library/scala/xml/Group.scala
+++ b/src/library/scala/xml/Group.scala
@@ -21,7 +21,7 @@ case class Group(val nodes: Seq[Node]) extends Node {
override def theSeq = nodes
- /** structural equality */
+ /** XXX this is ridiculous, we can't do equality like this. */
override def equals(x: Any) = x match {
case z:Group => (length == z.length) && sameElements(z)
case z:Node => (length == 1) && z == apply(0)
@@ -29,6 +29,8 @@ case class Group(val nodes: Seq[Node]) extends Node {
case z:String => text == z
case _ => false
}
+ /* As if there were a hashCode which could back up the above implementation! */
+ override def hashCode = nodes.hashCode
/**
* @throws Predef.UnsupportedOperationException (always)
diff --git a/src/library/scala/xml/NamespaceBinding.scala b/src/library/scala/xml/NamespaceBinding.scala
index 9af256501c..567686d58b 100644
--- a/src/library/scala/xml/NamespaceBinding.scala
+++ b/src/library/scala/xml/NamespaceBinding.scala
@@ -22,13 +22,11 @@ import Utility.sbToString
* @author Burak Emir
* @version 1.0
*/
-@serializable
+@SerialVersionUID(0 - 2518644165573446725L)
class NamespaceBinding(val prefix: String,
val uri: String,
val parent: NamespaceBinding) extends AnyRef {
- private val serialVersionUID = 0 - 2518644165573446725L
-
if (null != prefix && 0 == prefix.length())
throw new IllegalArgumentException("zero length prefix not allowed")