diff options
Diffstat (limited to 'src/library/scalax/collection/generic')
18 files changed, 202 insertions, 86 deletions
diff --git a/src/library/scalax/collection/generic/IterableFactory.scala b/src/library/scalax/collection/generic/IterableFactory.scala index 264e333ac5..1362e97079 100755 --- a/src/library/scalax/collection/generic/IterableFactory.scala +++ b/src/library/scalax/collection/generic/IterableFactory.scala @@ -8,6 +8,9 @@ trait IterableFactory[CC[A] <: Iterable[A]] { protected def newBuilder[A]: Builder[CC, A] = apply().newBuilder[A].asInstanceOf[Builder[CC, A]] + // can't have an empty here because it is defined in subclass covariant.IterableFactory with type + // CC[Nothing]. This type does not make sense for immutable iterables. + /** Concatenate all the argument lists into a single list. * * @param xss the lists that are to be concatenated diff --git a/src/library/scalax/collection/generic/IterableForwarder.scala b/src/library/scalax/collection/generic/IterableForwarder.scala index fba1e6d0e9..91e527dafa 100644 --- a/src/library/scalax/collection/generic/IterableForwarder.scala +++ b/src/library/scalax/collection/generic/IterableForwarder.scala @@ -12,7 +12,7 @@ package scalax.collection.generic import collection.mutable.Buffer -import collection.immutable.List +import collection.immutable.{List, Stream} /** This trait implements a forwarder for iterable objects. It forwards * all calls to a different iterable object, except for diff --git a/src/library/scalax/collection/generic/IterableTemplate.scala b/src/library/scalax/collection/generic/IterableTemplate.scala index 01a23f5ecf..e5e22aa7c8 100755 --- a/src/library/scalax/collection/generic/IterableTemplate.scala +++ b/src/library/scalax/collection/generic/IterableTemplate.scala @@ -12,7 +12,7 @@ package scalax.collection.generic import scalax.collection.mutable.{Buffer, ArrayBuffer, ListBuffer} -import scalax.collection.immutable.{List, Nil, ::} +import scalax.collection.immutable.{List, Nil, ::, Stream} import util.control.Break._ import Iterable._ @@ -65,7 +65,7 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], */ def hasDefiniteSize = true - /** Create a new sequence of type CC which contains all elements of this sequence + /** Create a new iterable of type CC which contains all elements of this iterable * followed by all elements of Iterable `that' */ def ++[B >: A](that: Iterable[B]): CC[B] = { @@ -75,7 +75,7 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], b.result } - /** Create a new sequence of type IterableType which contains all elements of this sequence + /** Create a new iterable of type CC which contains all elements of this iterable * followed by all elements of Iterator `that' */ def ++[B >: A](that: Iterator[B]): CC[B] = { @@ -85,12 +85,12 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], b.result } - /** Returns the sequence resulting from applying the given function - * <code>f</code> to each element of this sequence. + /** Returns the iterable resulting from applying the given function + * <code>f</code> to each element of this iterable. * * @param f function to apply to each element. * @return <code>f(a<sub>0</sub>), ..., f(a<sub>n</sub>)</code> if this - * sequence is <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. + * iterable is <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. */ def map[B](f: A => B): CC[B] = { val b = newBuilder[B] @@ -99,11 +99,11 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], } /** Applies the given function <code>f</code> to each element of - * this sequence, then concatenates the results. + * this iterable, then concatenates the results. * * @param f the function to apply on each element. * @return <code>f(a<sub>0</sub>) ::: ... ::: f(a<sub>n</sub>)</code> if - * this sequence is <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. + * this iterable is <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. */ def flatMap[B](f: A => Iterable[B]): CC[B] = { val b = newBuilder[B] @@ -111,10 +111,10 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], b.result } - /** Returns all the elements of this sequence that satisfy the + /** Returns all the elements of this iterable that satisfy the * predicate <code>p</code>. The order of the elements is preserved. - * @param p the predicate used to filter the list. - * @return the elements of this list satisfying <code>p</code>. + * @param p the predicate used to filter the iterable. + * @return the elements of this iterable satisfying <code>p</code>. */ def filter(p: A => Boolean): CC[A] = { val b = newBuilder[A] @@ -128,7 +128,7 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], * predicate inversed. * * @param p the predicate to use to test elements - * @return the list without all elements which satisfy <code>p</code> + * @return the iterable without all elements which satisfy <code>p</code> */ def remove(p: A => Boolean): CC[A] = filter(!p(_)) @@ -203,6 +203,8 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], * predicate, if any. * * @note may not terminate for infinite-sized collections. + * @note Might return different results for different runs, unless this iterable is ordered, or + * the operator is associative and commutative. * @param p the predicate * @return an option containing the first element in the iterable object * satisfying <code>p</code>, or <code>None</code> if none exists. @@ -221,8 +223,10 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], * the value <code>z</code>. * * @note Will not terminate for infinite-sized collections. + * @note Might return different results for different runs, unless this iterable is ordered, or + * the operator is associative and commutative. * @return <code>f(... (f(f(z, a<sub>0</sub>), a<sub>1</sub>) ...), - * a<sub>n</sub>)</code> if the list is + * a<sub>n</sub>)</code> if the iterable is * <code>[a<sub>0</sub>, a<sub>1</sub>, ..., a<sub>n</sub>]</code>. */ def foldLeft[B](z: B)(op: (B, A) => B): B = { @@ -232,32 +236,40 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], result } - /** Combines the elements of this list together using the binary + /** Combines the elements of this iterable together using the binary * function <code>f</code>, from right to left, and starting with * the value <code>z</code>. * * @note Will not terminate for infinite-sized collections. + * @note Might return different results for different runs, unless this iterable is ordered, or + * the operator is associative and commutative. * @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>. + * if the iterable is <code>[a<sub>0</sub>, a1, ..., a<sub>n</sub>]</code>. */ def foldRight[B](z: B)(op: (A, B) => B): B = elements.foldRight(z)(op) /** Similar to <code>foldLeft</code> but can be used as - * an operator with the order of list and zero arguments reversed. + * an operator with the order of iterable and zero arguments reversed. * That is, <code>z /: xs</code> is the same as <code>xs foldLeft z</code> * @note Will not terminate for infinite-sized collections. + * @note Might return different results for different runs, unless this iterable is ordered, or + * the operator is associative and commutative. */ def /: [B](z: B)(op: (B, A) => B): B = foldLeft(z)(op) /** An alias for <code>foldRight</code>. * That is, <code>xs :\ z</code> is the same as <code>xs foldRight z</code> * @note Will not terminate for infinite-sized collections. + * @note Might return different results for different runs, unless this iterable is ordered, or + * the operator is associative and commutative. */ def :\ [B](z: B)(op: (A, B) => B): B = foldRight(z)(op) /** Combines the elements of this iterable object together using the binary * operator <code>op</code>, from left to right * @note Will not terminate for infinite-sized collections. + * @note Might return different results for different runs, unless this iterable is ordered, or + * the operator is associative and commutative. * @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 iterable object has elements @@ -277,6 +289,8 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], /** 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. + * @note Might return different results for different runs, unless this iterable is ordered, or + * the operator is associative and commutative. * @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> @@ -288,7 +302,7 @@ trait IterableTemplate[+CC[/*+*/B] <: IterableTemplate[CC, B] with Iterable[B], def reduceRight[B >: A](op: (A, B) => B): B = elements.reduceRight(op) - /** Returns an iterable formed from this iterable and the specified list + /** Returns an iterable formed from this iterable and the specified iterable * `other` by associating each element of the former with * the element at the same position in the latter. * If one of the two iterables is longer than the other, its remaining elements are ignored. @@ -356,7 +370,7 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the } /** Fills the given array <code>xs</code> with at most `len` elements of - * this sequence starting at position `start`. + * this iterable starting at position `start`. * Copying will stop oce either the end of the current iterable is reached or * `len` elements have been copied. * @@ -378,7 +392,7 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the } /** Fills the given array <code>xs</code> with the elements of - * this sequence starting at position <code>start</code> + * this iterable starting at position <code>start</code> * until either the end of the current iterable or the end of array `xs` is reached. * * @note Will not terminate for infinite-sized collections. @@ -411,7 +425,7 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the * Returns a sequence containing all of the elements in this iterable object. * @note Will not terminate for infinite-sized collections. */ - def toSequence: Sequence[A] = toList.asInstanceOf[Sequence[A]] // !!! + def toSequence: Sequence[A] = toList /** @deprecated use toSequence instead */ @@ -431,7 +445,7 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the * same order in the sorted iterable as in the original. * * @param lt the comparison function - * @return a list sorted according to the comparison function + * @return a iterable sorted according to the comparison function * <code><(e1: a, e2: a) => Boolean</code>. * @ex <pre> * List("Steve", "Tom", "John", "Bob") @@ -454,7 +468,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the * <code>sep</code>. * * @ex <code>List(1, 2, 3).mkString("(", "; ", ")") = "(1; 2; 3)"</code> - * @note Will not terminate for infinite-sized collections. * @param start starting string. * @param sep separator string. * @param end ending string. @@ -467,7 +480,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the * representations of elements (w.r.t. the method <code>toString()</code>) * are separated by the string <code>sep</code>. * - * @note Will not terminate for infinite-sized collections. * @param sep separator string. * @return a string representation of this iterable object. */ @@ -475,7 +487,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the addString(new StringBuilder(), sep).toString /** Converts a collection into a flat <code>String</code> by each element's toString method. - * @note Will not terminate for infinite-sized collections. */ def mkString = addString(new StringBuilder()).toString @@ -485,7 +496,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the * <code>end</code>. Inside, the string representations of elements (w.r.t. * the method <code>toString()</code>) are separated by the string * <code>sep</code>. - * @note Will not terminate for infinite-sized collections. */ def addString(b: StringBuilder, start: String, sep: String, end: String): StringBuilder = { b append start @@ -501,28 +511,13 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the /** Write all elements of this string into given string builder. * The string representations of elements (w.r.t. the method <code>toString()</code>) * are separated by the string <code>sep</code>. - * @note Will not terminate for infinite-sized collections. */ - def addString(b: StringBuilder, sep: String): StringBuilder = { - var first = true - for (x <- this) { - if (first) first = false - else b append sep - b append x - } - b - } + def addString(b: StringBuilder, sep: String): StringBuilder = addString(b, "", sep, "") /** Write all elements of this string into given string builder without using * any separator between consecutive elements. - * @note Will not terminate for infinite-sized collections. */ - def addString(b: StringBuilder): StringBuilder = { - for (x <- this) { - b append x - } - b - } + def addString(b: StringBuilder): StringBuilder = addString(b, "") /** * returns a projection that can be used to call non-strict <code>filter</code>, @@ -557,10 +552,10 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the // The following methods return non-deterministic results, unless this iterable is an OrderedIterable - /** The first element of this sequence. + /** The first element of this iterable. * * @note Might return different results for different runs, unless this iterable is ordered - * @throws Predef.NoSuchAentException if the sequence is empty. + * @throws Predef.NoSuchElementException if the iterable is empty. */ def head: A = if (isEmpty) throw new NoSuchElementException else elements.next @@ -574,7 +569,7 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the def headOption: Option[A] = if (isEmpty) None else Some(head) /** @deprecated use headOption instead - * <code>None</code> if list is empty. + * <code>None</code> if iterable is empty. */ @deprecated def firstOption: Option[A] = headOption @@ -589,7 +584,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the * than <code>n</code> elements. * * @param n the number of elements to take - * @return a possibly projected sequence * @note Might return different results for different runs, unless this iterable is ordered */ def take(n: Int): CC[A] = { @@ -650,7 +644,7 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the /** The last element of this iterable. * - * @throws Predef.NoSuchElementException if the sequence is empty. + * @throws Predef.NoSuchElementException if the iterable is empty. * @note Might return different results for different runs, unless this iterable is ordered */ def last: A = { @@ -669,9 +663,11 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the def lastOption: Option[A] = if (isEmpty) None else Some(last) /** An iterable consisting of all elements of this iterable except the last one. + * @throws Predef.UnsupportedOperationException if the stream is empty. * @note Might return different results for different runs, unless this iterable is ordered */ def init: CC[A] = { + if (isEmpty) throw new UnsupportedOperationException("empty.init") var lst = head val b = newBuilder[A] for (x <- this) { @@ -732,12 +728,10 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the (l.result, r.result) } - /** Returns the longest prefix of this sequence whose elements satisfy + /** Returns the longest prefix of this iterable whose elements satisfy * the predicate <code>p</code>. * * @param p the test predicate. - * @return the longest prefix of this sequence whose elements satisfy - * the predicate <code>p</code>. * @note Might return different results for different runs, unless this iterable is ordered */ def takeWhile(p: A => Boolean): CC[A] = { @@ -751,12 +745,10 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the b.result } - /** Returns the longest suffix of this sequence whose first element + /** Returns the longest suffix of this iterable whose first element * does not satisfy the predicate <code>p</code>. * * @param p the test predicate. - * @return the longest suffix of the sequence whose first element - * does not satisfy the predicate <code>p</code>. * @note Might return different results for different runs, unless this iterable is ordered */ def dropWhile(p: A => Boolean): CC[A] = { @@ -769,12 +761,12 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the b.result } - /** Returns a pair consisting of the longest prefix of the list whose - * elements all satisfy the given predicate, and the rest of the list. + /** Returns a pair consisting of the longest prefix of the iterable whose + * elements all satisfy the given predicate, and the rest of the iterable. * * @param p the test predicate - * @return a pair consisting of the longest prefix of the list whose - * elements all satisfy <code>p</code>, and the rest of the list. + * @return a pair consisting of the longest prefix of the iterable whose + * elements all satisfy <code>p</code>, and the rest of the iterable. * @note Might return different results for different runs, unless this iterable is ordered */ def span(p: A => Boolean): (CC[A], CC[A]) = { @@ -801,13 +793,13 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the !these.hasNext && !those.hasNext } - /** A sub-sequence view starting at index `from` + /** A sub-iterable view starting at index `from` * and extending up to (but not including) index `until`. * * @param from The index of the first element of the slice * @param until The index of the element following the slice * @note The difference between `view` and `slice` is that `view` produces - * a view of the current sequence, whereas `slice` produces a new sequence. + * a view of the current iterable, whereas `slice` produces a new iterable. * * @note Might return different results for different runs, unless this iterable is ordered * @note view(from, to) is equivalent to view.slice(from, to) diff --git a/src/library/scalax/collection/generic/SequenceFactory.scala b/src/library/scalax/collection/generic/SequenceFactory.scala index ee97c80c75..26818c49c9 100755 --- a/src/library/scalax/collection/generic/SequenceFactory.scala +++ b/src/library/scalax/collection/generic/SequenceFactory.scala @@ -7,5 +7,5 @@ trait SequenceFactory[CC[A] <: Sequence[A]] extends IterableFactory[CC] { * @param x the selector value * @return sequence wrapped in an option, if this is a Sequence, otherwise none */ - def unapplySequence[A](x: CC[A]): Some[CC[A]] = Some(x) + def unapplySeq[A](x: CC[A]): Some[CC[A]] = Some(x) } diff --git a/src/library/scalax/collection/generic/SequenceTemplate.scala b/src/library/scalax/collection/generic/SequenceTemplate.scala index eba0e4bf98..b4a2c6f95a 100755 --- a/src/library/scalax/collection/generic/SequenceTemplate.scala +++ b/src/library/scalax/collection/generic/SequenceTemplate.scala @@ -53,13 +53,6 @@ self /*: CC[A]*/ => */ def isDefinedAt(x: Int): Boolean = (x >= 0) && (x < length) - /** Returns index of the first element satisying a predicate, or -1, if none exists. - * - * @note may not terminate for infinite-sized collections. - * @param p the predicate - */ - def indexWhere(p: A => Boolean): Int = indexWhere(p, 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. @@ -85,6 +78,13 @@ self /*: CC[A]*/ => */ def prefixLength(p: A => Boolean) = segmentLength(p, 0) + /** Returns index of the first element satisfying a predicate, or -1, if none exists. + * + * @note may not terminate for infinite-sized collections. + * @param p the predicate + */ + def indexWhere(p: A => Boolean): Int = indexWhere(p, 0) + /** Returns index of the first element starting from a start index * satisying a predicate, or -1, if none exists. * @@ -303,10 +303,8 @@ self /*: CC[A]*/ => b.result } - /** Returns a sequence of given length containing the elements of this sequence followed by zero - * or more occurrences of given elements. If this sequence is already at least as long as given - * length, it is returned directly. Otherwise, a new sequence is created consisting of the elements - * of this sequence followed by enough occurrences of the given elements to reach the given length. + /** Returns a new sequence of given length containing the elements of this sequence followed by zero + * or more occurrences of given elements. */ def padTo[B >: A](len: Int, elem: B): CC[B] = { var diff = len - length @@ -324,7 +322,7 @@ self /*: CC[A]*/ => * * @return the sequence itself */ - override def toSequence: Sequence[A] = this.asInstanceOf[Null] // !!! + override def toSequence: Sequence[A] = thisCC def indices: Range = 0 until length diff --git a/src/library/scalax/collection/generic/SequenceView.scala b/src/library/scalax/collection/generic/SequenceView.scala index 6178542241..43ce49d3a5 100755 --- a/src/library/scalax/collection/generic/SequenceView.scala +++ b/src/library/scalax/collection/generic/SequenceView.scala @@ -69,7 +69,7 @@ self => class Patched[/*+*/B >: A](from: Int, patch: Sequence[B], replaced: Int) extends Transformed[B] { val plen = patch.length - override def elements: Iterator[B] = self.elements patch (from, patch.asInstanceOf[Null], replaced) // !!! + override def elements: Iterator[B] = self.elements patch (from, patch, replaced) override def length: Int = self.length + plen - replaced override def apply(idx: Int): B = if (idx < from) self.apply(idx) @@ -101,7 +101,7 @@ self => override def zip[B](that: Iterable[B]): SequenceView[UC, (A, B)] = new Zipped(that.toSequence).asCC override def zipWithIndex: SequenceView[UC, (A, Int)] = - zip((0 until length).asInstanceOf[Null]) // !!! + zip((0 until length).asInstanceOf[Null]) // !@! /* override def zipAll[B, A1 >: A, B1 >: B](that: Iterable[B], thisElem: A1, thatElem: B1): SequenceView[UC, (A1, B1)] = { val that1 = that.toSequence diff --git a/src/library/scalax/collection/generic/covariant/IterableFactory.scala b/src/library/scalax/collection/generic/covariant/IterableFactory.scala index 67445f54d9..0fd2284cea 100755 --- a/src/library/scalax/collection/generic/covariant/IterableFactory.scala +++ b/src/library/scalax/collection/generic/covariant/IterableFactory.scala @@ -7,8 +7,14 @@ trait IterableFactory[CC[+A] <: Iterable[A]] extends generic.IterableFactory[CC] override protected def newBuilder[A]: Builder[CC, A] = empty.newBuilder[A].asInstanceOf[Builder[CC, A]] + // the cast here is unavoidable because CC is not constrained with covariant.IterableTemplate[CC, A] + // It's can't be constrained because some suntype links between covariant and generic Templates + // are missing. That's a consequence of our hacks to have both nonvariant and covariant templates. /** Create CC collection of specified elements */ override def apply[A](args: A*): CC[A] = - (empty ++ args.asInstanceOf[Iterable[A]]).asInstanceOf[CC[A]] // !!! + (empty ++ args.asInstanceOf[Iterable[A]]).asInstanceOf[CC[A]] + // the cast here is unavoidable because CC is not constrained with covariant.IterableTemplate[CC, A] + // It's can't be constrained because some suntype links between covariant and generic Templates + // are missing. That's a consequence of our hacks to have both nonvariant and covariant templates. } diff --git a/src/library/scalax/collection/generic/covariant/OrderedIterableTemplate.scala b/src/library/scalax/collection/generic/covariant/OrderedIterableTemplate.scala index 449bac9cfc..38c1c2ab4c 100755 --- a/src/library/scalax/collection/generic/covariant/OrderedIterableTemplate.scala +++ b/src/library/scalax/collection/generic/covariant/OrderedIterableTemplate.scala @@ -13,5 +13,5 @@ package scalax.collection.generic.covariant import annotation.unchecked.uncheckedVariance -trait OrderedIterableTemplate[+CC[+B] <: OrderedIterableTemplate[CC, B] with OrderedIterable[B], +A] +trait OrderedIterableTemplate[+CC[+B] <: OrderedIterable[B] with OrderedIterableTemplate[CC, B], +A] extends generic.OrderedIterableTemplate[CC, A @uncheckedVariance] {self /*: CC[A]*/ => } diff --git a/src/library/scalax/collection/generic/covartest/IterableForwarder.scala b/src/library/scalax/collection/generic/covartest/IterableForwarder.scala new file mode 100755 index 0000000000..9d78cb18e0 --- /dev/null +++ b/src/library/scalax/collection/generic/covartest/IterableForwarder.scala @@ -0,0 +1,61 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2008, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: IterableProxy.scala 15458 2008-06-28 20:23:22Z stepancheg $ + + +package scalax.collection.generic.covartest + +import collection.mutable.Buffer +import collection.immutable.{List, Stream} + +/** This trait implements a forwarder for iterable objects. It forwards + * all calls to a different iterable object, except for + * + * - toString, hashCode, equals, stringPrefix + * - newBuilder, view + * - all calls creating a new iterable objetc of the same kind + * + * The above methods are forwarded by subclass IterableProxy + * + * @author Martin Odersky + * @version 2.8 + */ +trait IterableForwarder[+A] extends Iterable[A] { + + /** The iterable object to which calls are forwarded */ + protected def underlying: Iterable[A] + + // Iterable delegates + // Iterable methods could be printed by cat IterableTemplate.scala | sed -n '/trait Iterable/,$ p' | egrep '^ (override )?def' + + override def elements = underlying.elements + override def isEmpty = underlying.isEmpty + override def hasDefiniteSize = underlying.hasDefiniteSize + override def foreach(f: A => Unit) = underlying.foreach(f) + override def forall(p: A => Boolean): Boolean = underlying.forall(p) + override def exists(p: A => Boolean): Boolean = underlying.exists(p) + override def count(p: A => Boolean): Int = underlying.count(p) + override def find(p: A => Boolean): Option[A] = underlying.find(p) + override def foldLeft[B](z: B)(op: (B, A) => B): B = underlying.foldLeft(z)(op) + override def foldRight[B](z: B)(op: (A, B) => B): B = underlying.foldRight(z)(op) + override def reduceLeft[B >: A](op: (B, A) => B): B = underlying.reduceLeft(op) + override def reduceRight[B >: A](op: (A, B) => B): B = underlying.reduceRight(op) + override def copyToBuffer[B >: A](dest: Buffer[B]) = underlying.copyToBuffer(dest) + override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) = underlying.copyToArray(xs, start, len) + override def toArray[B >: A]: Array[B] = underlying.toArray + override def toList: List[A] = underlying.toList + override def toSequence: Sequence[A] = underlying.toSequence + override def toStream: Stream[A] = underlying.toStream + override def mkString(start: String, sep: String, end: String): String = underlying.mkString(start, sep, end) + override def addString(b: StringBuilder, start: String, sep: String, end: String): StringBuilder = underlying.addString(b, start, sep, end) + + override def head: A = underlying.head + override def last: A = underlying.last + override def sameElements[B >: A](that: OrderedIterable[B]): Boolean = underlying.sameElements(that) +} diff --git a/src/library/scalax/collection/generic/covartest/IterableTemplate.scala b/src/library/scalax/collection/generic/covartest/IterableTemplate.scala index b83f3b9247..eb4281b427 100755 --- a/src/library/scalax/collection/generic/covartest/IterableTemplate.scala +++ b/src/library/scalax/collection/generic/covartest/IterableTemplate.scala @@ -12,7 +12,7 @@ package scalax.collection.generic.covartest import scalax.collection.mutable.{Buffer, ArrayBuffer, ListBuffer} -import scalax.collection.immutable.{List, Nil, ::} +import scalax.collection.immutable.{List, Nil, ::, Stream} import util.control.Break._ import Iterable._ @@ -411,7 +411,7 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the * Returns a sequence containing all of the elements in this iterable object. * @note Will not terminate for infinite-sized collections. */ - def toSequence: Sequence[A] = toList.asInstanceOf[Sequence[A]] // !!! + def toSequence: Sequence[A] = toList /** @deprecated use toSequence instead */ diff --git a/src/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala b/src/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala index c6be1a5acd..5256a4e40d 100755 --- a/src/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala +++ b/src/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala @@ -13,5 +13,11 @@ package scalax.collection.generic.covartest import OrderedIterable._ +/** Ordered iterables are iterables where the `elements` method always returns elements in the same + * order (namely the order in which elements were appended to the iterable). In particular, one has + * for every two ordered iterables `xs` and `ys`: + * + * `(xs ++ ys).elements = xs.elements ++ ys.elements + */ trait OrderedIterableTemplate[+CC[+B] <: OrderedIterableTemplate[CC, B] with OrderedIterable[B], +A] extends IterableTemplate[CC, A] diff --git a/src/library/scalax/collection/generic/covartest/SequenceFactory.scala b/src/library/scalax/collection/generic/covartest/SequenceFactory.scala index 1fb85d02db..eb6c093bff 100755 --- a/src/library/scalax/collection/generic/covartest/SequenceFactory.scala +++ b/src/library/scalax/collection/generic/covartest/SequenceFactory.scala @@ -7,5 +7,5 @@ trait SequenceFactory[CC[A] <: Sequence[A]] extends IterableFactory[CC] { * @param x the selector value * @return sequence wrapped in an option, if this is a Sequence, otherwise none */ - def unapplySequence[A](x: CC[A]): Some[CC[A]] = Some(x) + def unapplySeq[A](x: CC[A]): Some[CC[A]] = Some(x) } diff --git a/src/library/scalax/collection/generic/covartest/SequenceForwarder.scala b/src/library/scalax/collection/generic/covartest/SequenceForwarder.scala new file mode 100644 index 0000000000..d5ba7ea063 --- /dev/null +++ b/src/library/scalax/collection/generic/covartest/SequenceForwarder.scala @@ -0,0 +1,50 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: SeqProxy.scala 15458 2008-06-28 20:23:22Z stepancheg $ + + +package scalax.collection.generic.covartest + +/** This class implements a forwarder for sequences. It forwards + * all calls to a different sequence object except for + * + * - toString, hashCode, equals, stringPrefix + * - newBuilder, view, toSequence + * - all calls creating a new iterable objetc of the same kind + * + * The above methods are forwarded by subclass SequenceProxy + * + * @author Martin Odersky + * @version 2.8 + */ +trait SequenceForwarder[+A] extends Sequence[A] with IterableForwarder[A] { + + protected override def underlying: Sequence[A] + + // PartialFunction delegates + + override def apply(i: Int): A = underlying.apply(i) + override def isDefinedAt(x: Int): Boolean = underlying.isDefinedAt(x) + + // Sequence delegates + // Sequence methods could be printed by cat SequenceTemplate.scala | sed -n '/trait Seq/,$ p' | egrep '^ (override )?def' + + override def length: Int = underlying.length + override def lengthCompare(l: Int) = underlying lengthCompare l + override def segmentLength(p: A => Boolean, from: Int): Int = underlying.segmentLength(p, from) + override def prefixLength(p: A => Boolean) = underlying.prefixLength(p) + override def indexWhere(p: A => Boolean, from: Int): Int = underlying.indexWhere(p, from) + override def indexOf[B >: A](elem: B, from: Int): Int = underlying.indexOf(elem, from) + override def reversedElements: Iterator[A] = underlying.reversedElements + override def startsWith[B](that: Sequence[B], offset: Int): Boolean = underlying.startsWith(that, offset) + override def endsWith[B](that: Sequence[B]): Boolean = underlying.endsWith(that) + override def indexOf[B >: A](that: Sequence[B]): Int = underlying.indexOf(that) + override def contains(elem: Any): Boolean = underlying.contains(elem) + override def indices: Range = underlying.indices +} diff --git a/src/library/scalax/collection/generic/covartest/SequenceTemplate.scala b/src/library/scalax/collection/generic/covartest/SequenceTemplate.scala index bf1915edf0..ffc4c3d8f7 100755 --- a/src/library/scalax/collection/generic/covartest/SequenceTemplate.scala +++ b/src/library/scalax/collection/generic/covartest/SequenceTemplate.scala @@ -324,7 +324,7 @@ self /*: CC[A]*/ => * * @return the sequence itself */ - override def toSequence: Sequence[A] = this.asInstanceOf[Null] // !!! + override def toSequence: Sequence[A] = thisCC def indices: Range = 0 until length diff --git a/src/library/scalax/collection/generic/covartest/SequenceView.scala b/src/library/scalax/collection/generic/covartest/SequenceView.scala index 48477cf6e7..09d5c0efa1 100755 --- a/src/library/scalax/collection/generic/covartest/SequenceView.scala +++ b/src/library/scalax/collection/generic/covartest/SequenceView.scala @@ -69,7 +69,7 @@ self => class Patched[+B >: A](from: Int, patch: Sequence[B], replaced: Int) extends Transformed[B] { val plen = patch.length - override def elements: Iterator[B] = self.elements patch (from, patch.asInstanceOf[Null], replaced) // !!! + override def elements: Iterator[B] = self.elements patch (from, patch, replaced) override def length: Int = self.length + plen - replaced override def apply(idx: Int): B = if (idx < from) self.apply(idx) @@ -101,7 +101,7 @@ self => override def zip[B](that: Iterable[B]): SequenceView[UC, (A, B)] = new Zipped(that.toSequence).asCC override def zipWithIndex: SequenceView[UC, (A, Int)] = - zip((0 until length).asInstanceOf[Null]) // !!! + zip((0 until length).asInstanceOf[Null]) // !@! /* override def zipAll[B, A1 >: A, B1 >: B](that: Iterable[B], thisElem: A1, thatElem: B1): SequenceView[UC, (A1, B1)] = { val that1 = that.toSequence diff --git a/src/library/scalax/collection/generic/covartest/VectorTemplate.scala b/src/library/scalax/collection/generic/covartest/VectorTemplate.scala index 0771b078d9..6e44b6a6c5 100644 --- a/src/library/scalax/collection/generic/covartest/VectorTemplate.scala +++ b/src/library/scalax/collection/generic/covartest/VectorTemplate.scala @@ -208,7 +208,7 @@ self => b.result } - override def reversedElements = new Iterator[A] { + override def reversedElements: Iterator[A] = new Iterator[A] { var i = length def hasNext: Boolean = 0 < i def next: A = diff --git a/src/library/scalax/collection/generic/mutable/VectorTemplate.scala b/src/library/scalax/collection/generic/mutable/VectorTemplate.scala index aafee3ae3b..747cd01a4c 100644 --- a/src/library/scalax/collection/generic/mutable/VectorTemplate.scala +++ b/src/library/scalax/collection/generic/mutable/VectorTemplate.scala @@ -44,7 +44,7 @@ self => */ override def view(from: Int, until: Int): VectorView[CC, A] = view.slice(from, until) - def readOnly: Sequence[A] = new collection./*immutable.*/Vector[A] { //!!! + def readOnly: Sequence[A] = new collection.immutable.Vector[A] { //!!! def length = self.length def apply(idx : Int) = self.apply(idx) def newBuilder[B]: Builder[CC, B] = self.newBuilder[B] diff --git a/src/library/scalax/collection/generic/mutable/VectorView.scala b/src/library/scalax/collection/generic/mutable/VectorView.scala index 05a7bf6f5a..caebcb567f 100644 --- a/src/library/scalax/collection/generic/mutable/VectorView.scala +++ b/src/library/scalax/collection/generic/mutable/VectorView.scala @@ -75,7 +75,7 @@ self => new Zipped(toVector(that)).asCC override def zipWithIndex: VectorView[UC, (A, Int)] = - zip((0 until length).asInstanceOf[Null]) // !!! + zip((0 until length).asInstanceOf[Null]) // !@! override def take(n: Int): VectorView[UC, A] = slice(0, n) override def drop(n: Int): VectorView[UC, A] = |