diff options
-rw-r--r-- | src/library/scala/CollectionProxy.scala | 56 | ||||
-rw-r--r-- | src/library/scala/Enumeration.scala | 149 | ||||
-rw-r--r-- | src/library/scala/Iterable.scala | 76 | ||||
-rw-r--r-- | src/library/scala/Seq.scala | 3 | ||||
-rw-r--r-- | src/library/scala/collection/immutable/BitEnumeration.scala | 198 | ||||
-rw-r--r-- | src/library/scala/collection/jcl/Collection.scala | 2 | ||||
-rw-r--r-- | src/library/scala/collection/jcl/Map.scala | 10 | ||||
-rw-r--r-- | src/library/scala/collection/jcl/MapWrapper.scala | 1 | ||||
-rw-r--r-- | src/library/scala/collection/jcl/MutableIterable.scala | 23 | ||||
-rw-r--r-- | src/library/scala/collection/jcl/MutableSeq.scala | 3 | ||||
-rw-r--r-- | src/library/scala/collection/jcl/SortedMap.scala | 20 | ||||
-rw-r--r-- | src/library/scala/collection/jcl/Tests.scala | 2 | ||||
-rw-r--r-- | src/library/scala/collection/mutable/History.scala | 4 |
13 files changed, 314 insertions, 233 deletions
diff --git a/src/library/scala/CollectionProxy.scala b/src/library/scala/CollectionProxy.scala new file mode 100644 index 0000000000..5c46e6a1e7 --- /dev/null +++ b/src/library/scala/CollectionProxy.scala @@ -0,0 +1,56 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id: IterableProxy.scala 10572 2007-03-30 06:23:12Z mcdirmid $ + + +package scala + +import scala.collection.mutable.Buffer +import scala.compat.StringBuilder + + +/** This class implements a proxy for iterable objects. It forwards + * all calls to a different iterable object. + * + * @author Matthias Zenger + * @author Martin Odersky + * @version 2.0, 31/12/2006 + */ +trait CollectionProxy[+A] extends Collection[A] with IterableProxy[A] { + + def self: Collection[A] + override def size = self.size + @deprecated override def toArray[B >: A] : Array[B] = self.toArray +/* + override def elements: Iterator[A] = self.elements + override def map[B](f: A => B): Collection[B] = self map f + override def flatMap[B](f: A => Collection[B]): Collection[B] = self flatMap f + override def filter(p: A => Boolean): Collection[A] = self filter p + override def takeWhile(p: A => Boolean): Collection[A] = self takeWhile p + override def dropWhile(p: A => Boolean): Collection[A] = self dropWhile p + override def drop(n: Int): Collection[A] = self drop n + override def foreach(f: A => Unit): Unit = self foreach f + override def forall(p: A => Boolean): Boolean = self forall p + override def exists(p: A => Boolean): Boolean = self exists p + override def find(p: A => Boolean): Option[A] = self find p + override def findIndexOf(p: A => Boolean): Int = self findIndexOf p + override def indexOf[B >: A](elem: B): Int = self indexOf elem + override def foldLeft[B](z: B)(op: (B, A) => B): B = (self foldLeft z)(op) + override def foldRight[B](z: B)(op: (A, B) => B): B = (self foldRight z)(op) + override def /:[B](z: B)(op: (B, A) => B): B = (z /: self)(op) + override def :\[B](z: B)(op: (A, B) => B): B = (self :\ z)(op) + override def reduceLeft[B >: A](op: (B, B) => B): B = self reduceLeft op + override def reduceRight[B >: A](op: (B, B) => B): B = self reduceRight op + override def sameElements[B >: A](that: Iterable[B]): Boolean = self sameElements that + override def copyToBuffer[B >: A](dest: Buffer[B]): Unit = self copyToBuffer dest + override def toList: List[A] = self.toList + override def mkString(start: String, sep: String, end: String): String = self.mkString(start, sep, end) + override def addString(buf: StringBuilder, start: String, sep: String, end: String): StringBuilder = self.addString(buf, start, sep, end) + */ +} diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala index d7d02e210b..d377f72890 100644 --- a/src/library/scala/Enumeration.scala +++ b/src/library/scala/Enumeration.scala @@ -143,8 +143,23 @@ abstract class Enumeration(initial: Int, names: String*) { /** The type of the enumerated values. */ abstract class Value extends Ordered[Value] { + /** the id and bit location of this enumeration value */ def id: Int override def compare(that: Value): Int = this.id - that.id + /** this enumeration value as an <code>Int</code> bit mask. + * @throws IllegalArgumentException if <code>id</code> is greater than 31 + */ + def mask32 : Int = { + if (id >= 32) throw new IllegalArgumentException + 1 << id + } + /** this enumeration value as an <code>Long</code> bit mask. + * @throws IllegalArgumentException if <code>id</code> is greater than 63 + */ + def mask64 : Long = { + if (id >= 64) throw new IllegalArgumentException + 1L << id + } } /** A class implementing the Value type. This class can be overriden to @@ -166,4 +181,138 @@ abstract class Enumeration(initial: Int, names: String*) { else name } + /** A set that efficiently stores enumeration values as bits. + * @author Sean McDirmid + * + * @ex + * +<code> +object flags extends Enumeration { + val Public = Value(5, "public"); + val Private = Value(4, "private"); + val Protected = Value(6, "protected"); + val Final = Value(7, "final"); +} + +class Entity { + var flags0 : Int = ...; + def flags = flags.Set32(flags0); +} + +val e : Entity = ...; + +if (e.flags.contains(flags.Private)) + e.flags0 = (e.flags | flags.Final).underlying; +</code> + */ + abstract class SetXX extends collection.immutable.Set[Value] { + /** either Int or Long */ + type Underlying <: AnyVal + type TSet <: SetXX + /** The integer that bit-encodes a set of enumeration values. + */ + val underlying : Underlying + /** returns the underlying integer representation of this set as a long. */ + protected def underlyingAsLong : Long + /** Equivalent to <code>++</code> for bit sets. Returns a set + * that has all values in <code>this</code> and <code>set</code>. + */ + def |(set : TSet) : TSet + /** Equivalent to <code>+</code> for bit sets. Returns a set + * that has all values in <code>this</code> with the addition of <code>value</code>. + */ + def |(value : Value) : TSet + /** Equivalent to <code>**</code> for bit sets. + * Returns a bit set that has all values that are both in <code>this</code> and <code>set</code>. + */ + def &(set : TSet) : TSet + /** Equivalent to <code>-</code> for bit sets. + * Returns a bit set that has all values in <code>this</code> except for <code>value</code>. + */ + def &~(value : Value) : TSet + def -(value : Value) : TSet = this &~ value + def +(value : Value) : TSet = this | value + def ++(set : TSet) : TSet = this | set + def **(set : TSet) : TSet = this & set + def size = { + var x = underlyingAsLong + var sz = 0 + while (x != 0) { + if ((x & 1) != 0) sz = sz + 1 + x = x >> 1 + } + sz + } + override def stringPrefix = Enumeration.this.name; + def elements = new Iterator[Value] { + var bit = 0 + var underlying = underlyingAsLong + def hasNext = underlying != 0 + private def shift = { + underlying = underlying >> 1 + bit = bit + 1 + } + def next = { + if (underlying == 0) throw new NoSuchElementException + while ((underlying & 1) == 0) shift + val ret = values(bit) + shift + ret + } + } + def empty[B]: scala.collection.immutable.Set[B] = new scala.collection.immutable.HashSet[B]; + } + /** An enumeration bit set that can handle enumeration values with ids up to 31 in an <code>Int</code>. + */ + class Set32(val underlying : Int) extends SetXX { + def this() = this(0) + type Underlying = Int + type TSet = Set32 + def underlyingAsLong = { + if (underlying >= 0) underlying.toLong + else { + val underlying0 = (~(1 << 31)) & underlying + assert(underlying0 >= 0) + underlying0.toLong | (1L << 31) + } + } + def contains(value : Value) = (underlying & value.mask32) != 0 + def |( set : Set32) = new Set32(underlying | set.underlying) + def |(value : Value) = new Set32(underlying | value.mask32) + def &~(value : Value) = new Set32(underlying & (~value.mask32)) + def &(set : Set32) = new Set32(underlying & set.underlying) + } + /** create an empty 32 bit enumeration set */ + def Set32 = new Set32 + /** create a bit enumeration set according ot underlying */ + def Set32(underlying : Int) = new Set32(underlying) + /** An enumeration bit set that can handle enumeration values with ids up to 63 in a <code>Long</code>. + */ + class Set64(val underlying : Long) extends SetXX { + def this() = this(0) + type Underlying = Long + type TSet = Set64 + def underlyingAsLong = underlying + def contains(value : Value) = (underlying & value.mask64) != 0 + def |( set : Set64) = new Set64(underlying | set.underlying) + def |(value : Value) = new Set64(underlying | value.mask64) + def &~(value : Value) = new Set64(underlying & (~value.mask64)) + def &(set : Set64) = new Set64(underlying & set.underlying) + } + /** create an empty 64 bit enumeration set */ + def Set64 = new Set64 + /** create a bit enumeration set according ot underlying */ + def Set64(underlying : Long) = new Set64(underlying) + /** used to reverse engineer bit locations from pre-defined bit masks */ + def maskToBit(n : Long) = { + assert(n != 0) + var bit = 0 + var m = n + while ((m & 1) != 1) { + m = m >> 1 + bit = bit + 1 + } + assert(m == 1) + bit + } } diff --git a/src/library/scala/Iterable.scala b/src/library/scala/Iterable.scala index 914395d40a..2f09f4e136 100644 --- a/src/library/scala/Iterable.scala +++ b/src/library/scala/Iterable.scala @@ -76,6 +76,8 @@ object Iterable { * <code>elements</code> which returns an iterator over all the * elements contained in the collection. * + * @note If a collection has a known <code>size</code>, it should also sub-type <code>Collection</code>. + * Only potentially unbounded collections should directly sub-class <code>Iterable</code>. * @author Matthias Zenger * @version 1.1, 04/02/2004 */ @@ -92,6 +94,7 @@ trait Iterable[+A] { * * @return the new iterable object * @deprecated use <code>++</code> instead + * @note Will not terminate for infinite-sized collections. */ @deprecated def concat[B >: A](that: Iterable[B]): Collection[B] = @@ -100,6 +103,7 @@ trait Iterable[+A] { /** Appends two iterable objects. * * @return the new iterable object + * @note Will not terminate for infinite-sized collections. */ def ++ [B >: A](that: Iterable[B]): Collection[B] = { val buf = new ArrayBuffer[B] @@ -111,6 +115,7 @@ trait Iterable[+A] { /** Returns the iterable resulting from applying the given function * <code>f</code> to each element of this iterable. * + * @note Will not terminate for infinite-sized collections. * @param f function to apply to each element. * @return <code>f(a<sub>0</sub>), ..., f(a<sub>n</sub>)</code> * if this iterable is <code>a<sub>0</sub>, ..., an</code>. @@ -125,6 +130,7 @@ trait Iterable[+A] { /** Applies the given function <code>f</code> to each element of * this iterable, then concatenates the results. * + * @note Will not terminate for infinite-sized collections. * @param f the function to apply on each element. * @return <code>f(a<sub>0</sub>) ::: ... ::: f(a<sub>n</sub>)</code> if * this iterable is <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. @@ -139,6 +145,7 @@ trait Iterable[+A] { /** Returns all the elements of this iterable that satisfy the * predicate <code>p</code>. The order of the elements is preserved. * + * @note Will not terminate for infinite-sized collections. * @param p the predicate used to filter the list. * @return the elements of this list satisfying <code>p</code>. */ @@ -152,6 +159,7 @@ trait Iterable[+A] { /** Returns the longest prefix of this iterable whose elements satisfy * the predicate <code>p</code>. * + * @note May not terminate for infinite-sized collections. * @param p the test predicate. * @return the longest prefix of this iterable whose elements satisfy * the predicate <code>p</code>. @@ -162,6 +170,7 @@ trait Iterable[+A] { /** Returns the longest suffix of this iterable whose first element * does not satisfy the predicate <code>p</code>. * + * @note May not terminate for infinite-sized collections. * @param p the test predicate. * @return the longest suffix of the iterable whose first element * does not satisfy the predicate <code>p</code>. @@ -183,6 +192,7 @@ trait Iterable[+A] { * If this iterable has less than <code>n</code> elements, the empty * iterable is returned. * + * @note Will not terminate for infinite-sized collections. * @param n the number of elements to drop * @return the new iterable */ @@ -192,6 +202,7 @@ trait Iterable[+A] { /** Apply a function <code>f</code> to all elements of this * iterable object. * + * @note Will not terminate for infinite-sized collections. * @param f a function that is applied to every element. */ def foreach(f: A => Unit): Unit = elements.foreach(f) @@ -200,6 +211,7 @@ trait Iterable[+A] { * iterable object and return true, iff the predicate yields * true for all elements. * + * @note May not terminate for infinite-sized collections. * @param p the predicate * @return true, iff the predicate yields true for all elements. */ @@ -209,6 +221,7 @@ trait Iterable[+A] { * iterable object and return true, iff there is at least one * element for which <code>p</code> yields true. * + * @note May not terminate for infinite-sized collections. * @param p the predicate * @return true, iff the predicate yields true for at least one element. */ @@ -217,6 +230,7 @@ trait Iterable[+A] { /** Find and return the first element of the iterable object satisfying a * predicate, if any. * + * @note Will not terminate for infinite-sized collections. * @param p the predicate * @return the first element in the iterable object satisfying <code>p</code>, * or <code>None</code> if none exists. @@ -225,6 +239,7 @@ trait Iterable[+A] { /** Returns index of the first element satisying a predicate, or -1. * + * @note Will not terminate for infinite-sized collections. * @param p the predicate * @return the index of the first element satisfying <code>p</code>, * or -1 if such an element does not exist @@ -243,6 +258,7 @@ trait Iterable[+A] { /** Returns the index of the first occurence of the specified * object in this iterable object. * + * @note May not terminate for infinite-sized collections. * @param elem element to search for. * @return the index in this sequence of the first occurence of the * specified element, or -1 if the sequence does not contain @@ -266,6 +282,7 @@ trait Iterable[+A] { * function <code>f</code>, from left to right, and starting with * the value <code>z</code>. * + * @note Will not terminate for infinite-sized collections. * @return <code>f(... (f(f(z, a<sub>0</sub>), a<sub>1</sub>) ...), * a<sub>n</sub>)</code> if the list is * <code>[a<sub>0</sub>, a<sub>1</sub>, ..., a<sub>n</sub>]</code>. @@ -276,6 +293,7 @@ trait Iterable[+A] { * function <code>f</code>, from right to left, and starting with * the value <code>z</code>. * + * @note Will not terminate for infinite-sized collections. * @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>. */ @@ -284,16 +302,19 @@ trait Iterable[+A] { /** Similar to <code>foldLeft</code> but can be used as * an operator with the order of list 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. */ 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. */ 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. * @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 @@ -304,6 +325,7 @@ trait Iterable[+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. * @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> @@ -315,6 +337,7 @@ trait Iterable[+A] { def reduceRight[B >: A](op: (B, B) => B): B = elements.reduceRight(op) /** Copy all elements to a given buffer + * @note Will not terminate for infinite-sized collections. * @param dest The buffer to which elements are copied * @note Will not terminate if not finite. */ @@ -322,6 +345,7 @@ trait Iterable[+A] { /** Checks if the other iterable object contains the same elements. * + * @note Will not terminate for infinite-sized collections. * @param that the other iterable object * @return true, iff both iterable objects contain the same elements. */ @@ -337,6 +361,7 @@ trait Iterable[+A] { /** * Create a fresh list with all the elements of this iterable object. + * @note Will not terminate for infinite-sized collections. */ def toList: List[A] = elements.toList @@ -346,10 +371,9 @@ trait Iterable[+A] { * <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>. - * <p/> - * Ex: <br/> - * <code>List(1, 2, 3).mkString("(", "; ", ")") = "(1; 2; 3)"</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. @@ -364,6 +388,7 @@ trait Iterable[+A] { * 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. */ @@ -372,6 +397,7 @@ trait Iterable[+A] { /** Write all elements of this string into given string builder. * + * @note Will not terminate for infinite-sized collections. * @param buf ... * @return ... */ @@ -388,6 +414,7 @@ trait Iterable[+A] { /** Fills the given array <code>xs</code> with the elements of * this sequence starting at position <code>start</code>. * + * @note Will not terminate for infinite-sized collections. * @param xs the array to fill. * @param start starting index. * @pre the array must be large enough to hold all elements. @@ -399,4 +426,47 @@ trait Iterable[+A] { /** Is this collection empty? */ def isEmpty = elements.hasNext + private class Projection[+B](elements0 : () => Iterator[B]) extends Iterable[B] { + def elements = elements0(); + } + /** Returns all the elements of this iterable that satisfy the + * predicate <code>p</code>. The order of the elements is preserved. + * Unlike <code>filter</code>, this API is not strict + * and will terminate on infinite-sized collections. + * + * @param p the predicate used to filter the list. + * @return the elements of this list satisfying <code>p</code>. + */ + def pfilter(p: A => Boolean) : Iterable[A] = new Projection[A](() => { + Iterable.this.elements.filter(p) + }) + /** Returns the iterable resulting from applying the given function + * <code>f</code> to each element of this iterable. Unlike <code>map</code>, + * this API is not strict and will terminate on infinite-sized collections. + * + * @param f function to apply to each element. + * @return <code>f(a<sub>0</sub>), ..., f(a<sub>n</sub>)</code> + * if this iterable is <code>a<sub>0</sub>, ..., an</code>. + */ + def pmap[B](f: A => B) : Iterable[B] = new Projection[B](() => { + Iterable.this.elements.map(f) + }) + /** Applies the given function <code>f</code> to each element of + * this iterable, then concatenates the results. Unlike <code>flatMap</code>, + * this API is not strict and will terminate on infinite-sized collections. + * + * @param f the function to apply on each element. + * @return <code>f(a<sub>0</sub>) ::: ... ::: f(a<sub>n</sub>)</code> if + * this iterable is <code>a<sub>0</sub>, ..., a<sub>n</sub></code>. + */ + def pflatMap[B](f: A => Iterable[B]) : Iterable[B] = new Projection[B](() => { + Iterable.this.elements.flatMap(a => f(a).elements) + }) + + /** returns true iff this collection has a bound size. + * Only true if this iterable is a <code>Collection</code>. + * Many APIs in this trait will not work on collections of + * unbound sizes. + */ + final def hasDefiniteSize = this.isInstanceOf[Collection[Nothing]] } diff --git a/src/library/scala/Seq.scala b/src/library/scala/Seq.scala index 76939c3745..31f74fa768 100644 --- a/src/library/scala/Seq.scala +++ b/src/library/scala/Seq.scala @@ -76,7 +76,8 @@ trait Seq[+A] extends AnyRef with PartialFunction[Int, A] with Collection[A] { * @return the sequence length. */ def length: Int - final def size = length + /** should always be <code>length</code> */ + def size = length /** Returns true if length == 0 */ diff --git a/src/library/scala/collection/immutable/BitEnumeration.scala b/src/library/scala/collection/immutable/BitEnumeration.scala deleted file mode 100644 index e54d02b6d8..0000000000 --- a/src/library/scala/collection/immutable/BitEnumeration.scala +++ /dev/null @@ -1,198 +0,0 @@ -package scala.collection.immutable; -import scala.collection.mutable; - -/** Holds the two underlying bit enumeration representations. - * @author Sean McDirmid - */ -object BitEnumeration { - def At32 = new At32; - /** A bit enumeration that supports at most 32 values - */ - class At32 extends BitEnumeration { - type Underlying = Int; - def maxBits = 32; - def Set(underlying : Int) = new Set(underlying); - class Set(val underlying : Int) extends SetImpl { - def underlyingAsLong = { - if (underlying >= 0) underlying.toLong; - else { - val underlying0 = (~(1 << 31)) & underlying; - assert(underlying0 >= 0); - underlying0.toLong | (1L << 31); - } - } - def contains(value : Value) = (underlying & value.mask32) != 0; - def |( set : Set) = new Set(underlying | set.underlying); - def |(value : Value) = new Set(underlying | value.mask32); - def &~(value : Value) = new Set(underlying & (~value.mask32)); - def &(set : Set) = new Set(underlying & set.underlying); - } - } - def At64 = new At64; - /** A bit enumeration that supports at most 64 values - */ - class At64 extends BitEnumeration { - type Underlying = Long; - def maxBits = 64; - def Set(underlying : Long) = new Set(underlying); - class Set(val underlying : Long) extends SetImpl { - def underlyingAsLong = underlying; - def contains(value : Value) = (underlying & value.mask64) != 0; - def |( set : Set) = new Set(underlying | set.underlying); - def |(value : Value) = new Set(underlying | value.mask64); - def &~(value : Value) = new Set(underlying & (~value.mask64)); - def &(set : Set) = new Set(underlying & set.underlying); - } - } -} - -/** Defines a finite set of values specific to an enumeration. Unlike - * <code>scala.Enumeration</code>, each value in a bit enumeration is - * associated with a unique bit that enables efficient representation - * and manipulation as an integer bit mask. For this reason, only a - * small number (32 or 64) of values are supported per bit enumeration. - * Concrete sub-classes of this class include <code>BitEnumeration.At32</code> - * and <code>BitEnumeration.At64</code>, which respectively support 32 and 64 - * values. - * - * @ex - <style type="text/css"> - p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Courier New} - p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Courier New; color: #913030} - span.s1 {color: #808080} - span.s2 {color: #000000} - span.s3 {color: #1a417b} - span.s4 {color: #4c4c4c} - span.s5 {color: #913030} - span.s6 {color: #1229cd} - </style> - * <p class="p1"> <span class="s1"><b>import</b></span> <b>scala</b>.<b>collection</b>.<b>immutable</b>.<b>BitEnumeration</b>;</p> - * <p class="p2"><span class="s2"> </span><span class="s1"><b>object</b></span><span class="s2"> </span><b>fruits</b><span class="s2"> </span><span class="s1"><b>extends</b></span><span class="s2"> </span><b>BitEnumeration</b><span class="s2">.</span><b>At32</b><span class="s2"> {</span></p> - * - * <p class="p1"> <span class="s1"><b>override</b></span> <span class="s1"><b>def</b></span> <span class="s3"><b>stringPrefix</b></span> = <span class="s4"><i>"fruits"</i></span>;</p> - * <p class="p1"> }</p> - * <p class="p2"><span class="s2"> </span><span class="s1"><b>object</b></span><span class="s2"> </span><b>Apple</b><span class="s2"> </span><span class="s1"><b>extends</b></span><span class="s2"> </span><b>fruits</b><span class="s2">.</span><b>Value</b><span class="s2">(</span><span class="s4"><i>"apple"</i></span><span class="s2">, 1);</span></p> - * <p class="p2"><span class="s2"> </span><span class="s1"><b>object</b></span><span class="s2"> </span><b>Orange</b><span class="s2"> </span><span class="s1"><b>extends</b></span><span class="s2"> </span><b>fruits</b><span class="s2">.</span><b>Value</b><span class="s2">(</span><span class="s4"><i>"orange"</i></span><span class="s2">, 31);</span></p> - * <p class="p1"> <span class="s1"><b>object</b></span> <span class="s5"><b>Pear</b></span> <span class="s1"><b>extends</b></span> <span class="s5"><b>fruits</b></span>.<span class="s5"><b>Value</b></span>(<span class="s4"><i>"pear"</i></span>, 15);</p> - * <p class="p1"> </p> - * <p class="p1"> <span class="s1"><b>val</b></span> <span class="s6"><b>set</b></span> = <span class="s5"><b>fruits</b></span>.<span class="s3"><b>Empty</b></span>;</p> - * <p class="p1"> <span class="s1"><b>val</b></span> <span class="s6"><b>set0</b></span> = <span class="s6"><b>set</b></span> <span class="s3"><b>|</b></span> <span class="s5"><b>Apple</b></span> <span class="s3"><b>|</b></span> <span class="s5"><b>Orange</b></span> <span class="s3"><b>|</b></span> <span class="s5"><b>Pear</b></span>;</p> - * <p class="p1"> <span class="s1"><b>val</b></span> <span class="s6"><b>set1</b></span> = <span class="s6"><b>set0</b></span> <span class="s3"><b>&~</b></span> <span class="s5"><b>Orange</b></span>;</p> - * - * @param names Names that are added to the enumeration upon creation. - * - * @author Sean McDirmid - */ -sealed abstract class BitEnumeration { - private val bits = new mutable.HashMap[Int,Value]; - /** Maximum number of values supported by this bit enumeration. */ - protected def maxBits : Int; - /** Create a new value of a specified <code>name</code> and <code>bit</code>. - * @throw IllegalArgumentException if <code>bit</code> is already reserved for another value or is greater than <code>maxBits</code>. - */ - def Value(name : String, bit : Int) = new Value(name, bit); - /** Create a new value of a specified <code>name</code>, choose first available bit. - * @throw IllegalArgumentException if all bits in enumeration are already reserved. - */ - def Value(name : String ) : Value = Value(name, { - var bit = 0; - while (bits.contains(bit)) bit = bit + 1; - bit; - }); - /** Create a new value of a specified <code>bit</code>, name not specified. - * @throw IllegalArgumentException if <code>bit</code> is already reserved for another value or is greater than <code>maxBits</code>. - */ - def Value( bit : Int) : Value = Value(null, bit); - /** Create a new value with no name, choose first available bit. - * @throw IllegalArgumentException if all bits in enumeration are already reserved. - */ - def Value( ) : Value = Value(null); - - /** Represents values of the enumeration with a <code>name</code>, which is used for printing purposes only, - * and a <code>bit</code> that encodes this value in a set representation. - */ - class Value(name : String, bit : Int) { - - val existing = bits.get(bit); - if (!existing.isEmpty || bit >= maxBits) - throw new IllegalArgumentException("bit " + bit + " is invalid for " + this + { - if (!existing.isEmpty) " - already used for " + existing.get; - else ""; - }); - bits += (bit -> this); - override def toString = { - if (name == null) "bit" + bit else name; - } - def mask32 : Int = 1 << bit; - def mask64 : Long = 1L << bit; - } - /** Represents wrappers around integers that bit-encode sets of enumeration values. - */ - type Set <: SetImpl; - /** Underlying integer type of a set based on this bit enumeration. - */ - type Underlying <: AnyVal; - /** A set that contains no values in this bit enumeration. - */ - def Empty : Set = Set(0.asInstanceOf[Underlying]); - /** Given an integer that bit encodes a set of enumeration values, - * produces an object that wraps this integer with high-level Set APIs. - */ - def Set(underlying : Underlying) : Set; - protected def stringPrefix = "Bits"; - - abstract class SetImpl extends collection.immutable.Set[Value] { - /** The integer that bit-encodes a set of enumeration values. - */ - val underlying : Underlying; - /** Equivalent to <code>++</code> for bit sets. Returns a set - * that has all values in <code>this</code> and <code>set</code>. - */ - def |(set : Set ) : Set; - /** Equivalent to <code>+</code> for bit sets. Returns a set - * that has all values in <code>this</code> with the addition of <code>value</code>. - */ - def |(value : Value) : Set; - /** Equivalent to <code>**</code> for bit sets. - * Returns a bit set that has all values that are both in <code>this</code> and <code>set</code>. - */ - def &(set : Set ) : Set; - /** Equivalent to <code>-</code> for bit sets. - * Returns a bit set that has all values in <code>this</code> except for <code>value</code>. - */ - def &~(value : Value) : Set; - /** returns the underlying integer representation of this set as a long. */ - protected def underlyingAsLong : Long; - def -(value : Value) : Set = this &~ value; - def +(value : Value) : Set = this | value; - def ++(set : Set) : Set = this | set; - def **(set : Set) : Set = this & set; - def size = { - var x = underlyingAsLong; - var sz = 0; - while (x != 0) { - if ((x & 1) != 0) sz = sz + 1; - x = x >> 1; - } - sz; - } - override def stringPrefix = BitEnumeration.this.stringPrefix; - def elements = new Iterator[Value] { - var bit = 0; - var underlying = underlyingAsLong; - def hasNext = underlying != 0; - private def shift = { - underlying = underlying >> 1; - bit = bit + 1; - } - def next = { - if (underlying == 0) throw new NoSuchElementException; - while ((underlying & 1) == 0) shift; - val ret = bits(bit); - shift; - ret; - } - } - def empty[B]: scala.collection.immutable.Set[B] = new scala.collection.immutable.HashSet[B]; - } -} diff --git a/src/library/scala/collection/jcl/Collection.scala b/src/library/scala/collection/jcl/Collection.scala index 5f422364e9..e9344c0ef8 100644 --- a/src/library/scala/collection/jcl/Collection.scala +++ b/src/library/scala/collection/jcl/Collection.scala @@ -62,7 +62,7 @@ trait Collection[A] extends MutableIterable[A] { ** can update the filtered collection. ** @return a non-strict filter of this collection. **/ - def pfilter(p : A => Boolean) : MutableIterable[A] = new Filter(p); + override def pfilter(p : A => Boolean) : MutableIterable[A] = new Filter(p); /** Base implementation of a filtered collection */ class Filter(p : A => Boolean) extends Collection[A] { diff --git a/src/library/scala/collection/jcl/Map.scala b/src/library/scala/collection/jcl/Map.scala index 9a70e08016..5c66986626 100644 --- a/src/library/scala/collection/jcl/Map.scala +++ b/src/library/scala/collection/jcl/Map.scala @@ -55,7 +55,7 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl /** Produces a filtered projection of this map that includes only entries of the map * whose keys are true with respect to predicate "p." */ - def pfilter(p : K => Boolean) : jcl.Map[K,E] = new Filter(p); + def pfilterKeys(p : K => Boolean) : jcl.Map[K,E] = new Filter(p); /** */ def lense[F](f : E => F, g : F => E) : jcl.Map[K,F] = new Lense[F](f,g); @@ -65,8 +65,8 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl override def remove(key : K) = Map.this.remove(key).map(f); override def put(key : K, elem : F) = Map.this.put(key, g(elem)).map(f); override def get(key : K) = Map.this.get(key).map(f); - override def pfilter(p : K => Boolean) : jcl.Map[K,F] = - Map.this.pfilter(p).lense(f, g); + override def pfilterKeys(p : K => Boolean) : jcl.Map[K,F] = + Map.this.pfilterKeys(p).lense(f, g); override def lense[G](f0 : F => G, g0 : G => F) : jcl.Map[K,G] = Map.this.lense[G](x => f0(f(x)), y => g(g0(y))); override def size = size0; @@ -86,8 +86,8 @@ trait Map[K,E] extends MutableIterable[Tuple2[K,E]] with scala.collection.mutabl if (!p(key)) None; else Map.this.get(key); } - override def pfilter(p0 : K => Boolean) : jcl.Map[K,E] = - Map.this.pfilter(k => p(k) && p0(k)); + override def pfilterKeys(p0 : K => Boolean) : jcl.Map[K,E] = + Map.this.pfilterKeys(k => p(k) && p0(k)); override def size = size0; } protected class KeySet extends Set[K] { diff --git a/src/library/scala/collection/jcl/MapWrapper.scala b/src/library/scala/collection/jcl/MapWrapper.scala index 80b219c95c..5762310b66 100644 --- a/src/library/scala/collection/jcl/MapWrapper.scala +++ b/src/library/scala/collection/jcl/MapWrapper.scala @@ -54,6 +54,7 @@ trait MapWrapper[K,E] extends jcl.Map[K,E] { protected val underlying = MapWrapper.this.underlying.keySet; } class ValueSet extends IterableWrapper[E] { + def size = MapWrapper.this.size; val underlying = MapWrapper.this.underlying.values; override def has(e : E) = MapWrapper.this.underlying.containsValue(e); } diff --git a/src/library/scala/collection/jcl/MutableIterable.scala b/src/library/scala/collection/jcl/MutableIterable.scala index be7d071fec..fef43d9ea1 100644 --- a/src/library/scala/collection/jcl/MutableIterable.scala +++ b/src/library/scala/collection/jcl/MutableIterable.scala @@ -17,7 +17,7 @@ package scala.collection.jcl; * * @author Sean McDirmid */ -trait MutableIterable[A] extends Iterable[A] { +trait MutableIterable[A] extends scala.Collection[A] { /** @return true if t is in the collection. **/ def has(t : A ) : Boolean = elements.has(t); @@ -37,17 +37,17 @@ trait MutableIterable[A] extends Iterable[A] { } /** @return the collection that t was removed from. - **/ + */ def -(t : A) : this.type = { remove(t); this; } /** retain only elements in the collection that predicate p is true for. - **/ + */ def retain(p : A => Boolean) : Unit = elements.retain(p); /** retain only elements that are also in that. - **/ + */ def retainAll(that : Iterable[A]) : Boolean = elements.retain(s => that.exists(t => t == s)); /** @return the current number of elements in the collection. - **/ + */ protected def size0 : Int = { var count = 0; val i = elements; @@ -56,7 +56,7 @@ trait MutableIterable[A] extends Iterable[A] { } /** clear all elements from the collection. - **/ + */ def clear(): Unit = { val i = elements; while (i.hasNext) { @@ -64,16 +64,17 @@ trait MutableIterable[A] extends Iterable[A] { } } /** Creates a non-strict map of this collection. Any removals from the returned - ** collection will remove from this collection, while any changes to this collection will also be - ** reflected in the mapped collection. - ** @return a non-strict map of this collection. - **/ - def pmap[B](f : A => B) : MutableIterable[B] = new Map[B](f); + * collection will remove from this collection, while any changes to this collection will also be + * reflected in the mapped collection. + * @return a non-strict map of this collection. + */ + override def pmap[B](f : A => B) : MutableIterable[B] = new Map[B](f); /** The default implementation of a map over mutable iterable collections. **/ protected class Map[B](f : A => B) extends MutableIterable[B] { override def elements = MutableIterable.this.elements.map(f); override def toString = elements.toList.mkString("{", ", ", "}"); + override def size = MutableIterable.this.size; } override def elements : MutableIterator[A]; } diff --git a/src/library/scala/collection/jcl/MutableSeq.scala b/src/library/scala/collection/jcl/MutableSeq.scala index d3869465d3..2d3147ca6d 100644 --- a/src/library/scala/collection/jcl/MutableSeq.scala +++ b/src/library/scala/collection/jcl/MutableSeq.scala @@ -21,7 +21,7 @@ trait MutableSeq[A] extends MutableIterable[A] with Seq[A] { override def apply(idx : Int) = elements.seek(idx); - def pfilter(p : A => Boolean) : MutableSeq[A] = new Filter(p); + override def pfilter(p : A => Boolean) : MutableSeq[A] = new Filter(p); override def pmap[B](f : A => B) : MutableSeq[B] = new Map[B](f); @@ -76,6 +76,7 @@ trait MutableSeq[A] extends MutableIterable[A] with Seq[A] { protected class Map[B](f : A => B) extends super.Map[B](f) with MutableSeq[B] { override def elements = MutableSeq.this.elements.map(f); override def apply(idx : Int) = f(MutableSeq.this.apply(idx)); + override def size = length; } override def length = { var i = elements; diff --git a/src/library/scala/collection/jcl/SortedMap.scala b/src/library/scala/collection/jcl/SortedMap.scala index ede870a6c9..1f6dacddd6 100644 --- a/src/library/scala/collection/jcl/SortedMap.scala +++ b/src/library/scala/collection/jcl/SortedMap.scala @@ -26,13 +26,13 @@ trait SortedMap[K,E] extends scala.collection.SortedMap[K,E] with Map[K,E] with } override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = Range(from, until); override def keySet : SortedSet[K] = new KeySet; - override def pfilter(p : K => Boolean) : SortedMap[K,E] = new Filter(p); + override def pfilterKeys(p : K => Boolean) : SortedMap[K,E] = new Filter(p); override def lense[F](f : E => F, g : F => E) : jcl.SortedMap[K,F] = new Lense[F](f,g); protected class Lense[F](f : E => F, g : F => E) extends super.Lense[F](f,g) with SortedMap[K,F] { def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0, k1); - override def pfilter(p : K => Boolean) : jcl.SortedMap[K,F] = - SortedMap.this.pfilter(p).lense(f, g); + override def pfilterKeys(p : K => Boolean) : jcl.SortedMap[K,F] = + SortedMap.this.pfilterKeys(p).lense(f, g); override def lense[G](f0 : F => G, g0 : G => F) : jcl.SortedMap[K,G] = SortedMap.this.lense[G]({x:E => f0(f(x))}, {y:G => g(g0(y))}); override def rangeImpl(from : Option[K], until : Option[K]) = @@ -48,11 +48,11 @@ trait SortedMap[K,E] extends scala.collection.SortedMap[K,E] with Map[K,E] with protected class SuperFilter(p : K => Boolean) extends super.Filter(p); protected class Filter(p : K => Boolean) extends SuperFilter(p) with SortedMap[K,E] { def compare(k0 : K, k1 : K) = SortedMap.this.compare(k0,k1); - override def pfilter(p0 : K => Boolean) : SortedMap[K,E] = - SortedMap.this.pfilter(k => p(k) && p0(k)); + override def pfilterKeys(p0 : K => Boolean) : SortedMap[K,E] = + SortedMap.this.pfilterKeys(k => p(k) && p0(k)); override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = - SortedMap.this.Range(from, until).pfilter(p); + SortedMap.this.Range(from, until).pfilterKeys(p); } protected def Range(from : Option[K], until : Option[K]) : SortedMap[K,E] = new Range(from,until); @@ -78,13 +78,13 @@ trait SortedMap[K,E] extends scala.collection.SortedMap[K,E] with Map[K,E] with if (until != None && compare(this.until.get, until.get) < 0) return rangeImpl(from, this.until); SortedMap.this.Range(from, until); } - override def pfilter(p : K => Boolean) : SortedMap[K,E] = new Filter(p); + override def pfilterKeys(p : K => Boolean) : SortedMap[K,E] = new Filter(p); protected class Filter(p : K => Boolean) extends SuperFilter(p) with SortedMap[K,E] { def compare(k0 : K, k1 : K) = Range.this.compare(k0, k1); - override def pfilter(p0 : K => Boolean) = - Range.this.pfilter(key => p(key) && p0(key)); + override def pfilterKeys(p0 : K => Boolean) = + Range.this.pfilterKeys(key => p(key) && p0(key)); override def rangeImpl(from : Option[K], until : Option[K]) : SortedMap[K,E] = - Range.this.rangeImpl(from,until).pfilter(p); + Range.this.rangeImpl(from,until).pfilterKeys(p); } } } diff --git a/src/library/scala/collection/jcl/Tests.scala b/src/library/scala/collection/jcl/Tests.scala index 27844ab37e..b81a6f1984 100644 --- a/src/library/scala/collection/jcl/Tests.scala +++ b/src/library/scala/collection/jcl/Tests.scala @@ -47,7 +47,7 @@ private[jcl] object Tests { rmap + ("bad" -> 10); Console.println(rmap); //Console.println(map); - val fmap : SortedMap[String,Integer] = rmap.pfilter(k => k.length == 2); + val fmap : SortedMap[String,Integer] = rmap.pfilterKeys(k => k.length == 2); Console.println(fmap); } diff --git a/src/library/scala/collection/mutable/History.scala b/src/library/scala/collection/mutable/History.scala index bb077c3fa3..db557929df 100644 --- a/src/library/scala/collection/mutable/History.scala +++ b/src/library/scala/collection/mutable/History.scala @@ -21,7 +21,7 @@ package scala.collection.mutable * @version 1.0, 08/07/2003 */ @serializable -class History[A, B] extends AnyRef with Subscriber[A, B] with Iterable[(B, A)] { +class History[A, B] extends AnyRef with Subscriber[A, B] with Collection[(B, A)] { protected val log: Queue[(B, A)] = new Queue[(B, A)] @@ -42,7 +42,7 @@ class History[A, B] extends AnyRef with Subscriber[A, B] with Iterable[(B, A)] { def events: Iterator[A] = log.elements.map { case (_, e) => e } - def size: Int = log.length + override def size: Int = log.length def clear(): Unit = log.clear } |