diff options
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/Iterator.scala | 29 | ||||
-rw-r--r-- | src/library/scala/List.scala | 14 | ||||
-rw-r--r-- | src/library/scala/annotation/switch.scala | 17 | ||||
-rw-r--r-- | src/library/scala/annotation/tailrec.scala | 16 | ||||
-rwxr-xr-x | src/library/scalax/collection/immutable/Stream.scala | 2 |
5 files changed, 67 insertions, 11 deletions
diff --git a/src/library/scala/Iterator.scala b/src/library/scala/Iterator.scala index d04d32393a..b5092a2430 100644 --- a/src/library/scala/Iterator.scala +++ b/src/library/scala/Iterator.scala @@ -14,6 +14,7 @@ package scala import Predef._ import collection.mutable.{Buffer, ListBuffer, ArrayBuffer} +import annotation.tailrec /** The <code>Iterator</code> object provides various functions for * creating specialized iterators. @@ -248,8 +249,14 @@ trait Iterator[+A] { * @param n the number of elements to drop * @return the new iterator */ - def drop(n: Int): Iterator[A] = - if (n > 0 && hasNext) { next; drop(n - 1) } else this + def drop(n: Int): Iterator[A] = { + @tailrec + def loop(left: Int): Iterator[A] = + if (left > 0 && hasNext) { next; loop(left - 1) } + else this + + loop(n) + } /** A sub-iterator of <code>until - from elements * starting at index <code>from</code> @@ -366,12 +373,18 @@ trait Iterator[+A] { * @param p the predicate used to skip elements. * @return an iterator consisting of the remaining elements */ - def dropWhile(p: A => Boolean): Iterator[A] = - if (hasNext) { - val x = next - if (p(x)) dropWhile(p) - else Iterator.single(x) append this - } else this + def dropWhile(p: A => Boolean): Iterator[A] = { + @tailrec + def loop(): Iterator[A] = + if (hasNext) { + val x = next + if (p(x)) loop() + else Iterator.single(x) append this + } + else this + + loop() + } /** Return an iterator formed from this iterator and the specified iterator * <code>that</code> by associating each element of the former with diff --git a/src/library/scala/List.scala b/src/library/scala/List.scala index eda39f9ec9..5482deabf4 100644 --- a/src/library/scala/List.scala +++ b/src/library/scala/List.scala @@ -12,6 +12,7 @@ package scala import scala.collection.mutable.ListBuffer +import annotation.tailrec import Predef._ /** This object provides methods for creating specialized lists, and for @@ -702,6 +703,7 @@ sealed abstract class List[+A] extends Seq[A] with Product { * @return the suffix of length <code>n</code> of the list */ def takeRight(n: Int): List[A] = { + @tailrec def loop(lead: List[A], lag: List[A]): List[A] = lead match { case Nil => lag case _ :: tail => loop(tail, lag.tail) @@ -765,9 +767,14 @@ sealed abstract class List[+A] extends Seq[A] with Product { * @return the longest suffix of the list whose first element * does not satisfy the predicate <code>p</code>. */ - override def dropWhile(p: A => Boolean): List[A] = - if (isEmpty || !p(head)) this - else tail dropWhile p + override def dropWhile(p: A => Boolean): List[A] = { + @tailrec + def loop(xs: List[A]): List[A] = + if (xs.isEmpty || !p(xs.head)) xs + else loop(xs.tail) + + loop(this) + } /** Returns the longest prefix of the list whose elements all satisfy * the given predicate, and the rest of the list. @@ -823,6 +830,7 @@ sealed abstract class List[+A] extends Seq[A] with Product { * @return the reversed list of results. */ def reverseMap[B](f: A => B): List[B] = { + @tailrec def loop(l: List[A], res: List[B]): List[B] = l match { case Nil => res case head :: tail => loop(tail, f(head) :: res) diff --git a/src/library/scala/annotation/switch.scala b/src/library/scala/annotation/switch.scala new file mode 100644 index 0000000000..5ecbf73905 --- /dev/null +++ b/src/library/scala/annotation/switch.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation + +/** <p> + * An annotation to be applied to a match expression. If present, + * the compiler will verify that the match has been compiled to a + * tableswitch or lookupswitch, and issue an error if it instead + * compiles into a series of conditional expressions. + * </p> + */ +final class switch extends StaticAnnotation
\ No newline at end of file diff --git a/src/library/scala/annotation/tailrec.scala b/src/library/scala/annotation/tailrec.scala new file mode 100644 index 0000000000..6ce23a92fa --- /dev/null +++ b/src/library/scala/annotation/tailrec.scala @@ -0,0 +1,16 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ +package scala.annotation + +/** <p> + * A method annotation which verifies that the method will be compiled + * with tail call optimization. If it is present, the compiler will + * issue an error if the method cannot be optimized into a loop. + * </p> + */ +final class tailrec extends StaticAnnotation diff --git a/src/library/scalax/collection/immutable/Stream.scala b/src/library/scalax/collection/immutable/Stream.scala index 036fefe70c..4055be40bc 100755 --- a/src/library/scalax/collection/immutable/Stream.scala +++ b/src/library/scalax/collection/immutable/Stream.scala @@ -14,6 +14,7 @@ package scalax.collection.immutable import mutable.ListBuffer import generic.{SequenceTemplate, SequenceFactory, EmptyIterableFactory, Builder, LazyBuilder} import annotation.unchecked.uncheckedVariance +import annotation.tailrec /** * The object <code>Stream</code> provides helper functions @@ -486,6 +487,7 @@ self => * @param sep The separator string printed between consecutive elements. */ def print(sep: String) { + @tailrec def loop(these: Stream[A], start: String) { Console.print(start) if (isEmpty) Console.print("empty") |