Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Introduce IterableOnceOps as common abstraction for Iterable & Iterator #480

Merged
merged 1 commit into from
Feb 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,38 @@ import strawman.collection.decorators.ImmutableMapDecorator
* An immutable multiset
* @tparam A the element type of the collection
*/
class MultiSet[A] private (elems: Map[A, Int])
trait MultiSet[A]
extends collection.MultiSet[A]
with Iterable[A]
with collection.MultiSetOps[A, MultiSet, MultiSet[A]] {
with MultiSetOps[A, MultiSet, MultiSet[A]] {

override def iterableFactory: IterableFactory[MultiSet] = MultiSet
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you elaborate on the problem that is solved by introducing the separation MultiSet/MultiSetImpl?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh maybe that’s for making SortedMultiSet a subtype of MultiSet?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you want the usual diamond pattern with all of:

  • mutable.SortedMultiSet <: collection.SortedMultiSet

  • immutable.SortedMultiSet <: collection.SortedMultiSet

  • mutable.MultiSet <: collection.MultiSet

  • immutable.MultiSet <: collection.MultiSet

  • collection.SortedMultiSet <: collection.MultiSet

  • mutable.SortedMultiSet <: mutable.MultiSet

  • immutable.SortedMultiSet <: immutable.MultiSet

This requires that MultiSet is a trait.


trait MultiSetOps[A, +CC[X] <: MultiSet[X], +C <: MultiSet[A]] extends collection.MultiSetOps[A, CC, C] {
/**
* @return an immutable multiset containing all the elements of this multiset
* and one more occurrence of `elem`
* @param elem the element to add
*/
def incl(elem: A): C

/** Alias for `incl` */
@`inline` final def + (elem: A): C = incl(elem)

/**
* @return an immutable multiset containing all the elements of this multiset
* and one occurrence less of `elem`
*
* @param elem the element to remove
*/
def excl(elem: A): C

/** Alias for `excl` */
@`inline` final def - (elem: A): C = excl(elem)
}

class MultiSetImpl[A] private[immutable] (elems: Map[A, Int]) extends MultiSet[A] {

def occurrences: Map[A, Int] = elems

Expand All @@ -25,28 +53,22 @@ class MultiSet[A] private (elems: Map[A, Int])
* @param elem the element to add
*/
def incl(elem: A): MultiSet[A] =
new MultiSet(elems.updatedWith(elem) {
new MultiSetImpl(elems.updatedWith(elem) {
case None => Some(1)
case Some(n) => Some(n + 1)
})

/** Alias for `incl` */
@`inline` final def + (elem: A): MultiSet[A] = incl(elem)

/**
* @return an immutable multiset containing all the elements of this multiset
* and one occurrence less of `elem`
*
* @param elem the element to remove
*/
def excl(elem: A): MultiSet[A] =
new MultiSet(elems.updatedWith(elem) {
new MultiSetImpl(elems.updatedWith(elem) {
case Some(n) => if (n > 1) Some(n - 1) else None
})

/** Alias for `excl` */
@`inline` final def - (elem: A): MultiSet[A] = excl(elem)

}

object MultiSet extends IterableFactory[MultiSet] {
Expand All @@ -57,7 +79,7 @@ object MultiSet extends IterableFactory[MultiSet] {
case _ => (newBuilder[A]() ++= source).result()
}

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

def newBuilder[A](): Builder[A, MultiSet[A]] =
new ImmutableBuilder[A, MultiSet[A]](empty[A]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import strawman.collection.mutable.{Builder, ImmutableBuilder}
* @tparam A Type of elements
*/
class SortedMultiSet[A] private (elems: SortedMap[A, Int])(implicit val ordering: Ordering[A])
extends collection.SortedMultiSet[A]
with Iterable[A]
extends MultiSet[A]
with collection.SortedMultiSet[A]
with MultiSetOps[A, MultiSet, SortedMultiSet[A]]
with collection.SortedMultiSetOps[A, SortedMultiSet, SortedMultiSet[A]]
with collection.IterableOps[A, MultiSet, SortedMultiSet[A]] {

Expand All @@ -34,9 +35,6 @@ class SortedMultiSet[A] private (elems: SortedMap[A, Int])(implicit val ordering
case Some(n) => Some(n + 1)
})

/** Alias for `incl` */
@`inline` final def + (elem: A): SortedMultiSet[A] = incl(elem)

/**
* @return an immutable sorted multiset containing all the elements of
* this multiset and one occurrence less of `elem`
Expand All @@ -47,10 +45,6 @@ class SortedMultiSet[A] private (elems: SortedMap[A, Int])(implicit val ordering
new SortedMultiSet(elems.updatedWith(elem) {
case Some(n) => if (n > 1) Some(n - 1) else None
})

/** Alias for `excl` */
@`inline` final def - (elem: A): SortedMultiSet[A] = excl(elem)

}

object SortedMultiSet extends SortedIterableFactory[SortedMultiSet] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ import strawman.collection.decorators.MutableMapDecorator
/**
* A mutable multiset.
*/
class MultiSet[A] private (val elems: Map[A, Int])
trait MultiSet[A]
extends collection.MultiSet[A]
with collection.MultiSetOps[A, MultiSet, MultiSet[A]]
with Growable[A]
with Shrinkable [A] {

override def iterableFactory: IterableFactory[MultiSet] = MultiSet
}

class MultiSetImpl[A] private[mutable] (val elems: Map[A, Int]) extends MultiSet[A] {

def occurrences: collection.Map[A, Int] = elems

Expand All @@ -39,7 +42,7 @@ object MultiSet extends IterableFactory[MultiSet] {

def from[A](source: IterableOnce[A]): MultiSet[A] = (newBuilder[A]() ++= source).result()

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

def newBuilder[A](): Builder[A, MultiSet[A]] = new GrowableBuilder[A, MultiSet[A]](empty)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import strawman.collection.decorators.MutableMapDecorator
* @tparam A Type of elements
*/
class SortedMultiSet[A] private (elems: SortedMap[A, Int])(implicit val ordering: Ordering[A])
extends collection.SortedMultiSet[A]
extends MultiSet[A]
with collection.SortedMultiSet[A]
with collection.SortedMultiSetOps[A, SortedMultiSet, SortedMultiSet[A]]
with MultiSetOps[A, MultiSet, SortedMultiSet[A]]
with Growable[A]
with Shrinkable[A] {

Expand Down
Loading