/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ // $Id$ package scala import Predef._ import collection.mutable.ArrayBuffer object Seq { /** The empty sequence */ val empty = new Seq[Nothing] { def length = 0 def apply(i: Int): Nothing = throw new NoSuchElementException("empty sequence") def elements = Iterator.empty } /** This method is called in a pattern match { case Seq(...) => }. * * @param x the selector value * @return sequence wrapped in an option, if this is a Seq, otherwise none */ def unapplySeq[A](x: Seq[A]): Option[Seq[A]] = Some(x) /** Builds a singleton sequence. * * @param x ... * @return ... */ def single[A](x: A) = new Seq[A] { def length = 1 def elements = Iterator.single(x) override def isDefinedAt(x: Int): Boolean = (x == 0) def apply(i: Int) = x // caller's responsibility to check isDefinedAt } /* implicit def view[A <% Ordered[A]](xs: Seq[A]): Ordered[Seq[A]] = new Ordered[Seq[A]] with Proxy { def self: Any = xs; def compare[B >: Seq[A] <% Ordered[B]](that: B): Int = that match { case ys: Seq[A] => var res = 0; val xsit = xs.elements; val ysit = ys.elements; while (xsit.hasNext && ysit.hasNext && (res == 0)) { res = xsit.next compare ysit.next; } if (res != 0) res else if (xsit.hasNext) 1 else -1 case _ => -(that compare xs) } } */ } /** Class Seq[A] represents finite sequences of elements * of type A. * * @author Martin Odersky * @author Matthias Zenger * @version 1.0, 16/07/2003 */ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] { /** Returns the length of the sequence. * * @return the sequence length. */ def length: Int /** should always be length */ def size = length /** Returns true if length == 0 */ override def isEmpty: Boolean = { length == 0 } /** Appends two iterable objects. * * @return the new iterable object * @deprecated use ++ instead */ @deprecated override def concat [B >: A](that: Iterable[B]): Seq[B] = { val buf = new ArrayBuffer[B] this copyToBuffer buf that copyToBuffer buf buf } /** Appends two iterable objects. * * @param that .. * @return the new iterable object */ override def ++ [B >: A](that: Iterable[B]): Seq[B] = { val buf = new ArrayBuffer[B] this copyToBuffer buf that copyToBuffer buf buf } /** Is this partial function defined for the index x? * * @param x .. * @return true, iff x is a legal sequence index. */ def isDefinedAt(x: Int): Boolean = (x >= 0) && (x < length) /** Returns the index of the last occurence of the specified element * in this sequence, or -1 if the sequence does not contain this element. * * @param elem element to search for. * @return the index in this sequence of the last occurence of the * specified element, or -1 if the sequence does not contain * this element. */ def lastIndexOf[B >: A](elem: B): Int = { var i = length; var found = false; while (!found && (i > 0)) { i = i - 1; if (this(i) == elem) { found = true; } } if (found) i else -1; } /** Returns the sequence resulting from applying the given function * f to each element of this sequence. * * @param f function to apply to each element. * @return f(a0), ..., f(an) if this * sequence is a0, ..., an. */ override def map[B](f: A => B): Seq[B] = { // todo: malformed scala signature suing build when replaced by // super.map(f).asInstanceOf[Seq[B2]] val buf = new ArrayBuffer[B] val elems = elements while (elems.hasNext) buf += f(elems.next) buf } /** Applies the given function f to each element of * this sequence, then concatenates the results. * * @param f the function to apply on each element. * @return f(a0) ::: ... ::: f(an) if * this sequence is a0, ..., an. */ override def flatMap[B](f: A => Iterable[B]): Seq[B] = { val buf = new ArrayBuffer[B] val elems = elements while (elems.hasNext) f(elems.next) copyToBuffer buf buf } /** Returns all the elements of this sequence that satisfy the * predicate p. The order of the elements is preserved. * * @param p the predicate used to filter the list. * @return the elements of this list satisfying p. */ override def filter(p: A => Boolean): Seq[A] = super.filter(p).asInstanceOf[Seq[A]] /** Returns a sequence consisting only over the first n * elements of this sequence, or else the whole sequence, if it has less * than n elements. * * @param n the number of elements to take * @return the new sequence */ override def take(n: Int): Seq[A] = super.take(n).asInstanceOf[Seq[A]] /** Returns this sequence without its n first elements * If this sequence has less than n elements, the empty * sequence is returned. * * @param n the number of elements to drop * @return the new sequence */ override def drop(n: Int): Seq[A] = super.drop(n).asInstanceOf[Seq[A]] /** Returns the longest prefix of this sequence whose elements satisfy * the predicate p. * * @param p the test predicate. * @return the longest prefix of this sequence whose elements satisfy * the predicate p. */ override def takeWhile(p: A => Boolean): Seq[A] = super.takeWhile(p).asInstanceOf[Seq[A]] /** Returns the longest suffix of this sequence whose first element * does not satisfy the predicate p. * * @param p the test predicate. * @return the longest suffix of the sequence whose first element * does not satisfy the predicate p. */ override def dropWhile(p: A => Boolean): Seq[A] = super.dropWhile(p).asInstanceOf[Seq[A]] /** A sequence consisting of all elements of this sequence in reverse order. */ def reverse: Seq[A] = { var result: List[A] = Nil val elems = elements while (elems.hasNext) result = elems.next :: result result } /** Tests if the given value elem is a member of this * sequence. * * @param elem element whose membership has to be tested. * @return true iff there is an element of this sequence * which is equal (w.r.t. ==) to elem. */ def contains(elem: Any): Boolean = exists (.==(elem)) /** Returns a subsequence starting from index from * consisting of len elements. * * @param from .. * @param len .. * @return .. */ def slice(from: Int, len: Int): Seq[A] = this.drop(from).take(len) /** Returns a subsequence starting from index from * consisting of len elements. * * @deprecated use slice instead */ @deprecated def subseq(from: Int, end: Int): Seq[A] = slice(from, end - from) /** Converts this sequence to a fresh Array with length elements. */ override def toArray[B >: A]: Array[B] = { val result = new Array[B](length) copyToArray(result, 0) result } }