diff options
author | Martin Odersky <odersky@gmail.com> | 2008-02-06 18:43:12 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2008-02-06 18:43:12 +0000 |
commit | 5ffe50c3dfc793eb983f341f4e9e816de3636a4f (patch) | |
tree | ecb40df9cbf8595bcfad682045d45ab170880b79 | |
parent | 11d8e2c4870d13be7b4a651495aae8fb8946d60f (diff) | |
download | scala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.tar.gz scala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.tar.bz2 scala-5ffe50c3dfc793eb983f341f4e9e816de3636a4f.zip |
fixed problems with ranges
-rw-r--r-- | src/library/scala/Iterator.scala | 32 | ||||
-rw-r--r-- | src/library/scala/List.scala | 40 | ||||
-rw-r--r-- | src/library/scala/Stream.scala | 18 | ||||
-rw-r--r-- | test/files/neg/t0345.check | 4 | ||||
-rwxr-xr-x | test/files/neg/t0345.scala | 15 | ||||
-rw-r--r-- | test/files/neg/t0351.check | 4 | ||||
-rwxr-xr-x | test/files/neg/t0351.scala | 3 | ||||
-rw-r--r-- | test/files/run/iterators.scala | 16 |
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> < 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> < 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> < 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> < 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 |