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

Commit

Permalink
Merge pull request #358 from julienrf/generic-bitset-factory
Browse files Browse the repository at this point in the history
Add collection.BitSet factory object (and other cross-compatibility improvements)
  • Loading branch information
julienrf authored Jan 24, 2018
2 parents 9d19124 + 13c27d7 commit 158c79f
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 57 deletions.
10 changes: 9 additions & 1 deletion collections/src/main/scala/strawman/collection/BitSet.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package strawman
package collection

import scala.{Array, Boolean, `inline`, Int, Long, Option, Ordering, Unit}
import strawman.collection.mutable.Builder

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

/** Base type of bitsets.
Expand All @@ -18,6 +20,12 @@ import scala.Predef.{assert, intWrapper}
*/
trait BitSet extends SortedSet[Int] with BitSetOps[BitSet]

object BitSet extends SpecificIterableFactory[Int, BitSet] {
def empty: BitSet = immutable.BitSet.empty
def newBuilder(): Builder[Int, BitSet] = immutable.BitSet.newBuilder()
def fromSpecific(it: IterableOnce[Int]): BitSet = immutable.BitSet.fromSpecific(it)
}

/** Base implementation type of bitsets */
trait BitSetOps[+C <: BitSet with BitSetOps[C]]
extends SortedSetOps[Int, SortedSet, C] { self =>
Expand Down
108 changes: 53 additions & 55 deletions collections/src/main/scala/strawman/collection/Factory.scala
Original file line number Diff line number Diff line change
Expand Up @@ -102,61 +102,6 @@ trait IterableFactoryLike[+CC[_]] {
*/
def newBuilder[A](): Builder[A, CC[A]]

}

/** Base trait for companion objects of unconstrained collection types that can
* build a target collection `CC` from a source collection with a single traversal
* of the source.
*
* @tparam CC Collection type constructor (e.g. `List`)
*/
trait IterableFactory[+CC[_]] extends IterableFactoryLike[CC] {

// Since most collection factories can build a target collection instance by performing only one
// traversal of a source collection, the type of this source collection can be refined to be
// just `IterableOnce`
type Source[A] = IterableOnce[A]

implicit def iterableFactory[A]: Factory[A, CC[A]] = IterableFactory.toFactory(this)

}

object IterableFactory {

/**
* Fixes the element type of `factory` to `A`
* @param factory The factory to fix the element type
* @tparam A Type of elements
* @tparam CC Collection type constructor of the factory (e.g. `Seq`, `List`)
* @return A [[Factory]] that uses the given `factory` to build a collection of elements
* of type `A`
*/
implicit def toFactory[A, CC[_]](factory: IterableFactory[CC]): Factory[A, CC[A]] =
new Factory[A, CC[A]] {
def fromSpecific(it: IterableOnce[A]): CC[A] = factory.from[A](it)
def newBuilder(): Builder[A, CC[A]] = factory.newBuilder[A]()
}

implicit def toBuildFrom[A, CC[_]](factory: IterableFactory[CC]): BuildFrom[Any, A, CC[A]] =
new BuildFrom[Any, A, CC[A]] {
def fromSpecificIterable(from: Any)(it: Iterable[A]) = factory.from(it)
def newBuilder(from: Any) = factory.newBuilder()
}

class Delegate[CC[_]](delegate: IterableFactory[CC]) extends IterableFactory[CC] {
def empty[A]: CC[A] = delegate.empty
def from[E](it: IterableOnce[E]): CC[E] = delegate.from(it)
def newBuilder[A](): Builder[A, CC[A]] = delegate.newBuilder[A]()
}
}

/**
* Introduces factory methods `fill` and `tabulate`.
* @tparam CC Collection type constructor (e.g. `List`)
*/
trait SeqFactory[+CC[_]] extends IterableFactory[CC] {
def unapplySeq[A](x: CC[A] @uncheckedVariance): Some[CC[A]] = Some(x) //TODO is uncheckedVariance sound here?

/** Produces a $coll containing the results of some element computation a number of times.
* @param n the number of elements contained in the $coll.
* @param elem the element computation
Expand Down Expand Up @@ -259,6 +204,59 @@ trait SeqFactory[+CC[_]] extends IterableFactory[CC] {

}

/** Base trait for companion objects of unconstrained collection types that can
* build a target collection `CC` from a source collection with a single traversal
* of the source.
*
* @tparam CC Collection type constructor (e.g. `List`)
*/
trait IterableFactory[+CC[_]] extends IterableFactoryLike[CC] {

// Since most collection factories can build a target collection instance by performing only one
// traversal of a source collection, the type of this source collection can be refined to be
// just `IterableOnce`
type Source[A] = IterableOnce[A]

implicit def iterableFactory[A]: Factory[A, CC[A]] = IterableFactory.toFactory(this)

}

object IterableFactory {

/**
* Fixes the element type of `factory` to `A`
* @param factory The factory to fix the element type
* @tparam A Type of elements
* @tparam CC Collection type constructor of the factory (e.g. `Seq`, `List`)
* @return A [[Factory]] that uses the given `factory` to build a collection of elements
* of type `A`
*/
implicit def toFactory[A, CC[_]](factory: IterableFactory[CC]): Factory[A, CC[A]] =
new Factory[A, CC[A]] {
def fromSpecific(it: IterableOnce[A]): CC[A] = factory.from[A](it)
def newBuilder(): Builder[A, CC[A]] = factory.newBuilder[A]()
}

implicit def toBuildFrom[A, CC[_]](factory: IterableFactory[CC]): BuildFrom[Any, A, CC[A]] =
new BuildFrom[Any, A, CC[A]] {
def fromSpecificIterable(from: Any)(it: Iterable[A]) = factory.from(it)
def newBuilder(from: Any) = factory.newBuilder()
}

class Delegate[CC[_]](delegate: IterableFactory[CC]) extends IterableFactory[CC] {
def empty[A]: CC[A] = delegate.empty
def from[E](it: IterableOnce[E]): CC[E] = delegate.from(it)
def newBuilder[A](): Builder[A, CC[A]] = delegate.newBuilder[A]()
}
}

/**
* @tparam CC Collection type constructor (e.g. `List`)
*/
trait SeqFactory[+CC[_]] extends IterableFactory[CC] {
def unapplySeq[A](x: CC[A] @uncheckedVariance): Some[CC[A]] = Some(x) //TODO is uncheckedVariance sound here?
}

object SeqFactory {
class Delegate[CC[_]](delegate: SeqFactory[CC]) extends SeqFactory[CC] {
def empty[A]: CC[A] = delegate.empty
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,15 @@ final class StringOps(val s: String)
def patch(from: Int, other: String, replaced: Int): String =
fromSpecificIterable(new View.Patched(toIterable, from, other, replaced)) //TODO optimize

/** A copy of this string with one single replaced element.
* @param index the position of the replacement
* @param elem the replacing element
* @return a new string which is a copy of this string with the element at position `index` replaced by `elem`.
* @throws IndexOutOfBoundsException if `index` does not satisfy `0 <= index < length`.
*/
def updated(index: Int, elem: Char): String =
fromSpecificIterable(View.Updated(toIterable, index, elem)) // TODO optimize

override def toString = s

override def mkString = toString
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package immutable

import strawman.collection.mutable.{ArrayBuffer, Builder}

import scala.{Any, AnyRef, Boolean, Int, None, NoSuchElementException, noinline, Nothing, Option, PartialFunction, Some, StringContext, Unit, UnsupportedOperationException}
import scala.{Any, AnyRef, Boolean, Int, None, NoSuchElementException, noinline, Nothing, Option, PartialFunction, Some, StringContext, Unit, UnsupportedOperationException, deprecated}
import scala.Predef.String
import scala.annotation.tailrec

Expand Down Expand Up @@ -206,6 +206,9 @@ sealed abstract class LazyList[+A]
def lazyAppendAll[B >: A](suffix: => collection.IterableOnce[B]): LazyList[B] =
if (isEmpty) LazyList.fromIterator(suffix.iterator()) else LazyList.cons(head, tail.lazyAppendAll(suffix))

@deprecated("append has been renamed to lazyAppendAll", "2.13.0")
def append[B >: A](rest: => collection.IterableOnce[B]): LazyList[B] = lazyAppendAll(rest)

override def className = "LazyList"

override def equals(that: Any): Boolean =
Expand Down

0 comments on commit 158c79f

Please sign in to comment.