summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-02-06 18:43:12 +0000
committerMartin Odersky <odersky@gmail.com>2008-02-06 18:43:12 +0000
commit5ffe50c3dfc793eb983f341f4e9e816de3636a4f (patch)
treeecb40df9cbf8595bcfad682045d45ab170880b79
parent11d8e2c4870d13be7b4a651495aae8fb8946d60f (diff)
downloadscala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.tar.gz
scala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.tar.bz2
scala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.zip
fixed problems with ranges
-rw-r--r--src/library/scala/Iterator.scala32
-rw-r--r--src/library/scala/List.scala40
-rw-r--r--src/library/scala/Stream.scala18
-rw-r--r--test/files/neg/t0345.check4
-rwxr-xr-xtest/files/neg/t0345.scala15
-rw-r--r--test/files/neg/t0351.check4
-rwxr-xr-xtest/files/neg/t0351.scala3
-rw-r--r--test/files/run/iterators.scala16
8 files changed, 92 insertions, 40 deletions
diff --git a/src/library/scala/Iterator.scala b/src/library/scala/Iterator.scala
index fbfd4c3e5c..d0377c5692 100644
--- a/src/library/scala/Iterator.scala
+++ b/src/library/scala/Iterator.scala
@@ -119,33 +119,41 @@ object Iterator {
/** Create an iterator with elements
* <code>e<sub>n+1</sub> = e<sub>n</sub> + step</code>
* where <code>e<sub>0</sub> = start</code>
- * and <code>e<sub>i</sub> &lt; end</code>. Will return an empty range
- * for nonsensical range/step arguments.
+ * and elements are in the range between <code>start</code> (inclusive)
+ * and <code>end</code> (exclusive)
*
* @param start the start value of the iterator
* @param end the end value of the iterator
* @param step the increment value of the iterator (must be positive or negative)
* @return the iterator with values in range <code>[start;end)</code>.
*/
- def range(start: Int, end: Int, step: Int): Iterator[Int] = range(start, end, {(_:Int) + step})
+ def range(start: Int, end: Int, step: Int) = new Iterator[Int] {
+ private var i = start
+ def hasNext: Boolean = (step <= 0 || i < end) && (step >= 0 || i > end)
+ def next(): Int =
+ if (hasNext) { val j = i; i = i + step; j }
+ else throw new NoSuchElementException("next on empty iterator")
+ }
/** Create an iterator with elements
* <code>e<sub>n+1</sub> = step(e<sub>n</sub>)</code>
* where <code>e<sub>0</sub> = start</code>
- * and <code>e<sub>i</sub> &lt; end</code>.
+ * and elements are in the range between <code>start</code> (inclusive)
+ * and <code>end</code> (exclusive)
*
* @param start the start value of the iterator
* @param end the end value of the iterator
- * @param step the increment function of the iterator
+ * @param step the increment function of the iterator, must be monotonically increasing or decreasing
* @return the iterator with values in range <code>[start;end)</code>.
*/
- def range(start: Int, end: Int, step: Int => Int): Iterator[Int] =
- new Iterator[Int] {
- private var i = start
- def hasNext: Boolean = i < end
- def next(): Int =
- if (i < end) { val j = i; i = step(i); j }
- else throw new NoSuchElementException("next on empty iterator")
+ def range(start: Int, end: Int, step: Int => Int) = new Iterator[Int] {
+ private val up = step(start) > start
+ private val down = step(start) < start
+ private var i = start
+ def hasNext: Boolean = (!up || i < end) && (!down || i > end)
+ def next(): Int =
+ if (hasNext) { val j = i; i = step(i); j }
+ else throw new NoSuchElementException("next on empty iterator")
}
/** Create an iterator with elements
diff --git a/src/library/scala/List.scala b/src/library/scala/List.scala
index c0adc30db2..c2158b9f2a 100644
--- a/src/library/scala/List.scala
+++ b/src/library/scala/List.scala
@@ -39,37 +39,47 @@ object List {
* @param end the end value of the list
* @return the sorted list of all integers in range [from;end).
*/
- def range(from: Int, end: Int): List[Int] =
- range(from, end, 1)
+ def range(start: Int, end: Int): List[Int] =
+ range(start, end, 1)
- /** Create a sorted list of all integers in a range.
+ /** Create a list with element values
+ * <code>v<sub>n+1</sub> = v<sub>n</sub> + step</code>
+ * where <code>v<sub>0</sub> = start</code>
+ * and elements are in the range between <code>start</code> (inclusive)
+ * and <code>end</code> (exclusive)
*
- * @param from the start value of the list
+ * @param start the start value of the list
* @param end the end value of the list
* @param step the increment value of the list
- * @return the sorted list of all integers in range [from;end).
+ * @return the sorted list of all integers in range [start;end).
*/
- def range(from: Int, end: Int, step: Int): List[Int] = {
+ def range(start: Int, end: Int, step: Int): List[Int] = {
val b = new ListBuffer[Int]
- var i = from
- while (i < end) {
+ var i = start
+ while ((step <= 0 || i < end) && (step >= 0 || i > end)) {
b += i
i += step
}
b.toList
}
- /** Create a sorted list of all integers in a range.
+ /** Create a sorted list with element values
+ * <code>v<sub>n+1</sub> = step(v<sub>n</sub>)</code>
+ * where <code>v<sub>0</sub> = start</code>
+ * and elements are in the range between <code>start</code> (inclusive)
+ * and <code>end</code> (exclusive)
*
- * @param from the start value of the list
+ * @param start the start value of the list
* @param end the end value of the list
- * @param step the increment function of the list
- * @return the sorted list of all integers in range [from;end).
+ * @param step the increment function of the list, must be monotonically increasing or decreasing
+ * @return the sorted list of all integers in range [start;end).
*/
- def range(from: Int, end: Int, step: Int => Int): List[Int] = {
+ def range(start: Int, end: Int, step: Int => Int): List[Int] = {
+ val up = step(start) > start
+ val down = step(start) < start
val b = new ListBuffer[Int]
- var i = from
- while (i < end) {
+ var i = start
+ while ((!up || i < end) && (!down || i > end)) {
b += i
i += step(i)
}
diff --git a/src/library/scala/Stream.scala b/src/library/scala/Stream.scala
index 1415e3ad06..f16085080e 100644
--- a/src/library/scala/Stream.scala
+++ b/src/library/scala/Stream.scala
@@ -103,7 +103,8 @@ object Stream {
* Create a stream with element values
* <code>v<sub>n+1</sub> = v<sub>n</sub> + step</code>
* where <code>v<sub>0</sub> = start</code>
- * and <code>v<sub>i</sub> &lt; end</code>.
+ * and elements are in the range between <code>start</code> (inclusive)
+ * and <code>end</code> (exclusive)
*
* @param start the start value of the stream
* @param end the end value of the stream
@@ -112,8 +113,8 @@ object Stream {
*/
def range(start: Int, end: Int, step: Int): Stream[Int] = {
def loop(lo: Int): Stream[Int] =
- if (lo >= end) empty
- else cons(lo, loop(lo + step))
+ if ((step <= 0 || lo < end) && (step >= 0 || lo > end)) cons(lo, loop(lo + step))
+ else empty
loop(start)
}
@@ -121,17 +122,20 @@ object Stream {
* Create a stream with element values
* <code>v<sub>n+1</sub> = step(v<sub>n</sub>)</code>
* where <code>v<sub>0</sub> = start</code>
- * and <code>v<sub>i</sub> &lt; end</code>.
+ * and elements are in the range between <code>start</code> (inclusive)
+ * and <code>end</code> (exclusive)
*
* @param start the start value of the stream
* @param end the end value of the stream
- * @param step the increment function of the stream
+ * @param step the increment function of the stream, must be monotonically increasing or decreasing
* @return the stream starting at value <code>start</code>.
*/
def range(start: Int, end: Int, step: Int => Int): Stream[Int] = {
+ val up = step(start) > start
+ val down = step(start) < start
def loop(lo: Int): Stream[Int] =
- if (lo >= end) empty
- else cons(lo, loop(step(lo)))
+ if ((!up || lo < end) && (!down || lo > end)) cons(lo, loop(step(lo)))
+ else empty
loop(start)
}
diff --git a/test/files/neg/t0345.check b/test/files/neg/t0345.check
new file mode 100644
index 0000000000..f4a5275336
--- /dev/null
+++ b/test/files/neg/t0345.check
@@ -0,0 +1,4 @@
+t0345.scala:2: error: object creation impossible, since method cons in trait Lizt of type (Nothing)Unit is not defined
+ val empty = new Lizt[Nothing] {
+ ^
+one error found
diff --git a/test/files/neg/t0345.scala b/test/files/neg/t0345.scala
new file mode 100755
index 0000000000..f3652c183b
--- /dev/null
+++ b/test/files/neg/t0345.scala
@@ -0,0 +1,15 @@
+object Lizt {
+ val empty = new Lizt[Nothing] {
+ def cons[A](a : A) {}
+ }
+}
+
+trait Lizt[A] {
+ def cons(a : A) : Unit
+}
+class Test {
+ abstract class C[A] {}
+ val c = new C[Int] {
+ def f[A](x: A) {}
+ }
+ }
diff --git a/test/files/neg/t0351.check b/test/files/neg/t0351.check
new file mode 100644
index 0000000000..d374c905ed
--- /dev/null
+++ b/test/files/neg/t0351.check
@@ -0,0 +1,4 @@
+t0351.scala:2: error: no by-name parameter type allowed here
+ def identity[T](x : => T) : (=> T)
+ ^
+one error found
diff --git a/test/files/neg/t0351.scala b/test/files/neg/t0351.scala
new file mode 100755
index 0000000000..665bd89da4
--- /dev/null
+++ b/test/files/neg/t0351.scala
@@ -0,0 +1,3 @@
+abstract class Foo {
+ def identity[T](x : => T) : (=> T)
+}
diff --git a/test/files/run/iterators.scala b/test/files/run/iterators.scala
index 714861ef68..7972418059 100644
--- a/test/files/run/iterators.scala
+++ b/test/files/run/iterators.scala
@@ -22,10 +22,13 @@ object Test {
}
def check_range2: Int = {
- val r1 = Iterator.range(0, 10)
- val r2 = Iterator.range(r1.start, r1.end, r1.step + 1)
- val r3 = Iterator.range(r1.end, r1.start, -r1.step)
- val r4 = Iterator.range(0, 10, 11)
+ val r1start = 0
+ val r1end = 10
+ val r1step = 1
+ val r1 = Iterator.range(r1start, r1end, r1step) toList;
+ val r2 = Iterator.range(r1start, r1end, r1step + 1) toList;
+ val r3 = Iterator.range(r1end, r1start, -r1step) toList;
+ val r4 = Iterator.range(0, 10, 11) toList;
// 10 + 5 + 10 + 1
r1.length + r2.length + r3.length + r4.length
}
@@ -34,8 +37,9 @@ object Test {
def trues(xs: List[Boolean]) = xs.foldLeft(0)((a, b) => if (b) a+1 else a)
val r1 = Iterator.range(0, 10)
val xs1 = List(r1 contains 5, r1 contains 6)
- val r2 = Iterator.range(0, 10, 2)
- val xs2 = List(r2 contains 5, r2 contains 6)
+ val r2a = Iterator.range(0, 10, 2)
+ val r2b = Iterator.range(0, 10, 2)
+ val xs2 = List(r2a contains 5, r2b contains 6)
val r3 = Iterator.range(0, 10, 11)
val xs3 = List(r3 contains 5, r3 contains 6)
// 2 + 1 + 0