From e597bcf6c4e57656c5aa1a634dca8db10cee89bb Mon Sep 17 00:00:00 2001 From: NthPortal Date: Tue, 3 Nov 2020 23:44:07 -0500 Subject: [PATCH 1/7] Add scalafmt --- .scalafmt.conf | 7 +++++++ build.sbt | 13 +++++++------ project/plugins.sbt | 7 ++++--- 3 files changed, 18 insertions(+), 9 deletions(-) create mode 100644 .scalafmt.conf diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 0000000..3c89bd1 --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,7 @@ +version = "2.7.5" +align.preset = more +docstrings = JavaDoc +assumeStandardLibraryStripMargin = true +project.git = true +maxColumn = 100 +trailingCommas = multiple diff --git a/build.sbt b/build.sbt index 6d6a88a..09d8717 100644 --- a/build.sbt +++ b/build.sbt @@ -1,18 +1,19 @@ -lazy val root = project.in(file(".")) +lazy val root = project + .in(file(".")) .aggregate(scalaLibraryNextJVM, scalaLibraryNextJS) .settings( publish / skip := true, // With CrossType.Pure, the root project also picks up the sources in `src` Compile / unmanagedSourceDirectories := Nil, - Test / unmanagedSourceDirectories := Nil, + Test / unmanagedSourceDirectories := Nil, ) lazy val scalaLibraryNext = crossProject(JVMPlatform, JSPlatform) .crossType(CrossType.Pure) .in(file(".")) .jvmSettings( - libraryDependencies += "junit" % "junit" % "4.13.1" % Test, - libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test, + libraryDependencies += "junit" % "junit" % "4.13.1" % Test, + libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test, testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-v"), ) .jsConfigure(_.enablePlugins(ScalaJSJUnitPlugin)) @@ -21,11 +22,11 @@ lazy val scalaLibraryNext = crossProject(JVMPlatform, JSPlatform) scalaModuleMimaPreviousVersion := None, scalacOptions ++= Seq("-deprecation", "-feature", "-Werror"), libraryDependencies ++= Seq( - "org.scalacheck" %%% "scalacheck" % "1.15.0" % Test, + "org.scalacheck" %%% "scalacheck" % "1.15.0" % Test ), ) .jsSettings( - Test / fork := false, + Test / fork := false ) lazy val scalaLibraryNextJVM = scalaLibraryNext.jvm diff --git a/project/plugins.sbt b/project/plugins.sbt index 5ccad05..f9a6a26 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,3 +1,4 @@ -addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.2.3") -addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.3.0") -addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0") +addSbtPlugin("org.scala-lang.modules" % "sbt-scala-module" % "2.2.3") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.3.0") +addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.0.0") From 7aaae8bc9acb4cb933eb71222e49943caadb6d08 Mon Sep 17 00:00:00 2001 From: NthPortal Date: Sun, 1 Nov 2020 20:31:34 -0500 Subject: [PATCH 2/7] Add SeqSet and SetFromMap implementations --- src/main/scala/scala/collection/SeqSet.scala | 37 ++ .../scala/scala/collection/SetFromMap.scala | 113 +++++ .../scala/collection/SetFromMapOps.scala | 385 ++++++++++++++++++ .../scala/collection/concurrent/Set.scala | 37 ++ .../collection/concurrent/SetFromMap.scala | 58 +++ .../scala/collection/immutable/SeqSet.scala | 40 ++ .../collection/immutable/SetFromMap.scala | 148 +++++++ .../collection/immutable/next/package.scala | 34 ++ .../scala/collection/mutable/SeqSet.scala | 41 ++ .../scala/collection/mutable/SetFromMap.scala | 150 +++++++ .../collection/mutable/next/package.scala | 34 ++ .../scala/scala/collection/next/package.scala | 33 ++ 12 files changed, 1110 insertions(+) create mode 100644 src/main/scala/scala/collection/SeqSet.scala create mode 100644 src/main/scala/scala/collection/SetFromMap.scala create mode 100644 src/main/scala/scala/collection/SetFromMapOps.scala create mode 100644 src/main/scala/scala/collection/concurrent/Set.scala create mode 100644 src/main/scala/scala/collection/concurrent/SetFromMap.scala create mode 100644 src/main/scala/scala/collection/immutable/SeqSet.scala create mode 100644 src/main/scala/scala/collection/immutable/SetFromMap.scala create mode 100644 src/main/scala/scala/collection/immutable/next/package.scala create mode 100644 src/main/scala/scala/collection/mutable/SeqSet.scala create mode 100644 src/main/scala/scala/collection/mutable/SetFromMap.scala create mode 100644 src/main/scala/scala/collection/mutable/next/package.scala create mode 100644 src/main/scala/scala/collection/next/package.scala diff --git a/src/main/scala/scala/collection/SeqSet.scala b/src/main/scala/scala/collection/SeqSet.scala new file mode 100644 index 0000000..6f27019 --- /dev/null +++ b/src/main/scala/scala/collection/SeqSet.scala @@ -0,0 +1,37 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala.collection + +/** + * A generic trait for ordered sets. Concrete classes have to provide + * functionality for the abstract methods in `SeqSet`. + * + * Note that when checking for equality [[SeqSet]] does not take into account + * ordering. + * + * @tparam A the type of the values contained in this linked set. + * @define coll seq set + * @define Coll `collection.SeqSet` + */ +trait SeqSet[A] + extends Set[A] + with SetOps[A, SeqSet, SeqSet[A]] + with IterableFactoryDefaults[A, SeqSet] { + override def iterableFactory: IterableFactory[SeqSet] = SeqSet +} + +object SeqSet extends IterableFactory.Delegate[SeqSet](immutable.SeqSet) { + def fromMap(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = SeqSetFromMap(factory) + + def fromMap[A](map: SeqMap[A, Unit]): SeqSet[A] = SeqSetFromMap(map) +} diff --git a/src/main/scala/scala/collection/SetFromMap.scala b/src/main/scala/scala/collection/SetFromMap.scala new file mode 100644 index 0000000..728d2a4 --- /dev/null +++ b/src/main/scala/scala/collection/SetFromMap.scala @@ -0,0 +1,113 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection + +import scala.collection.generic.DefaultSerializable + +@SerialVersionUID(3L) +private class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) + extends AbstractSet[A] + with SetFromMapOps.Unknown[A, Map, Map[A, Unit], SetFromMap, SetFromMap[A]] + with SetFromMapOps.Unsorted[A, Map, SetFromMap] + with IterableFactoryDefaults[A, SetFromMap] + with DefaultSerializable { + protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) + + override protected[this] def className: String = "SetFromMap" + + override def iterableFactory: IterableFactory[SetFromMap] = + new SetFromMap.WrapperFactory(underlying.mapFactory) +} + +private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { + def apply(factory: MapFactory[Map]): IterableFactory[Set] = new WrapperFactory(factory) + + def apply[A](map: Map[A, Unit]): Set[A] = new SetFromMap(map) + + @SerialVersionUID(3L) + private class WrapperFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, SetFromMap](mf) { + protected[this] def fromMap[A](map: Map[A, Unit]): SetFromMap[A] = + new SetFromMap(map) + } + +} + +@SerialVersionUID(3L) +private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) + extends AbstractSet[A] + with SeqSet[A] + with SetFromMapOps.Unknown[A, SeqMap, SeqMap[A, Unit], SeqSetFromMap, SeqSetFromMap[A]] + with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with IterableFactoryDefaults[A, SeqSetFromMap] + with DefaultSerializable { + protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = new SeqSetFromMap(m) + + override protected[this] def className: String = "SeqSetFromMap" + + override def iterableFactory: IterableFactory[SeqSetFromMap] = + new SeqSetFromMap.WrapperFactory(underlying.mapFactory) +} + +private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { + def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = new WrapperFactory(factory) + + def apply[A](map: SeqMap[A, Unit]): SeqSet[A] = new SeqSetFromMap(map) + + @SerialVersionUID(3L) + private class WrapperFactory(mf: MapFactory[SeqMap]) + extends SetFromMapFactory[SeqMap, SeqSetFromMap](mf) { + protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSetFromMap[A] = + new SeqSetFromMap(map) + } + +} + +@SerialVersionUID(3L) +private class SortedSetFromMap[A](protected[collection] val underlying: SortedMap[A, Unit])(implicit + val ordering: Ordering[A] +) extends AbstractSet[A] + with SetFromMapOps.Unknown[A, Map, SortedMap[A, Unit], Set, SortedSetFromMap[A]] + with SetFromMapOps.Sorted[A, SortedMap, Set, SortedSetFromMap] + with SortedSet[A] + with SortedSetOps[A, SortedSetFromMap, SortedSetFromMap[A]] + with IterableFactoryDefaults[A, Set] + with SortedSetFactoryDefaults[A, SortedSetFromMap, Set] + with DefaultSerializable { + protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) + + protected[this] def fromSortedMap[B: Ordering](m: SortedMap[B, Unit]): SortedSetFromMap[B] = + new SortedSetFromMap(m) + + override protected[this] def className: String = "SortedSetFromMap" + + override def iterableFactory: IterableFactory[Set] = SetFromMap(underlying.mapFactory) + + override def sortedIterableFactory: SortedIterableFactory[SortedSetFromMap] = + new SortedSetFromMap.WrapperFactory(underlying.sortedMapFactory) +} + +private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, SortedSet] { + def apply(factory: SortedMapFactory[SortedMap]): SortedIterableFactory[SortedSet] = + new WrapperFactory(factory) + + def apply[A](map: SortedMap[A, Unit]): SortedSet[A] = new SortedSetFromMap(map)(map.ordering) + + @SerialVersionUID(3L) + private final class WrapperFactory(mf: SortedMapFactory[SortedMap]) + extends SortedSetFromMapFactory[SortedMap, SortedSetFromMap](mf) { + protected[this] def fromMap[A: Ordering](map: SortedMap[A, Unit]): SortedSetFromMap[A] = + new SortedSetFromMap(map) + } + +} diff --git a/src/main/scala/scala/collection/SetFromMapOps.scala b/src/main/scala/scala/collection/SetFromMapOps.scala new file mode 100644 index 0000000..a0e1bf5 --- /dev/null +++ b/src/main/scala/scala/collection/SetFromMapOps.scala @@ -0,0 +1,385 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection + +import scala.annotation.implicitNotFound +import scala.collection.SetFromMapOps.WrappedMap +import scala.reflect.ClassTag + +trait SetFromMapOps[ + A, + +MM[K, V] <: MapOps[K, V, MM, _], + +M <: MapOps[A, Unit, MM, M], + +CC[_], + +C <: SetFromMapOps[A, MM, M, CC, C], +] extends SetOps[A, CC, C] + with WrappedMap[A] + with Serializable { + protected[collection] val underlying: M + + protected[this] def fromMap[B](m: MM[B, Unit]): CC[B] + + protected[this] def fromSpecificMap(m: M): C + + // methods for adapting functions for a set to functions for a map + @inline protected[this] def adapted[B](f: A => B): ((A, Unit)) => B = { case (elem, _) => + f(elem) + } + + @inline protected[this] def adaptedTuple[B](f: A => B): ((A, Unit)) => (B, Unit) = { + case (elem, _) => f(elem) -> () + } + + @inline protected[this] def adaptedTuplePF[B]( + pf: PartialFunction[A, B] + ): PartialFunction[(A, Unit), (B, Unit)] = + adapted(pf.lift).andThen(_.map(_ -> ())).unlift + + def contains(elem: A): Boolean = underlying contains elem + + def iterator: Iterator[A] = underlying.keysIterator + + override def isEmpty: Boolean = underlying.isEmpty + + override def size: Int = underlying.size + + override def knownSize: Int = underlying.knownSize + + override def head: A = underlying.head._1 + + override def headOption: Option[A] = underlying.headOption.map(_._1) + + override def last: A = underlying.last._1 + + override def lastOption: Option[A] = underlying.lastOption.map(_._1) + + override def collect[B](pf: PartialFunction[A, B]): CC[B] = fromMap( + underlying collect adaptedTuplePF(pf) + ) + + override def collectFirst[B](pf: PartialFunction[A, B]): Option[B] = + underlying collectFirst adapted(pf.lift).unlift + + override def copyToArray[B >: A](xs: Array[B], start: Int): Int = + underlying.keySet.copyToArray(xs, start) + + override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int): Int = + underlying.keySet.copyToArray(xs, start, len) + + override def count(p: A => Boolean): Int = underlying.keySet count p + + override def drop(n: Int): C = fromSpecificMap(underlying drop n) + + override def dropRight(n: Int): C = fromSpecificMap(underlying dropRight n) + + override def dropWhile(p: A => Boolean): C = fromSpecificMap(underlying dropWhile adapted(p)) + + override def exists(p: A => Boolean): Boolean = underlying exists adapted(p) + + override def filter(pred: A => Boolean): C = fromSpecificMap(underlying filter adapted(pred)) + + override def filterNot(pred: A => Boolean): C = fromSpecificMap( + underlying filterNot adapted(pred) + ) + + override def find(p: A => Boolean): Option[A] = underlying.keySet find p + + override def flatMap[B](f: A => IterableOnce[B]): CC[B] = fromMap { + underlying flatMap { case (elem, _) => + f(elem) match { + case that: WrappedMap[B] => that.underlying + case that => that.iterator map { _ -> () } + } + } + } + + override def flatten[B](implicit asIterable: A => IterableOnce[B]): CC[B] = flatMap(asIterable) + + override def foldLeft[B](z: B)(op: (B, A) => B): B = underlying.keySet.foldLeft(z)(op) + + override def foldRight[B](z: B)(op: (A, B) => B): B = underlying.keySet.foldRight(z)(op) + + override def forall(p: A => Boolean): Boolean = underlying.keySet forall p + + override def foreach[U](f: A => U): Unit = underlying.keySet foreach f + + override def groupMapReduce[K, B](key: A => K)(f: A => B)( + reduce: (B, B) => B + ): immutable.Map[K, B] = + underlying.keySet.groupMapReduce(key)(f)(reduce) + + @deprecated( + "Check .knownSize instead of .hasDefiniteSize for more actionable information (see scaladoc for details)", + "2.13.0", + ) + override def hasDefiniteSize: Boolean = underlying.hasDefiniteSize + + override def map[B](f: A => B): CC[B] = fromMap(underlying map adaptedTuple(f)) + + override def max[B >: A: Ordering]: A = underlying.keySet.max[B] + + override def maxBy[B: Ordering](f: A => B): A = underlying.keySet maxBy f + + override def min[B >: A: Ordering]: A = underlying.keySet.min[B] + + override def minBy[B: Ordering](f: A => B): A = underlying.keySet minBy f + + override def partition(p: A => Boolean): (C, C) = { + val (a, b) = underlying partition adapted(p) + (fromSpecificMap(a), fromSpecificMap(b)) + } + + override def partitionMap[A1, A2](f: A => Either[A1, A2]): (CC[A1], CC[A2]) = { + val (a, b) = underlying partitionMap adapted(f) + (iterableFactory.from(a), iterableFactory.from(b)) + } + + override def reduceLeft[B >: A](op: (B, A) => B): B = underlying.keySet reduceLeft op + + override def reduceLeftOption[B >: A](op: (B, A) => B): Option[B] = + underlying.keySet reduceLeftOption op + + override def reduceRight[B >: A](op: (A, B) => B): B = underlying.keySet reduceRight op + + override def reduceRightOption[B >: A](op: (A, B) => B): Option[B] = + underlying.keySet reduceRightOption op + + override def scanLeft[B](z: B)(op: (B, A) => B): CC[B] = + iterableFactory.from(underlying.scanLeft(z)((acc, t) => op(acc, t._1))) + + override def scanRight[B](z: B)(op: (A, B) => B): CC[B] = + iterableFactory.from(underlying.scanRight(z)((t, acc) => op(t._1, acc))) + + override def slice(from: Int, until: Int): C = fromSpecificMap(underlying.slice(from, until)) + + override def span(p: A => Boolean): (C, C) = { + val (a, b) = underlying span adapted(p) + (fromSpecificMap(a), fromSpecificMap(b)) + } + + override def splitAt(n: Int): (C, C) = { + val (a, b) = underlying splitAt n + (fromSpecificMap(a), fromSpecificMap(b)) + } + + override def stepper[S <: Stepper[_]](implicit shape: StepperShape[A, S]): S = + underlying.keyStepper + + override def take(n: Int): C = fromSpecificMap(underlying take n) + + override def takeRight(n: Int): C = fromSpecificMap(underlying takeRight n) + + override def takeWhile(p: A => Boolean): C = fromSpecificMap(underlying takeWhile adapted(p)) + + override def tapEach[U](f: A => U): C = fromSpecificMap(underlying tapEach adapted(f)) + + override def toArray[B >: A: ClassTag]: Array[B] = underlying.keySet.toArray[B] + + override def view: View[A] = underlying.keySet.view +} + +object SetFromMapOps { + + // top type to make pattern matching easier + sealed trait WrappedMap[A] extends IterableOnce[A] { + protected[collection] val underlying: IterableOnce[(A, Unit)] + } + + // unknown whether mutable or immutable + trait Unknown[ + A, + +MM[K, V] <: MapOps[K, V, MM, _], + +M <: MapOps[A, Unit, MM, M], + +CC[_], + +C <: Unknown[A, MM, M, CC, C], + ] extends SetFromMapOps[A, MM, M, CC, C] { + def diff(that: Set[A]): C = + toIterable + .foldLeft(newSpecificBuilder)((b, elem) => if (that contains elem) b else b += elem) + .result() + } + + trait Unsorted[A, +MM[K, V] <: MapOps[K, V, MM, MM[K, V]], +CC[X] <: Unsorted[X, MM, CC]] + extends SetFromMapOps[A, MM, MM[A, Unit], CC, CC[A]] { + protected[this] final def fromSpecificMap(m: MM[A, Unit]): CC[A] = fromMap(m) + + override def concat(that: IterableOnce[A]): CC[A] = fromMap { + that match { + case coll: WrappedMap[A] => underlying concat coll.underlying + case coll => underlying concat coll.iterator.map((_, ())) + } + } + } + + trait Sorted[ + A, + +MM[K, V] <: Map[K, V] with SortedMapOps[K, V, MM, MM[K, V]], + +UnsortedCC[X] <: Set[X], + +CC[X] <: Sorted[X, MM, UnsortedCC, CC] with SortedSet[X] with SortedSetOps[X, CC, CC[X]], + ] extends SetFromMapOps[A, Map, MM[A, Unit], UnsortedCC, CC[A]] + with SortedSetOps[A, CC, CC[A]] { + override protected[collection] val underlying: MM[A, Unit] + + @inline protected[this] final implicit def implicitOrd: Ordering[A] = ordering + + protected[this] def fromSortedMap[B: Ordering](m: MM[B, Unit]): CC[B] + + protected[this] final def fromSpecificMap(m: MM[A, Unit]): CC[A] = fromSortedMap(m) + + def iteratorFrom(start: A): Iterator[A] = underlying.keysIteratorFrom(start) + + def rangeImpl(from: Option[A], until: Option[A]): CC[A] = + fromSortedMap(underlying.rangeImpl(from, until)) + + override def rangeTo(to: A): CC[A] = fromSortedMap(underlying rangeTo to) + + override def head: A = underlying.firstKey + + override def firstKey: A = underlying.firstKey + + override def headOption: Option[A] = underlying.headOption.map(_._1) + + override def last: A = underlying.lastKey + + override def lastKey: A = underlying.lastKey + + override def lastOption: Option[A] = underlying.lastOption.map(_._1) + + override def collect[B](pf: PartialFunction[A, B])(implicit + @implicitNotFound(SortedSetOps.ordMsg) ev: Ordering[B] + ): CC[B] = + fromSortedMap(underlying collect adaptedTuplePF(pf)) + + override def concat(that: IterableOnce[A]): CC[A] = fromSortedMap { + that match { + case coll: WrappedMap[A] => underlying concat coll.underlying + case coll => underlying concat coll.iterator.map((_, ())) + } + } + + override def flatMap[B]( + f: A => IterableOnce[B] + )(implicit @implicitNotFound(SortedSetOps.ordMsg) ev: Ordering[B]): CC[B] = + fromSortedMap { + underlying flatMap { case (elem, _) => + f(elem) match { + case that: WrappedMap[B] => that.underlying + case that => that.iterator map { _ -> () } + } + } + } + + override def map[B](f: A => B)(implicit + @implicitNotFound(SortedSetOps.ordMsg) ev: Ordering[B] + ): CC[B] = + fromSortedMap(underlying map adaptedTuple(f)) + + override def max[B >: A: Ordering]: A = super[SortedSetOps].max[B] + + override def maxBefore(key: A): Option[A] = underlying maxBefore key map { _._1 } + + override def min[B >: A: Ordering]: A = super[SortedSetOps].min + + override def minAfter(key: A): Option[A] = underlying minAfter key map { _._1 } + } + +} + +abstract class SetFromMapFactory[+MM[K, V] <: Map[K, V], +CC[A] <: WrappedMap[A]]( + mf: MapFactory[MM] +) extends IterableFactory[CC] + with Serializable { + protected[this] def fromMap[A](map: MM[A, Unit]): CC[A] + + def from[A](source: IterableOnce[A]): CC[A] = + source match { + case coll: WrappedMap[A] => fromMap(mf from coll.underlying) + case coll => newBuilder[A].addAll(coll).result() + } + + def empty[A]: CC[A] = fromMap(mf.empty) + + def newBuilder[A]: mutable.Builder[A, CC[A]] = new WrappedBuilder(mf.newBuilder) + + private final class WrappedBuilder[A](b: mutable.Builder[(A, Unit), MM[A, Unit]]) + extends mutable.Builder[A, CC[A]] { + def clear(): Unit = b.clear() + + def result(): CC[A] = fromMap(b.result()) + + def addOne(elem: A): this.type = { b.addOne((elem, ())); this } + + override def addAll(xs: IterableOnce[A]): this.type = + xs match { + case coll: WrappedMap[A] => + b.addAll(coll.underlying) + this + case coll => super.addAll(coll) + } + + override def sizeHint(size: Int): Unit = b.sizeHint(size) + } + +} + +abstract class SortedSetFromMapFactory[+MM[K, V] <: SortedMap[K, V], +CC[A] <: WrappedMap[A]]( + mf: SortedMapFactory[MM] +) extends SortedIterableFactory[CC] + with Serializable { + protected[this] def fromMap[A: Ordering](map: MM[A, Unit]): CC[A] + + def from[A: Ordering](it: IterableOnce[A]): CC[A] = + it match { + case coll: WrappedMap[A] => fromMap(mf from coll.underlying) + case coll => newBuilder[A].addAll(coll).result() + } + + def empty[A: Ordering]: CC[A] = fromMap(mf.empty) + + def newBuilder[A: Ordering]: mutable.Builder[A, CC[A]] = new WrapperBuilder[A](mf.newBuilder) + + private final class WrapperBuilder[A: Ordering](b: mutable.Builder[(A, Unit), MM[A, Unit]]) + extends mutable.Builder[A, CC[A]] { + def clear(): Unit = b.clear() + + def result(): CC[A] = fromMap(b.result()) + + def addOne(elem: A): this.type = { b.addOne((elem, ())); this } + + override def addAll(xs: IterableOnce[A]): this.type = + xs match { + case coll: WrappedMap[A] => + b.addAll(coll.underlying) + this + case coll => super.addAll(coll) + } + + override def sizeHint(size: Int): Unit = b.sizeHint(size) + } + +} + +sealed abstract class SetFromMapMetaFactoryBase[MM[K, V] <: Map[K, V], +CC[A] <: Set[A]] { + def apply[A](map: MM[A, Unit]): CC[A] +} + +abstract class SetFromMapMetaFactory[MM[K, V] <: Map[K, V], +CC[A] <: Set[A]] + extends SetFromMapMetaFactoryBase[MM, CC] { + def apply(factory: MapFactory[MM]): IterableFactory[CC] +} + +abstract class SortedSetFromMapMetaFactory[MM[K, V] <: SortedMap[K, V], +CC[A] <: SortedSet[A]] + extends SetFromMapMetaFactoryBase[MM, CC] { + def apply(factory: SortedMapFactory[MM]): SortedIterableFactory[CC] +} diff --git a/src/main/scala/scala/collection/concurrent/Set.scala b/src/main/scala/scala/collection/concurrent/Set.scala new file mode 100644 index 0000000..73faaa1 --- /dev/null +++ b/src/main/scala/scala/collection/concurrent/Set.scala @@ -0,0 +1,37 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection +package concurrent + +/** + * A template trait for mutable sets that allow concurrent access. + * + * $concurrentsetinfo + * + * @tparam A the value type of the set + * @define Coll `concurrent.Set` + * @define coll concurrent set + * @define concurrentsetinfo + * This is a base trait for all Scala concurrent set implementations. It + * provides all of the methods a `Set` does, with the difference that all the + * changes are atomic. + * @note The concurrent set do not accept `null` for values. + */ +trait Set[A] extends scala.collection.mutable.Set[A] + +object Set extends IterableFactory.Delegate[Set](SetFromMap(TrieMap)) { + def fromMap(factory: MapFactory[Map]): IterableFactory[Set] = SetFromMap(factory) + + def fromMap[A](map: Map[A, Unit]): Set[A] = SetFromMap(map) +} diff --git a/src/main/scala/scala/collection/concurrent/SetFromMap.scala b/src/main/scala/scala/collection/concurrent/SetFromMap.scala new file mode 100644 index 0000000..4b976b6 --- /dev/null +++ b/src/main/scala/scala/collection/concurrent/SetFromMap.scala @@ -0,0 +1,58 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection +package concurrent + +import scala.collection.generic.DefaultSerializable +import scala.collection.{mutable => m} + +@SerialVersionUID(3L) +private class SetFromMap[A](override protected[collection] val underlying: Map[A, Unit]) + extends mutable.SetFromMap[A](underlying) + with Set[A] + with mutable.SetFromMapOps[A, m.Map, m.Map[A, Unit], m.SetFromMap, m.SetFromMap[A]] + with IterableFactoryDefaults[A, m.SetFromMap] + with DefaultSerializable { + override protected[this] def fromMap[B](m: mutable.Map[B, Unit]): mutable.SetFromMap[B] = + SetFromMap.fromMutableMap(m) + + override protected[this] def className: String = "SetFromMap" + + override def iterableFactory: IterableFactory[m.SetFromMap] = + new SetFromMap.MutableFactory(underlying.mapFactory) +} + +private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { + def apply(factory: MapFactory[Map]): IterableFactory[SetFromMap] = new WrapperFactory(factory) + + def apply[A](map: Map[A, Unit]): Set[A] = new SetFromMap(map) + + @inline private def fromMutableMap[A](map: m.Map[A, Unit]): m.SetFromMap[A] = + map match { + case conc: Map[A, Unit] => new SetFromMap(conc) + case mut => new m.SetFromMap(mut) + } + + @SerialVersionUID(3L) + private class WrapperFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, SetFromMap](mf) { + protected[this] def fromMap[A](map: Map[A, Unit]): SetFromMap[A] = new SetFromMap(map) + } + + @SerialVersionUID(3L) + private class MutableFactory(mf: MapFactory[m.Map]) + extends SetFromMapFactory[m.Map, m.SetFromMap](mf) { + protected[this] def fromMap[A](map: m.Map[A, Unit]): m.SetFromMap[A] = fromMutableMap(map) + } + +} diff --git a/src/main/scala/scala/collection/immutable/SeqSet.scala b/src/main/scala/scala/collection/immutable/SeqSet.scala new file mode 100644 index 0000000..e09f40b --- /dev/null +++ b/src/main/scala/scala/collection/immutable/SeqSet.scala @@ -0,0 +1,40 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection +package immutable + +/** + * A generic trait for ordered immutable sets. Concrete classes have to provide + * functionality for the abstract methods in `SeqSet`. + * + * Note that when checking for equality [[SeqSet]] does not take into account + * ordering. + * + * @tparam A the type of the values contained in this linked set. + * @define coll immutable seq set + * @define Coll `immutable.SeqSet` + */ +trait SeqSet[A] + extends Set[A] + with collection.SeqSet[A] + with SetOps[A, SeqSet, SeqSet[A]] + with IterableFactoryDefaults[A, SeqSet] { + override def iterableFactory: IterableFactory[SeqSet] = SeqSet +} + +object SeqSet extends IterableFactory.Delegate[SeqSet](SeqSetFromMap(SeqMap)) { + def fromMap(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = SeqSetFromMap(factory) + + def fromMap[A](map: SeqMap[A, Unit]): SeqSet[A] = SeqSetFromMap(map) +} diff --git a/src/main/scala/scala/collection/immutable/SetFromMap.scala b/src/main/scala/scala/collection/immutable/SetFromMap.scala new file mode 100644 index 0000000..070d873 --- /dev/null +++ b/src/main/scala/scala/collection/immutable/SetFromMap.scala @@ -0,0 +1,148 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection +package immutable + +import scala.collection.generic.DefaultSerializable + +trait SetFromMapOps[ + A, + +MM[K, +V] <: MapOps[K, V, MM, _], + +M <: MapOps[A, Unit, MM, M], + +CC[_], + +C <: SetFromMapOps[A, MM, M, CC, C], +] extends SetOps[A, CC, C] + with collection.SetFromMapOps[A, MM, M, CC, C] { + def excl(elem: A): C = fromSpecificMap(underlying removed elem) + + override def removedAll(that: IterableOnce[A]): C = fromSpecificMap(underlying removedAll that) +} + +object SetFromMapOps { + + trait Unsorted[ + A, + +MM[K, +V] <: MapOps[K, V, MM, MM[K, V]], + +CC[X] <: Unsorted[X, MM, CC], + ] extends SetFromMapOps[A, MM, MM[A, Unit], CC, CC[A]] + with collection.SetFromMapOps.Unsorted[A, MM, CC] { + def incl(elem: A): CC[A] = fromMap(underlying.updated(elem, ())) + } + +} + +@SerialVersionUID(3L) +private class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) + extends AbstractSet[A] + with SetFromMapOps.Unsorted[A, Map, SetFromMap] + with IterableFactoryDefaults[A, SetFromMap] + with DefaultSerializable { + protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) + + override protected[this] def className: String = "SetFromMap" + + override def iterableFactory: IterableFactory[SetFromMap] = + new SetFromMap.WrapperFactory(underlying.mapFactory) +} + +private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { + def apply(factory: MapFactory[Map]): IterableFactory[Set] = new WrapperFactory(factory) + + def apply[A](map: Map[A, Unit]): Set[A] = new SetFromMap(map) + + @SerialVersionUID(3L) + private class WrapperFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, SetFromMap](mf) { + protected[this] def fromMap[A](map: Map[A, Unit]): SetFromMap[A] = + new SetFromMap(map) + } + +} + +@SerialVersionUID(3L) +private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) + extends AbstractSet[A] + with SeqSet[A] + with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with IterableFactoryDefaults[A, SeqSetFromMap] + with DefaultSerializable { + protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = + new SeqSetFromMap(m) + + override protected[this] def className: String = "SeqSetFromMap" + + override def iterableFactory: IterableFactory[SeqSetFromMap] = + new SeqSetFromMap.WrapperFactory(underlying.mapFactory) +} + +private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { + def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = new WrapperFactory(factory) + + def apply[A](map: SeqMap[A, Unit]): SeqSet[A] = new SeqSetFromMap(map) + + @SerialVersionUID(3L) + private class WrapperFactory(mf: MapFactory[SeqMap]) + extends SetFromMapFactory[SeqMap, SeqSetFromMap](mf) { + protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSetFromMap[A] = + new SeqSetFromMap(map) + } + +} + +@SerialVersionUID(3L) +private class SortedSetFromMap[A](protected[collection] val underlying: SortedMap[A, Unit])(implicit + val ordering: Ordering[A] +) extends AbstractSet[A] + with SetFromMapOps[A, Map, SortedMap[A, Unit], Set, SortedSetFromMap[A]] + with collection.SetFromMapOps.Sorted[A, SortedMap, Set, SortedSetFromMap] + with SortedSet[A] + with SortedSetOps[A, SortedSetFromMap, SortedSetFromMap[A]] + with IterableFactoryDefaults[A, Set] + with SortedSetFactoryDefaults[A, SortedSetFromMap, Set] + with DefaultSerializable { + + import SortedSetFromMap.ssfm + + protected[this] def fromMap[B](m: Map[B, Unit]): Set[B] = new SetFromMap(m) + + protected[this] def fromSortedMap[B: Ordering](m: SortedMap[B, Unit]): SortedSetFromMap[B] = + new SortedSetFromMap(m) + + override protected[this] def className: String = "SortedSetFromMap" + + override def iterableFactory: IterableFactory[Set] = SetFromMap(underlying.mapFactory) + + override def sortedIterableFactory: SortedIterableFactory[SortedSetFromMap] = + new SortedSetFromMap.WrapperFactory(underlying.sortedMapFactory) + + override def incl(elem: A): SortedSetFromMap[A] = ssfm(underlying.updated(elem, ())) +} + +private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, SortedSet] { + @inline private def ssfm[A: Ordering](map: SortedMap[A, Unit]): SortedSetFromMap[A] = + new SortedSetFromMap(map) + + def apply(factory: SortedMapFactory[SortedMap]): SortedIterableFactory[SortedSet] = + new WrapperFactory(factory) + + def apply[A](map: SortedMap[A, Unit]): SortedSet[A] = ssfm(map)(map.ordering) + + @SerialVersionUID(3L) + private final class WrapperFactory(mf: SortedMapFactory[SortedMap]) + extends SortedSetFromMapFactory[SortedMap, SortedSetFromMap](mf) { + protected[this] def fromMap[A: Ordering](map: SortedMap[A, Unit]): SortedSetFromMap[A] = ssfm( + map + ) + } + +} diff --git a/src/main/scala/scala/collection/immutable/next/package.scala b/src/main/scala/scala/collection/immutable/next/package.scala new file mode 100644 index 0000000..292e30f --- /dev/null +++ b/src/main/scala/scala/collection/immutable/next/package.scala @@ -0,0 +1,34 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection +package immutable + +import scala.annotation.unused + +package object next { + implicit final class NextSCISetCompanionExtensions(@unused private val self: Set.type) + extends AnyVal { + def fromMap(factory: MapFactory[Map]): IterableFactory[Set] = SetFromMap(factory) + + def fromMap[A](map: Map[A, Unit]): Set[A] = SetFromMap(map) + } + + implicit final class NextSCISortedSetCompanionExtensions(@unused private val self: SortedSet.type) + extends AnyVal { + def fromMap(factory: SortedMapFactory[SortedMap]): SortedIterableFactory[SortedSet] = + SortedSetFromMap(factory) + + def fromMap[A](map: SortedMap[A, Unit]): SortedSet[A] = SortedSetFromMap(map) + } +} diff --git a/src/main/scala/scala/collection/mutable/SeqSet.scala b/src/main/scala/scala/collection/mutable/SeqSet.scala new file mode 100644 index 0000000..9ec1279 --- /dev/null +++ b/src/main/scala/scala/collection/mutable/SeqSet.scala @@ -0,0 +1,41 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection +package mutable + +/** + * A generic trait for ordered mutable sets. Concrete classes have to provide + * functionality for the abstract methods in `SeqSet`. + * + * Note that when checking for equality [[SeqSet]] does not take into account + * ordering. + * + * @tparam A the type of the values contained in this linked set. + * @define coll mutable seq set + * @define Coll `mutable.SeqSet` + */ +trait SeqSet[A] + extends Set[A] + with collection.SeqSet[A] + with SetOps[A, SeqSet, SeqSet[A]] + with IterableFactoryDefaults[A, SeqSet] { + override def iterableFactory: IterableFactory[SeqSet] = SeqSet +} + +object SeqSet extends IterableFactory.Delegate[SeqSet](SeqSetFromMap(SeqMap)) { + // TODO: migrate? + def fromMap(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = SeqSetFromMap(factory) + + def fromMap[A](map: SeqMap[A, Unit]): SeqSet[A] = SeqSetFromMap(map) +} diff --git a/src/main/scala/scala/collection/mutable/SetFromMap.scala b/src/main/scala/scala/collection/mutable/SetFromMap.scala new file mode 100644 index 0000000..5938ba1 --- /dev/null +++ b/src/main/scala/scala/collection/mutable/SetFromMap.scala @@ -0,0 +1,150 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection +package mutable + +import scala.collection.SetFromMapOps.WrappedMap +import scala.collection.generic.DefaultSerializable + +trait SetFromMapOps[ + A, + +MM[K, V] <: MapOps[K, V, MM, _], + +M <: MapOps[A, Unit, MM, M], + +CC[_], + +C <: SetFromMapOps[A, MM, M, CC, C], +] extends SetOps[A, CC, C] + with collection.SetFromMapOps[A, MM, M, CC, C] { + def clear(): Unit = underlying.clear() + + def addOne(elem: A): this.type = { underlying.update(elem, ()); this } + + override def add(elem: A): Boolean = underlying.put(elem, ()).isEmpty + + override def addAll(xs: IterableOnce[A]): this.type = + xs match { + case coll: WrappedMap[A] => + underlying.addAll(coll.underlying) + this + case coll => super.addAll(coll) + } + + def subtractOne(elem: A): this.type = { underlying.subtractOne(elem); this } + + override def remove(elem: A): Boolean = underlying.remove(elem).isDefined + + override def subtractAll(xs: IterableOnce[A]): this.type = { underlying.subtractAll(xs); this } + + override def knownSize: Int = underlying.knownSize +} + +@SerialVersionUID(3L) +private[collection] class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) + extends AbstractSet[A] + with SetFromMapOps[A, Map, Map[A, Unit], SetFromMap, SetFromMap[A]] + with SetFromMapOps.Unsorted[A, Map, SetFromMap] + with IterableFactoryDefaults[A, SetFromMap] + with DefaultSerializable { + protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) + + override protected[this] def className: String = "SetFromMap" + + override def iterableFactory: IterableFactory[SetFromMap] = SetFromMap(underlying.mapFactory) +} + +private[collection] object SetFromMap extends SetFromMapMetaFactory[Map, Set] { + def apply(factory: MapFactory[Map]): IterableFactory[SetFromMap] = new WrapperFactory(factory) + + def apply[A](map: Map[A, Unit]): Set[A] = new SetFromMap(map) + + @SerialVersionUID(3L) + private class WrapperFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, SetFromMap](mf) { + protected[this] def fromMap[A](map: Map[A, Unit]): SetFromMap[A] = + new SetFromMap(map) + } + +} + +@SerialVersionUID(3L) +private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) + extends AbstractSet[A] + with SeqSet[A] + with SetFromMapOps[A, SeqMap, SeqMap[A, Unit], SeqSetFromMap, SeqSetFromMap[A]] + with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with IterableFactoryDefaults[A, SeqSetFromMap] + with DefaultSerializable { + protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = new SeqSetFromMap(m) + + override protected[this] def className: String = "SeqSetFromMap" + + override def iterableFactory: IterableFactory[SeqSetFromMap] = SeqSetFromMap( + underlying.mapFactory + ) +} + +private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { + def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSetFromMap] = new WrapperFactory( + factory + ) + + def apply[A](map: SeqMap[A, Unit]): mutable.SeqSet[A] = new SeqSetFromMap(map) + + @SerialVersionUID(3L) + private class WrapperFactory(mf: MapFactory[SeqMap]) + extends SetFromMapFactory[SeqMap, SeqSetFromMap](mf) { + protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSetFromMap[A] = + new SeqSetFromMap(map) + } + +} + +@SerialVersionUID(3L) +private class SortedSetFromMap[A](protected[collection] val underlying: SortedMap[A, Unit])(implicit + val ordering: Ordering[A] +) extends AbstractSet[A] + with SetFromMapOps[A, Map, SortedMap[A, Unit], Set, SortedSetFromMap[A]] + with SetFromMapOps.Sorted[A, SortedMap, Set, SortedSetFromMap] + with SortedSet[A] + with SortedSetOps[A, SortedSetFromMap, SortedSetFromMap[A]] + with IterableFactoryDefaults[A, Set] + with SortedSetFactoryDefaults[A, SortedSetFromMap, Set] + with DefaultSerializable { + protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) + + protected[this] def fromSortedMap[B: Ordering](m: SortedMap[B, Unit]): SortedSetFromMap[B] = + new SortedSetFromMap(m) + + override protected[this] def className: String = "SortedSetFromMap" + + override def iterableFactory: IterableFactory[SetFromMap] = SetFromMap(underlying.mapFactory) + + override def sortedIterableFactory: SortedIterableFactory[SortedSetFromMap] = + new SortedSetFromMap.WrapperFactory(underlying.sortedMapFactory) +} + +private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, SortedSet] { + def apply(factory: SortedMapFactory[SortedMap]): SortedIterableFactory[SortedSet] = + new WrapperFactory(factory) + + def apply[A](map: SortedMap[A, Unit]): mutable.SortedSet[A] = new SortedSetFromMap(map)( + map.ordering + ) + + @SerialVersionUID(3L) + private final class WrapperFactory(mf: SortedMapFactory[SortedMap]) + extends SortedSetFromMapFactory[SortedMap, SortedSetFromMap](mf) { + protected[this] def fromMap[A: Ordering](map: SortedMap[A, Unit]): SortedSetFromMap[A] = + new SortedSetFromMap(map) + } + +} diff --git a/src/main/scala/scala/collection/mutable/next/package.scala b/src/main/scala/scala/collection/mutable/next/package.scala new file mode 100644 index 0000000..4c87d5c --- /dev/null +++ b/src/main/scala/scala/collection/mutable/next/package.scala @@ -0,0 +1,34 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection +package mutable + +import scala.annotation.unused + +package object next { + implicit final class NextSCMSetCompanionExtensions(@unused private val self: Set.type) + extends AnyVal { + def fromMap(factory: MapFactory[Map]): IterableFactory[Set] = SetFromMap(factory) + + def fromMap[A](map: Map[A, Unit]): Set[A] = SetFromMap(map) + } + + implicit final class NextSCMSortedSetCompanionExtensions(@unused private val self: SortedSet.type) + extends AnyVal { + def fromMap(factory: SortedMapFactory[SortedMap]): SortedIterableFactory[SortedSet] = + SortedSetFromMap(factory) + + def fromMap[A](map: SortedMap[A, Unit]): SortedSet[A] = SortedSetFromMap(map) + } +} diff --git a/src/main/scala/scala/collection/next/package.scala b/src/main/scala/scala/collection/next/package.scala new file mode 100644 index 0000000..6a32f1f --- /dev/null +++ b/src/main/scala/scala/collection/next/package.scala @@ -0,0 +1,33 @@ +/* + * Scala (https://www.scala-lang.org) + * + * Copyright EPFL and Lightbend, Inc. + * + * Licensed under Apache License 2.0 + * (http://www.apache.org/licenses/LICENSE-2.0). + * + * See the NOTICE file distributed with this work for + * additional information regarding copyright ownership. + */ + +package scala +package collection + +import scala.annotation.unused + +package object next { + implicit final class NextSCSetCompanionExtensions(@unused private val self: Set.type) + extends AnyVal { + def fromMap(factory: MapFactory[Map]): IterableFactory[Set] = SetFromMap(factory) + + def fromMap[A](map: Map[A, Unit]): Set[A] = SetFromMap(map) + } + + implicit final class NextSCSortedSetCompanionExtensions(@unused private val self: SortedSet.type) + extends AnyVal { + def fromMap(factory: SortedMapFactory[SortedMap]): SortedIterableFactory[SortedSet] = + SortedSetFromMap(factory) + + def fromMap[A](map: SortedMap[A, Unit]): SortedSet[A] = SortedSetFromMap(map) + } +} From 023ba1bb6379a2523c8a5b7e5663f231e6722f36 Mon Sep 17 00:00:00 2001 From: NthPortal Date: Sun, 1 Nov 2020 20:51:02 -0500 Subject: [PATCH 3/7] fixup! Add SeqSet and SetFromMap implementations tweak SeqSet inheritance order --- src/main/scala/scala/collection/SetFromMap.scala | 2 +- src/main/scala/scala/collection/concurrent/SetFromMap.scala | 2 -- src/main/scala/scala/collection/immutable/SetFromMap.scala | 2 +- src/main/scala/scala/collection/mutable/SetFromMap.scala | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/scala/scala/collection/SetFromMap.scala b/src/main/scala/scala/collection/SetFromMap.scala index 728d2a4..bfb4704 100644 --- a/src/main/scala/scala/collection/SetFromMap.scala +++ b/src/main/scala/scala/collection/SetFromMap.scala @@ -46,9 +46,9 @@ private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { @SerialVersionUID(3L) private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) extends AbstractSet[A] - with SeqSet[A] with SetFromMapOps.Unknown[A, SeqMap, SeqMap[A, Unit], SeqSetFromMap, SeqSetFromMap[A]] with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with SeqSet[A] with IterableFactoryDefaults[A, SeqSetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = new SeqSetFromMap(m) diff --git a/src/main/scala/scala/collection/concurrent/SetFromMap.scala b/src/main/scala/scala/collection/concurrent/SetFromMap.scala index 4b976b6..b75da63 100644 --- a/src/main/scala/scala/collection/concurrent/SetFromMap.scala +++ b/src/main/scala/scala/collection/concurrent/SetFromMap.scala @@ -27,8 +27,6 @@ private class SetFromMap[A](override protected[collection] val underlying: Map[A override protected[this] def fromMap[B](m: mutable.Map[B, Unit]): mutable.SetFromMap[B] = SetFromMap.fromMutableMap(m) - override protected[this] def className: String = "SetFromMap" - override def iterableFactory: IterableFactory[m.SetFromMap] = new SetFromMap.MutableFactory(underlying.mapFactory) } diff --git a/src/main/scala/scala/collection/immutable/SetFromMap.scala b/src/main/scala/scala/collection/immutable/SetFromMap.scala index 070d873..8410653 100644 --- a/src/main/scala/scala/collection/immutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/immutable/SetFromMap.scala @@ -72,8 +72,8 @@ private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { @SerialVersionUID(3L) private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) extends AbstractSet[A] - with SeqSet[A] with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with SeqSet[A] with IterableFactoryDefaults[A, SeqSetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = diff --git a/src/main/scala/scala/collection/mutable/SetFromMap.scala b/src/main/scala/scala/collection/mutable/SetFromMap.scala index 5938ba1..cd054f1 100644 --- a/src/main/scala/scala/collection/mutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/mutable/SetFromMap.scala @@ -78,9 +78,9 @@ private[collection] object SetFromMap extends SetFromMapMetaFactory[Map, Set] { @SerialVersionUID(3L) private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) extends AbstractSet[A] - with SeqSet[A] with SetFromMapOps[A, SeqMap, SeqMap[A, Unit], SeqSetFromMap, SeqSetFromMap[A]] with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with SeqSet[A] with IterableFactoryDefaults[A, SeqSetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = new SeqSetFromMap(m) From 2fd665dcb55d2f9f42182e4fc876738fbe60fbff Mon Sep 17 00:00:00 2001 From: NthPortal Date: Sun, 1 Nov 2020 20:52:25 -0500 Subject: [PATCH 4/7] fixup! fixup! Add SeqSet and SetFromMap implementations dynamic `className` impl using `collectionClassName` --- src/main/scala/scala/collection/SetFromMap.scala | 9 +++------ src/main/scala/scala/collection/SetFromMapOps.scala | 6 ++++++ .../scala/scala/collection/immutable/SetFromMap.scala | 9 +++------ src/main/scala/scala/collection/mutable/SetFromMap.scala | 9 +++------ 4 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/main/scala/scala/collection/SetFromMap.scala b/src/main/scala/scala/collection/SetFromMap.scala index bfb4704..5d2191e 100644 --- a/src/main/scala/scala/collection/SetFromMap.scala +++ b/src/main/scala/scala/collection/SetFromMap.scala @@ -20,12 +20,11 @@ private class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) extends AbstractSet[A] with SetFromMapOps.Unknown[A, Map, Map[A, Unit], SetFromMap, SetFromMap[A]] with SetFromMapOps.Unsorted[A, Map, SetFromMap] + with SetFromMapOps.DynamicClassName with IterableFactoryDefaults[A, SetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) - override protected[this] def className: String = "SetFromMap" - override def iterableFactory: IterableFactory[SetFromMap] = new SetFromMap.WrapperFactory(underlying.mapFactory) } @@ -48,13 +47,12 @@ private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, U extends AbstractSet[A] with SetFromMapOps.Unknown[A, SeqMap, SeqMap[A, Unit], SeqSetFromMap, SeqSetFromMap[A]] with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with SetFromMapOps.DynamicClassName with SeqSet[A] with IterableFactoryDefaults[A, SeqSetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = new SeqSetFromMap(m) - override protected[this] def className: String = "SeqSetFromMap" - override def iterableFactory: IterableFactory[SeqSetFromMap] = new SeqSetFromMap.WrapperFactory(underlying.mapFactory) } @@ -79,6 +77,7 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa ) extends AbstractSet[A] with SetFromMapOps.Unknown[A, Map, SortedMap[A, Unit], Set, SortedSetFromMap[A]] with SetFromMapOps.Sorted[A, SortedMap, Set, SortedSetFromMap] + with SetFromMapOps.DynamicClassName with SortedSet[A] with SortedSetOps[A, SortedSetFromMap, SortedSetFromMap[A]] with IterableFactoryDefaults[A, Set] @@ -89,8 +88,6 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa protected[this] def fromSortedMap[B: Ordering](m: SortedMap[B, Unit]): SortedSetFromMap[B] = new SortedSetFromMap(m) - override protected[this] def className: String = "SortedSetFromMap" - override def iterableFactory: IterableFactory[Set] = SetFromMap(underlying.mapFactory) override def sortedIterableFactory: SortedIterableFactory[SortedSetFromMap] = diff --git a/src/main/scala/scala/collection/SetFromMapOps.scala b/src/main/scala/scala/collection/SetFromMapOps.scala index a0e1bf5..b60e070 100644 --- a/src/main/scala/scala/collection/SetFromMapOps.scala +++ b/src/main/scala/scala/collection/SetFromMapOps.scala @@ -196,6 +196,12 @@ object SetFromMapOps { protected[collection] val underlying: IterableOnce[(A, Unit)] } + trait DynamicClassName { self: Iterable[_] => + protected[collection] val underlying: Iterable[_] + + override protected[this] def className: String = s"SetFrom_${underlying.collectionClassName}" + } + // unknown whether mutable or immutable trait Unknown[ A, diff --git a/src/main/scala/scala/collection/immutable/SetFromMap.scala b/src/main/scala/scala/collection/immutable/SetFromMap.scala index 8410653..31f0f25 100644 --- a/src/main/scala/scala/collection/immutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/immutable/SetFromMap.scala @@ -46,12 +46,11 @@ object SetFromMapOps { private class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) extends AbstractSet[A] with SetFromMapOps.Unsorted[A, Map, SetFromMap] + with collection.SetFromMapOps.DynamicClassName with IterableFactoryDefaults[A, SetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) - override protected[this] def className: String = "SetFromMap" - override def iterableFactory: IterableFactory[SetFromMap] = new SetFromMap.WrapperFactory(underlying.mapFactory) } @@ -73,14 +72,13 @@ private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) extends AbstractSet[A] with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with collection.SetFromMapOps.DynamicClassName with SeqSet[A] with IterableFactoryDefaults[A, SeqSetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = new SeqSetFromMap(m) - override protected[this] def className: String = "SeqSetFromMap" - override def iterableFactory: IterableFactory[SeqSetFromMap] = new SeqSetFromMap.WrapperFactory(underlying.mapFactory) } @@ -105,6 +103,7 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa ) extends AbstractSet[A] with SetFromMapOps[A, Map, SortedMap[A, Unit], Set, SortedSetFromMap[A]] with collection.SetFromMapOps.Sorted[A, SortedMap, Set, SortedSetFromMap] + with collection.SetFromMapOps.DynamicClassName with SortedSet[A] with SortedSetOps[A, SortedSetFromMap, SortedSetFromMap[A]] with IterableFactoryDefaults[A, Set] @@ -118,8 +117,6 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa protected[this] def fromSortedMap[B: Ordering](m: SortedMap[B, Unit]): SortedSetFromMap[B] = new SortedSetFromMap(m) - override protected[this] def className: String = "SortedSetFromMap" - override def iterableFactory: IterableFactory[Set] = SetFromMap(underlying.mapFactory) override def sortedIterableFactory: SortedIterableFactory[SortedSetFromMap] = diff --git a/src/main/scala/scala/collection/mutable/SetFromMap.scala b/src/main/scala/scala/collection/mutable/SetFromMap.scala index cd054f1..8a88402 100644 --- a/src/main/scala/scala/collection/mutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/mutable/SetFromMap.scala @@ -53,12 +53,11 @@ private[collection] class SetFromMap[A](protected[collection] val underlying: Ma extends AbstractSet[A] with SetFromMapOps[A, Map, Map[A, Unit], SetFromMap, SetFromMap[A]] with SetFromMapOps.Unsorted[A, Map, SetFromMap] + with SetFromMapOps.DynamicClassName with IterableFactoryDefaults[A, SetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) - override protected[this] def className: String = "SetFromMap" - override def iterableFactory: IterableFactory[SetFromMap] = SetFromMap(underlying.mapFactory) } @@ -80,13 +79,12 @@ private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, U extends AbstractSet[A] with SetFromMapOps[A, SeqMap, SeqMap[A, Unit], SeqSetFromMap, SeqSetFromMap[A]] with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] + with SetFromMapOps.DynamicClassName with SeqSet[A] with IterableFactoryDefaults[A, SeqSetFromMap] with DefaultSerializable { protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = new SeqSetFromMap(m) - override protected[this] def className: String = "SeqSetFromMap" - override def iterableFactory: IterableFactory[SeqSetFromMap] = SeqSetFromMap( underlying.mapFactory ) @@ -114,6 +112,7 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa ) extends AbstractSet[A] with SetFromMapOps[A, Map, SortedMap[A, Unit], Set, SortedSetFromMap[A]] with SetFromMapOps.Sorted[A, SortedMap, Set, SortedSetFromMap] + with SetFromMapOps.DynamicClassName with SortedSet[A] with SortedSetOps[A, SortedSetFromMap, SortedSetFromMap[A]] with IterableFactoryDefaults[A, Set] @@ -124,8 +123,6 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa protected[this] def fromSortedMap[B: Ordering](m: SortedMap[B, Unit]): SortedSetFromMap[B] = new SortedSetFromMap(m) - override protected[this] def className: String = "SortedSetFromMap" - override def iterableFactory: IterableFactory[SetFromMap] = SetFromMap(underlying.mapFactory) override def sortedIterableFactory: SortedIterableFactory[SortedSetFromMap] = From 7edb8423488239dd8137174212ce042337b1d09d Mon Sep 17 00:00:00 2001 From: NthPortal Date: Tue, 3 Nov 2020 21:52:22 -0500 Subject: [PATCH 5/7] fixup! fixup! fixup! Add SeqSet and SetFromMap implementations all private plus a few comments --- .../scala/collection/SetFromMapOps.scala | 31 ++++++++++++------- .../collection/immutable/SetFromMap.scala | 4 +-- .../scala/collection/mutable/SetFromMap.scala | 11 +++++-- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/main/scala/scala/collection/SetFromMapOps.scala b/src/main/scala/scala/collection/SetFromMapOps.scala index b60e070..c98518d 100644 --- a/src/main/scala/scala/collection/SetFromMapOps.scala +++ b/src/main/scala/scala/collection/SetFromMapOps.scala @@ -17,7 +17,13 @@ import scala.annotation.implicitNotFound import scala.collection.SetFromMapOps.WrappedMap import scala.reflect.ClassTag -trait SetFromMapOps[ +// Implementation note: The `concurrent.Set` implementation +// inherits from this, so we have to be careful about +// making changes that do more than forward to the +// underlying `Map`. If we have a method implementation +// that is not atomic, we MUST override that method in +// `concurrent.SetFromMap`. +private trait SetFromMapOps[ A, +MM[K, V] <: MapOps[K, V, MM, _], +M <: MapOps[A, Unit, MM, M], @@ -189,14 +195,15 @@ trait SetFromMapOps[ override def view: View[A] = underlying.keySet.view } -object SetFromMapOps { +private object SetFromMapOps { // top type to make pattern matching easier sealed trait WrappedMap[A] extends IterableOnce[A] { protected[collection] val underlying: IterableOnce[(A, Unit)] } - trait DynamicClassName { self: Iterable[_] => + trait DynamicClassName { + self: Iterable[_] => protected[collection] val underlying: Iterable[_] override protected[this] def className: String = s"SetFrom_${underlying.collectionClassName}" @@ -302,7 +309,7 @@ object SetFromMapOps { } -abstract class SetFromMapFactory[+MM[K, V] <: Map[K, V], +CC[A] <: WrappedMap[A]]( +private abstract class SetFromMapFactory[+MM[K, V] <: Map[K, V], +CC[A] <: WrappedMap[A]]( mf: MapFactory[MM] ) extends IterableFactory[CC] with Serializable { @@ -339,9 +346,10 @@ abstract class SetFromMapFactory[+MM[K, V] <: Map[K, V], +CC[A] <: WrappedMap[A] } -abstract class SortedSetFromMapFactory[+MM[K, V] <: SortedMap[K, V], +CC[A] <: WrappedMap[A]]( - mf: SortedMapFactory[MM] -) extends SortedIterableFactory[CC] +private abstract class SortedSetFromMapFactory[+MM[K, V] <: SortedMap[K, V], +CC[A] <: WrappedMap[ + A +]](mf: SortedMapFactory[MM]) + extends SortedIterableFactory[CC] with Serializable { protected[this] def fromMap[A: Ordering](map: MM[A, Unit]): CC[A] @@ -376,16 +384,17 @@ abstract class SortedSetFromMapFactory[+MM[K, V] <: SortedMap[K, V], +CC[A] <: W } -sealed abstract class SetFromMapMetaFactoryBase[MM[K, V] <: Map[K, V], +CC[A] <: Set[A]] { +private sealed abstract class SetFromMapMetaFactoryBase[MM[K, V] <: Map[K, V], +CC[A] <: Set[A]] { def apply[A](map: MM[A, Unit]): CC[A] } -abstract class SetFromMapMetaFactory[MM[K, V] <: Map[K, V], +CC[A] <: Set[A]] +private abstract class SetFromMapMetaFactory[MM[K, V] <: Map[K, V], +CC[A] <: Set[A]] extends SetFromMapMetaFactoryBase[MM, CC] { def apply(factory: MapFactory[MM]): IterableFactory[CC] } -abstract class SortedSetFromMapMetaFactory[MM[K, V] <: SortedMap[K, V], +CC[A] <: SortedSet[A]] - extends SetFromMapMetaFactoryBase[MM, CC] { +private abstract class SortedSetFromMapMetaFactory[MM[K, V] <: SortedMap[K, V], +CC[A] <: SortedSet[ + A +]] extends SetFromMapMetaFactoryBase[MM, CC] { def apply(factory: SortedMapFactory[MM]): SortedIterableFactory[CC] } diff --git a/src/main/scala/scala/collection/immutable/SetFromMap.scala b/src/main/scala/scala/collection/immutable/SetFromMap.scala index 31f0f25..9799df1 100644 --- a/src/main/scala/scala/collection/immutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/immutable/SetFromMap.scala @@ -16,7 +16,7 @@ package immutable import scala.collection.generic.DefaultSerializable -trait SetFromMapOps[ +private trait SetFromMapOps[ A, +MM[K, +V] <: MapOps[K, V, MM, _], +M <: MapOps[A, Unit, MM, M], @@ -29,7 +29,7 @@ trait SetFromMapOps[ override def removedAll(that: IterableOnce[A]): C = fromSpecificMap(underlying removedAll that) } -object SetFromMapOps { +private object SetFromMapOps { trait Unsorted[ A, diff --git a/src/main/scala/scala/collection/mutable/SetFromMap.scala b/src/main/scala/scala/collection/mutable/SetFromMap.scala index 8a88402..5cdec54 100644 --- a/src/main/scala/scala/collection/mutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/mutable/SetFromMap.scala @@ -17,7 +17,13 @@ package mutable import scala.collection.SetFromMapOps.WrappedMap import scala.collection.generic.DefaultSerializable -trait SetFromMapOps[ +// Implementation note: The `concurrent.Set` implementation +// inherits from this, so we have to be careful about +// making changes that do more than forward to the +// underlying `Map`. If we have a method implementation +// that is not atomic, we MUST override that method in +// `concurrent.SetFromMap`. +private[collection] trait SetFromMapOps[ A, +MM[K, V] <: MapOps[K, V, MM, _], +M <: MapOps[A, Unit, MM, M], @@ -45,7 +51,8 @@ trait SetFromMapOps[ override def subtractAll(xs: IterableOnce[A]): this.type = { underlying.subtractAll(xs); this } - override def knownSize: Int = underlying.knownSize + // We need to define this explicitly because there's a multiple inheritance diamond + override def knownSize: Int = super[SetFromMapOps].knownSize } @SerialVersionUID(3L) From 9e391c3fc176bea7ccd17bcd4f18be568772b69e Mon Sep 17 00:00:00 2001 From: NthPortal Date: Wed, 4 Nov 2020 00:01:56 -0500 Subject: [PATCH 6/7] fixup! fixup! fixup! fixup! Add SeqSet and SetFromMap implementations remove unnecessary implicit `Ordering` --- src/main/scala/scala/collection/SetFromMap.scala | 4 ++-- src/main/scala/scala/collection/SetFromMapOps.scala | 2 +- src/main/scala/scala/collection/immutable/SetFromMap.scala | 5 ++--- src/main/scala/scala/collection/mutable/SetFromMap.scala | 4 ++-- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/main/scala/scala/collection/SetFromMap.scala b/src/main/scala/scala/collection/SetFromMap.scala index 5d2191e..1817add 100644 --- a/src/main/scala/scala/collection/SetFromMap.scala +++ b/src/main/scala/scala/collection/SetFromMap.scala @@ -103,8 +103,8 @@ private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, S @SerialVersionUID(3L) private final class WrapperFactory(mf: SortedMapFactory[SortedMap]) extends SortedSetFromMapFactory[SortedMap, SortedSetFromMap](mf) { - protected[this] def fromMap[A: Ordering](map: SortedMap[A, Unit]): SortedSetFromMap[A] = - new SortedSetFromMap(map) + protected[this] def fromMap[A](map: SortedMap[A, Unit]): SortedSetFromMap[A] = + new SortedSetFromMap(map)(map.ordering) } } diff --git a/src/main/scala/scala/collection/SetFromMapOps.scala b/src/main/scala/scala/collection/SetFromMapOps.scala index c98518d..f604130 100644 --- a/src/main/scala/scala/collection/SetFromMapOps.scala +++ b/src/main/scala/scala/collection/SetFromMapOps.scala @@ -351,7 +351,7 @@ private abstract class SortedSetFromMapFactory[+MM[K, V] <: SortedMap[K, V], +CC ]](mf: SortedMapFactory[MM]) extends SortedIterableFactory[CC] with Serializable { - protected[this] def fromMap[A: Ordering](map: MM[A, Unit]): CC[A] + protected[this] def fromMap[A](map: MM[A, Unit]): CC[A] def from[A: Ordering](it: IterableOnce[A]): CC[A] = it match { diff --git a/src/main/scala/scala/collection/immutable/SetFromMap.scala b/src/main/scala/scala/collection/immutable/SetFromMap.scala index 9799df1..715a273 100644 --- a/src/main/scala/scala/collection/immutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/immutable/SetFromMap.scala @@ -137,9 +137,8 @@ private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, S @SerialVersionUID(3L) private final class WrapperFactory(mf: SortedMapFactory[SortedMap]) extends SortedSetFromMapFactory[SortedMap, SortedSetFromMap](mf) { - protected[this] def fromMap[A: Ordering](map: SortedMap[A, Unit]): SortedSetFromMap[A] = ssfm( - map - ) + protected[this] def fromMap[A](map: SortedMap[A, Unit]): SortedSetFromMap[A] = + ssfm(map)(map.ordering) } } diff --git a/src/main/scala/scala/collection/mutable/SetFromMap.scala b/src/main/scala/scala/collection/mutable/SetFromMap.scala index 5cdec54..d730fb3 100644 --- a/src/main/scala/scala/collection/mutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/mutable/SetFromMap.scala @@ -147,8 +147,8 @@ private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, S @SerialVersionUID(3L) private final class WrapperFactory(mf: SortedMapFactory[SortedMap]) extends SortedSetFromMapFactory[SortedMap, SortedSetFromMap](mf) { - protected[this] def fromMap[A: Ordering](map: SortedMap[A, Unit]): SortedSetFromMap[A] = - new SortedSetFromMap(map) + protected[this] def fromMap[A](map: SortedMap[A, Unit]): SortedSetFromMap[A] = + new SortedSetFromMap(map)(map.ordering) } } From 2ed714d7b3f1a624051d89325fdd79c2d0a47d22 Mon Sep 17 00:00:00 2001 From: NthPortal Date: Wed, 4 Nov 2020 00:05:48 -0500 Subject: [PATCH 7/7] fixup! fixup! fixup! fixup! fixup! Add SeqSet and SetFromMap implementations try to retain type information mirroring that of the wrapped map --- .../scala/scala/collection/SetFromMap.scala | 49 ++++++++++++++++--- .../scala/collection/SetFromMapOps.scala | 9 ++-- .../collection/concurrent/SetFromMap.scala | 6 +-- .../collection/immutable/SetFromMap.scala | 41 ++++++++++------ .../scala/collection/mutable/SetFromMap.scala | 49 +++++++++++-------- 5 files changed, 103 insertions(+), 51 deletions(-) diff --git a/src/main/scala/scala/collection/SetFromMap.scala b/src/main/scala/scala/collection/SetFromMap.scala index 1817add..699ea27 100644 --- a/src/main/scala/scala/collection/SetFromMap.scala +++ b/src/main/scala/scala/collection/SetFromMap.scala @@ -30,9 +30,18 @@ private class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) } private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { - def apply(factory: MapFactory[Map]): IterableFactory[Set] = new WrapperFactory(factory) - - def apply[A](map: Map[A, Unit]): Set[A] = new SetFromMap(map) + def apply(factory: MapFactory[Map]): IterableFactory[Set] = new DynamicFactory(factory) + + // Dynamically create a narrower return type as a best-effort + // not to lose runtime type information from the `Map`. + def apply[A](map: Map[A, Unit]): Set[A] = map match { + case map: immutable.Map[A, Unit] => immutable.SetFromMap(map) + case map: concurrent.Map[A, Unit] => concurrent.SetFromMap(map) + case map: mutable.Map[A, Unit] => mutable.SetFromMap(map) + case map: SeqMap[A, Unit] => new SeqSetFromMap(map) + case map: SortedMap[A, Unit] => new SortedSetFromMap(map)(map.ordering) + case map => new SetFromMap(map) + } @SerialVersionUID(3L) private class WrapperFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, SetFromMap](mf) { @@ -40,6 +49,11 @@ private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { new SetFromMap(map) } + @SerialVersionUID(3L) + private class DynamicFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, Set](mf) { + protected[this] def fromMap[A](map: Map[A, Unit]): Set[A] = SetFromMap(map) + } + } @SerialVersionUID(3L) @@ -58,9 +72,13 @@ private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, U } private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { - def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = new WrapperFactory(factory) + def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = new DynamicFactory(factory) - def apply[A](map: SeqMap[A, Unit]): SeqSet[A] = new SeqSetFromMap(map) + def apply[A](map: SeqMap[A, Unit]): SeqSet[A] = map match { + case map: immutable.SeqMap[A, Unit] => immutable.SeqSetFromMap(map) + case map: mutable.SeqMap[A, Unit] => mutable.SeqSetFromMap(map) + case map => new SeqSetFromMap(map) + } @SerialVersionUID(3L) private class WrapperFactory(mf: MapFactory[SeqMap]) @@ -69,6 +87,12 @@ private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { new SeqSetFromMap(map) } + @SerialVersionUID(3L) + private class DynamicFactory(mf: MapFactory[SeqMap]) + extends SetFromMapFactory[SeqMap, SeqSet](mf) { + protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSet[A] = SeqSetFromMap(map) + } + } @SerialVersionUID(3L) @@ -96,9 +120,13 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, SortedSet] { def apply(factory: SortedMapFactory[SortedMap]): SortedIterableFactory[SortedSet] = - new WrapperFactory(factory) + new DynamicFactory(factory) - def apply[A](map: SortedMap[A, Unit]): SortedSet[A] = new SortedSetFromMap(map)(map.ordering) + def apply[A](map: SortedMap[A, Unit]): SortedSet[A] = map match { + case map: immutable.SortedMap[A, Unit] => immutable.SortedSetFromMap(map) + case map: mutable.SortedMap[A, Unit] => mutable.SortedSetFromMap(map) + case map => new SortedSetFromMap(map)(map.ordering) + } @SerialVersionUID(3L) private final class WrapperFactory(mf: SortedMapFactory[SortedMap]) @@ -107,4 +135,11 @@ private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, S new SortedSetFromMap(map)(map.ordering) } + @SerialVersionUID(3L) + private class DynamicFactory(mf: SortedMapFactory[SortedMap]) + extends SortedSetFromMapFactory[SortedMap, SortedSet](mf) { + protected[this] def fromMap[A](map: SortedMap[A, Unit]): SortedSet[A] = + SortedSetFromMap(map) + } + } diff --git a/src/main/scala/scala/collection/SetFromMapOps.scala b/src/main/scala/scala/collection/SetFromMapOps.scala index f604130..ffdd361 100644 --- a/src/main/scala/scala/collection/SetFromMapOps.scala +++ b/src/main/scala/scala/collection/SetFromMapOps.scala @@ -309,7 +309,7 @@ private object SetFromMapOps { } -private abstract class SetFromMapFactory[+MM[K, V] <: Map[K, V], +CC[A] <: WrappedMap[A]]( +private abstract class SetFromMapFactory[+MM[K, V] <: Map[K, V], +CC[A] <: Set[A]]( mf: MapFactory[MM] ) extends IterableFactory[CC] with Serializable { @@ -346,10 +346,9 @@ private abstract class SetFromMapFactory[+MM[K, V] <: Map[K, V], +CC[A] <: Wrapp } -private abstract class SortedSetFromMapFactory[+MM[K, V] <: SortedMap[K, V], +CC[A] <: WrappedMap[ - A -]](mf: SortedMapFactory[MM]) - extends SortedIterableFactory[CC] +private abstract class SortedSetFromMapFactory[+MM[K, V] <: SortedMap[K, V], +CC[A] <: Set[A]]( + mf: SortedMapFactory[MM] +) extends SortedIterableFactory[CC] with Serializable { protected[this] def fromMap[A](map: MM[A, Unit]): CC[A] diff --git a/src/main/scala/scala/collection/concurrent/SetFromMap.scala b/src/main/scala/scala/collection/concurrent/SetFromMap.scala index b75da63..bc602aa 100644 --- a/src/main/scala/scala/collection/concurrent/SetFromMap.scala +++ b/src/main/scala/scala/collection/concurrent/SetFromMap.scala @@ -18,7 +18,7 @@ import scala.collection.generic.DefaultSerializable import scala.collection.{mutable => m} @SerialVersionUID(3L) -private class SetFromMap[A](override protected[collection] val underlying: Map[A, Unit]) +private[collection] class SetFromMap[A](override protected[collection] val underlying: Map[A, Unit]) extends mutable.SetFromMap[A](underlying) with Set[A] with mutable.SetFromMapOps[A, m.Map, m.Map[A, Unit], m.SetFromMap, m.SetFromMap[A]] @@ -31,8 +31,8 @@ private class SetFromMap[A](override protected[collection] val underlying: Map[A new SetFromMap.MutableFactory(underlying.mapFactory) } -private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { - def apply(factory: MapFactory[Map]): IterableFactory[SetFromMap] = new WrapperFactory(factory) +private[collection] object SetFromMap extends SetFromMapMetaFactory[Map, Set] { + def apply(factory: MapFactory[Map]): IterableFactory[Set] = new WrapperFactory(factory) def apply[A](map: Map[A, Unit]): Set[A] = new SetFromMap(map) diff --git a/src/main/scala/scala/collection/immutable/SetFromMap.scala b/src/main/scala/scala/collection/immutable/SetFromMap.scala index 715a273..9c6c9df 100644 --- a/src/main/scala/scala/collection/immutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/immutable/SetFromMap.scala @@ -16,7 +16,7 @@ package immutable import scala.collection.generic.DefaultSerializable -private trait SetFromMapOps[ +private[collection] trait SetFromMapOps[ A, +MM[K, +V] <: MapOps[K, V, MM, _], +M <: MapOps[A, Unit, MM, M], @@ -29,7 +29,7 @@ private trait SetFromMapOps[ override def removedAll(that: IterableOnce[A]): C = fromSpecificMap(underlying removedAll that) } -private object SetFromMapOps { +private[collection] object SetFromMapOps { trait Unsorted[ A, @@ -43,7 +43,7 @@ private object SetFromMapOps { } @SerialVersionUID(3L) -private class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) +private[collection] class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) extends AbstractSet[A] with SetFromMapOps.Unsorted[A, Map, SetFromMap] with collection.SetFromMapOps.DynamicClassName @@ -55,21 +55,29 @@ private class SetFromMap[A](protected[collection] val underlying: Map[A, Unit]) new SetFromMap.WrapperFactory(underlying.mapFactory) } -private object SetFromMap extends SetFromMapMetaFactory[Map, Set] { - def apply(factory: MapFactory[Map]): IterableFactory[Set] = new WrapperFactory(factory) +private[collection] object SetFromMap extends SetFromMapMetaFactory[Map, Set] { + def apply(factory: MapFactory[Map]): IterableFactory[Set] = new DynamicFactory(factory) - def apply[A](map: Map[A, Unit]): Set[A] = new SetFromMap(map) + def apply[A](map: Map[A, Unit]): Set[A] = map match { + case map: SeqMap[A, Unit] => SeqSetFromMap(map) + case map: SortedMap[A, Unit] => SortedSetFromMap(map) + case map => apply(map) + } @SerialVersionUID(3L) private class WrapperFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, SetFromMap](mf) { - protected[this] def fromMap[A](map: Map[A, Unit]): SetFromMap[A] = - new SetFromMap(map) + protected[this] def fromMap[A](map: Map[A, Unit]): SetFromMap[A] = new SetFromMap(map) + } + + @SerialVersionUID(3L) + private class DynamicFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, Set](mf) { + protected[this] def fromMap[A](map: Map[A, Unit]): Set[A] = SetFromMap(map) } } @SerialVersionUID(3L) -private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) +private[collection] class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) extends AbstractSet[A] with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] with collection.SetFromMapOps.DynamicClassName @@ -83,7 +91,7 @@ private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, U new SeqSetFromMap.WrapperFactory(underlying.mapFactory) } -private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { +private[collection] object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = new WrapperFactory(factory) def apply[A](map: SeqMap[A, Unit]): SeqSet[A] = new SeqSetFromMap(map) @@ -91,16 +99,16 @@ private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { @SerialVersionUID(3L) private class WrapperFactory(mf: MapFactory[SeqMap]) extends SetFromMapFactory[SeqMap, SeqSetFromMap](mf) { - protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSetFromMap[A] = - new SeqSetFromMap(map) + protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSetFromMap[A] = new SeqSetFromMap(map) } } @SerialVersionUID(3L) -private class SortedSetFromMap[A](protected[collection] val underlying: SortedMap[A, Unit])(implicit - val ordering: Ordering[A] -) extends AbstractSet[A] +private[collection] class SortedSetFromMap[A]( + protected[collection] val underlying: SortedMap[A, Unit] +)(implicit val ordering: Ordering[A]) + extends AbstractSet[A] with SetFromMapOps[A, Map, SortedMap[A, Unit], Set, SortedSetFromMap[A]] with collection.SetFromMapOps.Sorted[A, SortedMap, Set, SortedSetFromMap] with collection.SetFromMapOps.DynamicClassName @@ -125,7 +133,8 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa override def incl(elem: A): SortedSetFromMap[A] = ssfm(underlying.updated(elem, ())) } -private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, SortedSet] { +private[collection] object SortedSetFromMap + extends SortedSetFromMapMetaFactory[SortedMap, SortedSet] { @inline private def ssfm[A: Ordering](map: SortedMap[A, Unit]): SortedSetFromMap[A] = new SortedSetFromMap(map) diff --git a/src/main/scala/scala/collection/mutable/SetFromMap.scala b/src/main/scala/scala/collection/mutable/SetFromMap.scala index d730fb3..a2ef4eb 100644 --- a/src/main/scala/scala/collection/mutable/SetFromMap.scala +++ b/src/main/scala/scala/collection/mutable/SetFromMap.scala @@ -65,24 +65,34 @@ private[collection] class SetFromMap[A](protected[collection] val underlying: Ma with DefaultSerializable { protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m) - override def iterableFactory: IterableFactory[SetFromMap] = SetFromMap(underlying.mapFactory) + override def iterableFactory: IterableFactory[SetFromMap] = + new SetFromMap.WrapperFactory(underlying.mapFactory) } private[collection] object SetFromMap extends SetFromMapMetaFactory[Map, Set] { - def apply(factory: MapFactory[Map]): IterableFactory[SetFromMap] = new WrapperFactory(factory) + def apply(factory: MapFactory[Map]): IterableFactory[Set] = new DynamicFactory(factory) - def apply[A](map: Map[A, Unit]): Set[A] = new SetFromMap(map) + def apply[A](map: Map[A, Unit]): Set[A] = map match { + case map: concurrent.Map[A, Unit] => concurrent.SetFromMap(map) + case map: SeqMap[A, Unit] => SeqSetFromMap(map) + case map: SortedMap[A, Unit] => SortedSetFromMap(map) + case map => new SetFromMap(map) + } @SerialVersionUID(3L) private class WrapperFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, SetFromMap](mf) { - protected[this] def fromMap[A](map: Map[A, Unit]): SetFromMap[A] = - new SetFromMap(map) + protected[this] def fromMap[A](map: Map[A, Unit]): SetFromMap[A] = new SetFromMap(map) + } + + @SerialVersionUID(3L) + private class DynamicFactory(mf: MapFactory[Map]) extends SetFromMapFactory[Map, Set](mf) { + protected[this] def fromMap[A](map: Map[A, Unit]): Set[A] = SetFromMap(map) } } @SerialVersionUID(3L) -private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) +private[collection] class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, Unit]) extends AbstractSet[A] with SetFromMapOps[A, SeqMap, SeqMap[A, Unit], SeqSetFromMap, SeqSetFromMap[A]] with SetFromMapOps.Unsorted[A, SeqMap, SeqSetFromMap] @@ -92,31 +102,29 @@ private class SeqSetFromMap[A](protected[collection] val underlying: SeqMap[A, U with DefaultSerializable { protected[this] def fromMap[B](m: SeqMap[B, Unit]): SeqSetFromMap[B] = new SeqSetFromMap(m) - override def iterableFactory: IterableFactory[SeqSetFromMap] = SeqSetFromMap( - underlying.mapFactory - ) + override def iterableFactory: IterableFactory[SeqSetFromMap] = + new SeqSetFromMap.WrapperFactory(underlying.mapFactory) } -private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { - def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSetFromMap] = new WrapperFactory( - factory - ) +private[collection] object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] { + def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = + new WrapperFactory(factory) def apply[A](map: SeqMap[A, Unit]): mutable.SeqSet[A] = new SeqSetFromMap(map) @SerialVersionUID(3L) private class WrapperFactory(mf: MapFactory[SeqMap]) extends SetFromMapFactory[SeqMap, SeqSetFromMap](mf) { - protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSetFromMap[A] = - new SeqSetFromMap(map) + protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSetFromMap[A] = new SeqSetFromMap(map) } } @SerialVersionUID(3L) -private class SortedSetFromMap[A](protected[collection] val underlying: SortedMap[A, Unit])(implicit - val ordering: Ordering[A] -) extends AbstractSet[A] +private[collection] class SortedSetFromMap[A]( + protected[collection] val underlying: SortedMap[A, Unit] +)(implicit val ordering: Ordering[A]) + extends AbstractSet[A] with SetFromMapOps[A, Map, SortedMap[A, Unit], Set, SortedSetFromMap[A]] with SetFromMapOps.Sorted[A, SortedMap, Set, SortedSetFromMap] with SetFromMapOps.DynamicClassName @@ -130,13 +138,14 @@ private class SortedSetFromMap[A](protected[collection] val underlying: SortedMa protected[this] def fromSortedMap[B: Ordering](m: SortedMap[B, Unit]): SortedSetFromMap[B] = new SortedSetFromMap(m) - override def iterableFactory: IterableFactory[SetFromMap] = SetFromMap(underlying.mapFactory) + override def iterableFactory: IterableFactory[Set] = SetFromMap(underlying.mapFactory) override def sortedIterableFactory: SortedIterableFactory[SortedSetFromMap] = new SortedSetFromMap.WrapperFactory(underlying.sortedMapFactory) } -private object SortedSetFromMap extends SortedSetFromMapMetaFactory[SortedMap, SortedSet] { +private[collection] object SortedSetFromMap + extends SortedSetFromMapMetaFactory[SortedMap, SortedSet] { def apply(factory: SortedMapFactory[SortedMap]): SortedIterableFactory[SortedSet] = new WrapperFactory(factory)