diff options
Diffstat (limited to 'src/library/scala/collection/immutable')
8 files changed, 88 insertions, 34 deletions
diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index e4b7371ed4..837143784b 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -194,7 +194,7 @@ class HashSet[A] extends AbstractSet[A] protected def get0(key: A, hash: Int, level: Int): Boolean = false - def updated0(key: A, hash: Int, level: Int): HashSet[A] = + private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] = new HashSet.HashSet1(key, hash) protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = this @@ -256,10 +256,10 @@ object HashSet extends ImmutableSetFactory[HashSet] { class HashSet1[A](private[HashSet] val key: A, private[HashSet] val hash: Int) extends LeafHashSet[A] { override def size = 1 - override def get0(key: A, hash: Int, level: Int): Boolean = + override protected def get0(key: A, hash: Int, level: Int): Boolean = (hash == this.hash && key == this.key) - override def subsetOf0(that: HashSet[A], level: Int) = { + override protected def subsetOf0(that: HashSet[A], level: Int) = { // check if that contains this.key // we use get0 with our key and hash at the correct level instead of calling contains, // which would not work since that might not be a top-level HashSet @@ -267,7 +267,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { that.get0(key, hash, level) } - override def updated0(key: A, hash: Int, level: Int): HashSet[A] = + override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] = if (hash == this.hash && key == this.key) this else { if (hash != this.hash) { @@ -312,7 +312,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { override private[immutable] def diff0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = if (that.get0(key, hash, level)) null else this - override def removed0(key: A, hash: Int, level: Int): HashSet[A] = + override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = if (hash == this.hash && key == this.key) null else this override protected def filter0(p: A => Boolean, negate: Boolean, level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = @@ -326,10 +326,10 @@ object HashSet extends ImmutableSetFactory[HashSet] { override def size = ks.size - override def get0(key: A, hash: Int, level: Int): Boolean = + override protected def get0(key: A, hash: Int, level: Int): Boolean = if (hash == this.hash) ks.contains(key) else false - override def subsetOf0(that: HashSet[A], level: Int) = { + override protected def subsetOf0(that: HashSet[A], level: Int) = { // we have to check each element // we use get0 with our hash at the correct level instead of calling contains, // which would not work since that might not be a top-level HashSet @@ -337,11 +337,11 @@ object HashSet extends ImmutableSetFactory[HashSet] { ks.forall(key => that.get0(key, hash, level)) } - override def updated0(key: A, hash: Int, level: Int): HashSet[A] = + override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] = if (hash == this.hash) new HashSetCollision1(hash, ks + key) else makeHashTrieSet(this.hash, this, hash, new HashSet1(key, hash), level) - override def union0(that: LeafHashSet[A], level: Int): HashSet[A] = that match { + override private[immutable] def union0(that: LeafHashSet[A], level: Int): HashSet[A] = that match { case that if that.hash != this.hash => // different hash code, so there is no need to investigate further. // Just create a branch node containing the two. @@ -374,7 +374,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { } } - override def union0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = that match { + override private[immutable] def union0(that: HashSet[A], level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = that match { case that: LeafHashSet[A] => // switch to the simpler Tree/Leaf implementation this.union0(that, level) @@ -431,7 +431,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { } } - override def removed0(key: A, hash: Int, level: Int): HashSet[A] = + override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = if (hash == this.hash) { val ks1 = ks - key ks1.size match { @@ -528,7 +528,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { override def size = size0 - override def get0(key: A, hash: Int, level: Int): Boolean = { + override protected def get0(key: A, hash: Int, level: Int): Boolean = { val index = (hash >>> level) & 0x1f val mask = (1 << index) if (bitmap == - 1) { @@ -540,7 +540,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { false } - override def updated0(key: A, hash: Int, level: Int): HashSet[A] = { + override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] = { val index = (hash >>> level) & 0x1f val mask = (1 << index) val offset = Integer.bitCount(bitmap & (mask-1)) @@ -842,7 +842,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { case _ => this } - override def removed0(key: A, hash: Int, level: Int): HashSet[A] = { + override protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = { val index = (hash >>> level) & 0x1f val mask = (1 << index) val offset = Integer.bitCount(bitmap & (mask-1)) @@ -879,7 +879,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { } } - override def subsetOf0(that: HashSet[A], level: Int): Boolean = if (that eq this) true else that match { + override protected def subsetOf0(that: HashSet[A], level: Int): Boolean = if (that eq this) true else that match { case that: HashTrieSet[A] if this.size0 <= that.size0 => // create local mutable copies of members var abm = this.bitmap diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala index aa9dec2761..a8f1149615 100644 --- a/src/library/scala/collection/immutable/List.scala +++ b/src/library/scala/collection/immutable/List.scala @@ -13,7 +13,7 @@ package immutable import generic._ import mutable.{Builder, ListBuffer} import scala.annotation.tailrec -import java.io._ +import java.io.{ObjectOutputStream, ObjectInputStream} /** A class for immutable linked lists representing ordered collections * of elements of type. @@ -85,7 +85,7 @@ sealed abstract class List[+A] extends AbstractSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqOptimized[A, List[A]] - with Serializable { + with scala.Serializable { override def companion: GenericCompanion[List] = List import scala.collection.{Iterable, Traversable, Seq, IndexedSeq} diff --git a/src/library/scala/collection/immutable/ListMap.scala b/src/library/scala/collection/immutable/ListMap.scala index 7c40e84280..c5773338f5 100644 --- a/src/library/scala/collection/immutable/ListMap.scala +++ b/src/library/scala/collection/immutable/ListMap.scala @@ -29,7 +29,11 @@ object ListMap extends ImmutableMapFactory[ListMap] { new MapCanBuildFrom[A, B] def empty[A, B]: ListMap[A, B] = EmptyListMap.asInstanceOf[ListMap[A, B]] - private object EmptyListMap extends ListMap[Any, Nothing] { } + @SerialVersionUID(-8256686706655863282L) + private object EmptyListMap extends ListMap[Any, Nothing] { + override def apply(key: Any) = throw new NoSuchElementException("key not found: " + key) + override def contains(key: Any) = false + } } /** This class implements immutable maps using a list-based data structure. @@ -159,7 +163,6 @@ extends AbstractMap[A, B] */ override def apply(k: A): B1 = apply0(this, k) - @tailrec private def apply0(cur: ListMap[A, B1], k: A): B1 = if (cur.isEmpty) throw new NoSuchElementException("key not found: "+k) else if (k == cur.key) cur.value @@ -176,7 +179,16 @@ extends AbstractMap[A, B] @tailrec private def get0(cur: ListMap[A, B1], k: A): Option[B1] = if (k == cur.key) Some(cur.value) else if (cur.next.nonEmpty) get0(cur.next, k) else None - + + + override def contains(key: A): Boolean = contains0(this, key) + + @tailrec private def contains0(cur: ListMap[A, B1], k: A): Boolean = + if (k == cur.key) true + else if (cur.next.nonEmpty) contains0(cur.next, k) + else false + + /** This method allows one to create a new map with an additional mapping * from `key` to `value`. If the map contains already a mapping for `key`, * it will be overridden by this function. @@ -186,6 +198,7 @@ extends AbstractMap[A, B] new m.Node[B2](k, v) } + /** Creates a new mapping without the given `key`. * If the map does not contain a mapping for the given key, the * method returns the same map. diff --git a/src/library/scala/collection/immutable/Map.scala b/src/library/scala/collection/immutable/Map.scala index 5178d5a862..63ddcb18cf 100644 --- a/src/library/scala/collection/immutable/Map.scala +++ b/src/library/scala/collection/immutable/Map.scala @@ -94,6 +94,8 @@ object Map extends ImmutableMapFactory[Map] { private object EmptyMap extends AbstractMap[Any, Nothing] with Map[Any, Nothing] with Serializable { override def size: Int = 0 + override def apply(key: Any) = throw new NoSuchElementException("key not found: " + key) + override def contains(key: Any) = false def get(key: Any): Option[Nothing] = None def iterator: Iterator[(Any, Nothing)] = Iterator.empty override def updated [B1] (key: Any, value: B1): Map[Any, B1] = new Map1(key, value) @@ -103,6 +105,8 @@ object Map extends ImmutableMapFactory[Map] { class Map1[A, +B](key1: A, value1: B) extends AbstractMap[A, B] with Map[A, B] with Serializable { override def size = 1 + override def apply(key: A) = if (key == key1) value1 else throw new NoSuchElementException("key not found: " + key) + override def contains(key: A) = key == key1 def get(key: A): Option[B] = if (key == key1) Some(value1) else None def iterator = Iterator((key1, value1)) @@ -119,6 +123,11 @@ object Map extends ImmutableMapFactory[Map] { class Map2[A, +B](key1: A, value1: B, key2: A, value2: B) extends AbstractMap[A, B] with Map[A, B] with Serializable { override def size = 2 + override def apply(key: A) = + if (key == key1) value1 + else if (key == key2) value2 + else throw new NoSuchElementException("key not found: " + key) + override def contains(key: A) = (key == key1) || (key == key2) def get(key: A): Option[B] = if (key == key1) Some(value1) else if (key == key2) Some(value2) @@ -140,6 +149,12 @@ object Map extends ImmutableMapFactory[Map] { class Map3[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B) extends AbstractMap[A, B] with Map[A, B] with Serializable { override def size = 3 + override def apply(key: A) = + if (key == key1) value1 + else if (key == key2) value2 + else if (key == key3) value3 + else throw new NoSuchElementException("key not found: " + key) + override def contains(key: A) = (key == key1) || (key == key2) || (key == key3) def get(key: A): Option[B] = if (key == key1) Some(value1) else if (key == key2) Some(value2) @@ -164,6 +179,13 @@ object Map extends ImmutableMapFactory[Map] { class Map4[A, +B](key1: A, value1: B, key2: A, value2: B, key3: A, value3: B, key4: A, value4: B) extends AbstractMap[A, B] with Map[A, B] with Serializable { override def size = 4 + override def apply(key: A) = + if (key == key1) value1 + else if (key == key2) value2 + else if (key == key3) value3 + else if (key == key4) value4 + else throw new NoSuchElementException("key not found: " + key) + override def contains(key: A) = (key == key1) || (key == key2) || (key == key3) || (key == key4) def get(key: A): Option[B] = if (key == key1) Some(value1) else if (key == key2) Some(value2) diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala index 3a64820be6..fb9f6703a9 100644 --- a/src/library/scala/collection/immutable/PagedSeq.scala +++ b/src/library/scala/collection/immutable/PagedSeq.scala @@ -12,7 +12,7 @@ package scala package collection package immutable -import java.io._ +import java.io.{File, FileReader, Reader} import scala.util.matching.Regex import scala.reflect.ClassTag diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala index 3ae8a2c342..0b380517f8 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -202,7 +202,24 @@ extends scala.collection.AbstractSeq[Int] copy(locationAfterN(n), end, step) } ) - + + /** Creates a new range containing the elements starting at `from` up to but not including `until`. + * + * $doesNotUseBuilders + * + * @param from the element at which to start + * @param until the element at which to end (not included in the range) + * @return a new range consisting of a contiguous interval of values in the old range + */ + override def slice(from: Int, until: Int): Range = + if (from <= 0) take(until) + else if (until >= numRangeElements && numRangeElements >= 0) drop(from) + else { + val fromValue = locationAfterN(from) + if (from >= until) newEmptyRange(fromValue) + else new Range.Inclusive(fromValue, locationAfterN(until-1), step) + } + /** Creates a new range containing all the elements of this range except the last one. * * $doesNotUseBuilders diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala index 714d5117d3..91a4e1c43d 100644 --- a/src/library/scala/collection/immutable/Stream.scala +++ b/src/library/scala/collection/immutable/Stream.scala @@ -499,6 +499,16 @@ self => ) else super.flatMap(f)(bf) + override private[scala] def filterImpl(p: A => Boolean, isFlipped: Boolean): Stream[A] = { + // optimization: drop leading prefix of elems for which f returns false + // var rest = this dropWhile (!p(_)) - forget DRY principle - GC can't collect otherwise + var rest = this + while (!rest.isEmpty && p(rest.head) == isFlipped) rest = rest.tail + // private utility func to avoid `this` on stack (would be needed for the lazy arg) + if (rest.nonEmpty) Stream.filteredTail(rest, p, isFlipped) + else Stream.Empty + } + /** Returns all the elements of this `Stream` that satisfy the predicate `p` * in a new `Stream` - i.e., it is still a lazy data structure. The order of * the elements is preserved @@ -512,15 +522,7 @@ self => * // produces * }}} */ - override def filter(p: A => Boolean): Stream[A] = { - // optimization: drop leading prefix of elems for which f returns false - // var rest = this dropWhile (!p(_)) - forget DRY principle - GC can't collect otherwise - var rest = this - while (!rest.isEmpty && !p(rest.head)) rest = rest.tail - // private utility func to avoid `this` on stack (would be needed for the lazy arg) - if (rest.nonEmpty) Stream.filteredTail(rest, p) - else Stream.Empty - } + override def filter(p: A => Boolean): Stream[A] = filterImpl(p, isFlipped = false) // This override is only left in 2.11 because of binary compatibility, see PR #3925 override final def withFilter(p: A => Boolean): StreamWithFilter = new StreamWithFilter(p) @@ -1284,8 +1286,8 @@ object Stream extends SeqFactory[Stream] { else cons(start, range(start + step, end, step)) } - private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean) = { - cons(stream.head, stream.tail filter p) + private[immutable] def filteredTail[A](stream: Stream[A], p: A => Boolean, isFlipped: Boolean) = { + cons(stream.head, stream.tail.filterImpl(p, isFlipped)) } private[immutable] def collectedTail[A, B, That](head: B, stream: Stream[A], pf: PartialFunction[A, B], bf: CanBuildFrom[Stream[A], B, That]) = { diff --git a/src/library/scala/collection/immutable/StreamViewLike.scala b/src/library/scala/collection/immutable/StreamViewLike.scala index c2eb85815d..4d7eaeff2a 100644 --- a/src/library/scala/collection/immutable/StreamViewLike.scala +++ b/src/library/scala/collection/immutable/StreamViewLike.scala @@ -53,6 +53,7 @@ extends SeqView[A, Coll] /** boilerplate */ protected override def newForced[B](xs: => scala.collection.GenSeq[B]): Transformed[B] = new { val forced = xs } with AbstractTransformed[B] with Forced[B] protected override def newAppended[B >: A](that: scala.collection.GenTraversable[B]): Transformed[B] = new { val rest = that } with AbstractTransformed[B] with Appended[B] + protected override def newPrepended[B >: A](that: scala.collection.GenTraversable[B]): Transformed[B] = new { protected[this] val fst = that } with AbstractTransformed[B] with Prepended[B] protected override def newMapped[B](f: A => B): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with Mapped[B] protected override def newFlatMapped[B](f: A => scala.collection.GenTraversableOnce[B]): Transformed[B] = new { val mapping = f } with AbstractTransformed[B] with FlatMapped[B] protected override def newFiltered(p: A => Boolean): Transformed[A] = new { val pred = p } with AbstractTransformed[A] with Filtered @@ -67,7 +68,6 @@ extends SeqView[A, Coll] protected override def newPatched[B >: A](_from: Int, _patch: scala.collection.GenSeq[B], _replaced: Int): Transformed[B] = { new { val from = _from; val patch = _patch; val replaced = _replaced } with AbstractTransformed[B] with Patched[B] } - protected override def newPrepended[B >: A](elem: B): Transformed[B] = new { protected[this] val fst = elem } with AbstractTransformed[B] with Prepended[B] override def stringPrefix = "StreamView" } |