From dbce4463e8d0fb7fef571139008c6011215b1e1a Mon Sep 17 00:00:00 2001 From: michelou Date: Tue, 1 May 2007 15:59:31 +0000 Subject: added scala.Range and test cases --- src/library/scala/BufferedIterator.scala | 4 +- src/library/scala/Iterator.scala | 87 ++++++++++++++------------------ src/library/scala/Range.scala | 39 ++++++++++++++ src/library/scala/runtime/RichInt.scala | 2 - test/files/run/iterators.check | 2 + test/files/run/iterators.scala | 77 ++++++++++++++++++---------- 6 files changed, 129 insertions(+), 82 deletions(-) create mode 100644 src/library/scala/Range.scala diff --git a/src/library/scala/BufferedIterator.scala b/src/library/scala/BufferedIterator.scala index 67d5016193..38d81eb513 100644 --- a/src/library/scala/BufferedIterator.scala +++ b/src/library/scala/BufferedIterator.scala @@ -1,7 +1,7 @@ /* __ *\ ** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2006, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ diff --git a/src/library/scala/Iterator.scala b/src/library/scala/Iterator.scala index e813c6ade2..b4936d1a76 100644 --- a/src/library/scala/Iterator.scala +++ b/src/library/scala/Iterator.scala @@ -14,7 +14,6 @@ package scala import Predef._ import collection.mutable.{Buffer, ListBuffer} -import compat.StringBuilder /** The Iterator object provides various functions for * creating specialized iterators. @@ -102,54 +101,42 @@ object Iterator { /** Create an iterator with elements * en+1 = en + 1 - * where e0 = lo + * where e0 = start * and ei < end. * - * @param lo the start value of the iterator - * @param end the end value of the iterator - * @return the iterator with values in range [lo;end). + * @param start the start value of the iterator + * @param end the end value of the iterator + * @return the iterator with values in range [start;end). */ - def range(lo: Int, end: Int): Iterator[Int] = - range(lo, end, 1) + def range(start: Int, end: Int): Range = range(start, end, 1) /** Create an iterator with elements * en+1 = en + step - * where e0 = lo + * where e0 = start * and ei < end. * - * @param lo 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 [lo;end). + * @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 [start;end). */ - def range(lo: Int, end: Int, step: Int): Iterator[Int] = { - assert(step != 0) - new BufferedIterator[Int] { - private var i = lo - def hasNext: Boolean = if (step > 0) i < end else i > end - def next(): Int = - if (hasNext) { val j = i; i += step; j } - else throw new NoSuchElementException("next on empty iterator") - def head: Int = - if (hasNext) i - else throw new NoSuchElementException("head on empty iterator") - } - } + def range(start: Int, end: Int, step: Int): Range = + new Range(start, end, step) /** Create an iterator with elements * en+1 = step(en) - * where e0 = lo + * where e0 = start * and ei < end. * - * @param lo the start value of the iterator - * @param end the end value of the iterator - * @param step the increment function of the iterator - * @return the iterator with values in range [lo;end). + * @param start the start value of the iterator + * @param end the end value of the iterator + * @param step the increment function of the iterator + * @return the iterator with values in range [start;end). */ - def range(lo: Int, end: Int, step: Int => Int): Iterator[Int] = + def range(start: Int, end: Int, step: Int => Int): Iterator[Int] = new BufferedIterator[Int] { - private var i = lo - def hasNext: Boolean = i < end + 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") @@ -160,25 +147,25 @@ object Iterator { /** Create an iterator with elements * en+1 = en + 1 - * where e0 = lo. + * where e0 = start. * - * @param lo the start value of the iterator - * @return the iterator starting at value lo. + * @param start the start value of the iterator + * @return the iterator starting at value start. */ - def from(lo: Int): Iterator[Int] = - from(lo, 1) + def from(start: Int): Iterator[Int] = + from(start, 1) /** Create an iterator with elements * en+1 = en + step - * where e0 = lo. + * where e0 = start. * - * @param lo the start value of the iterator - * @param step the increment value of the iterator - * @return the iterator starting at value lo. + * @param start the start value of the iterator + * @param step the increment value of the iterator + * @return the iterator starting at value start. */ - def from(lo: Int, step: Int): Iterator[Int] = + def from(start: Int, step: Int): Iterator[Int] = new BufferedIterator[Int] { - private var i = lo + private var i = start def hasNext: Boolean = true def next(): Int = { val j = i; i += step; j } def head: Int = i @@ -186,15 +173,15 @@ object Iterator { /** Create an iterator with elements * en+1 = step(en) - * where e0 = lo. + * where e0 = start. * - * @param lo the start value of the iterator - * @param step the increment function of the iterator - * @return the iterator starting at value lo. + * @param start the start value of the iterator + * @param step the increment function of the iterator + * @return the iterator starting at value start. */ - def from(lo: Int, step: Int => Int): Iterator[Int] = + def from(start: Int, step: Int => Int): Iterator[Int] = new BufferedIterator[Int] { - private var i = lo + private var i = start def hasNext: Boolean = true def next(): Int = { val j = i; i = step(i); j } def head: Int = i diff --git a/src/library/scala/Range.scala b/src/library/scala/Range.scala new file mode 100644 index 0000000000..8e3fcce9ca --- /dev/null +++ b/src/library/scala/Range.scala @@ -0,0 +1,39 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2006-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: $ + + +package scala + +/** The Range class represents integer values in range + * [start;end) with . + * + * @author Stephane Micheloud + * @version 1.0, 01/05/2007 + */ +class Range(val start: Int, val end: Int, val step: Int) extends BufferedIterator[Int] { + assert(step != 0) + private var i = start + + def hasNext: Boolean = if (step > 0) i < end else i > end + + def next(): Int = + if (hasNext) { val j = i; i += step; j } + else throw new NoSuchElementException("next on empty iterator") + + def head: Int = + if (hasNext) i + else throw new NoSuchElementException("head on empty iterator") + + def length: Int = + 1 + (Math.abs(start - end) - 1) / Math.abs(step) + + def contains(x: Int): Boolean = + Iterator.range(0, length) exists { x == start + _ * step } +} diff --git a/src/library/scala/runtime/RichInt.scala b/src/library/scala/runtime/RichInt.scala index 60264226c3..dfa47dbedc 100644 --- a/src/library/scala/runtime/RichInt.scala +++ b/src/library/scala/runtime/RichInt.scala @@ -18,8 +18,6 @@ final class RichInt(x: Int) extends Proxy with Ordered[Int] { // Ordered[Int] def compare (y: Int): Int = if (x < y) -1 else if (x > y) 1 else 0 - def upto(y: Int): List[Int] = List.range(x, y + 1) - def until(y: Int): Iterator[Int] = Iterator.range(x, y) def to(y: Int): Iterator[Int] = Iterator.range(x, y + 1) diff --git a/test/files/run/iterators.check b/test/files/run/iterators.check index a4b1053577..b55b63e9dc 100644 --- a/test/files/run/iterators.check +++ b/test/files/run/iterators.check @@ -1,5 +1,7 @@ test check_from was successful test check_range was successful +test check_range2 was successful +test check_range3 was successful test check_take was successful test check_drop was successful test check_foreach was successful diff --git a/test/files/run/iterators.scala b/test/files/run/iterators.scala index 7d1e44a0df..a5e3a4897c 100644 --- a/test/files/run/iterators.scala +++ b/test/files/run/iterators.scala @@ -8,8 +8,8 @@ object Test { def check_from: Int = { - val it1 = Iterator.from(-1); - val it2 = Iterator.from(0, -1); + val it1 = Iterator.from(-1) + val it2 = Iterator.from(0, -1) it1.next + it2.next } @@ -18,61 +18,82 @@ object Test { val xs2 = Iterator.range(0, 10, -2) toList; val xs3 = Iterator.range(10, 0, -2) toList; val xs4 = Iterator.range(10, 0, 2) toList; - xs1.length + xs2.length + xs3.length + xs4.length + val xs5 = Iterator.range(0, 10, 11) toList; + xs1.length + xs2.length + xs3.length + xs4.length + xs5.length + } + + 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) + // 10 + 5 + 10 + 1 + r1.length + r2.length + r3.length + r4.length + } + + def check_range3: Int = { + 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) + // 2 + 1 + trues(xs1) + trues(xs2) } def check_take: Int = { - val it1 = Iterator.from(0); + val it1 = Iterator.from(0) val xs1 = it1 take 10 toList; xs1.length } def check_drop: Int = { - val it1 = Iterator.from(0); - val it2 = it1 map { x => 2 * x }; - val n1 = it1 drop 2 next; + val it1 = Iterator.from(0) + val it2 = it1 map { 2 * _ } + val n1 = it1 drop 2 next val n2 = it2 drop 2 next; n1 + n2 } def check_foreach: Int = { - val it1 = Iterator.from(0) take 20; - var n = 0; - it1 foreach { x => n = n + x } + val it1 = Iterator.from(0) take 20 + var n = 0 + it1 foreach { n += _ } n } def check_forall: Int = { - val it1 = Iterator.from(0); - val it2 = Iterator.from(1); + val it1 = Iterator.from(0) + val it2 = Iterator.from(1) 0 } def check_success[A](name: String, closure: => A, expected: A): Unit = { - Console.print("test " + name); + Console.print("test " + name) try { - val actual: A = closure; + val actual: A = closure if (actual == expected) - Console.print(" was successful"); + Console.print(" was successful") else - Console.print(" failed: expected "+ expected +", found "+ actual); + Console.print(" failed: expected "+ expected +", found "+ actual) } catch { - case exception: Throwable => { - Console.print(" raised exception " + exception); - } + case exception: Throwable => + Console.print(" raised exception " + exception) } - Console.println; + Console.println } - def main(args: Array[String]): Unit = { - check_success("check_from", check_from, -1); - check_success("check_range", check_range, 10); - check_success("check_take", check_take, 10); - check_success("check_drop", check_drop, 12); - check_success("check_foreach", check_foreach, 190); - check_success("check_forall", check_forall, 0); - Console.println; + def main(args: Array[String]) { + check_success("check_from", check_from, -1) + check_success("check_range", check_range, 11) + check_success("check_range2", check_range2, 26) + check_success("check_range3", check_range3, 3) + check_success("check_take", check_take, 10) + check_success("check_drop", check_drop, 12) + check_success("check_foreach", check_foreach, 190) + check_success("check_forall", check_forall, 0) + Console.println } } -- cgit v1.2.3