Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
language: scala
jdk: oraclejdk8
script:
- sbt ++2.12.4 memoryBenchmark/compile test ++2.13.0-M2 timeBenchmark/compile test ++0.7.0-RC1 test
- sbt ++2.12.4 memoryBenchmark/compile test ++2.13.0-M2 timeBenchmark/compile test
- sbt ++0.8.0-bin-20180323-5be1360-NIGHTLY test junit/test:compile collections-contribJVM/compile
- sbt ++2.13.0-M2 collections-contribJVM/test junit/test scalacheck/test
- sbt ++2.12.4 collectionsJS/test ++2.13.0-M2 collectionsJS/test collections-contribJS/test
before_script:
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import org.scalajs.sbtplugin.cross.CrossProject

// Convenient setting that allows writing `set scalaVersion := dotty.value` in sbt shell to switch from Scala to Dotty
val dotty = settingKey[String]("dotty version")
dotty in ThisBuild := "0.7.0-RC1"
dotty in ThisBuild := "0.8.0-bin-20180323-5be1360-NIGHTLY"

val collectionsScalaVersionSettings = Seq(
scalaVersion := "2.13.0-M2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package strawman.collection

import annotation.unchecked.uncheckedVariance

/**
* A multidict is a map that can associate a set of values to a given key.
*
Expand Down Expand Up @@ -40,7 +42,7 @@ trait MultiDict[K, V]
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 Down Expand Up @@ -133,13 +135,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 +200,23 @@ trait MultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K, V]]

}

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)
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package strawman
package collection

import annotation.unchecked.uncheckedVariance

/**
* A multidict whose keys are sorted
* @tparam K the type of keys
Expand All @@ -20,7 +22,7 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
extends MultiDictOps[K, V, MultiDict, C]
with SortedOps[K, C] {

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

def sortedMultiMapFactory: SortedMapFactory[SortedMultiDictCC]

Expand Down Expand Up @@ -51,13 +53,8 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,
until(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 +127,24 @@ trait SortedMultiDictOps[K, V, +CC[X, Y] <: MultiDict[X, Y], +C <: MultiDict[K,

}

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)
Original file line number Diff line number Diff line change
Expand Up @@ -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 @@ -62,21 +62,8 @@ trait SortedMultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]]
until(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)
3 changes: 2 additions & 1 deletion collections/src/main/scala/strawman/collection/BitSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import strawman.collection.mutable.Builder

import scala.{Array, Boolean, Int, Long, Option, Ordering, Unit, `inline`}
import scala.Predef.{assert, intWrapper}
import scala.annotation.unchecked.uncheckedVariance

/** Base type of bitsets.
*
Expand Down Expand Up @@ -37,7 +38,7 @@ trait BitSetOps[+C <: BitSet with BitSetOps[C]]

def bitSetFactory: SpecificIterableFactory[Int, BitSetC]

protected[this] type BitSetC = C
protected[this] type BitSetC = C @uncheckedVariance

final def ordering: Ordering[Int] = Ordering.Int

Expand Down
65 changes: 40 additions & 25 deletions collections/src/main/scala/strawman/collection/Iterable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import scala.reflect.ClassTag
import scala.{Any, AnyRef, Array, Boolean, Either, `inline`, Int, None, Numeric, Option, Ordering, PartialFunction, StringContext, Some, Unit, deprecated, IllegalArgumentException, Function1, deprecatedOverriding}
import java.lang.{String, UnsupportedOperationException}
import scala.Predef.<:<
import scala.annotation.unchecked.uncheckedVariance

import strawman.collection.mutable.{ArrayBuffer, Builder, StringBuilder}
import java.lang.String
Expand All @@ -26,8 +27,8 @@ trait Iterable[+A] extends IterableOnce[A] with IterableOps[A, Iterable, Iterabl
//TODO scalac generates an override for this in AbstractMap; Making it final leads to a VerifyError
protected[this] def coll: this.type = this

protected[this] def fromSpecificIterable(coll: Iterable[A]): IterableCC[A] = iterableFactory.from(coll)
protected[this] def newSpecificBuilder(): Builder[A, IterableCC[A]] = iterableFactory.newBuilder[A]()
protected[this] def fromSpecificIterable(coll: Iterable[A @uncheckedVariance]): IterableCC[A] @uncheckedVariance = iterableFactory.from(coll)
protected[this] def newSpecificBuilder(): Builder[A, IterableCC[A]] @uncheckedVariance = iterableFactory.newBuilder[A]()

def iterableFactory: IterableFactory[IterableCC] = Iterable
}
Expand Down Expand Up @@ -68,7 +69,7 @@ trait Iterable[+A] extends IterableOnce[A] with IterableOps[A, Iterable, Iterabl
*/
trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with IterableOnceOps[A, CC, C] {

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

/**
* @return This collection as an `Iterable[A]`. No new collection will be built if `this` is already an `Iterable[A]`.
Expand All @@ -87,7 +88,7 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
* the elements of the resulting collections). In other words, this methods defines
* the evaluation model of the collection.
*/
protected[this] def fromSpecificIterable(coll: Iterable[A]): C
protected[this] def fromSpecificIterable(coll: Iterable[A @uncheckedVariance]): C

/** Similar to `fromSpecificIterable`, but for a (possibly) different type of element.
* Note that the return type is now `CC[E]`.
Expand All @@ -107,7 +108,7 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
* As a consequence, operations should preferably be implemented with `fromSpecificIterable`
* instead of this method.
*/
protected[this] def newSpecificBuilder(): Builder[A, C]
protected[this] def newSpecificBuilder(): Builder[A @uncheckedVariance, C]

/** Selects the first element of this $coll.
* $orderDependent
Expand Down Expand Up @@ -317,26 +318,7 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
* All these operations apply to those elements of this $coll
* which satisfy the predicate `p`.
*/
def withFilter(p: A => Boolean): collection.WithFilter[A, CC] = new WithFilter(p)

/** A template trait that contains just the `map`, `flatMap`, `foreach` and `withFilter` methods
* of trait `Iterable`.
*
* @define coll iterable collection
*/
class WithFilter(p: A => Boolean) extends collection.WithFilter[A, CC] {

protected[this] def filtered = new View.Filter(IterableOps.this, p, isFlipped = false)

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

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

def foreach[U](f: A => U): Unit = filtered.foreach(f)

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

}
def withFilter(p: A => Boolean): collection.WithFilter[A, CC] = new IterableOps.WithFilter(this, p)

/** A pair of, first, all elements that satisfy prediacte `p` and, second,
* all elements that do not. Interesting because it splits a collection in two.
Expand Down Expand Up @@ -712,6 +694,39 @@ trait IterableOps[+A, +CC[_], +C] extends Any with IterableOnce[A] with Iterable
}
}

object IterableOps {

/** A trait that contains just the `map`, `flatMap`, `foreach` and `withFilter` methods
* of trait `Iterable`.
*
* @tparam A Element type (e.g. `Int`)
* @tparam CC Collection type constructor (e.g. `List`)
*
* @define coll collection
*/
class WithFilter[+A, +CC[_]](
`this`: IterableOps[A, CC, _],
p: A => Boolean
) extends collection.WithFilter[A, CC] {

protected[this] def filtered: Iterable[A] =
new View.Filter(`this`, p, isFlipped = false)

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

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

def foreach[U](f: A => U): Unit = filtered.foreach(f)

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

}

}

object Iterable extends IterableFactory.Delegate[Iterable](immutable.Iterable) {
implicit def toLazyZipOps[A, CC[X] <: Iterable[X]](that: CC[A]): LazyZipOps[A, CC[A]] = new LazyZipOps(that)
}
Expand Down
Loading