diff options
author | Martin Odersky <odersky@gmail.com> | 2009-12-11 18:18:44 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-12-11 18:18:44 +0000 |
commit | 8388f495600bfb2fd213e2eeacfd0133ea91a848 (patch) | |
tree | 8bbebfcf452e9bfd6807b21e0ce4744a1cb172c9 | |
parent | fffe6449d14387df980f25aee9e9c1795b5f13aa (diff) | |
download | scala-8388f495600bfb2fd213e2eeacfd0133ea91a848.tar.gz scala-8388f495600bfb2fd213e2eeacfd0133ea91a848.tar.bz2 scala-8388f495600bfb2fd213e2eeacfd0133ea91a848.zip |
allowed $super variables in doc comment; some m...
allowed $super variables in doc comment; some more documentation of
collection classes.
-rwxr-xr-x | src/compiler/scala/tools/nsc/ast/DocComments.scala | 66 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala | 1 | ||||
-rw-r--r-- | src/library/scala/PartialFunction.scala | 31 | ||||
-rw-r--r-- | src/library/scala/collection/IndexedSeqLike.scala | 159 | ||||
-rw-r--r-- | src/library/scala/collection/LinearSeqLike.scala | 250 | ||||
-rw-r--r-- | src/library/scala/collection/MapLike.scala | 27 | ||||
-rw-r--r-- | src/library/scala/collection/SeqLike.scala | 181 |
7 files changed, 406 insertions, 309 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala index 8dc1586400..bbd515d40c 100755 --- a/src/compiler/scala/tools/nsc/ast/DocComments.scala +++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala @@ -41,12 +41,12 @@ trait DocComments { self: SymbolTable => */ def cookedDocComment(sym: Symbol): String = { val ownComment = docComments get sym map (_.template) getOrElse "" - sym.allOverriddenSymbols.view map cookedDocComment find ("" !=) match { + superComment(sym) match { case None => ownComment - case Some(superComment) => - if (ownComment == "") superComment - else merge(superComment, ownComment, sym) + case Some(sc) => + if (ownComment == "") sc + else merge(sc, ownComment, sym) } } @@ -59,7 +59,7 @@ trait DocComments { self: SymbolTable => * interpreted as a recursive variable definition. */ def expandedDocComment(sym: Symbol, site: Symbol): String = - expandVariables(cookedDocComment(sym), site) + expandVariables(cookedDocComment(sym), sym, site) /** The cooked doc comment of symbol `sym` after variable expansion, or "" if missing. * @param sym The symbol for which doc comment is returned (site is always the containing class) @@ -80,7 +80,7 @@ trait DocComments { self: SymbolTable => def getUseCases(dc: DocComment) = { for (uc <- dc.useCases; defn <- uc.expandedDefs(site)) yield (defn, - expandVariables(merge(cookedDocComment(sym), uc.comment.raw, defn, copyFirstPara = true), site)) + expandVariables(merge(cookedDocComment(sym), uc.comment.raw, defn, copyFirstPara = true), sym, site)) } getDocComment(sym) map getUseCases getOrElse List() } @@ -116,6 +116,10 @@ trait DocComments { self: SymbolTable => case some => some } + /** The cooked doc comment of an overridden symbol */ + private def superComment(sym: Symbol): Option[String] = + sym.allOverriddenSymbols.view map cookedDocComment find ("" !=) + private def mapFind[A, B](xs: Iterable[A])(f: A => Option[B]): Option[B] = { var res: Option[B] = None val it = xs.iterator @@ -125,6 +129,11 @@ trait DocComments { self: SymbolTable => res } + private def isMovable(str: String, sec: (Int, Int)): Boolean = + startsWithTag(str, sec, "@param") || + startsWithTag(str, sec, "@tparam") || + startsWithTag(str, sec, "@return") + /** Merge elements of doccomment `src` into doc comment `dst` for symbol `sym`. * In detail: * 1. If `copyFirstPara` is true, copy first paragraph @@ -141,13 +150,7 @@ trait DocComments { self: SymbolTable => val dstTParams = paramDocs(dst, "@tparam", dstSections) val out = new StringBuilder var copied = 0 - - var tocopy = startTag( - dst, - dstSections dropWhile (sec => - !startsWithTag(dst, sec, "@param") && - !startsWithTag(dst, sec, "@tparam") && - !startsWithTag(dst, sec, "@return"))) + var tocopy = startTag(dst, dstSections dropWhile (!isMovable(dst, _))) if (copyFirstPara) { val eop = // end of first para, which is delimited by blank line, or tag, or end of comment @@ -215,10 +218,11 @@ trait DocComments { self: SymbolTable => * a expandLimit is exceeded. * * @param str The string to be expanded + * @param sym The symbol for which doc comments are generated * @param site The class for which doc comments are generated * @return Expanded string */ - private def expandVariables(str: String, site: Symbol): String = + private def expandVariables(str: String, sym: Symbol, site: Symbol): String = if (expandCount < expandLimit) { try { val out = new StringBuilder @@ -228,27 +232,33 @@ trait DocComments { self: SymbolTable => if ((str charAt idx) == '$') { val vstart = idx idx = skipVariable(str, idx + 1) + def replaceWith(repl: String) { + out append str.substring(copied, vstart) + out append repl + copied = idx + } val vname = variableName(str.substring(vstart + 1, idx)) - if (vname.length > 0) { - lookupVariable(vname, site) match { - case Some(replacement) => - out append str.substring(copied, vstart) - out append replacement - copied = idx + if (vname == "super") { + superComment(sym) match { + case Some(sc) => + val superSections = tagIndex(sc) + replaceWith(sc.substring(3, startTag(sc, superSections))) + for (sec @ (start, end) <- superSections) + if (!isMovable(sc, sec)) out append sc.substring(start, end) case None => - //println("no replacement for "+vname) // !!! } - } else { - idx += 1 - } - } else { - idx += 1 - } + } else if (vname.length > 0) { + lookupVariable(vname, site) match { + case Some(replacement) => replaceWith(replacement) + case None => //println("no replacement for "+vname) // DEBUG + } + } else idx += 1 + } else idx += 1 } if (out.length == 0) str else { out append str.substring(copied) - expandVariables(out.toString, site) + expandVariables(out.toString, sym, site) } } finally { expandCount -= 1 diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 84e5f97ebd..d09cd85137 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -153,6 +153,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT } if (settings.verbose.value && onlyPresentation && !sym.isAnonymousClass) { println("========== scaladoc of "+sym+" =============================") + println(toJavaDoc(expandedDocComment(sym))) for (member <- sym.info.members) { println(member+":"+sym.thisType.memberInfo(member)+"\n"+ toJavaDoc(expandedDocComment(member, sym))) diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala index 1543673015..37464421f9 100644 --- a/src/library/scala/PartialFunction.scala +++ b/src/library/scala/PartialFunction.scala @@ -12,22 +12,32 @@ package scala /** A partial function of type <code>PartialFunction[A, B]</code> is a - * unary function where the domain does not include all values of type + * unary function where the domain does not necessarily include all values of type * <code>A</code>. The function <code>isDefinedAt</code> allows to - * test dynamically, if a value is in the domain of the function. + * test dynamically if a value is in the domain of the function. * * @author Martin Odersky * @version 1.0, 16/07/2003 */ -trait PartialFunction[-A, +B] extends AnyRef with (A => B) { +trait PartialFunction[-A, +B] extends (A => B) { - /** Checks if a value is contained in the functions domain. + /** Checks if a value is contained in the function's domain. * * @param x the value to test - * @return true, iff <code>x</code> is in the domain of this function. + * @return `true`, iff <code>x</code> is in the domain of this function, `false` otherwise. */ def isDefinedAt(x: A): Boolean + /** Composes this partial function with a fallback partial function which gets applied where this partial function + * is not defined. + * + * @param that the fallback function + * @tparam A1 the argument type of the fallback function + * @tparam B1 the result type of the fallback function + * @return a partial function which has as domain the union of the domains + * of this partial function and `that`. The resulting partial function + * takes `x` to `this(x)` where `this` is defined, and to `that(x)` where it is not. + */ def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = new PartialFunction[A1, B1] { def isDefinedAt(x: A1): Boolean = @@ -37,11 +47,22 @@ trait PartialFunction[-A, +B] extends AnyRef with (A => B) { else that.apply(x) } + /** Composes this partial function with a transformation function that gets applied + * to results of this partial function. + * @param k the transformation function + * @tparam C the result type of the transformation function. + * @return a partial function with the same domain as this partial function, which maps + * arguments `x` to `k(this(x))`. + */ override def andThen[C](k: B => C) : PartialFunction[A, C] = new PartialFunction[A, C] { def isDefinedAt(x: A): Boolean = PartialFunction.this.isDefinedAt(x) def apply(x: A): C = k(PartialFunction.this.apply(x)) } + /** Turns this partial function into an plain function returning an `Option` result. + * @return a function that takes an argument `x` to `Some(this(x))` if `this` + * is defined for `x`, and to `None` otherwise. + */ def lift: A => Option[B] = { x => if (isDefinedAt(x)) Some(this(x)) else None } } diff --git a/src/library/scala/collection/IndexedSeqLike.scala b/src/library/scala/collection/IndexedSeqLike.scala index 7041078229..7951dc99c5 100644 --- a/src/library/scala/collection/IndexedSeqLike.scala +++ b/src/library/scala/collection/IndexedSeqLike.scala @@ -15,23 +15,31 @@ import generic._ import mutable.ArrayBuffer import scala.annotation.tailrec -/** Sequences that support O(1) element access and O(1) length computation. - * This class does not add any methods to Seq but overrides several - * methods with optimized implementations. +/** A template trait for indexed sequences of type `IndexedSeq[A]`. * + * $indexedSeqInfo * @author Sean McDirmid * @author Martin Odersky * @version 2.8 * @since 2.8 + * @define indexedSeqInfo + * Indexed sequences support constant-time or near constant-time element + * access and length computation. + * + * Indexed sequences do not define any new methods wrt `Seq`. However, some `Seq` methods + * are overridden with optimized implementations. + * + * @tparam A the element type of the $coll + * @tparam Repr the type of the actual $coll containing the elements. */ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => override protected[this] def thisCollection: IndexedSeq[A] = this.asInstanceOf[IndexedSeq[A]] override protected[this] def toCollection(repr: Repr): IndexedSeq[A] = repr.asInstanceOf[IndexedSeq[A]] - // Overridden methods from IterableLike - - /** The iterator returned by the iterator method + /** The class of the iterator returned by the `iterator` method. + * multiple `take`, `drop`, and `slice` operations on this iterator are bunched + * together for better efficiency. */ @serializable @SerialVersionUID(1756321872811029277L) protected class Elements(start: Int, end: Int) extends BufferedIterator[A] { @@ -49,36 +57,48 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => def head = if (i < end) self(i) else Iterator.empty.next - /** drop is overridden to enable fast searching in the middle of random access sequences */ + /** $super + * @note `drop` is overridden to enable fast searching in the middle of indexed sequences. + */ override def drop(n: Int): Iterator[A] = if (n > 0) new Elements(start + n, end) else this - /** take is overridden to be symmetric to drop */ + /** $super + * @note `take` is overridden to be symmetric to `drop`. + */ override def take(n: Int): Iterator[A] = if (n <= 0) Iterator.empty.buffered else if (start + n < end) new Elements(start, start + n) else this } - override def iterator: Iterator[A] = new Elements(0, length) + override /*IterableLike*/ + def iterator: Iterator[A] = new Elements(0, length) - override def isEmpty: Boolean = { length == 0 } + override /*IterableLike*/ + def isEmpty: Boolean = { length == 0 } - override def foreach[U](f: A => U): Unit = { + override /*IterableLike*/ + def foreach[U](f: A => U): Unit = { var i = 0 val len = length while (i < len) { f(this(i)); i += 1 } } - override def forall(p: A => Boolean): Boolean = prefixLength(p(_)) == length - override def exists(p: A => Boolean): Boolean = prefixLength(!p(_)) != length + override /*IterableLike*/ + def forall(p: A => Boolean): Boolean = prefixLength(p(_)) == length - override def find(p: A => Boolean): Option[A] = { + override /*IterableLike*/ + def exists(p: A => Boolean): Boolean = prefixLength(!p(_)) != length + + override /*IterableLike*/ + def find(p: A => Boolean): Option[A] = { val i = prefixLength(!p(_)) if (i < length) Some(this(i)) else None } /* - override def mapFind[B](f: A => Option[B]): Option[B] = { + override /*IterableLike*/ + def mapFind[B](f: A => Option[B]): Option[B] = { var i = 0 var res: Option[B] = None val len = length @@ -99,16 +119,24 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => if (start == end) z else foldr(start, end - 1, op(this(end - 1), z), op) - override def foldLeft[B](z: B)(op: (B, A) => B): B = + override /*TraversableLike*/ + def foldLeft[B](z: B)(op: (B, A) => B): B = foldl(0, length, z, op) - override def foldRight[B](z: B)(op: (A, B) => B): B = + + override /*IterableLike*/ + def foldRight[B](z: B)(op: (A, B) => B): B = foldr(0, length, z, op) - override def reduceLeft[B >: A](op: (B, A) => B): B = + + override /*TraversableLike*/ + def reduceLeft[B >: A](op: (B, A) => B): B = if (length > 0) foldl(1, length, this(0), op) else super.reduceLeft(op) - override def reduceRight[B >: A](op: (A, B) => B): B = + + override /*IterableLike*/ + def reduceRight[B >: A](op: (A, B) => B): B = if (length > 0) foldr(0, length - 1, this(length - 1), op) else super.reduceRight(op) - override def zip[A1 >: A, B, That](that: Iterable[B])(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = that match { + override /*IterableLike*/ + def zip[A1 >: A, B, That](that: Iterable[B])(implicit bf: CanBuildFrom[Repr, (A1, B), That]): That = that match { case that: IndexedSeq[_] => val b = bf(repr) var i = 0 @@ -123,7 +151,8 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => super.zip[A1, B, That](that)(bf) } - override def zipWithIndex[A1 >: A, That](implicit bf: CanBuildFrom[Repr, (A1, Int), That]): That = { + override /*IterableLike*/ + def zipWithIndex[A1 >: A, That](implicit bf: CanBuildFrom[Repr, (A1, Int), That]): That = { val b = bf(repr) val len = length b.sizeHint(len) @@ -135,7 +164,8 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => b.result } - override def slice(from: Int, until: Int): Repr = { + override /*IterableLike*/ + def slice(from: Int, until: Int): Repr = { var i = from max 0 val end = until min length val b = newBuilder @@ -147,20 +177,44 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => b.result } - override def head: A = if (isEmpty) super.head else this(0) - override def tail: Repr = if (isEmpty) super.tail else slice(1, length) - override def last: A = if (length > 0) this(length - 1) else super.last - override def init: Repr = if (length > 0) slice(0, length - 1) else super.init - override def take(n: Int): Repr = slice(0, n) - override def drop(n: Int): Repr = slice(n, length) - override def takeRight(n: Int): Repr = slice(length - n, length) - override def dropRight(n: Int): Repr = slice(0, length - n) - override def splitAt(n: Int): (Repr, Repr) = (take(n), drop(n)) - override def takeWhile(p: A => Boolean): Repr = take(prefixLength(p)) - override def dropWhile(p: A => Boolean): Repr = drop(prefixLength(p)) - override def span(p: A => Boolean): (Repr, Repr) = splitAt(prefixLength(p)) - - override def sameElements[B >: A](that: Iterable[B]): Boolean = that match { + override /*IterableLike*/ + def head: A = if (isEmpty) super.head else this(0) + + override /*TraversableLike*/ + def tail: Repr = if (isEmpty) super.tail else slice(1, length) + + override /*TraversableLike*/ + def last: A = if (length > 0) this(length - 1) else super.last + + override /*IterableLike*/ + def init: Repr = if (length > 0) slice(0, length - 1) else super.init + + override /*TraversableLike*/ + def take(n: Int): Repr = slice(0, n) + + override /*TraversableLike*/ + def drop(n: Int): Repr = slice(n, length) + + override /*IterableLike*/ + def takeRight(n: Int): Repr = slice(length - n, length) + + override /*IterableLike*/ + def dropRight(n: Int): Repr = slice(0, length - n) + + override /*TraversableLike*/ + def splitAt(n: Int): (Repr, Repr) = (take(n), drop(n)) + + override /*IterableLike*/ + def takeWhile(p: A => Boolean): Repr = take(prefixLength(p)) + + override /*TraversableLike*/ + def dropWhile(p: A => Boolean): Repr = drop(prefixLength(p)) + + override /*TraversableLike*/ + def span(p: A => Boolean): (Repr, Repr) = splitAt(prefixLength(p)) + + override /*IterableLike*/ + def sameElements[B >: A](that: Iterable[B]): Boolean = that match { case that: IndexedSeq[_] => val len = length len == that.length && { @@ -172,7 +226,8 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => super.sameElements(that) } - override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) { + override /*IterableLike*/ + def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) { var i = 0 var j = start val end = length min len min (xs.length - start) @@ -186,9 +241,11 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => // Overridden methods from Seq - override def lengthCompare(len: Int): Int = length - len + override /*SeqLike*/ + def lengthCompare(len: Int): Int = length - len - override def segmentLength(p: A => Boolean, from: Int): Int = { + override /*SeqLike*/ + def segmentLength(p: A => Boolean, from: Int): Int = { val start = from val len = length var i = start @@ -198,18 +255,21 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => private def negLength(n: Int) = if (n == length) -1 else n - override def indexWhere(p: A => Boolean, from: Int): Int = { + override /*SeqLike*/ + def indexWhere(p: A => Boolean, from: Int): Int = { val start = from max 0 negLength(start + segmentLength(!p(_), start)) } - override def lastIndexWhere(p: A => Boolean, end: Int): Int = { + override /*SeqLike*/ + def lastIndexWhere(p: A => Boolean, end: Int): Int = { var i = end while (i >= 0 && !p(this(i))) i -= 1 i } - override def reverse: Repr = { + override /*SeqLike*/ + def reverse: Repr = { val b = newBuilder b.sizeHint(length) var i = length @@ -220,7 +280,8 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => b.result } - override def reverseIterator: Iterator[A] = new Iterator[A] { + override /*SeqLike*/ + def reverseIterator: Iterator[A] = new Iterator[A] { private var i = self.length def hasNext: Boolean = 0 < i def next: A = @@ -230,7 +291,8 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => } else Iterator.empty.next } - override def startsWith[B](that: Seq[B], offset: Int): Boolean = that match { + override /*SeqLike*/ + def startsWith[B](that: Seq[B], offset: Int): Boolean = that match { case that: IndexedSeq[_] => var i = offset var j = 0 @@ -254,7 +316,8 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => !thatElems.hasNext } - override def endsWith[B](that: Seq[B]): Boolean = that match { + override /*SeqLike*/ + def endsWith[B](that: Seq[B]): Boolean = that match { case that: IndexedSeq[_] => var i = length - 1 var j = that.length - 1 @@ -272,13 +335,15 @@ trait IndexedSeqLike[+A, +Repr] extends SeqLike[A, Repr] { self => super.endsWith(that) } - override def view = new IndexedSeqView[A, Repr] { + override /*SeqLike*/ + def view = new IndexedSeqView[A, Repr] { protected lazy val underlying = self.repr override def iterator = self.iterator override def length = self.length override def apply(idx: Int) = self.apply(idx) } - override def view(from: Int, until: Int) = view.slice(from, until) + override /*SeqLike*/ + def view(from: Int, until: Int) = view.slice(from, until) } diff --git a/src/library/scala/collection/LinearSeqLike.scala b/src/library/scala/collection/LinearSeqLike.scala index 08bb071da9..9bed88967c 100644 --- a/src/library/scala/collection/LinearSeqLike.scala +++ b/src/library/scala/collection/LinearSeqLike.scala @@ -16,33 +16,49 @@ import mutable.ListBuffer import immutable.List import scala.util.control.Breaks._ -/** Class <code>Linear[A]</code> represents linear sequences of elements. - * For such sequences `isEmpty`, `head` and `tail` are guaranteed to be - * efficient constant time (or near so) operations. - * It does not add any methods to <code>Seq</code> but overrides - * several methods with optimized implementations. +/** A template trait for linear sequences of type `LinearSeq[A]`. * + * $linearSeqInfo * @author Martin Odersky * @author Matthias Zenger * @version 1.0, 16/07/2003 * @since 2.8 + * + * @define Coll LinearSeq + * @define linearSeqInfo + * Linear sequences are defined in terms of three abstract methods, which are assumed + * to have efficient implementations. These are: + * {{{ + * def isEmpty: Boolean + * def head: A + * def tail: Repr + * }}} + * Here, `A` is the type of the sequence elements and `Repr` is the type of the sequence itself. + * + * Linear sequences do not define any new methods wrt `Seq`. However, abstract `Seq` methods + * are defined in terms of `isEmpty`, `head`, and `tail`, and several other methods are overridden + * with optimized implementations. + * + * @tparam A the element type of the $coll + * @tparam Repr the type of the actual $coll containing the elements. */ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr] { self: Repr => override protected[this] def thisCollection: LinearSeq[A] = this.asInstanceOf[LinearSeq[A]] override protected[this] def toCollection(repr: Repr): LinearSeq[A] = repr.asInstanceOf[LinearSeq[A]] - /** Abstract method to be implemented in a subclass */ def isEmpty: Boolean - /** Abstract method to be implemented in a subclass */ def head: A - /** Abstract method to be implemented in a subclass */ def tail: Repr - /** Returns the number of elements in the linear sequence. - */ + /** The length of the $coll. + * + * $willNotTerminateInf + * + * Note: the execution of `length` may take time proportial to the length of the sequence. + */ def length: Int = { var these = self var len = 0 @@ -53,21 +69,18 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr len } - /** Returns the <code>n</code>-th element of this linear sequence. The first element - * (head of the linear sequence) is at position 0. - * - * @param n index of the element to return - * @return the element at position <code>n</code> in this linear sequence. - * @throws Predef.NoSuchElementException if the linear sequence is too short. + /** Selects an element by its index in the $coll. + * Note: the execution of `apply` may take time proportial to the index value. + * @throws `IndexOutOfBoundsEsxception` if `idx` does not satisfy `0 <= idx < length`. */ def apply(n: Int): A = { - require(n >= 0) - drop(n).head + val rest = drop(n) + if (n < 0 || rest.isEmpty) throw new IndexOutOfBoundsException + rest.head } - /** Returns the elements in the sequence as an iterator - */ - override def iterator: Iterator[A] = new Iterator[A] { + override /*IterableLike*/ + def iterator: Iterator[A] = new Iterator[A] { var these = self def hasNext: Boolean = !these.isEmpty def next: A = @@ -77,12 +90,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr override def toList: List[A] = these.toList } - /** Apply the given function <code>f</code> to each element of this linear sequence - * (while respecting the order of the elements). - * - * @param f the treatment to apply to each element. - */ - override def foreach[B](f: A => B) { + override /*IterableLike*/ + def foreach[B](f: A => B) { var these = this while (!these.isEmpty) { f(these.head) @@ -90,14 +99,9 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr } } - /** Tests if the predicate <code>p</code> is satisfied by all elements - * in this list. - * - * @param p the test predicate. - * @return <code>true</code> iff all elements of this list satisfy the - * predicate <code>p</code>. - */ - override def forall(p: A => Boolean): Boolean = { + + override /*IterableLike*/ + def forall(p: A => Boolean): Boolean = { var these = this while (!these.isEmpty) { if (!p(these.head)) return false @@ -106,14 +110,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr true } - /** Tests the existence in this list of an element that satisfies the - * predicate <code>p</code>. - * - * @param p the test predicate. - * @return <code>true</code> iff there exists an element in this list that - * satisfies the predicate <code>p</code>. - */ - override def exists(p: A => Boolean): Boolean = { + override /*IterableLike*/ + def exists(p: A => Boolean): Boolean = { var these = this while (!these.isEmpty) { if (p(these.head)) return true @@ -122,12 +120,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr false } - /** Count the number of elements in the iterable which satisfy a predicate. - * - * @param p the predicate for which to count - * @return the number of elements satisfying the predicate <code>p</code>. - */ - override def count(p: A => Boolean): Int = { + override /*TraversableLike*/ + def count(p: A => Boolean): Int = { var these = this var cnt = 0 while (!these.isEmpty) { @@ -137,14 +131,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr cnt } - /** Find and return the first element of the list satisfying a - * predicate, if any. - * - * @param p the predicate - * @return the first element in the list satisfying <code>p</code>, - * or <code>None</code> if none exists. - */ - override def find(p: A => Boolean): Option[A] = { + override /*IterableLike*/ + def find(p: A => Boolean): Option[A] = { var these = this while (!these.isEmpty) { if (p(these.head)) return Some(these.head) @@ -163,15 +151,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr res } */ - /** Combines the elements of this list together using the binary - * function <code>f</code>, from left to right, and starting with - * the value <code>z</code>. - * - * @return <code>f(... (f(f(z, a<sub>0</sub>), a<sub>1</sub>) ...), - * a<sub>n</sub>)</code> if the list is - * <code>[a<sub>0</sub>, a<sub>1</sub>, ..., a<sub>n</sub>]</code>. - */ - override def foldLeft[B](z: B)(f: (B, A) => B): B = { + override /*TraversableLike*/ + def foldLeft[B](z: B)(f: (B, A) => B): B = { var acc = z var these = this while (!these.isEmpty) { @@ -181,50 +162,24 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr acc } - /** Combines the elements of this list together using the binary - * function <code>f</code>, from right to left, and starting with - * the value <code>z</code>. - * - * @return <code>f(a<sub>0</sub>, f(a<sub>1</sub>, f(..., f(a<sub>n</sub>, z)...)))</code> - * if the list is <code>[a<sub>0</sub>, a1, ..., a<sub>n</sub>]</code>. - */ - override def foldRight[B](z: B)(f: (A, B) => B): B = + override /*IterableLike*/ + def foldRight[B](z: B)(f: (A, B) => B): B = if (this.isEmpty) z else f(head, tail.foldRight(z)(f)) - /** Combines the elements of this list together using the binary - * operator <code>op</code>, from left to right - * @param op The operator to apply - * @return <code>op(... op(a<sub>0</sub>,a<sub>1</sub>), ..., a<sub>n</sub>)</code> - if the list has elements - * <code>a<sub>0</sub>, a<sub>1</sub>, ..., a<sub>n</sub></code>. - * @throws Predef.UnsupportedOperationException if the list is empty. - */ - override def reduceLeft[B >: A](f: (B, A) => B): B = + override /*TraversableLike*/ + def reduceLeft[B >: A](f: (B, A) => B): B = if (isEmpty) throw new UnsupportedOperationException("empty.reduceLeft") else tail.foldLeft[B](head)(f) - /** Combines the elements of this iterable object together using the binary - * operator <code>op</code>, from right to left - * @note Will not terminate for infinite-sized collections. - * @param op The operator to apply - * - * @return <code>a<sub>0</sub> op (... op (a<sub>n-1</sub> op a<sub>n</sub>)...)</code> - * if the iterable object has elements <code>a<sub>0</sub>, a<sub>1</sub>, ..., - * a<sub>n</sub></code>. - * - * @throws Predef.UnsupportedOperationException if the iterator is empty. - */ - override def reduceRight[B >: A](op: (A, B) => B): B = + override /*IterableLike*/ + def reduceRight[B >: A](op: (A, B) => B): B = if (isEmpty) throw new UnsupportedOperationException("Nil.reduceRight") else if (tail.isEmpty) head else op(head, tail.reduceRight(op)) - /** The last element of this linear sequence. - * - * @throws Predef.NoSuchElementException if the linear sequence is empty. - */ - override def last: A = { + override /*TraversableLike*/ + def last: A = { if (isEmpty) throw new NoSuchElementException var these = this var nx = these.tail @@ -235,7 +190,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr these.head } - override def take(n: Int): Repr = { + override /*IterableLike*/ + def take(n: Int): Repr = { val b = newBuilder var i = 0 var these = repr @@ -247,7 +203,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr b.result } - override def drop(n: Int): Repr = { + override /*TraversableLike*/ + def drop(n: Int): Repr = { var these: Repr = repr var count = n while (!these.isEmpty && count > 0) { @@ -257,10 +214,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr these } - /** Returns the rightmost <code>n</code> elements from this iterable. - * @param n the number of elements to take - */ - override def dropRight(n: Int): Repr = { + override /*IterableLike*/ + def dropRight(n: Int): Repr = { val b = newBuilder var these = this var lead = this drop n @@ -272,17 +227,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr b.result } - /** A sub-traversable starting at index `from` - * and extending up to (but not including) index `until`. - * - * @note c.slice(from, to) is equivalent to (but possibly more efficient than) - * c.drop(from).take(to - from) - * - * @param from The index of the first element of the returned subsequence - * @param until The index of the element following the returned subsequence - * @note Might return different results for different runs, unless this traversable is ordered - */ - override def slice(from: Int, until: Int): Repr = { + override /*IterableLike*/ + def slice(from: Int, until: Int): Repr = { val b = newBuilder var i = from var these = this drop from @@ -294,13 +240,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr b.result } - /** Returns the longest prefix of this traversable whose elements satisfy - * the predicate <code>p</code>. - * - * @param p the test predicate. - * @note Might return different results for different runs, unless this traversable is ordered - */ - override def takeWhile(p: A => Boolean): Repr = { + override /*IterableLike*/ + def takeWhile(p: A => Boolean): Repr = { val b = newBuilder var these = this while (!these.isEmpty && p(these.head)) { @@ -310,12 +251,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr b.result } - /** Returns a pair consisting of the longest prefix of the linear sequence whose - * elements all satisfy the given predicate, and the rest of the linear sequence. - * - * @param p the test predicate - */ - override def span(p: A => Boolean): (Repr, Repr) = { + override /*TraversableLike*/ + def span(p: A => Boolean): (Repr, Repr) = { var these: Repr = repr val b = newBuilder while (!these.isEmpty && p(these.head)) { @@ -325,13 +262,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr (b.result, these) } - /** Returns <code>true</code> iff the other linear sequence contains the - * same elements as this one. - * - * @note will not terminate for two infinite-sized linear sequences. - * @param that the other linear sequence - */ - override def sameElements[B >: A](that: Iterable[B]): Boolean = that match { + override /*IterableLike*/ + def sameElements[B >: A](that: Iterable[B]): Boolean = that match { case that1: LinearSeq[_] => var these = this var those = that1 @@ -344,15 +276,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr super.sameElements(that) } - // Overridden methods from Seq - - /** Result of comparing <code>length</code> with operand <code>len</code>. - * returns <code>x</code> where - * <code>x < 0</code> iff <code>this.length < len</code> - * <code>x == 0</code> iff <code>this.length == len</code> - * <code>x > 0</code> iff <code>this.length > len</code>. - */ - override def lengthCompare(len: Int): Int = { + override /*SeqLike*/ + def lengthCompare(len: Int): Int = { var i = 0 var these = self while (!these.isEmpty && i <= len) { @@ -362,17 +287,11 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr i - len } - /** Is this partial function defined for the index <code>x</code>? - */ - override def isDefinedAt(x: Int): Boolean = x >= 0 && lengthCompare(x) > 0 + override /*SeqLike*/ + def isDefinedAt(x: Int): Boolean = x >= 0 && lengthCompare(x) > 0 - /** Returns length of longest segment starting from a start index `from` - * such that every element of the segment satisfies predicate `p`. - * @note may not terminate for infinite-sized collections. - * @param p the predicate - * @param from the start index - */ - override def segmentLength(p: A => Boolean, from: Int): Int = { + override /*SeqLike*/ + def segmentLength(p: A => Boolean, from: Int): Int = { var i = 0 var these = this drop from while (!these.isEmpty && p(these.head)) { @@ -382,14 +301,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr i } - /** Returns index of the first element starting from a start index - * satisying a predicate, or -1, if none exists. - * - * @note may not terminate for infinite-sized linear sequences. - * @param p the predicate - * @param from the start index - */ - override def indexWhere(p: A => Boolean, from: Int): Int = { + override /*SeqLike*/ + def indexWhere(p: A => Boolean, from: Int): Int = { var i = from var these = this drop from while (!these.isEmpty && !p(these.head)) { @@ -399,13 +312,8 @@ trait LinearSeqLike[+A, +Repr <: LinearSeqLike[A, Repr]] extends SeqLike[A, Repr if (these.isEmpty) -1 else i } - /** Returns index of the last element satisying a predicate, or -1, if none exists. - * - * @param p the predicate - * @return the index of the last element satisfying <code>p</code>, - * or -1 if such an element does not exist - */ - override def lastIndexWhere(p: A => Boolean, end: Int): Int = { + override /*SeqLike*/ + def lastIndexWhere(p: A => Boolean, end: Int): Int = { var i = 0 var these = this var last = -1 diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala index a9ea82b2f9..c856fd61a2 100644 --- a/src/library/scala/collection/MapLike.scala +++ b/src/library/scala/collection/MapLike.scala @@ -14,13 +14,19 @@ import generic._ import mutable.{Builder, StringBuilder, MapBuilder} import PartialFunction._ -/** - * A generic template for maps from keys of type `A` to values - * of type `B`. +/** A template trait for maps of type `Map[A, B]` which associate keys of type `A` + * with values of type `B`. * - * To implement a concrete map, 'you' need to provide implementations of the - * following methods (where `This` is the type of the map in - * question): + * @tparam A the type of the keys. + * @tparam B the type of associated values. + * @tparam This the type of the `Map` itself. + * @author Martin Odersky + * @version 2.8 + * @since 2.8 + * $mapnote + * @define $mapnote @note + * To implement a concrete map, you need to provide implementations of the + * following methods * {{{ * def get(key: A): Option[B] * @@ -30,18 +36,13 @@ import PartialFunction._ * * def -(key: A): This</pre> * }}} - * If you wish that methods <code>like</code>, <code>take</code>, <code>drop</code>, - * <code>filter</code> return the same kind of map, you should also override: + * If you wish that methods like `take`, `drop`, `filter` also return the same kind of map + * you should also override: * {{{ * def empty: This * }}} - * * It is also good idea to override methods `foreach` and * `size` for efficiency. - * - * @author Martin Odersky - * @version 2.8 - * @since 2.8 */ trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]] extends PartialFunction[A, B] diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala index 7e07a6460f..e36f2e6ad2 100644 --- a/src/library/scala/collection/SeqLike.scala +++ b/src/library/scala/collection/SeqLike.scala @@ -163,10 +163,11 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => */ def length: Int - /** Selects an element by its index in the $coll + /** Selects an element by its index in the $coll. * - * @param idx The index to select - * @return the element of tyh + * @param idx The index to select. + * @return the element of this $coll at index `idx`, where `0` indicates the first element. + * @throws `IndexOutOfBoundsEsxception` if `idx` does not satisfy `0 <= idx < length`. */ def apply(idx: Int): A @@ -449,7 +450,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => !j.hasNext } - /** Finds first index where this $coll contains a given sequence. + /** Finds first index where this $coll contains a given sequence as a slice. * $mayNotTerminateInf * @param that the sequence to test * @return the first index such that the elements of this $coll starting at this index @@ -457,7 +458,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => */ def indexOfSlice[B >: A](that: Seq[B]): Int = indexOfSlice(that, 0) - /** Finds first index where this $coll contains a given sequence after or at a start index. + /** Finds first index after or at a start index where this $coll contains a given sequence as a slice. * $mayNotTerminateInf * @param that the sequence to test * @param from the start index @@ -480,7 +481,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => -1 } - /** Finds last index where this $coll contains a given sequence. + /** Finds last index where this $coll contains a given sequence as a slice. * $willNotTerminateInf * @param that the sequence to test * @return the last index such that the elements of this $coll starting a this index @@ -488,7 +489,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => */ def lastIndexOfSlice[B >: A](that: Seq[B]): Int = lastIndexOfSlice(that, that.length) - /** Finds last index where this $coll contains a given sequence before or at a given end index. + /** Finds last index before or at a given end index where this $coll contains a given sequence as a slice. * @param that the sequence to test * @param end the end idnex * @return the last index `<= end` such that the elements of this $coll starting at this index @@ -497,6 +498,15 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => def lastIndexOfSlice[B >: A](that: Seq[B], end: Int): Int = SeqLike.lastIndexOf(thisCollection, 0, length, that, 0, that.length, end) + + /** Tests whether this $coll contains a given sequence as a slice. + * $mayNotTerminateInf + * @param that the sequence to test + * @return `true` if this $coll contains a slice with the same elements + * as `that`, otherwise `false`. + */ + def containsSlice[B](that: Seq[B]): Boolean = indexOfSlice(that) != -1 + /** Tests whether this $coll contains a given value as an element. * $mayNotTerminateInf * @@ -508,6 +518,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => /** Produces a new sequence which contains all elements of this $coll and also all elements of * a given sequence. `xs union ys` is equivalent to `xs ++ ys`. + * $willNotTerminateInf * * Another way to express this * is that `xs union ys` computes the order-presevring multi-set union of `xs` and `ys`. @@ -529,6 +540,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => this ++ that /** Computes the multiset difference between this $coll and another sequence. + * $willNotTerminateInf * * @param that the sequence of elements to remove * @tparam B the element type of the returned $coll. @@ -556,6 +568,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => } /** Computes the multiset intersection between this $coll and another sequence. + * $mayNotTerminateInf * * @param that the sequence of elements to intersect with. * @tparam B the element type of the returned $coll. @@ -591,6 +604,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => } /** Builds a new $coll from this $coll without any duplicate elements. + * $willNotTerminateInf * * @return A new $coll which contains the first occurrence of every element of this $coll. */ @@ -631,7 +645,15 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => b.result } - /** Returns a copy of this sequence with the element at position `index` replaced by `elem`. + /** A copy of this $coll with one single replaced element. + * @param index the position of the replacement + * @param elem the replacing element + * @tparam B the element type of the returned $coll. + * @tparam That $thatinfo + * @param bf $bfinfo + * @return a new collection of type `That` which is a copy of this $coll with the element at position `index` replaced by `elem`. + * @usecase def updated(index: Int, elem: A): $Coll[A] + * @return a copy of this $coll with the element at position `index` replaced by `elem`. */ def updated[B >: A, That](index: Int, elem: B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) @@ -642,7 +664,16 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => b.result } - /** Returns a new sequence consisting of `elem` followed by the elements of this sequence. + /** Prepends an element to this $coll + * @param elem the prepended element + * @tparam B the element type of the returned $coll. + * @tparam That $thatinfo + * @param bf $bfinfo + * @return a new collection of type `That` consisting of `elem` followed + * by all elements of this $coll. + * @usecase def +:(elem: A): $Coll[A] + * @return a new $coll consisting of `elem` followed + * by all elements of this $coll. */ def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) @@ -651,7 +682,17 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => b.result } - /** Returns a new sequence consisting of the elements of this sequence followed by `elem`. + /** Appends an element to this $coll + * $willNotTerminateInf + * @param elem the appended element + * @tparam B the element type of the returned $coll. + * @tparam That $thatinfo + * @param bf $bfinfo + * @return a new collection of type `That` consisting of + * all elements of this $coll followed by `elem`. + * @usecase def :+(elem: A): $Coll[A] + * @return a new $coll consisting of + * all elements of this $coll followed by `elem`. */ def :+[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) @@ -660,11 +701,19 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => b.result } - - - - /** Returns a new sequence of given length containing the elements of this sequence followed by zero - * or more occurrences of given elements. + /** Appends an element value to this $coll until a given target length is reached. + * @param len the target length + * @param elem the padding value + * @tparam B the element type of the returned $coll. + * @tparam That $thatinfo + * @param bf $bfinfo + * @return a new collection of type `That` consisting of + * all elements of this $coll followed by the minimal number of occurrences of `elem` so + * that the resulting collection has a length of at least `len`. + * @usecase def padTo(len: Int, elem: A): $Coll[A] + * @return a new $coll consisting of + * all elements of this $coll followed by the minimal number of occurrences of `elem` so + * that the resulting $coll has a length of at least `len`. */ def padTo[B >: A, That](len: Int, elem: B)(implicit bf: CanBuildFrom[Repr, B, That]): That = { val b = bf(repr) @@ -678,23 +727,55 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => b.result } - /** Sort the sequence according to the comparison function - * <code>lt(e1: a, e2: a) => Boolean</code>, - * which should be true iff <code>e1</code> precedes - * <code>e2</code> in the desired ordering. - * The sort is stable. That is elements that are equal wrt `lt` appear in the + /** Tests whether every element of this $coll relates to the + * corresponding element of another sequence by satisfying a test predicate. + * + * @param that the other sequence + * @param p the test predicate, which relates elements from both sequences + * @tparam B the type of the elements of `that` + * @return `true` if both sequences have the same length and + * `p(x, y)` is `true` for all corresponding elements `x` of this $coll + * and `y` of `that`, otherwise `false`. + */ + def corresponds[B](that: Seq[B])(p: (A,B) => Boolean): Boolean = { + val i = this.iterator + val j = that.iterator + while (i.hasNext && j.hasNext) + if (!p(i.next, j.next)) + return false + + !i.hasNext && !j.hasNext + } + + /** Sorts this $coll according to a comparison function. + * $willNotTerminateInf + * + * The sort is stable. That is, elements that are equal wrt `lt` appear in the * same order in the sorted sequence as in the original. * - * @param lt the comparison function - * @return a sequence sorted according to the comparison function - * <code>lt(e1: a, e2: a) => Boolean</code>. - * @ex <pre> - * List("Steve", "Tom", "John", "Bob") - * .sortWith((e1, e2) => (e1 compareTo e2) < 0) = - * List("Bob", "John", "Steve", "Tom")</pre> + * @param lt the comparison function which tests whether + * its first argument precedes its second argument in + * the desired ordering. + * @return a $coll consisting of the elements of this $coll + * sorted according to the comparison function `lt`. + * @ex {{{ + * List("Steve", "Tom", "John", "Bob").sortWith(_.compareTo(_) < 0) = + * List("Bob", "John", "Steve", "Tom") + * }}} */ def sortWith(lt: (A, A) => Boolean): Repr = sortWith(Ordering fromLessThan lt) + /** Sorts this $coll according to an Ordering. + * + * The sort is stable. That is, elements that are equal wrt `lt` appear in the + * same order in the sorted sequence as in the original. + * + * @see scala.math.Ordering + * + * @param ord the ordering to be used to compare elements. + * @return a $coll consisting of the elements of this $coll + * sorted according to the ordering `ord`. + */ def sortWith[B >: A](ord: Ordering[B]): Repr = { val arr = new GenericArray[A](this.length) var i = 0 @@ -709,19 +790,25 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => b.result } - /** Sort the sequence according to the Ordering which results from transforming - * the implicitly given Ordering[B] to an Ordering[A]. For example: - * - * <code> + /** Sorts this $Coll according to the Ordering which results from transforming + * an implicitly given Ordering with a transformation function. + * @see scala.math.Ordering + * $willNotTerminateInf + * @param f the transformation function mapping elements + * to some other domain `B`. + * @param ord the ordering assumed on domain `B`. + * @tparam B the target type of the transformation `f`, and the type where + * the ordering `ord` is defined. + * @return a $coll consisting of the elements of this $coll + * sorted according to the ordering where `x < y` if + * `ord.lt(f(x), f(y))`. + * + * @ex {{{ * val words = "The quick brown fox jumped over the lazy dog".split(' ') * // this works because scala.Ordering will implicitly provide an Ordering[Tuple2[Int, Char]] * words.sortBy(x => (x.length, x.head)) * res0: Array[String] = Array(The, dog, fox, the, lazy, over, brown, quick, jumped) - * </code> - * - * @param f the transformation function A => B - * @param ord the Ordering[B] - * @return the sorted representation + * }}} */ def sortBy[B](f: A => B)(implicit ord: Ordering[B]): Repr = sortWith(ord on f) @@ -732,7 +819,9 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => */ override def toSeq: Seq[A] = thisCollection - /** The range of all indices of this sequence. + /** Produces the range of all indices of this sequence. + * + * @range a `Range` value from `0` to one less than the length of this $coll. */ def indices: Range = 0 until length @@ -745,6 +834,9 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => override def view(from: Int, until: Int) = view.slice(from, until) + /** Hashcodes for $Coll produce a value from the hashcodes of all the + * elements of the $coll. + */ override def hashCode() = (Seq.hashSeed /: this)(_ * 41 + _.hashCode) override def equals(that: Any): Boolean = that match { @@ -752,15 +844,17 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => case _ => false } - /** Need to override string, so that it's not the Function1's string that gets mixed in. + /* Need to override string, so that it's not the Function1's string that gets mixed in. */ override def toString = super[IterableLike].toString - /** Returns index of the last element satisying a predicate, or -1. */ - @deprecated("use `lastIndexWhere' instead") + /** Returns index of the last element satisying a predicate, or -1. + * @deprecated use `lastIndexWhere' instead + */ def findLastIndexOf(p: A => Boolean): Int = lastIndexWhere(p) - @deprecated("Should be replaced by <code>(s1, s2) forall { case (x, y) => f(x, y) }</code>") + /** @deprecated Use `corresponds` instead. + */ def equalsWith[B](that: Seq[B])(f: (A,B) => Boolean): Boolean = { val i = this.iterator val j = that.iterator @@ -771,10 +865,7 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self => !i.hasNext && !j.hasNext } - /** Is <code>that</code> a slice in this? */ - def containsSlice[B](that: Seq[B]): Boolean = indexOfSlice(that) != -1 - - /** + /** @deprecated Use `view' instead. * returns a projection that can be used to call non-strict <code>filter</code>, * <code>map</code>, and <code>flatMap</code> methods that build projections * of the collection. |