Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SeqSet and SetFromMap implementations #35

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version = "2.7.5"
align.preset = more
docstrings = JavaDoc
assumeStandardLibraryStripMargin = true
project.git = true
maxColumn = 100
trailingCommas = multiple
13 changes: 7 additions & 6 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -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))
Expand All @@ -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
Expand Down
7 changes: 4 additions & 3 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -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")
37 changes: 37 additions & 0 deletions src/main/scala/scala/collection/SeqSet.scala
Original file line number Diff line number Diff line change
@@ -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)
}
145 changes: 145 additions & 0 deletions src/main/scala/scala/collection/SetFromMap.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* 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 SetFromMapOps.DynamicClassName
with IterableFactoryDefaults[A, SetFromMap]
with DefaultSerializable {
protected[this] def fromMap[B](m: Map[B, Unit]): SetFromMap[B] = new SetFromMap(m)

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 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) {
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])
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 def iterableFactory: IterableFactory[SeqSetFromMap] =
new SeqSetFromMap.WrapperFactory(underlying.mapFactory)
}

private object SeqSetFromMap extends SetFromMapMetaFactory[SeqMap, SeqSet] {
def apply(factory: MapFactory[SeqMap]): IterableFactory[SeqSet] = new DynamicFactory(factory)

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])
extends SetFromMapFactory[SeqMap, SeqSetFromMap](mf) {
protected[this] def fromMap[A](map: SeqMap[A, Unit]): SeqSetFromMap[A] =
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)
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 SetFromMapOps.DynamicClassName
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 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 DynamicFactory(factory)

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])
extends SortedSetFromMapFactory[SortedMap, SortedSetFromMap](mf) {
protected[this] def fromMap[A](map: SortedMap[A, Unit]): SortedSetFromMap[A] =
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)
}

}
Loading