Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// TODO Make it a cross project when Scala.js is released for 2.13.0-M4

scalaVersion := "2.13.0-M4-pre-20d3c21"
scalaVersion := "2.13.0-M4"

organization := "org.scala-lang"

Expand Down
43 changes: 30 additions & 13 deletions src/main/scala/scala/collection/MultiDict.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package scala.collection

import annotation.unchecked.uncheckedVariance
import scala.util.hashing.MurmurHash3

/**
* A multidict is a map that can associate a set of values to a given key.
*
Expand All @@ -14,7 +17,7 @@ trait MultiDict[K, V]
def multiMapFactory: MapFactory[MultiDictCC] = MultiDict

override protected[this] def fromSpecificIterable(coll: Iterable[(K, V)]): MultiDictCC[K, V] = multiMapFactory.from(coll)
override protected[this] def newSpecificBuilder(): mutable.Builder[(K, V), MultiDictCC[K, V]] = multiMapFactory.newBuilder[K, V]()
override protected[this] def newSpecificBuilder: mutable.Builder[(K, V), MultiDictCC[K, V]] = multiMapFactory.newBuilder[K, V]

def canEqual(that: Any): Boolean = true

Expand All @@ -32,15 +35,15 @@ trait MultiDict[K, V]
case _ => false
}

override def hashCode(): Int = Set.unorderedHash(sets, "MultiMap".##)
override def hashCode(): Int = MurmurHash3.unorderedHash(sets, "MultiMap".##)

}


trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
extends IterableOps[(K, V), Iterable, C] {

protected[this] type MultiDictCC[K, V] = CC[K, V]
protected[this] type MultiDictCC[K, V] = CC[K, V] @uncheckedVariance

def multiMapFactory: MapFactory[MultiDictCC]

Expand All @@ -58,8 +61,8 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
*/
def sets: Map[K, Set[V]]

def iterator(): Iterator[(K, V)] =
sets.iterator().flatMap { case (k, vs) => vs.view.map(v => (k, v)) }
def iterator: Iterator[(K, V)] =
sets.iterator.flatMap { case (k, vs) => vs.view.map(v => (k, v)) }

/**
* @return The set of values associated with the given `key`, or the empty
Expand Down Expand Up @@ -133,13 +136,8 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
def concat(that: Iterable[(K, V)]): C =
fromSpecificIterable(new View.Concat(toIterable, that))

override def withFilter(p: ((K, V)) => Boolean): MultiMapWithFilter = new MultiMapWithFilter(p)

class MultiMapWithFilter(p: ((K, V)) => Boolean) extends WithFilter(p) {
def map[L, W](f: ((K, V)) => (L, W)): CC[L, W] = multiMapFromIterable(new View.Map(filtered, f))
def flatMap[L, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] = multiMapFromIterable(new View.FlatMap(filtered, f))
override def withFilter(q: ((K, V)) => Boolean): MultiMapWithFilter = new MultiMapWithFilter(kv => p(kv) && q(kv))
}
override def withFilter(p: ((K, V)) => Boolean): MultiDictOps.WithFilter[K, V, IterableCC, CC] =
new MultiDictOps.WithFilter(this, p)

/**
* @return Whether there exists a value associated with the given `key`
Expand Down Expand Up @@ -203,4 +201,23 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]

}

object MultiDict extends MapFactory.Delegate[MultiDict](immutable.MultiDict)
object MultiDictOps {

class WithFilter[K, V, +IterableCC[_], +CC[X, Y] <: MultiDict[X, Y]](
`this`: MultiDictOps[K, V, CC, _] with IterableOps[(K, V), IterableCC, _],
p: ((K, V)) => Boolean
) extends IterableOps.WithFilter[(K, V), IterableCC](`this`, p) {

def map[L, W](f: ((K, V)) => (L, W)): CC[L, W] =
`this`.multiMapFactory.from(new View.Map(filtered, f))

def flatMap[L, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] =
`this`.multiMapFactory.from(new View.FlatMap(filtered, f))

override def withFilter(q: ((K, V)) => Boolean): WithFilter[K, V, IterableCC, CC] =
new WithFilter[K, V, IterableCC, CC](`this`, (kv: (K, V)) => p(kv) && q(kv))
}

}

object MultiDict extends MapFactory.Delegate[MultiDict](immutable.MultiDict)
8 changes: 5 additions & 3 deletions src/main/scala/scala/collection/MultiSet.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package scala.collection

import scala.util.hashing.MurmurHash3

/**
* A multiset is a set that can contain multiple occurrences of a same value.
*
Expand All @@ -26,7 +28,7 @@ trait MultiSet[A]
case _ => false
}

override def hashCode(): Int = collection.Set.unorderedHash(occurrences, "MultiSet".##)
override def hashCode(): Int = MurmurHash3.unorderedHash(occurrences, "MultiSet".##)

}

Expand All @@ -45,8 +47,8 @@ trait MultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
*/
def occurrences: Map[A, Int]

