forked from scala/scala-collection-compat
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Martijn Hoekstra
committed
May 28, 2018
1 parent
a4c5413
commit 386b318
Showing
16 changed files
with
450 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package scala.util.compat | ||
|
||
private[compat] class SwappableEither[+A, +B](underlying: Either[A, B]) { | ||
def swap: Either[B, A] = underlying match { | ||
case Right(b) => Left(b) | ||
case Left(a) => Right(a) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package scala.util | ||
|
||
package object compat { | ||
implicit def bias[A, B](src: Either[A, B]) = src.right | ||
implicit def swappable[A, B](src: Either[A, B]): SwappableEither[A, B] = new SwappableEither[A, B](src) | ||
} |
39 changes: 39 additions & 0 deletions
39
src/main/scala-2.12/scala/collection/compat/BuildFrom.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package scala.collection.compat | ||
|
||
import scala.collection.generic.CanBuildFrom | ||
import scala.collection.{Iterable, mutable} | ||
|
||
/** Builds a collection of type `C` from elements of type `A` when a source collection of type `From` is available. | ||
* Implicit instances of `BuildFrom` are available for all collection types. | ||
* | ||
* @tparam From Type of source collection | ||
* @tparam A Type of elements (e.g. `Int`, `Boolean`, etc.) | ||
* @tparam C Type of collection (e.g. `List[Int]`, `TreeMap[Int, String]`, etc.) | ||
*/ | ||
trait BuildFrom[-From, -A, +C] extends Any { | ||
|
||
def fromSpecificIterable(from: From)(it: Iterable[A]): C | ||
|
||
/** Get a Builder for the collection. For non-strict collection types this will use an intermediate buffer. | ||
* Building collections with `fromSpecificIterable` is preferred because it can be lazy for lazy collections. */ | ||
def newBuilder(from: From): mutable.Builder[A, C] | ||
|
||
@deprecated("Use newBuilder() instead of apply()", "2.13.0") | ||
@`inline` def apply(from: From): mutable.Builder[A, C] = newBuilder(from) | ||
|
||
} | ||
|
||
object BuildFrom { | ||
|
||
// Implicit instance derived from an implicit CanBuildFrom instance | ||
implicit def fromCanBuildFrom[From, A, C](implicit cbf: CanBuildFrom[From, A, C]): BuildFrom[From, A, C] = | ||
new BuildFrom[From, A, C] { | ||
def fromSpecificIterable(from: From)(it: Iterable[A]): C = (cbf(from) ++= it).result() | ||
def newBuilder(from: From): mutable.Builder[A, C] = cbf(from) | ||
} | ||
|
||
// Implicit conversion derived from an implicit conversion to CanBuildFrom | ||
implicit def fromCanBuildFromConversion[X, From, A, C](x: X)(implicit toCanBuildFrom: X => CanBuildFrom[From, A, C]): BuildFrom[From, A, C] = | ||
fromCanBuildFrom(toCanBuildFrom(x)) | ||
|
||
} |
15 changes: 15 additions & 0 deletions
15
src/main/scala-2.12/scala/collection/compat/CompatImpl.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package scala.collection.compat | ||
|
||
import scala.collection.generic.CanBuildFrom | ||
import scala.collection.mutable.Builder | ||
import scala.collection.{immutable => i, mutable => m} | ||
|
||
private[compat] object CompatImpl { | ||
def simpleCBF[A, C](f: => Builder[A, C]): CanBuildFrom[Any, A, C] = new CanBuildFrom[Any, A, C] { | ||
def apply(from: Any): Builder[A, C] = apply() | ||
def apply(): Builder[A, C] = f | ||
} | ||
|
||
type ImmutableBitSetCC[X] = ({ type L[_] = i.BitSet })#L[X] | ||
type MutableBitSetCC[X] = ({ type L[_] = m.BitSet })#L[X] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package scala.collection.compat | ||
|
||
import scala.collection.generic.CanBuildFrom | ||
import scala.collection.{TraversableOnce, mutable} | ||
|
||
/** | ||
* A factory that builds a collection of type `C` with elements of type `A`. | ||
* | ||
* @tparam A Type of elements (e.g. `Int`, `Boolean`, etc.) | ||
* @tparam C Type of collection (e.g. `List[Int]`, `TreeMap[Int, String]`, etc.) | ||
*/ | ||
trait Factory[-A, +C] extends Any { | ||
|
||
/** | ||
* @return A collection of type `C` containing the same elements | ||
* as the source collection `it`. | ||
* @param it Source collection | ||
*/ | ||
def fromSpecific(it: TraversableOnce[A]): C | ||
|
||
/** Get a Builder for the collection. For non-strict collection types this will use an intermediate buffer. | ||
* Building collections with `fromSpecific` is preferred because it can be lazy for lazy collections. */ | ||
def newBuilder(): mutable.Builder[A, C] | ||
} | ||
|
||
object Factory { | ||
|
||
implicit def fromCanBuildFrom[A, C](implicit cbf: CanBuildFrom[Nothing, A, C]): Factory[A, C] = | ||
new Factory[A, C] { | ||
def fromSpecific(it: TraversableOnce[A]): C = (cbf() ++= it).result() | ||
def newBuilder(): mutable.Builder[A, C] = cbf() | ||
} | ||
|
||
implicit def fromCanBuildFromConversion[X, A, C](x: X)(implicit toCanBuildFrom: X => CanBuildFrom[Nothing, A, C]): Factory[A, C] = | ||
fromCanBuildFrom(toCanBuildFrom(x)) | ||
|
||
} |
226 changes: 226 additions & 0 deletions
226
src/main/scala-2.12/scala/collection/compat/immutable/ArraySeq.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
package scala.collection.compat.immutable | ||
|
||
import java.util.Arrays | ||
|
||
import scala.annotation.unchecked.uncheckedVariance | ||
import scala.collection.AbstractSeq | ||
import scala.collection.generic._ | ||
import scala.collection.immutable.IndexedSeq | ||
import scala.collection.mutable.{ArrayBuilder, Builder, WrappedArrayBuilder} | ||
import scala.reflect.ClassTag | ||
import scala.util.hashing.MurmurHash3 | ||
|
||
/** | ||
* An immutable array. | ||
* | ||
* Supports efficient indexed access and has a small memory footprint. | ||
* | ||
* @define Coll `ArraySeq` | ||
* @define coll wrapped array | ||
* @define orderDependent | ||
* @define orderDependentFold | ||
* @define mayNotTerminateInf | ||
* @define willNotTerminateInf | ||
*/ | ||
abstract class ArraySeq[+T] | ||
extends AbstractSeq[T] | ||
with IndexedSeq[T] | ||
{ | ||
|
||
override protected[this] def thisCollection: ArraySeq[T] = this | ||
|
||
/** The tag of the element type */ | ||
protected[this] def elemTag: ClassTag[T] | ||
|
||
/** The length of the array */ | ||
def length: Int | ||
|
||
/** The element at given index */ | ||
def apply(index: Int): T | ||
|
||
/** The underlying array */ | ||
def unsafeArray: Array[T @uncheckedVariance] | ||
|
||
override def stringPrefix = "ArraySeq" | ||
|
||
/** Clones this object, including the underlying Array. */ | ||
override def clone(): ArraySeq[T] = ArraySeq unsafeWrapArray unsafeArray.clone() | ||
|
||
/** Creates new builder for this collection ==> move to subclasses | ||
*/ | ||
override protected[this] def newBuilder: Builder[T, ArraySeq[T]] = | ||
new WrappedArrayBuilder[T](elemTag).mapResult(w => ArraySeq.unsafeWrapArray(w.array)) | ||
|
||
} | ||
|
||
/** A companion object used to create instances of `ArraySeq`. | ||
*/ | ||
object ArraySeq { | ||
// This is reused for all calls to empty. | ||
private val EmptyArraySeq = new ofRef[AnyRef](new Array[AnyRef](0)) | ||
def empty[T <: AnyRef]: ArraySeq[T] = EmptyArraySeq.asInstanceOf[ArraySeq[T]] | ||
|
||
/** | ||
* Wrap an existing `Array` into an `ArraySeq` of the proper primitive specialization type | ||
* without copying. | ||
* | ||
* Note that an array containing boxed primitives can be wrapped in an `ArraySeq` without | ||
* copying. For example, `val a: Array[Any] = Array(1)` is an array of `Object` at runtime, | ||
* containing `Integer`s. An `ArraySeq[Int]` can be obtained with a cast: | ||
* `ArraySeq.unsafeWrapArray(a).asInstanceOf[ArraySeq[Int]]`. The values are still | ||
* boxed, the resulting instance is an [[ArraySeq.ofRef]]. Writing | ||
* `ArraySeq.unsafeWrapArray(a.asInstanceOf[Array[Int]])` does not work, it throws a | ||
* `ClassCastException` at runtime. | ||
*/ | ||
def unsafeWrapArray[T](x: Array[T]): ArraySeq[T] = (x.asInstanceOf[Array[_]] match { | ||
case null => null | ||
case x: Array[AnyRef] => new ofRef[AnyRef](x) | ||
case x: Array[Int] => new ofInt(x) | ||
case x: Array[Double] => new ofDouble(x) | ||
case x: Array[Long] => new ofLong(x) | ||
case x: Array[Float] => new ofFloat(x) | ||
case x: Array[Char] => new ofChar(x) | ||
case x: Array[Byte] => new ofByte(x) | ||
case x: Array[Short] => new ofShort(x) | ||
case x: Array[Boolean] => new ofBoolean(x) | ||
case x: Array[Unit] => new ofUnit(x) | ||
}).asInstanceOf[ArraySeq[T]] | ||
|
||
implicit def canBuildFrom[T](implicit m: ClassTag[T]): CanBuildFrom[ArraySeq[_], T, ArraySeq[T]] = | ||
new CanBuildFrom[ArraySeq[_], T, ArraySeq[T]] { | ||
def apply(from: ArraySeq[_]): Builder[T, ArraySeq[T]] = | ||
ArrayBuilder.make[T]()(m) mapResult ArraySeq.unsafeWrapArray[T] | ||
def apply: Builder[T, ArraySeq[T]] = | ||
ArrayBuilder.make[T]()(m) mapResult ArraySeq.unsafeWrapArray[T] | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofRef[T <: AnyRef](val unsafeArray: Array[T]) extends ArraySeq[T] with Serializable { | ||
lazy val elemTag = ClassTag[T](unsafeArray.getClass.getComponentType) | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): T = unsafeArray(index) | ||
def update(index: Int, elem: T) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofRef[_] => Arrays.equals(unsafeArray.asInstanceOf[Array[AnyRef]], that.unsafeArray.asInstanceOf[Array[AnyRef]]) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofByte(val unsafeArray: Array[Byte]) extends ArraySeq[Byte] with Serializable { | ||
def elemTag = ClassTag.Byte | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Byte = unsafeArray(index) | ||
def update(index: Int, elem: Byte) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.bytesHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofByte => Arrays.equals(unsafeArray, that.unsafeArray) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofShort(val unsafeArray: Array[Short]) extends ArraySeq[Short] with Serializable { | ||
def elemTag = ClassTag.Short | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Short = unsafeArray(index) | ||
def update(index: Int, elem: Short) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofShort => Arrays.equals(unsafeArray, that.unsafeArray) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofChar(val unsafeArray: Array[Char]) extends ArraySeq[Char] with Serializable { | ||
def elemTag = ClassTag.Char | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Char = unsafeArray(index) | ||
def update(index: Int, elem: Char) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofChar => Arrays.equals(unsafeArray, that.unsafeArray) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofInt(val unsafeArray: Array[Int]) extends ArraySeq[Int] with Serializable { | ||
def elemTag = ClassTag.Int | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Int = unsafeArray(index) | ||
def update(index: Int, elem: Int) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofInt => Arrays.equals(unsafeArray, that.unsafeArray) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofLong(val unsafeArray: Array[Long]) extends ArraySeq[Long] with Serializable { | ||
def elemTag = ClassTag.Long | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Long = unsafeArray(index) | ||
def update(index: Int, elem: Long) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofLong => Arrays.equals(unsafeArray, that.unsafeArray) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofFloat(val unsafeArray: Array[Float]) extends ArraySeq[Float] with Serializable { | ||
def elemTag = ClassTag.Float | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Float = unsafeArray(index) | ||
def update(index: Int, elem: Float) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofFloat => Arrays.equals(unsafeArray, that.unsafeArray) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofDouble(val unsafeArray: Array[Double]) extends ArraySeq[Double] with Serializable { | ||
def elemTag = ClassTag.Double | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Double = unsafeArray(index) | ||
def update(index: Int, elem: Double) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofDouble => Arrays.equals(unsafeArray, that.unsafeArray) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofBoolean(val unsafeArray: Array[Boolean]) extends ArraySeq[Boolean] with Serializable { | ||
def elemTag = ClassTag.Boolean | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Boolean = unsafeArray(index) | ||
def update(index: Int, elem: Boolean) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofBoolean => Arrays.equals(unsafeArray, that.unsafeArray) | ||
case _ => super.equals(that) | ||
} | ||
} | ||
|
||
@SerialVersionUID(3L) | ||
final class ofUnit(val unsafeArray: Array[Unit]) extends ArraySeq[Unit] with Serializable { | ||
def elemTag = ClassTag.Unit | ||
def length: Int = unsafeArray.length | ||
def apply(index: Int): Unit = unsafeArray(index) | ||
def update(index: Int, elem: Unit) { unsafeArray(index) = elem } | ||
override def hashCode = MurmurHash3.arrayHash(unsafeArray, MurmurHash3.seqSeed) | ||
override def equals(that: Any) = that match { | ||
case that: ofUnit => unsafeArray.length == that.unsafeArray.length | ||
case _ => super.equals(that) | ||
} | ||
} | ||
} |
Oops, something went wrong.