summaryrefslogtreecommitdiff
path: root/src/library/scalax/collection/generic
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-02-13 11:59:49 +0000
committerMartin Odersky <odersky@gmail.com>2009-02-13 11:59:49 +0000
commit04840e2ed4530df9a5ca59b984bf2b37a976dc70 (patch)
tree61394762e202f8ab60e0d3a8e8ac688404241bc3 /src/library/scalax/collection/generic
parent708baf94764e2a839e24ca6204060a8d0664d88c (diff)
downloadscala-04840e2ed4530df9a5ca59b984bf2b37a976dc70.tar.gz
scala-04840e2ed4530df9a5ca59b984bf2b37a976dc70.tar.bz2
scala-04840e2ed4530df9a5ca59b984bf2b37a976dc70.zip
new version of collection libraries
Diffstat (limited to 'src/library/scalax/collection/generic')
-rwxr-xr-xsrc/library/scalax/collection/generic/Addable.scala64
-rw-r--r--src/library/scalax/collection/generic/AddableBuilder.scala22
-rwxr-xr-xsrc/library/scalax/collection/generic/Builder.scala31
-rw-r--r--src/library/scalax/collection/generic/Cloneable.scala5
-rwxr-xr-xsrc/library/scalax/collection/generic/EmptyIterableFactory.scala17
-rwxr-xr-xsrc/library/scalax/collection/generic/Growable.scala58
-rwxr-xr-xsrc/library/scalax/collection/generic/IterableFactory.scala6
-rw-r--r--src/library/scalax/collection/generic/IterableForwarder.scala2
-rwxr-xr-xsrc/library/scalax/collection/generic/IterableTemplate.scala135
-rwxr-xr-xsrc/library/scalax/collection/generic/IterableView.scala11
-rwxr-xr-xsrc/library/scalax/collection/generic/LazyBuilder.scala24
-rwxr-xr-xsrc/library/scalax/collection/generic/MapFactory.scala9
-rwxr-xr-xsrc/library/scalax/collection/generic/MapTemplate.scala247
-rw-r--r--src/library/scalax/collection/generic/MapView.scala44
-rwxr-xr-xsrc/library/scalax/collection/generic/MutableVectorTemplate.scala56
-rwxr-xr-xsrc/library/scalax/collection/generic/MutableVectorView.scala95
-rwxr-xr-xsrc/library/scalax/collection/generic/OrderedIterableForwarder.scala37
-rwxr-xr-xsrc/library/scalax/collection/generic/OrderedIterableTemplate.scala140
-rwxr-xr-xsrc/library/scalax/collection/generic/OrderedIterableView.scala85
-rw-r--r--src/library/scalax/collection/generic/SetFactory.scala2
-rwxr-xr-xsrc/library/scalax/collection/generic/SetTemplate.scala63
-rwxr-xr-xsrc/library/scalax/collection/generic/Shrinkable.scala54
-rwxr-xr-xsrc/library/scalax/collection/generic/Subtractable.scala64
-rwxr-xr-xsrc/library/scalax/collection/generic/covartest/IterableForwarder.scala2
-rwxr-xr-xsrc/library/scalax/collection/generic/covartest/IterableTemplate.scala229
-rwxr-xr-xsrc/library/scalax/collection/generic/covartest/IterableView.scala11
-rwxr-xr-xsrc/library/scalax/collection/generic/covartest/OrderedIterableForwarder.scala37
-rwxr-xr-xsrc/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala140
-rw-r--r--src/library/scalax/collection/generic/covartest/SequenceForwarder.scala2
29 files changed, 1297 insertions, 395 deletions
diff --git a/src/library/scalax/collection/generic/Addable.scala b/src/library/scalax/collection/generic/Addable.scala
new file mode 100755
index 0000000000..40a4f60e6e
--- /dev/null
+++ b/src/library/scalax/collection/generic/Addable.scala
@@ -0,0 +1,64 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Iterable.scala 15188 2008-05-24 15:01:02Z stepancheg $
+
+package scalax.collection.generic
+
+/** This class represents collections that can be augmented using a += operator.
+ *
+ * @autor Martin Odersky
+ * @owner Martin Odersky
+ * @version 2.8
+ */
+trait Addable[+C <: Addable[C, A], A] {
+
+ protected def thisCC: C
+
+ /** Adds a single element to this collection and returns
+ * either the collection itself (if it is mutable), or a new collection
+ * with the added element.
+ *
+ * @param elem the element to add.
+ */
+ def +(elem: A): C
+
+ /** Adds two or more elements to this collection and returns
+ * either the collection itself (if it is mutable), or a new collection
+ * with the added elements.
+ *
+ * @param elem1 the first element to add.
+ * @param elem2 the second element to add.
+ * @param elems the remaining elements to add.
+ */
+ def +(elem1: A, elem2: A, elems: A*): C =
+ thisCC + elem1 + elem2 ++ elems.asInstanceOf[Iterable[A]] // !@!
+
+ /** Adds a number of elements provided by an iterable object
+ * via its <code>elements</code> method and returns
+ * either the collection itself (if it is mutable), or a new collection
+ * with the added elements.
+ *
+ * @param iter the iterable object.
+ */
+ def ++(iter: Iterable[A]): C = (thisCC /: iter) (_ + _)
+
+ /** Adds a number of elements provided by an iterator
+ * via its <code>elements</code> method and returns
+ * either the collection itself (if it is mutable), or a new collection
+ * with the added elements.
+ *
+ * @param iter the iterator
+ */
+ def ++(iter: Iterator[A]): C = (thisCC /: iter) (_ + _)
+
+}
+
+
+
+
diff --git a/src/library/scalax/collection/generic/AddableBuilder.scala b/src/library/scalax/collection/generic/AddableBuilder.scala
new file mode 100644
index 0000000000..b1f3e4e522
--- /dev/null
+++ b/src/library/scalax/collection/generic/AddableBuilder.scala
@@ -0,0 +1,22 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: ListBuffer.scala 14378 2008-03-13 11:39:05Z dragos $
+
+package scalax.collection.generic
+
+import collection.mutable.ListBuffer
+import collection.immutable.{List, Nil, ::}
+
+class AddableBuilder[CC[B] <: Iterable[B] with Addable[CC[B], B], A](empty: CC[A]) extends Builder[CC, A] {
+ protected var elems: CC[A] = empty
+ def +=(x: A) { elems = elems + x }
+ def elements: Iterator[A] = elems.elements
+ def clear() { elems = empty }
+ def result: CC[A] = elems
+}
diff --git a/src/library/scalax/collection/generic/Builder.scala b/src/library/scalax/collection/generic/Builder.scala
new file mode 100755
index 0000000000..155ca553fa
--- /dev/null
+++ b/src/library/scalax/collection/generic/Builder.scala
@@ -0,0 +1,31 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: ListBuffer.scala 14378 2008-03-13 11:39:05Z dragos $
+
+package scalax.collection.generic
+
+import generic._
+
+trait Builder[+CC[B], A] extends Growable[A] {
+ def +=(x: A)
+ def elements: Iterator[A]
+ def result: CC[A]
+
+ def mapResult[DD[B]](f: CC[A] => DD[A]) =
+ new Builder[DD, A] with Proxy {
+ val self = Builder.this
+ def +=(x: A) = self += x
+ def elements: Iterator[A] = self.elements
+ def clear() = self.clear()
+ override def ++=(xs: Iterator[A]) = self ++= xs
+ override def ++=(xs: collection.Iterable[A]) = self ++= xs
+ def result: DD[A] = f(Builder.this.result)
+ }
+}
+
diff --git a/src/library/scalax/collection/generic/Cloneable.scala b/src/library/scalax/collection/generic/Cloneable.scala
index 455c88e47b..acf9a16686 100644
--- a/src/library/scalax/collection/generic/Cloneable.scala
+++ b/src/library/scalax/collection/generic/Cloneable.scala
@@ -9,10 +9,11 @@
// $Id: CloneableCollection.scala 16893 2009-01-13 13:09:22Z cunei $
-package scala.collection.generic
+package scalax.collection.generic
/** A trait for cloneable collections.
*/
-trait Cloneable[A <: AnyRef] extends java.lang.Cloneable {
+@cloneable
+trait Cloneable[A <: AnyRef] {
override def clone(): A = super.clone().asInstanceOf[A]
}
diff --git a/src/library/scalax/collection/generic/EmptyIterableFactory.scala b/src/library/scalax/collection/generic/EmptyIterableFactory.scala
new file mode 100755
index 0000000000..7f110d13d2
--- /dev/null
+++ b/src/library/scalax/collection/generic/EmptyIterableFactory.scala
@@ -0,0 +1,17 @@
+package scalax.collection.generic
+
+import annotation.unchecked.uncheckedVariance
+
+trait EmptyIterableFactory[CC[+A] <: Iterable[A] with IterableTemplate[CC, A @uncheckedVariance]] extends IterableFactory[CC] {
+
+ /** The empty collection of type CC */
+ val empty: CC[Nothing]
+
+ /** An override of newBuilder, to work off the empty object */
+ override protected def newBuilder[A]: Builder[CC, A] =
+ empty.newBuilder[A]
+
+ /** Create CC collection of specified elements */
+ override def apply[A](args: A*): CC[A] =
+ empty ++ args.asInstanceOf[Iterable[A]]
+}
diff --git a/src/library/scalax/collection/generic/Growable.scala b/src/library/scalax/collection/generic/Growable.scala
new file mode 100755
index 0000000000..960384f9d0
--- /dev/null
+++ b/src/library/scalax/collection/generic/Growable.scala
@@ -0,0 +1,58 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Iterable.scala 15188 2008-05-24 15:01:02Z stepancheg $
+
+package scalax.collection.generic
+
+/** This class represents collections that can be augmented using a += operator.
+ *
+ * @autor Martin Odersky
+ * @owner Martin Odersky
+ * @version 2.8
+ */
+trait Growable[A] {
+
+ /** Adds a single element to this collection.
+ *
+ * @param elem the element to add.
+ */
+ def +=(elem: A): Unit
+
+ /** Adds two or more elements to this collection.
+ *
+ * @param elem1 the first element to add.
+ * @param elem2 the second element to add.
+ * @param elems the remaining elements to add.
+ */
+ def +=(elem1: A, elem2: A, elems: A*) {
+ this += elem1
+ this += elem2
+ this ++= elems.asInstanceOf[Iterable[A]] // !@!
+ }
+
+ /** Adds a number of elements provided by an iterator to this collection.
+ *
+ * @param iter the iterator.
+ */
+ def ++=(iter: collection.Iterator[A]) { iter foreach += }
+
+ /** Adds a number of elements provided by an iterable object to this collection.
+ *
+ * @param iter the iterable object.
+ */
+ def ++=(iter: collection.Iterable[A]) { iter foreach += }
+
+ /** Clears the collection contents.
+ */
+ def clear()
+}
+
+
+
+
diff --git a/src/library/scalax/collection/generic/IterableFactory.scala b/src/library/scalax/collection/generic/IterableFactory.scala
index 9570970abe..0cf9c8ac95 100755
--- a/src/library/scalax/collection/generic/IterableFactory.scala
+++ b/src/library/scalax/collection/generic/IterableFactory.scala
@@ -8,7 +8,7 @@ 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
+ // can't have an empty here because it is defined in subclass EmptyIterableFactory with type
// CC[Nothing]. This type does not make sense for immutable iterables.
/** Concatenate all the argument lists into a single list.
@@ -88,10 +88,10 @@ trait IterableFactory[CC[A] <: Iterable[A]] {
* increasing n. If `step > 0` the sequence terminates
* with the largest value less than `end`. If `step < 0`
* the sequence terminates with the smallest value greater than `end`.
- * If `step == 0`, the sequence gors on infinitely (in that
- * case the `range` operation might not terminate.
+ * If `step == 0`, an IllegalArgumentException is thrown.
*/
def range(start: Int, end: Int, step: Int): CC[Int] = {
+ if (step == 0) throw new IllegalArgumentException("zero step")
val b = newBuilder[Int]
var i = start
while ((step <= 0 || i < end) && (step >= 0 || i > end)) {
diff --git a/src/library/scalax/collection/generic/IterableForwarder.scala b/src/library/scalax/collection/generic/IterableForwarder.scala
index 8613b18345..e38f030414 100644
--- a/src/library/scalax/collection/generic/IterableForwarder.scala
+++ b/src/library/scalax/collection/generic/IterableForwarder.scala
@@ -56,6 +56,4 @@ trait IterableForwarder[+A] extends Iterable[A] {
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/IterableTemplate.scala b/src/library/scalax/collection/generic/IterableTemplate.scala
index adbf5d2de7..cc562c308a 100755
--- a/src/library/scalax/collection/generic/IterableTemplate.scala
+++ b/src/library/scalax/collection/generic/IterableTemplate.scala
@@ -646,76 +646,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the
b.result
}
- /** The last element of this iterable.
- *
- * @throws Predef.NoSuchElementException if the iterable is empty.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def last: A = {
- var lst = head
- for (x <- this)
- lst = x
- lst
- }
-
- /** Returns as an option the last element of this iterable or
- * <code>None</code> if iterable is empty.
- *
- * @return the last element as an option.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- 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) {
- b += lst
- lst = x
- }
- b.result
- }
-
- /** Returns the rightmost <code>n</code> elements from this iterable.
- *
- * @param n the number of elements to take
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def takeRight(n: Int): CC[A] = {
- val b = newBuilder[A]
- val lead = elements drop n
- var go = false
- for (x <- this) {
- if (go) b += x
- else if (lead.hasNext) lead.next
- else go = true
- }
- b.result
- }
-
- /** Returns the iterable wihtout its rightmost <code>n</code> elements.
- *
- * @param n the number of elements to take
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def dropRight(n: Int): CC[A] = {
- val b = newBuilder[A]
- val lead = elements drop n
- breakable {
- for (x <- this) {
- if (!lead.hasNext) break
- lead.next
- b += x
- }
- }
- b.result
- }
-
/** Split the iterable at a given point and return the two parts thus
* created.
*
@@ -732,71 +662,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the
(l.result, r.result)
}
- /** Returns the longest prefix of this iterable whose elements satisfy
- * the predicate <code>p</code>.
- *
- * @param p the test predicate.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def takeWhile(p: A => Boolean): CC[A] = {
- val b = newBuilder[A]
- breakable {
- for (x <- this) {
- if (!p(x)) break
- b += x
- }
- }
- b.result
- }
-
- /** Returns the longest suffix of this iterable whose first element
- * does not satisfy the predicate <code>p</code>.
- *
- * @param p the test predicate.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def dropWhile(p: A => Boolean): CC[A] = {
- val b = newBuilder[A]
- var go = false
- for (x <- this) {
- if (go) b += x
- else if (!p(x)) { go = true; b += x }
- }
- b.result
- }
-
- /** 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 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]) = {
- val l, r = newBuilder[A]
- var toLeft = true
- for (x <- this) {
- toLeft = toLeft && p(x)
- (if (toLeft) l else r) += x
- }
- (l.result, r.result)
- }
-
- /** Checks if the other iterable object contains the same elements as this one.
- *
- * @note will not terminate for infinite-sized iterables.
- * @param that the other iterable
- * @return true, iff both iterables contain the same elements.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def sameElements[B >: A](that: OrderedIterable[B]): Boolean = {
- val these = this.elements
- val those = that.elements
- while (these.hasNext && those.hasNext && these.next() == those.next()) {}
- !these.hasNext && !those.hasNext
- }
-
/** A sub-iterable view starting at index `from`
* and extending up to (but not including) index `until`.
*
diff --git a/src/library/scalax/collection/generic/IterableView.scala b/src/library/scalax/collection/generic/IterableView.scala
index 45a0a50be2..bb111e2252 100755
--- a/src/library/scalax/collection/generic/IterableView.scala
+++ b/src/library/scalax/collection/generic/IterableView.scala
@@ -25,7 +25,7 @@ trait IterableView[+UC[/*+*/B] <: Iterable[B], /*+*/A] extends Iterable[A] { sel
case _ => origin
}
- private def isDelay = elements eq underlying.elements
+ protected def isDelay = elements eq underlying.elements
private[this] var forced: UC[A] = _
private[this] var wasForced = false
@@ -100,15 +100,6 @@ trait IterableView[+UC[/*+*/B] <: Iterable[B], /*+*/A] extends Iterable[A] { sel
/** Non-strict variant of @see Iterable.slice */
override def slice(from: Int, until: Int): IterableView[UC, A] = newView(elements slice (from, until))
- /** Non-strict variant of @see Iterable.takeWhile */
- override def takeWhile(p: A => Boolean): IterableView[UC, A] = newView(elements takeWhile p)
-
- /** Non-strict variant of @see Iterable.dropWhile */
- override def dropWhile(p: A => Boolean): IterableView[UC, A] = newView(elements dropWhile p)
-
- /** Non-strict variant of @see Iterable.span */
- override def span(p: A => Boolean): (IterableView[UC, A], IterableView[UC, A]) = (takeWhile(p), dropWhile(p))
-
/** The projection resulting from the concatenation of this projection with the <code>rest</code> projection.
* @param rest The projection that gets appended to this projection
* @deprecated Use ++ instead
diff --git a/src/library/scalax/collection/generic/LazyBuilder.scala b/src/library/scalax/collection/generic/LazyBuilder.scala
new file mode 100755
index 0000000000..74764351b6
--- /dev/null
+++ b/src/library/scalax/collection/generic/LazyBuilder.scala
@@ -0,0 +1,24 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: ListBuffer.scala 14378 2008-03-13 11:39:05Z dragos $
+
+package scalax.collection.generic
+
+import collection.mutable.ListBuffer
+import collection.immutable.{List, Nil, ::}
+
+abstract class LazyBuilder[+CC[B], A] extends Builder[CC, A] {
+ protected var parts = new ListBuffer[Iterator[A]]
+ def +=(x: A) = { parts += Iterator.single(x) }
+ override def ++=(xs: Iterator[A]) { parts += xs }
+ override def ++=(xs: Iterable[A]) { parts += xs.elements }
+ def elements: Iterator[A] = Iterator.iteratorIteratorWrapper(parts.elements).flatten // !!! can remove the wrapper once new compiler is in starr
+ def result: CC[A]
+ def clear() { parts.clear() }
+}
diff --git a/src/library/scalax/collection/generic/MapFactory.scala b/src/library/scalax/collection/generic/MapFactory.scala
new file mode 100755
index 0000000000..d7413b8928
--- /dev/null
+++ b/src/library/scalax/collection/generic/MapFactory.scala
@@ -0,0 +1,9 @@
+package scalax.collection.generic
+
+trait MapFactory[CC[A, B] <: MapTemplate[A, B, CC]] {
+
+ def empty[A, B]: CC[A, B]
+
+ def apply[A, B](elems: (A, B)*): CC[A, B] = empty[A, B] ++ elems.asInstanceOf[Iterable[(A, B)]] // !@!
+
+}
diff --git a/src/library/scalax/collection/generic/MapTemplate.scala b/src/library/scalax/collection/generic/MapTemplate.scala
new file mode 100755
index 0000000000..6d1a9e3c93
--- /dev/null
+++ b/src/library/scalax/collection/generic/MapTemplate.scala
@@ -0,0 +1,247 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Map.scala 16884 2009-01-09 16:52:09Z cunei $
+
+
+package scalax.collection.generic
+
+import collection.immutable.Set
+import collection.mutable.ArrayBuffer
+import annotation.unchecked.uncheckedVariance
+
+/** <p>
+* A map is a collection that maps each key to one or zero values.
+ * </p>
+ * <p>
+ * This trait provides a limited interface, only allowing reading of elements.
+ * There are two extensions of this trait, in packages
+ * <code><a href="mutable$content.html" target="contentFrame">
+ * scala.collection.mutable</a></code>
+ * and <code><a href="immutable$content.html" target="contentFrame">
+ * scala.collection.immutable</a></code>, which provide functionality for
+ * adding new key/value mappings to a map. The trait in the first package is
+ * for maps that are modified destructively, whereas the trait in
+ * the second package is for immutable maps which create a new map
+ * when something is added or removed from them.
+ * </p>
+ *
+ * @author Matthias Zenger
+ * @author Martin Odersky
+ * @version 1.2, 31/12/2006
+ */
+trait MapTemplate[A, B, +CC[A1, B1] <: Map[A1, B1] with MapTemplate[A1, B1, CC]]
+ extends PartialFunction[A, B]
+ with SizedIterable[(A, B)]
+ with Addable[CC[A, B], (A, B)]
+ with Subtractable[CC[A, B], A] {
+self: CC[A, B] =>
+
+ def newBuilder[B]: Builder[SizedIterable, B] = new ArrayBuffer[B]
+
+ override def thisCC: CC[A, B] = this
+
+ /** This method returns a new map instance of the same class
+ * mapping keys of the same type to values of type <code>C</code>.
+ */
+ def empty[C]: CC[A, C]
+
+ /** Compute the number of key-to-value mappings.
+ *
+ * @return the number of mappings
+ */
+ def size: Int
+
+ /** Check if this map maps <code>key</code> to a value and return the
+ * value if it exists.
+ *
+ * @param key the key of the mapping of interest
+ * @return the value of the mapping, if it exists
+ */
+ def get(key: A): Option[B]
+
+ /** Check if this map maps <code>key</code> to a value.
+ * Return that value if it exists, otherwise return <code>default</code>.
+ */
+ def getOrElse[B2 >: B](key: A, default: => B2): B2 =
+ get(key) match {
+ case Some(v) => v
+ case None => default
+ }
+
+ /** Is this an empty map?
+ *
+ * @return <code>true</code> iff the map is empty.
+ */
+ override def isEmpty: Boolean = size == 0
+
+ /** Retrieve the value which is associated with the given key. This
+ * method throws an exception if there is no mapping from the given
+ * key to a value.
+ *
+ * @param key the key
+ * @return the value associated with the given key.
+ */
+ def apply(key: A): B = get(key) match {
+ case None => default(key)
+ case Some(value) => value
+ }
+
+ /** Is the given key mapped to a value by this map?
+ *
+ * @param key the key
+ * @return <code>true</code> iff there is a mapping for key in this map
+ */
+ def contains(key: A): Boolean = get(key) match {
+ case None => false
+ case Some(_) => true
+ }
+
+ /** Does this map contain a mapping from the given key to a value?
+ *
+ * @param key the key
+ * @return <code>true</code> iff there is a mapping for key in this map
+ */
+ def isDefinedAt(key: A) = contains(key)
+
+ /** Creates an iterator for all keys.
+ *
+ * @return an iterator over all keys.
+ */
+ def keys: Iterator[A] = new Iterator[A] {
+ val iter = self.elements
+ def hasNext = iter.hasNext
+ def next = iter.next._1
+ }
+
+ /** @return the keys of this map as a set.
+ */
+ def keySet: Set[A] = new Set[A] {
+ def size = self.size
+ def contains(key : A) = self.contains(key)
+ def elements = self.elements.map(_._1)
+ def + (elem: A): Set[A] = immutable.Set[A]() ++ this + elem
+ def - (elem: A): Set[A] = immutable.Set[A]() ++ this - elem
+ override def newBuilder[B]: Builder[Set, B] = Set.newBuilder[B]
+ }
+
+ /** Creates an iterator for a contained values.
+ *
+ * @return an iterator over all values.
+ */
+ def values: Iterator[B] = new Iterator[B] {
+ val iter = self.elements
+ def hasNext = iter.hasNext
+ def next = iter.next._2
+ }
+
+ /** Creates a string representation for this map.
+ *
+ * @return a string showing all mappings
+ */
+ override def toString() =
+ elements.toList.map(kv => kv._1 + " -> " + kv._2).mkString(stringPrefix + "(", ", ", ")")
+
+ /** The default value for the map, returned when a key is not found
+ * The method implemented here yields an error,
+ * but it might be overridden in subclasses.
+ *
+ * @param key the given key value
+ * @throws Predef.NoSuchElementException
+ */
+ def default(key: A): B =
+ throw new NoSuchElementException("key not found: " + key)
+
+/*
+ override def view: Map.View[A,B] = new Map.View[A, B] {
+ override def elements = self.elements
+ override def size = self.size
+ override def get(key: A): Option[B] = self.get(key)
+ }
+*/
+ def filterKeys(p: A => Boolean) = new MapView[CC, A, B] {
+ val origin = self
+ override def foreach(f: ((A, B)) => Unit): Unit = for (kv <- self) if (p(kv._1)) f(kv)
+ def elements = self.elements.filter(kv => p(kv._1))
+ def size = { var sz = 0; foreach(_ => sz += 1); sz }
+ override def contains(key: A) = self.contains(key) && p(key)
+ def get(key: A) = if (!p(key)) None else self.get(key)
+ }
+
+ def mapElements[C](f: B => C) = new MapView[CC, A,C] {
+ val origin = self
+ override def foreach(g: ((A, C)) => Unit): Unit = for ((k, v) <- self) g((k, f(v)))
+ def elements = for ((k, v) <- self.elements) yield (k, f(v))
+ def size = self.size
+ override def contains(key: A) = self.contains(key)
+ def get(key: A) = self.get(key).map(f)
+ }
+
+ /** Defines the prefix of this object's <code>toString</code> representation.
+ */
+ override def stringPrefix: String = "Map"
+
+ /** Add a key/value pair to this map.
+ * @param key the key
+ * @param value the value
+ * @return A new map with the new binding added to this map
+ */
+ def update (key: A, value: B): CC[A, B]
+
+ /** Add a key/value pair to this map.
+ * @param kv the key/value pair.
+ * @return A new map with the new binding added to this map
+ */
+ def + (kv: (A, B)): CC[A, B] = update(kv._1, kv._2)
+
+ /** Remove a key from this map
+ * @param key the key to be removed
+ * @return If the map does not contain a binding for <code>key</code>
+ * it is returned unchanged. Otherwise, return a new map
+ * without a binding for <code>key</code>
+ */
+ def - (key: A): CC[A, B]
+
+ /** This function transforms all the values of mappings contained
+ * in this map with function <code>f</code>.
+ *
+ * @param f A function over keys and values
+ * @return the updated map
+ */
+ def transform[C](f: (A, B) => C): CC[A, C] = {
+ var res = empty[C]
+ for ((key, value) <- this) res += ((key, f(key, value)))
+ res
+ }
+
+ /** Builds a new map with all key/value pairs of this map
+ * for which the predicate <code>p</code> returns <code>true</code>.
+ *
+ * @param p A predicate over key-value pairs
+ * @return the updated map
+ */
+ override def filter(p: ((A, B)) => Boolean): CC[A, B] = {
+ var res = empty[B]
+ for (kv <- this)
+ if (p(kv)) res += kv
+ res
+ }
+
+ /** Removes all the mappings for which the predicate
+ * <code>p</code> returns <code>false</code>.
+ *
+ * @param p A predicate over key-value pairs
+ * @return the updated map
+ */
+ override def remove(p: ((A, B)) => Boolean): CC[A, B] = {
+ var res = this
+ for (kv <- this)
+ if (!p(kv)) res -= kv._1
+ res
+ }
+}
diff --git a/src/library/scalax/collection/generic/MapView.scala b/src/library/scalax/collection/generic/MapView.scala
new file mode 100644
index 0000000000..924fd1173e
--- /dev/null
+++ b/src/library/scalax/collection/generic/MapView.scala
@@ -0,0 +1,44 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Iterable.scala 15188 2008-05-24 15:01:02Z stepancheg $
+
+package scalax.collection.generic
+
+/** A non-strict view of a map.
+ * @author Martin Odersky
+ * @version 2.8
+ */
+trait MapView[+UC[A1, B1] <: MapTemplate[A1, B1, UC] with Map[A1, B1], A, B] extends Map[A, B] { self =>
+
+ val origin: Map[A, _]
+
+ def empty[C] = origin.empty[C]
+
+ def elements: Iterator[(A, B)]
+
+ val underlying: Map[A, _] = origin match {
+ case v: MapView[t, _, _] => v.underlying
+ case _ => origin
+ }
+ private[this] var forced: UC[A, B] = _
+ private[this] var wasForced = false
+
+ def force: UC[A, B] = {
+ if (!wasForced) {
+ forced = underlying.empty[B].asInstanceOf[UC[A, B]] ++ elements
+ wasForced = true
+ }
+ forced
+ }
+
+ def update (key: A, value: B): UC[A, B] = force update (key, value)
+ def - (key: A): UC[A, B] = force - key
+}
+
+
diff --git a/src/library/scalax/collection/generic/MutableVectorTemplate.scala b/src/library/scalax/collection/generic/MutableVectorTemplate.scala
new file mode 100755
index 0000000000..71c3f7bdf8
--- /dev/null
+++ b/src/library/scalax/collection/generic/MutableVectorTemplate.scala
@@ -0,0 +1,56 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2006-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Vector.scala 15437 2008-06-25 16:22:45Z stepancheg $
+
+package scalax.collection.generic
+
+import collection.mutable.Vector
+import collection.mutable.Vector._
+
+/** Sequences that support O(1) element access and O(1) length computation.
+ * plus an update operation.
+ * @author Sean McDirmid
+ * @author Martin Odersky
+ * @version 2.8
+ */
+trait MutableVectorTemplate[+CC[B] <: MutableVectorTemplate[CC, B] with Vector[B], A] extends VectorTemplate[CC, A] {
+self =>
+
+ def update(idx: Int, elem: A)
+
+ /** Creates a view of this iterable @see OrderedIterable.View
+ */
+ override def view: MutableVectorView[CC, A] = new MutableVectorView[CC, A] { // !!! Martin: We should maybe infer the type parameters here?
+ val origin: Vector[_] = thisCC
+ val length: Int = self.length
+ def apply(idx: Int): A = self.apply(idx)
+ def update(idx: Int, elem: A) = self.update(idx, elem)
+ }
+
+ /** A sub-sequence 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.
+ *
+ * @note view(from, to) is equivalent to view.slice(from, to)
+ */
+ override def view(from: Int, until: Int): MutableVectorView[CC, A] = view.slice(from, until)
+
+ def readOnly: collection.Vector[A] = new collection.Vector[A] { //!!! just use a VectorProxy?
+ def length = self.length
+ def apply(idx : Int) = self.apply(idx)
+ def newBuilder[B]: Builder[collection.Vector, B] = self.newBuilder[B] //mapResult (_.readOnly)
+ override def foreach(f: A => Unit) = self.foreach(f)
+ override def stringPrefix = self.stringPrefix+"RO"
+ }
+}
+
diff --git a/src/library/scalax/collection/generic/MutableVectorView.scala b/src/library/scalax/collection/generic/MutableVectorView.scala
new file mode 100755
index 0000000000..450943f61d
--- /dev/null
+++ b/src/library/scalax/collection/generic/MutableVectorView.scala
@@ -0,0 +1,95 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Sequence.scala 16092 2008-09-12 10:37:06Z nielsen $
+
+
+package scalax.collection.generic
+
+import collection.mutable.Vector
+import collection.mutable.Vector._
+
+/** A non-strict projection of an iterable.
+ * @author Sean McDirmid
+ * @author Martin Odersky
+ * @note this should really be a virtual class of SequenceFactory
+ */
+trait MutableVectorView[+UC[B] <: Vector[B], A] extends SequenceView[UC, A] with Vector[A] {
+self =>
+
+ /** refined from Iterable.View */
+ val origin: Vector[_]
+
+ trait Transformed[B] extends super.Transformed[B] with MutableVectorView[UC, B] {
+ override val origin = self
+ override def elements: Iterator[B] = new Elements(0, length)
+ override protected def asCC = asInstanceOf[MutableVectorView[UC, B]]
+ }
+
+ class Appended(that: Vector[A]) extends super.Appended[A](that) with Transformed[A] {
+ override def update(idx: Int, elem: A) {
+ val ll = self.length
+ if (idx < ll) self.update(idx, elem) else that.update(idx - ll, elem)
+ }
+ }
+
+ class Sliced(from: Int, to: Int) extends super.Sliced(from, to) with Transformed[A] {
+ override def update(idx: Int, elem: A) {
+ if (idx >= 0 && idx < length) self.update(idx + from, elem)
+ else throw new IndexOutOfBoundsException(idx.toString)
+ }
+ override def slice(from1: Int, to1: Int) =
+ new self.Sliced(from + (from1 min length max 0) , to + (to1 min length max 0))
+ }
+
+ class Reversed extends super.Reversed with Transformed[A] {
+ override def update(idx: Int, elem: A) {
+ self.update(length - 1 - idx, elem)
+ }
+ }
+
+ class Zipped[B](that: Vector[B]) extends super.Zipped[B](that) with Transformed[(A, B)] {
+ override def update(idx: Int, elem: (A, B)) {
+ self.update(idx, elem._1)
+ that.update(idx, elem._2)
+ }
+ }
+
+ def ++(that: Vector[A]): MutableVectorView[UC, A] =
+ new Appended(that).asCC
+
+ override def reverse: MutableVectorView[UC, A] =
+ (new Reversed).asCC
+
+ private def toVector[B](xs: Iterable[B]): Vector[B] = xs match {
+ case ras: Vector[_] => ras.asInstanceOf[Vector[B]]
+ case _ => Vector() ++ xs
+ }
+
+ override def zip[B](that: Iterable[B]): MutableVectorView[UC, (A, B)] =
+ new Zipped(toVector(that)).asCC
+
+ override def zipWithIndex: MutableVectorView[UC, (A, Int)] =
+ zip((0 until length).asInstanceOf[Null]) // !@!
+ override def take(n: Int): MutableVectorView[UC, A] =
+ slice(0, n)
+ override def drop(n: Int): MutableVectorView[UC, A] =
+ slice(n, Math.MAX_INT)
+ override def splitAt(n: Int): (MutableVectorView[UC, A], MutableVectorView[UC, A]) = (take(n), drop(n))
+ override def slice(from: Int, until: Int): MutableVectorView[UC, A] =
+ new Sliced(from, until).asCC
+ override def takeWhile(p: A => Boolean): MutableVectorView[UC, A] =
+ take(prefixLength(p))
+ override def dropWhile(p: A => Boolean): MutableVectorView[UC, A] =
+ drop(prefixLength(p))
+ override def span(p: A => Boolean): (MutableVectorView[UC, A], MutableVectorView[UC, A]) = {
+ val n = prefixLength(p)
+ (take(n), drop(n))
+ }
+}
+
diff --git a/src/library/scalax/collection/generic/OrderedIterableForwarder.scala b/src/library/scalax/collection/generic/OrderedIterableForwarder.scala
new file mode 100755
index 0000000000..643f31d861
--- /dev/null
+++ b/src/library/scalax/collection/generic/OrderedIterableForwarder.scala
@@ -0,0 +1,37 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: IterableProxy.scala 15458 2008-06-28 20:23:22Z stepancheg $
+
+
+package scalax.collection.generic
+
+/** 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 object of the same kind
+ *
+ * The above methods are forwarded by subclass IterableProxy
+ *
+ * @author Martin Odersky
+ * @version 2.8
+ */
+trait OrderedIterableForwarder[+A] extends OrderedIterable[A] with IterableForwarder[A] {
+
+ /** The iterable object to which calls are forwarded */
+ protected def underlying: OrderedIterable[A]
+
+ // Iterable delegates
+ // Iterable methods could be printed by cat IterableTemplate.scala | sed -n '/trait Iterable/,$ p' | egrep '^ (override )?def'
+
+ override def last: A = underlying.last
+ override def lastOption: Option[A] = underlying.lastOption
+ override def sameElements[B >: A](that: OrderedIterable[B]): Boolean = underlying.sameElements(that)
+}
diff --git a/src/library/scalax/collection/generic/OrderedIterableTemplate.scala b/src/library/scalax/collection/generic/OrderedIterableTemplate.scala
index 9e61daa418..501cbf6447 100755
--- a/src/library/scalax/collection/generic/OrderedIterableTemplate.scala
+++ b/src/library/scalax/collection/generic/OrderedIterableTemplate.scala
@@ -13,6 +13,8 @@ package scalax.collection.generic
import OrderedIterable._
+import util.control.Breaks._
+
/** 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`:
@@ -20,4 +22,140 @@ import OrderedIterable._
* `(xs ++ ys).elements = xs.elements ++ ys.elements
*/
trait OrderedIterableTemplate[+CC[/*+*/B] <: OrderedIterableTemplate[CC, B] with OrderedIterable[B], /*+*/A]
- extends IterableTemplate[CC, A]
+ extends IterableTemplate[CC, A] {
+
+ /** The last element of this iterable.
+ *
+ * @throws Predef.NoSuchElementException if the iterable is empty.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def last: A = {
+ var lst = head
+ for (x <- this)
+ lst = x
+ lst
+ }
+
+ /** Returns as an option the last element of this iterable or
+ * <code>None</code> if iterable is empty.
+ *
+ * @return the last element as an option.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ 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) {
+ b += lst
+ lst = x
+ }
+ b.result
+ }
+
+ /** Returns the rightmost <code>n</code> elements from this iterable.
+ *
+ * @param n the number of elements to take
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def takeRight(n: Int): CC[A] = {
+ val b = newBuilder[A]
+ val lead = elements drop n
+ var go = false
+ for (x <- this) {
+ if (go) b += x
+ else if (lead.hasNext) lead.next
+ else go = true
+ }
+ b.result
+ }
+
+ /** Returns the iterable wihtout its rightmost <code>n</code> elements.
+ *
+ * @param n the number of elements to take
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def dropRight(n: Int): CC[A] = {
+ val b = newBuilder[A]
+ val lead = elements drop n
+ breakable {
+ for (x <- this) {
+ if (!lead.hasNext) break
+ lead.next
+ b += x
+ }
+ }
+ b.result
+ }
+
+ /** Returns the longest prefix of this iterable whose elements satisfy
+ * the predicate <code>p</code>.
+ *
+ * @param p the test predicate.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def takeWhile(p: A => Boolean): CC[A] = {
+ val b = newBuilder[A]
+ breakable {
+ for (x <- this) {
+ if (!p(x)) break
+ b += x
+ }
+ }
+ b.result
+ }
+
+ /** Returns the longest suffix of this iterable whose first element
+ * does not satisfy the predicate <code>p</code>.
+ *
+ * @param p the test predicate.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def dropWhile(p: A => Boolean): CC[A] = {
+ val b = newBuilder[A]
+ var go = false
+ for (x <- this) {
+ if (go) b += x
+ else if (!p(x)) { go = true; b += x }
+ }
+ b.result
+ }
+
+ /** 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 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]) = {
+ val l, r = newBuilder[A]
+ var toLeft = true
+ for (x <- this) {
+ toLeft = toLeft && p(x)
+ (if (toLeft) l else r) += x
+ }
+ (l.result, r.result)
+ }
+
+ /** Checks if the other iterable object contains the same elements as this one.
+ *
+ * @note will not terminate for infinite-sized iterables.
+ * @param that the other iterable
+ * @return true, iff both iterables contain the same elements.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def sameElements[B >: A](that: OrderedIterable[B]): Boolean = {
+ val these = this.elements
+ val those = that.elements
+ while (these.hasNext && those.hasNext && these.next() == those.next()) {}
+ !these.hasNext && !those.hasNext
+ }
+}
diff --git a/src/library/scalax/collection/generic/OrderedIterableView.scala b/src/library/scalax/collection/generic/OrderedIterableView.scala
new file mode 100755
index 0000000000..fd04daa0b6
--- /dev/null
+++ b/src/library/scalax/collection/generic/OrderedIterableView.scala
@@ -0,0 +1,85 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Iterable.scala 15188 2008-05-24 15:01:02Z stepancheg $
+
+package scalax.collection.generic
+
+/** A non-strict projection of an iterable.
+ * @author Sean McDirmid
+ * @author Martin Odersky
+ * @note this should really be a virtual class of SequenceFactory
+ */
+trait OrderedIterableView[+UC[/*+*/B] <: Iterable[B], /*+*/A] extends IterableView[UC, A] with OrderedIterable[A] { self =>
+
+ val origin: OrderedIterable[_]
+
+ /** Builds a new view object. This method needs to be overridden in subclasses
+ * which refine in IterableView type
+ */
+ protected override def newView[B](elems: Iterator[B]) = new OrderedIterableView[UC, B] {
+ val origin = if (self.isDelay) self.origin else self
+ val elements = elems
+ }
+
+ /** Non-strict variant of @see IterableLike.++ */
+ override def ++[B >: A](that: Iterator[B]): OrderedIterableView[UC, B] = newView(elements ++ that)
+
+ /** Non-strict variant of @see IterableLike.++ */
+ override def ++[B >: A](that: Iterable[B]): OrderedIterableView[UC, B] = newView(elements ++ that.elements)
+
+ /** Non-strict variant of @see IterableLike.map */
+ override def map[B](f: A => B): OrderedIterableView[UC, B] = newView(elements map f)
+
+ /** Non-strict variant of @see IterableLike.flatMap */
+ override def flatMap[B](f: A => Iterable[B]): OrderedIterableView[UC, B] = newView(elements flatMap (f(_).elements))
+
+ /** Non-strict variant of @see IterableLike.filter */
+ override def filter(p: A => Boolean): OrderedIterableView[UC, A] = newView(elements filter p)
+
+ /** Non-strict variant of @see IterableLike.partition */
+ override def partition(p: A => Boolean): (OrderedIterableView[UC, A], OrderedIterableView[UC, A]) = {
+ val (li, ri) = elements partition p
+ (newView(li), newView(ri))
+ }
+
+ /** Non-strict variant of @see IterableLike.zip */
+ override def zip[B](other: Iterable[B]): OrderedIterableView[UC, (A, B)] = newView(elements zip other.elements)
+
+ /** Non-strict variant of @see IterableLike.zipWithIndex */
+ override def zipWithIndex: OrderedIterableView[UC, (A, Int)] = newView(elements.zipWithIndex)
+
+ /* Non-strict variant of @see IterableLike.zipAll
+ * This is not enabled because it can't be specialized in VectorView:
+ * VectorView is not covariant, yet must maintain updatability. Impossible to do this
+ * with this type signature.
+ override def zipAll[B, A1 >: A, B1 >: B](that: Iterable[B], thisElem: A1, thatElem: B1): OrderedIterableView[UC, (A1, B1)] =
+ newView(elements zipAll (that.elements, thisElem, thatElem))
+ */
+
+ /** Non-strict variant of @see Iterable.take */
+ override def take(n: Int): OrderedIterableView[UC, A] = newView(elements take n)
+
+ /** Non-strict variant of @see Iterable.drop */
+ override def drop(n: Int): OrderedIterableView[UC, A] = newView(elements drop n)
+
+ /** Non-strict variant of @see Iterable.splitAt */
+ override def splitAt(n: Int): (OrderedIterableView[UC, A], OrderedIterableView[UC, A]) = (take(n), drop(n))
+
+ /** Non-strict variant of @see Iterable.slice */
+ override def slice(from: Int, until: Int): OrderedIterableView[UC, A] = newView(elements slice (from, until))
+
+ /** Non-strict variant of @see Iterable.takeWhile */
+ override def takeWhile(p: A => Boolean): OrderedIterableView[UC, A] = newView(elements takeWhile p)
+
+ /** Non-strict variant of @see Iterable.dropWhile */
+ override def dropWhile(p: A => Boolean): OrderedIterableView[UC, A] = newView(elements dropWhile p)
+
+ /** Non-strict variant of @see Iterable.span */
+ override def span(p: A => Boolean): (OrderedIterableView[UC, A], OrderedIterableView[UC, A]) = (takeWhile(p), dropWhile(p))
+}
diff --git a/src/library/scalax/collection/generic/SetFactory.scala b/src/library/scalax/collection/generic/SetFactory.scala
index 0fbcf68466..458d4bbade 100644
--- a/src/library/scalax/collection/generic/SetFactory.scala
+++ b/src/library/scalax/collection/generic/SetFactory.scala
@@ -6,4 +6,6 @@ trait SetFactory[CC[A] <: SetTemplate[CC, A] with Set[A]] extends IterableFactor
def apply[A](elems: A*): CC[A] = empty[A] ++ elems.asInstanceOf[Iterable[A]] // !@!
+ override def newBuilder[B]: Builder[CC, B] = new AddableBuilder[CC, B](empty)
+
}
diff --git a/src/library/scalax/collection/generic/SetTemplate.scala b/src/library/scalax/collection/generic/SetTemplate.scala
index 9c3056cc04..bd94f10fc0 100755
--- a/src/library/scalax/collection/generic/SetTemplate.scala
+++ b/src/library/scalax/collection/generic/SetTemplate.scala
@@ -31,7 +31,12 @@ package scalax.collection.generic
* @author Martin Odersky
* @version 2.8
*/
-trait SetTemplate[+CC[B] <: SetTemplate[CC, B] with Set[B], A] extends (A => Boolean) with SizedIterable[A] with OrderedIterableTemplate[CC, A] {
+trait SetTemplate[+CC[B] <: SetTemplate[CC, B] with Set[B], A]
+ extends (A => Boolean)
+ with SizedIterable[A]
+ with IterableTemplate[CC, A]
+ with Addable[CC[A], A]
+ with Subtractable[CC[A], A] {
/** Returns the number of elements in this set.
*
@@ -52,13 +57,13 @@ trait SetTemplate[+CC[B] <: SetTemplate[CC, B] with Set[B], A] extends (A => Boo
/** Create a new set with an additional element.
*/
- def +(elem: A): CC[A]
+ def + (elem: A): CC[A]
/** Remove a single element from a set.
* @param elem the element to be removed
* @return a new set with the element removed.
*/
- def -(elem: A): CC[A]
+ def - (elem: A): CC[A]
/** Checks if this set is empty.
*
@@ -76,43 +81,6 @@ trait SetTemplate[+CC[B] <: SetTemplate[CC, B] with Set[B], A] extends (A => Boo
*/
def apply(elem: A): Boolean = contains(elem)
- /** Add two or more elements to this set.
- * @param elem1 the first element.
- * @param elem2 the second element.
- * @param elems the remaining elements.
- * @return a new set with the elements added.
- */
- def + (elem1: A, elem2: A, elems: A*): CC[A] = {
- thisCC + elem1 + elem2 ++ elems.asInstanceOf[Iterable[A]]
- }
-
- /** Remove two or more elements from this set.
- *
- * @param elem1 the first element.
- * @param elem2 the second element.
- * @param elems the remaining elements.
- * @return a new set with the elements removed.
- */
- def - (elem1: A, elem2: A, elems: A*): CC[A] =
- this - elem1 - elem2 -- elems.asInstanceOf[Iterable[A]]
-
- /** Remove all the elements provided by an iterator
- * of the iterable object <code>elems</code> from the set.
- *
- * @param elems An iterable object containing the elements to remove from the set.
- * @return a new set with the elements removed.
- */
- def -- (elems: Iterable[A]): CC[A] = this -- elems.elements
-
- /** Remove all the elements provided by an iterator
- * <code>elems</code> from the set.
- *
- * @param elems An iterator containing the elements to remove from the set.
- * @return a new set with the elements removed.
- */
- def -- (elems: Iterator[A]): CC[A] =
- (thisCC /: elems) (_ - _)
-
/** This method computes an intersection with set <code>that</code>.
* It removes all the elements that are not present in <code>that</code>.
*
@@ -137,6 +105,9 @@ trait SetTemplate[+CC[B] <: SetTemplate[CC, B] with Set[B], A] extends (A => Boo
*/
def subsetOf(that: Set[A]): Boolean = forall(that.contains)
+/* What a mess! We need to remove these methods, but can't without breaking
+ * existing code. What to do?
+
/** Compares this set with another object and returns true, iff the
* other object is also a set which contains the same elements as
* this set.
@@ -156,18 +127,22 @@ trait SetTemplate[+CC[B] <: SetTemplate[CC, B] with Set[B], A] extends (A => Boo
false
}
- /* @deprecated hashCode is not stable for mutable sets.
- * if you intend to have object identity hashCode and wish the deprecated warning
+ /* @deprecated Since the previous hashCode is not stable for mutable sets,
+ * the implementation of this method has been changed to
+ * standard address-based hashCode from java.lang.Object.
+ * If you relied on the old behavior, y
+ * IT has been
+ * if you intend to have object identity hashCode and wish the deprecated warning
* to go away, cast this set to AnyRef before calling hashCode.
*/
@deprecated override def hashCode() =
(0 /: this)((hash, e) => hash + e.hashCode())
-
+*/
/** Defines the prefix of this object's <code>toString</code> representation.
*/
override def stringPrefix: String = "Set"
/** Need to override string, so that it's not the Function1's string that gets mixed in.
*/
- override def toString = super[OrderedIterableTemplate].toString
+ override def toString = super[IterableTemplate].toString
}
diff --git a/src/library/scalax/collection/generic/Shrinkable.scala b/src/library/scalax/collection/generic/Shrinkable.scala
new file mode 100755
index 0000000000..e6d3b085f3
--- /dev/null
+++ b/src/library/scalax/collection/generic/Shrinkable.scala
@@ -0,0 +1,54 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Iterable.scala 15188 2008-05-24 15:01:02Z stepancheg $
+
+package scalax.collection.generic
+
+/** This class represents collections that can be reduced using a -= operator.
+ *
+ * @autor Martin Odersky
+ * @owner Martin Odersky
+ * @version 2.8
+ */
+trait Shrinkable[A] {
+
+ /** Removes a single element from this collection.
+ *
+ * @param elem the element to remove.
+ */
+ def -=(elem: A): Unit
+
+ /** Removes two or more elements from this collection.
+ *
+ * @param elem1 the first element to remove.
+ * @param elem2 the second element to remove.
+ * @param elems the remaining elements to remove.
+ */
+ def -=(elem1: A, elem2: A, elems: A*) {
+ this -= elem1
+ this -= elem2
+ this --= elems.asInstanceOf[Iterable[A]] // !@!
+ }
+
+ /** Removes a number of elements provided by an iterator from this collection.
+ *
+ * @param iter the iterator.
+ */
+ def --=(iter: collection.Iterator[A]) { iter foreach -= }
+
+ /** Removes a number of elements provided by an iterable object from this collection.
+ *
+ * @param iter the iterable object.
+ */
+ def --=(iter: collection.Iterable[A]) { iter foreach -= }
+}
+
+
+
+
diff --git a/src/library/scalax/collection/generic/Subtractable.scala b/src/library/scalax/collection/generic/Subtractable.scala
new file mode 100755
index 0000000000..93fe2f8190
--- /dev/null
+++ b/src/library/scalax/collection/generic/Subtractable.scala
@@ -0,0 +1,64 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: Iterable.scala 15188 2008-05-24 15:01:02Z stepancheg $
+
+package scalax.collection.generic
+
+/** This class represents collections that can be reduced using a -= operator.
+ *
+ * @autor Martin Odersky
+ * @owner Martin Odersky
+ * @version 2.8
+ */
+trait Subtractable[+C <: Subtractable[C, A], A] {
+
+ protected def thisCC: C
+
+ /** Removes a single element from this collection and returns
+ * either the collection itself (if it is mutable), or a new collection
+ * with the removed element.
+ *
+ * @param elem the element to remove.
+ */
+ def -(elem: A): C
+
+ /** Removes two or more elements from this collection and returns
+ * either the collection itself (if it is mutable), or a new collection
+ * with the removed elements.
+ *
+ * @param elem1 the first element to remove.
+ * @param elem2 the second element to remove.
+ * @param elems the remaining elements to remove.
+ */
+ def -(elem1: A, elem2: A, elems: A*): C =
+ thisCC - elem1 - elem2 -- elems.asInstanceOf[Iterable[A]] // !@!
+
+ /** Removes a number of elements provided by an iterable object
+ * via its <code>elements</code> method and returns
+ * either the collection itself (if it is mutable), or a new collection
+ * with the removed elements.
+ *
+ * @param iter the iterable object.
+ */
+ def --(iter: Iterable[A]): C = (thisCC /: iter) (_ - _)
+
+ /** Removes a number of elements provided by an iterator
+ * via its <code>elements</code> method and returns
+ * either the collection itself (if it is mutable), or a new collection
+ * with the removed elements.
+ *
+ * @param iter the iterator
+ */
+ def --(iter: Iterator[A]): C = (thisCC /: iter) (_ - _)
+
+}
+
+
+
+
diff --git a/src/library/scalax/collection/generic/covartest/IterableForwarder.scala b/src/library/scalax/collection/generic/covartest/IterableForwarder.scala
index cd4a754e97..58290cfc68 100755
--- a/src/library/scalax/collection/generic/covartest/IterableForwarder.scala
+++ b/src/library/scalax/collection/generic/covartest/IterableForwarder.scala
@@ -56,6 +56,4 @@ trait IterableForwarder[+A] extends Iterable[A] {
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 27772b2ece..791d698a75 100755
--- a/src/library/scalax/collection/generic/covartest/IterableTemplate.scala
+++ b/src/library/scalax/collection/generic/covartest/IterableTemplate.scala
@@ -56,6 +56,11 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
*/
def newBuilder[B]: Builder[CC, B]
+ /** Create a new builder for this IterableType
+ * with a hint what that its size should be size `sizeHint`
+ */
+ def newBuilder[B](sizeHint: Int): Builder[CC, B] = newBuilder[B]
+
/** Is this collection empty? */
def isEmpty: Boolean = !elements.hasNext
@@ -65,7 +70,7 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
*/
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 +80,7 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
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 +90,12 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
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 +104,11 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
}
/** 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 +116,10 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
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 +133,7 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
* 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 +208,8 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
* 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 +228,10 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
* 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 +241,40 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
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 +294,8 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
/** 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 +307,7 @@ trait IterableTemplate[+CC[+B] <: IterableTemplate[CC, B] with Iterable[B], +A]
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 +375,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 +397,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.
@@ -431,7 +450,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>&lt;(e1: a, e2: a) =&gt; Boolean</code>.
* @ex <pre>
* List("Steve", "Tom", "John", "Bob")
@@ -454,7 +473,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 +485,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 +492,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 +501,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 +516,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>,
@@ -547,7 +547,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the
string
}
-
/** Creates a view of this iterable @see IterableView
*/
def view: IterableView[CC, A] = new IterableView[CC, A] { // !!! Martin: We should maybe infer the type parameters here?
@@ -557,10 +556,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 +573,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 +588,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] = {
@@ -648,74 +646,6 @@ b * @param thatElem element <code>thatElem</code> is used to fill up the
b.result
}
- /** The last element of this iterable.
- *
- * @throws Predef.NoSuchElementException if the sequence is empty.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def last: A = {
- var lst = head
- for (x <- this)
- lst = x
- lst
- }
-
- /** Returns as an option the last element of this iterable or
- * <code>None</code> if iterable is empty.
- *
- * @return the last element as an option.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def lastOption: Option[A] = if (isEmpty) None else Some(last)
-
- /** An iterable consisting of all elements of this iterable except the last one.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def init: CC[A] = {
- var lst = head
- val b = newBuilder[A]
- for (x <- this) {
- b += lst
- lst = x
- }
- b.result
- }
-
- /** Returns the rightmost <code>n</code> elements from this iterable.
- *
- * @param n the number of elements to take
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def takeRight(n: Int): CC[A] = {
- val b = newBuilder[A]
- val lead = elements drop n
- var go = false
- for (x <- this) {
- if (go) b += x
- else if (lead.hasNext) lead.next
- else go = true
- }
- b.result
- }
-
- /** Returns the iterable wihtout its rightmost <code>n</code> elements.
- *
- * @param n the number of elements to take
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def dropRight(n: Int): CC[A] = {
- val b = newBuilder[A]
- val lead = elements drop n
- breakable {
- for (x <- this) {
- if (!lead.hasNext) break
- lead.next
- b += x
- }
- }
- b.result
- }
-
/** Split the iterable at a given point and return the two parts thus
* created.
*
@@ -732,82 +662,13 @@ 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
- * 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] = {
- val b = newBuilder[A]
- breakable {
- for (x <- this) {
- if (!p(x)) break
- b += x
- }
- }
- b.result
- }
-
- /** Returns the longest suffix of this sequence 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] = {
- val b = newBuilder[A]
- var go = false
- for (x <- this) {
- if (go) b += x
- else if (!p(x)) { go = true; b += x }
- }
- 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.
- *
- * @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.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def span(p: A => Boolean): (CC[A], CC[A]) = {
- val l, r = newBuilder[A]
- var toLeft = true
- for (x <- this) {
- toLeft = toLeft && p(x)
- (if (toLeft) l else r) += x
- }
- (l.result, r.result)
- }
-
- /** Checks if the other iterable object contains the same elements as this one.
- *
- * @note will not terminate for infinite-sized iterables.
- * @param that the other iterable
- * @return true, iff both iterables contain the same elements.
- * @note Might return different results for different runs, unless this iterable is ordered
- */
- def sameElements[B >: A](that: OrderedIterable[B]): Boolean = {
- val these = this.elements
- val those = that.elements
- while (these.hasNext && those.hasNext && these.next() == those.next()) {}
- !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/covartest/IterableView.scala b/src/library/scalax/collection/generic/covartest/IterableView.scala
index 855e4d259b..43a1f68dc0 100755
--- a/src/library/scalax/collection/generic/covartest/IterableView.scala
+++ b/src/library/scalax/collection/generic/covartest/IterableView.scala
@@ -25,7 +25,7 @@ trait IterableView[+UC[+B] <: Iterable[B], +A] extends Iterable[A] { self =>
case _ => origin
}
- private def isDelay = elements eq underlying.elements
+ protected def isDelay = elements eq underlying.elements
private[this] var forced: UC[A] = _
private[this] var wasForced = false
@@ -100,15 +100,6 @@ trait IterableView[+UC[+B] <: Iterable[B], +A] extends Iterable[A] { self =>
/** Non-strict variant of @see Iterable.slice */
override def slice(from: Int, until: Int): IterableView[UC, A] = newView(elements slice (from, until))
- /** Non-strict variant of @see Iterable.takeWhile */
- override def takeWhile(p: A => Boolean): IterableView[UC, A] = newView(elements takeWhile p)
-
- /** Non-strict variant of @see Iterable.dropWhile */
- override def dropWhile(p: A => Boolean): IterableView[UC, A] = newView(elements dropWhile p)
-
- /** Non-strict variant of @see Iterable.span */
- override def span(p: A => Boolean): (IterableView[UC, A], IterableView[UC, A]) = (takeWhile(p), dropWhile(p))
-
/** The projection resulting from the concatenation of this projection with the <code>rest</code> projection.
* @param rest The projection that gets appended to this projection
* @deprecated Use ++ instead
diff --git a/src/library/scalax/collection/generic/covartest/OrderedIterableForwarder.scala b/src/library/scalax/collection/generic/covartest/OrderedIterableForwarder.scala
new file mode 100755
index 0000000000..3a33dc6694
--- /dev/null
+++ b/src/library/scalax/collection/generic/covartest/OrderedIterableForwarder.scala
@@ -0,0 +1,37 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+// $Id: IterableProxy.scala 15458 2008-06-28 20:23:22Z stepancheg $
+
+
+package scalax.collection.generic.covartest
+
+/** 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 object of the same kind
+ *
+ * The above methods are forwarded by subclass IterableProxy
+ *
+ * @author Martin Odersky
+ * @version 2.8
+ */
+trait OrderedIterableForwarder[+A] extends OrderedIterable[A] with IterableForwarder[A] {
+
+ /** The iterable object to which calls are forwarded */
+ protected def underlying: OrderedIterable[A]
+
+ // Iterable delegates
+ // Iterable methods could be printed by cat IterableTemplate.scala | sed -n '/trait Iterable/,$ p' | egrep '^ (override )?def'
+
+ override def last: A = underlying.last
+ override def lastOption: Option[A] = underlying.lastOption
+ override def sameElements[B >: A](that: OrderedIterable[B]): Boolean = underlying.sameElements(that)
+}
diff --git a/src/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala b/src/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala
index 4316c9b34d..f3c509887c 100755
--- a/src/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala
+++ b/src/library/scalax/collection/generic/covartest/OrderedIterableTemplate.scala
@@ -13,6 +13,8 @@ package scalax.collection.generic.covartest
import OrderedIterable._
+import util.control.Breaks._
+
/** 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`:
@@ -20,4 +22,140 @@ import OrderedIterable._
* `(xs ++ ys).elements = xs.elements ++ ys.elements
*/
trait OrderedIterableTemplate[+CC[+B] <: OrderedIterableTemplate[CC, B] with OrderedIterable[B], +A]
- extends IterableTemplate[CC, A]
+ extends IterableTemplate[CC, A] {
+
+ /** The last element of this iterable.
+ *
+ * @throws Predef.NoSuchElementException if the iterable is empty.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def last: A = {
+ var lst = head
+ for (x <- this)
+ lst = x
+ lst
+ }
+
+ /** Returns as an option the last element of this iterable or
+ * <code>None</code> if iterable is empty.
+ *
+ * @return the last element as an option.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ 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) {
+ b += lst
+ lst = x
+ }
+ b.result
+ }
+
+ /** Returns the rightmost <code>n</code> elements from this iterable.
+ *
+ * @param n the number of elements to take
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def takeRight(n: Int): CC[A] = {
+ val b = newBuilder[A]
+ val lead = elements drop n
+ var go = false
+ for (x <- this) {
+ if (go) b += x
+ else if (lead.hasNext) lead.next
+ else go = true
+ }
+ b.result
+ }
+
+ /** Returns the iterable wihtout its rightmost <code>n</code> elements.
+ *
+ * @param n the number of elements to take
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def dropRight(n: Int): CC[A] = {
+ val b = newBuilder[A]
+ val lead = elements drop n
+ breakable {
+ for (x <- this) {
+ if (!lead.hasNext) break
+ lead.next
+ b += x
+ }
+ }
+ b.result
+ }
+
+ /** Returns the longest prefix of this iterable whose elements satisfy
+ * the predicate <code>p</code>.
+ *
+ * @param p the test predicate.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def takeWhile(p: A => Boolean): CC[A] = {
+ val b = newBuilder[A]
+ breakable {
+ for (x <- this) {
+ if (!p(x)) break
+ b += x
+ }
+ }
+ b.result
+ }
+
+ /** Returns the longest suffix of this iterable whose first element
+ * does not satisfy the predicate <code>p</code>.
+ *
+ * @param p the test predicate.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def dropWhile(p: A => Boolean): CC[A] = {
+ val b = newBuilder[A]
+ var go = false
+ for (x <- this) {
+ if (go) b += x
+ else if (!p(x)) { go = true; b += x }
+ }
+ b.result
+ }
+
+ /** 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 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]) = {
+ val l, r = newBuilder[A]
+ var toLeft = true
+ for (x <- this) {
+ toLeft = toLeft && p(x)
+ (if (toLeft) l else r) += x
+ }
+ (l.result, r.result)
+ }
+
+ /** Checks if the other iterable object contains the same elements as this one.
+ *
+ * @note will not terminate for infinite-sized iterables.
+ * @param that the other iterable
+ * @return true, iff both iterables contain the same elements.
+ * @note Might return different results for different runs, unless this iterable is ordered
+ */
+ def sameElements[B >: A](that: OrderedIterable[B]): Boolean = {
+ val these = this.elements
+ val those = that.elements
+ while (these.hasNext && those.hasNext && these.next() == those.next()) {}
+ !these.hasNext && !those.hasNext
+ }
+}
diff --git a/src/library/scalax/collection/generic/covartest/SequenceForwarder.scala b/src/library/scalax/collection/generic/covartest/SequenceForwarder.scala
index 5ada55f62d..47c512545d 100644
--- a/src/library/scalax/collection/generic/covartest/SequenceForwarder.scala
+++ b/src/library/scalax/collection/generic/covartest/SequenceForwarder.scala
@@ -23,7 +23,7 @@ package scalax.collection.generic.covartest
* @author Martin Odersky
* @version 2.8
*/
-trait SequenceForwarder[+A] extends Sequence[A] with IterableForwarder[A] {
+trait SequenceForwarder[+A] extends Sequence[A] with OrderedIterableForwarder[A] {
protected override def underlying: Sequence[A]