def iterator(): Iterator[A] =
occurrences.iterator().flatMap { case (elem, n) => new View.Fill(n)(elem) }
def iterator: Iterator[A] =
occurrences.iterator.flatMap { case (elem, n) => new View.Fill(n)(elem) }

/**
* @return The number of occurrences of `elem` in this multiset
Expand Down
44 changes: 30 additions & 14 deletions src/main/scala/scala/collection/SortedMultiDict.scala
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package scala.collection

import annotation.unchecked.uncheckedVariance

/**
* A multidict whose keys are sorted
*
* @tparam K the type of keys
* @tparam V the type of values
*/
Expand All @@ -13,14 +14,14 @@ trait SortedMultiDict[K, V]
def unsorted: MultiDict[K, V] = this

override protected[this] def fromSpecificIterable(coll: Iterable[(K, V)]): SortedMultiDictCC[K, V] = sortedMultiMapFactory.from(coll)
override protected[this] def newSpecificBuilder(): mutable.Builder[(K, V), SortedMultiDictCC[K, V]] = sortedMultiMapFactory.newBuilder[K, V]()
override protected[this] def newSpecificBuilder: mutable.Builder[(K, V), SortedMultiDictCC[K, V]] = sortedMultiMapFactory.newBuilder[K, V]
}

trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]
extends MultiDictOps[K, V, MultiDict, C]
with SortedOps[K, C] {

protected[this] type SortedMultiDictCC[K, V] = CC[K, V]
protected[this] type SortedMultiDictCC[X, Y] = CC[X, Y] @uncheckedVariance

def sortedMultiMapFactory: SortedMapFactory[SortedMultiDictCC]

Expand All @@ -41,23 +42,18 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
def lastKey: K = sets.lastKey

def rangeTo(to: K): C = {
val i = from(to).iterator()
val i = rangeFrom(to).iterator
if (i.isEmpty) return coll
val next = i.next()._1
if (ordering.compare(next, to) == 0)
if (i.isEmpty) coll
else until(i.next()._1)
else rangeUntil(i.next()._1)
else
until(next)
rangeUntil(next)
}

override def withFilter(p: ((K, V)) => Boolean): SortedMultiMapWithFilter = new SortedMultiMapWithFilter(p)

class SortedMultiMapWithFilter(p: ((K, V)) => Boolean) extends MultiMapWithFilter(p) {
def map[L : Ordering, W](f: ((K, V)) => (L, W)): CC[L, W] = sortedFromIterable(new View.Map(filtered, f))
def flatMap[L : Ordering, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] = sortedFromIterable(new View.FlatMap(filtered, f))
override def withFilter(q: ((K, V)) => Boolean): SortedMultiMapWithFilter = new SortedMultiMapWithFilter(kv => p(kv) && q(kv))
}
override def withFilter(p: ((K, V)) => Boolean): SortedMultiDictOps.WithFilter[K, V, IterableCC, MultiDictCC, CC] =
new SortedMultiDictOps.WithFilter[K, V, IterableCC, MultiDictCC, CC](this, p)

/**
* @return a sorted multidict that contains all the entries of `this` sorted multidict,
Expand Down Expand Up @@ -130,4 +126,24 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,

}

object SortedMultiDict extends SortedMapFactory.Delegate[SortedMultiDict](immutable.SortedMultiDict)
object SortedMultiDictOps {

class WithFilter[K, V, +IterableCC[_], +MultiDictCC[X, Y] <: MultiDict[X, Y], +CC[X, Y] <: MultiDict[X, Y]](
`this`: SortedMultiDictOps[K, V, CC, _] with MultiDictOps[K, V, MultiDictCC, _] with IterableOps[(K, V), IterableCC, _],
p: ((K, V)) => Boolean
) extends MultiDictOps.WithFilter[K, V, IterableCC, MultiDictCC](`this`, p) {

def map[L : Ordering, W](f: ((K, V)) => (L, W)): CC[L, W] =
`this`.sortedMultiMapFactory.from(new View.Map(filtered, f))

def flatMap[L : Ordering, W](f: ((K, V)) => IterableOnce[(L, W)]): CC[L, W] =
`this`.sortedMultiMapFactory.from(new View.FlatMap(filtered, f))

override def withFilter(q: ((K, V)) => Boolean): WithFilter[K, V, IterableCC, MultiDictCC, CC] =
new WithFilter[K, V, IterableCC, MultiDictCC, CC](`this`, kv => p(kv) && q(kv))

}

}

object SortedMultiDict extends SortedMapFactory.Delegate[SortedMultiDict](immutable.SortedMultiDict)
51 changes: 31 additions & 20 deletions src/main/scala/scala/collection/SortedMultiSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ trait SortedMultiSet[A]
def unsorted: MultiSet[A] = this

override protected[this] def fromSpecificIterable(coll: Iterable[A]): SortedIterableCC[A] = sortedIterableFactory.from(coll)
override protected[this] def newSpecificBuilder(): mutable.Builder[A, SortedIterableCC[A]] = sortedIterableFactory.newBuilder[A]()
override protected[this] def newSpecificBuilder: mutable.Builder[A, SortedIterableCC[A]] = sortedIterableFactory.newBuilder[A]

protected[this] def sortedFromIterable[B : Ordering](it: scala.collection.Iterable[B]): SortedIterableCC[B] = sortedIterableFactory.from(it)

Expand All @@ -24,7 +24,7 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
extends MultiSetOps[A, MultiSet, C]
with SortedOps[A, C] {

protected[this] type SortedIterableCC[X] = CC[X]
protected[this] type SortedIterableCC[X] = CC[X] @uncheckedVariance

def sortedIterableFactory: SortedIterableFactory[SortedIterableCC]

Expand Down Expand Up @@ -52,31 +52,18 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
def lastKey: A = occurrences.lastKey

def rangeTo(to: A): C = {
val i = from(to).iterator()
val i = rangeFrom(to).iterator
if (i.isEmpty) return coll
val next = i.next()
if (ordering.compare(next, to) == 0)
if (i.isEmpty) coll
else until(i.next())
else rangeUntil(i.next())
else
until(next)
rangeUntil(next)
}

override def withFilter(p: A => Boolean): SortedWithFilter = new SortedWithFilter(p)

/** Specialize `WithFilter` for sorted collections
*
* @define coll sorted collection
*/
class SortedWithFilter(p: A => Boolean) extends WithFilter(p) {

def map[B : Ordering](f: A => B): CC[B] = sortedIterableFactory.from(new View.Map(filtered, f))

def flatMap[B : Ordering](f: A => IterableOnce[B]): CC[B] = sortedIterableFactory.from(new View.FlatMap(filtered, f))

override def withFilter(q: A => Boolean): SortedWithFilter = new SortedWithFilter(a => p(a) && q(a))

}
override def withFilter(p: A => Boolean): SortedMultiSetOps.WithFilter[A, IterableCC, CC] =
new SortedMultiSetOps.WithFilter(this, p)

/** Builds a new sorted multiset by applying a function to all elements of this sorted multiset.
*
Expand Down Expand Up @@ -169,4 +156,28 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]

}

object SortedMultiSetOps {

/** Specialize `WithFilter` for sorted collections
*
* @define coll sorted collection
*/
class WithFilter[A, +IterableCC[_], +CC[X] <: MultiSet[X]](
`this`: SortedMultiSetOps[A, CC, _] with IterableOps[A, IterableCC, _],
p: A => Boolean
) extends IterableOps.WithFilter(`this`, p) {

def map[B : Ordering](f: A => B): CC[B] =
`this`.sortedIterableFactory.from(new View.Map(filtered, f))

def flatMap[B : Ordering](f: A => IterableOnce[B]): CC[B] =
`this`.sortedIterableFactory.from(new View.FlatMap(filtered, f))

override def withFilter(q: A => Boolean): WithFilter[A, IterableCC, CC] =
new WithFilter[A, IterableCC, CC](`this`, a => p(a) && q(a))

}

}

object SortedMultiSet extends SortedIterableFactory.Delegate(immutable.SortedMultiSet)
6 changes: 3 additions & 3 deletions src/main/scala/scala/collection/decorators/HasSeqOps.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package scala.collection
package decorators

import scala.collection.immutable.{ImmutableArray, Range}
import scala.collection.immutable.{ArraySeq, Range}

/** Type class witnessing that a collection type `C` has
* elements of type `A` and has a conversion to `SeqOps[A, _, _]`.
Expand Down Expand Up @@ -31,7 +31,7 @@ object HasSeqOps {
implicit def stringHasSeqOps: HasSeqOps[String] { type A = Char } =
new HasSeqOps[String] {
type A = Char
def apply(c: String): SeqOps[Char, AnyConstr, _] = stringToStringOps(c)
def apply(c: String): SeqOps[Char, AnyConstr, _] = c: Seq[Char]
}

// 3. StringView
Expand All @@ -45,7 +45,7 @@ object HasSeqOps {
implicit def arrayHasSeqOps[A0]: HasSeqOps[Array[A0]] { type A = A0 } =
new HasSeqOps[Array[A0]] {
type A = A0
def apply(c: Array[A0]): SeqOps[A0, AnyConstr, _] = ImmutableArray.unsafeWrapArray(c)
def apply(c: Array[A0]): SeqOps[A0, AnyConstr, _] = mutable.ArraySeq.make(c)
}

// 5. Range collections
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class IterableDecorator[C, I <: HasIterableOps[C]](coll: C)(implicit val it: I)
* all the elements have been traversed or earlier if the operator returns `None`
*/
def foldSomeLeft[B](z: B)(op: (B, it.A) => Option[B]): B =
it(coll).iterator().foldSomeLeft(z)(op)
it(coll).iterator.foldSomeLeft(z)(op)

/**
* Right to left fold that can be interrupted before traversing the whole collection.
Expand All @@ -29,6 +29,6 @@ class IterableDecorator[C, I <: HasIterableOps[C]](coll: C)(implicit val it: I)
* `f` is applied to the previous result to produce the new result and the fold continues.
*/
def lazyFoldRight[B](z: B)(op: it.A => Either[B, B => B]): B =
it(coll).iterator().lazyFoldRight(z)(op)
it(coll).iterator.lazyFoldRight(z)(op)

}
4 changes: 2 additions & 2 deletions src/main/scala/scala/collection/decorators/views.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ object View {
type SomeIterableOps[+A] = IterableOps[A, AnyConstr, _]

class Intersperse[A](underlying: SomeIterableOps[A], sep: A) extends View[A] {
def iterator(): Iterator[A] = underlying.iterator().intersperse(sep)
def iterator: Iterator[A] = underlying.iterator.intersperse(sep)

override def knownSize: Int = if (underlying.knownSize > 0) (2 * underlying.knownSize - 1) else underlying.knownSize
}

class IntersperseSurround[A](underlying: SomeIterableOps[A], start: A, sep: A, end: A) extends View[A] {
def iterator(): Iterator[A] = underlying.iterator().intersperse(start, sep, end)
def iterator: Iterator[A] = underlying.iterator.intersperse(start, sep, end)

override def knownSize: Int =
if (underlying.knownSize > 0) (2 * underlying.knownSize + 1)
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/scala/collection/immutable/MultiDict.scala
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ object MultiDict extends MapFactory[MultiDict] {
def from[K, V](source: IterableOnce[(K, V)]): MultiDict[K, V] =
source match {
case mm: MultiDict[K, V] => mm
case _ => (newBuilder[K, V]() ++= source).result()
case _ => (newBuilder[K, V] ++= source).result()
}

def newBuilder[K, V](): Builder[(K, V), MultiDict[K, V]] =
def newBuilder[K, V]: Builder[(K, V), MultiDict[K, V]] =
new ImmutableBuilder[(K, V), MultiDict[K, V]](empty[K, V]) {
def addOne(elem: (K, V)): this.type = { elems = elems + elem; this }
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/scala/collection/immutable/MultiSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,12 @@ object MultiSet extends IterableFactory[MultiSet] {
def from[A](source: IterableOnce[A]): MultiSet[A] =
source match {
case ms: MultiSet[A] => ms
case _ => (newBuilder[A]() ++= source).result()
case _ => (newBuilder[A] ++= source).result()
}

def empty[A] = new MultiSetImpl[A](Map.empty)

def newBuilder[A](): Builder[A, MultiSet[A]] =
def newBuilder[A]: Builder[A, MultiSet[A]] =
new ImmutableBuilder[A, MultiSet[A]](empty[A]) {
def addOne(elem: A): this.type = { elems = elems + elem; this }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,10 @@ object SortedMultiDict extends SortedMapFactory[SortedMultiDict] {
def from[K: Ordering, V](it: IterableOnce[(K, V)]): SortedMultiDict[K, V] =
it match {
case smm: SortedMultiDict[K, V] => smm
case _ => (newBuilder[K, V]() ++= it).result()
case _ => (newBuilder[K, V] ++= it).result()
}

def newBuilder[K: Ordering, V](): Builder[(K, V), SortedMultiDict[K, V]] =
def newBuilder[K: Ordering, V]: Builder[(K, V), SortedMultiDict[K, V]] =
new ImmutableBuilder[(K, V), SortedMultiDict[K, V]](empty[K, V]) {
def addOne(elem: (K, V)): this.type = { elems = elems + elem; this }
}
Expand Down
Loading