summaryrefslogtreecommitdiff
path: root/src/library/scala
diff options
context:
space:
mode:
authorSeth Tisue <seth@tisue.net>2017-02-16 14:14:39 -0800
committerSeth Tisue <seth@tisue.net>2017-02-16 14:34:18 -0800
commit04c45e15f198c3e33b0e6709fb8ca5267f129fac (patch)
tree215307f083dba29d2c53c83ca3702c8d4a34d27f /src/library/scala
parent6be69d6d5e710e2022772a326a48baf093a70508 (diff)
parent096502880900d8daa75d813c63ac88aa50c25ef0 (diff)
downloadscala-04c45e15f198c3e33b0e6709fb8ca5267f129fac.tar.gz
scala-04c45e15f198c3e33b0e6709fb8ca5267f129fac.tar.bz2
scala-04c45e15f198c3e33b0e6709fb8ca5267f129fac.zip
Merge commit '0965028809' into merge-2.11.x-to-2.12.x-20170214
Diffstat (limited to 'src/library/scala')
-rw-r--r--src/library/scala/collection/immutable/FilteredTraversableInternal.scala104
-rw-r--r--src/library/scala/collection/immutable/List.scala53
-rw-r--r--src/library/scala/collection/immutable/RedBlackTree.scala5
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala74
-rw-r--r--src/library/scala/collection/mutable/WrappedArray.scala71
5 files changed, 265 insertions, 42 deletions
diff --git a/src/library/scala/collection/immutable/FilteredTraversableInternal.scala b/src/library/scala/collection/immutable/FilteredTraversableInternal.scala
new file mode 100644
index 0000000000..35585b7826
--- /dev/null
+++ b/src/library/scala/collection/immutable/FilteredTraversableInternal.scala
@@ -0,0 +1,104 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala
+package collection
+package immutable
+
+import scala.annotation.tailrec
+
+/**
+ * Optimised filter functions for List
+ * n.b. this is an internal class to help maintain compatibility and should not be used directly.
+ */
+private[immutable] trait FilteredTraversableInternal[+A, +Repr <: AnyRef with TraversableLike[A, Repr]] extends TraversableLike[A, Repr] {
+
+ // Optimized for List
+
+ override def filter(p: A => Boolean): Self = filterImpl(p, isFlipped = false)
+
+ override def filterNot(p: A => Boolean): Self = filterImpl(p, isFlipped = true)
+
+ private[this] def filterImpl(p: A => Boolean, isFlipped: Boolean): Self = {
+
+ // everything seen so far so far is not included
+ @tailrec def noneIn(l: Repr): Repr = {
+ if (l.isEmpty)
+ Nil.asInstanceOf[Repr]
+ else {
+ val h = l.head
+ val t = l.tail
+ if (p(h) != isFlipped)
+ allIn(l, t)
+ else
+ noneIn(t)
+ }
+ }
+
+ // everything from 'start' is included, if everything from this point is in we can return the origin
+ // start otherwise if we discover an element that is out we must create a new partial list.
+ @tailrec def allIn(start: Repr, remaining: Repr): Repr = {
+ if (remaining.isEmpty)
+ start
+ else {
+ val x = remaining.head
+ if (p(x) != isFlipped)
+ allIn(start, remaining.tail)
+ else
+ partialFill(start, remaining)
+ }
+ }
+
+ // we have seen elements that should be included then one that should be excluded, start building
+ def partialFill(origStart: Repr, firstMiss: Repr): Repr = {
+ val newHead = new ::(origStart.head, Nil)
+ var toProcess = origStart.tail
+ var currentLast = newHead
+
+ // we know that all elements are :: until at least firstMiss.tail
+ while (!(toProcess eq firstMiss)) {
+ val newElem = new ::(toProcess.head, Nil)
+ currentLast.tl = newElem
+ currentLast = newElem
+ toProcess = toProcess.tail
+ }
+
+ // at this point newHead points to a list which is a duplicate of all the 'in' elements up to the first miss.
+ // currentLast is the last element in that list.
+
+ // now we are going to try and share as much of the tail as we can, only moving elements across when we have to.
+ var next = firstMiss.tail
+ var nextToCopy = next // the next element we would need to copy to our list if we cant share.
+ while (!next.isEmpty) {
+ // generally recommended is next.isNonEmpty but this incurs an extra method call.
+ val head: A = next.head
+ if (p(head) != isFlipped) {
+ next = next.tail
+ } else {
+ // its not a match - do we have outstanding elements?
+ while (!(nextToCopy eq next)) {
+ val newElem = new ::(nextToCopy.head, Nil)
+ currentLast.tl = newElem
+ currentLast = newElem
+ nextToCopy = nextToCopy.tail
+ }
+ nextToCopy = next.tail
+ next = next.tail
+ }
+ }
+
+ // we have remaining elements - they are unchanged attach them to the end
+ if (!nextToCopy.isEmpty)
+ currentLast.tl = nextToCopy.asInstanceOf[List[A]]
+
+ newHead.asInstanceOf[Repr]
+ }
+
+ noneIn(repr)
+ }
+} \ No newline at end of file
diff --git a/src/library/scala/collection/immutable/List.scala b/src/library/scala/collection/immutable/List.scala
index e5444533a8..e12ce7c2eb 100644
--- a/src/library/scala/collection/immutable/List.scala
+++ b/src/library/scala/collection/immutable/List.scala
@@ -88,6 +88,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
with Product
with GenericTraversableTemplate[A, List]
with LinearSeqOptimized[A, List[A]]
+ with FilteredTraversableInternal[A, List[A]]
with scala.Serializable {
override def companion: GenericCompanion[List] = List
@@ -163,30 +164,41 @@ sealed abstract class List[+A] extends AbstractSeq[A]
// Note to developers: there exists a duplication between this function and `reflect.internal.util.Collections#map2Conserve`.
// If any successful optimization attempts or other changes are made, please rehash them there too.
@tailrec
- def loop(mapped: ListBuffer[B], unchanged: List[A], pending: List[A]): List[B] =
- if (pending.isEmpty) {
- if (mapped eq null) unchanged
- else mapped.prependToList(unchanged)
+ def loop(mappedHead: List[B] = Nil, mappedLast: ::[B], unchanged: List[A], pending: List[A]): List[B] =
+ if (pending.isEmpty) {
+ if (mappedHead eq null) unchanged
+ else {
+ mappedLast.tl = unchanged
+ mappedHead
}
+ }
+ else {
+ val head0 = pending.head
+ val head1 = f(head0)
+
+ if (head1 eq head0.asInstanceOf[AnyRef])
+ loop(mappedHead, mappedLast, unchanged, pending.tail)
else {
- val head0 = pending.head
- val head1 = f(head0)
-
- if (head1 eq head0.asInstanceOf[AnyRef])
- loop(mapped, unchanged, pending.tail)
- else {
- val b = if (mapped eq null) new ListBuffer[B] else mapped
- var xc = unchanged
- while (xc ne pending) {
- b += xc.head
- xc = xc.tail
- }
- b += head1
- val tail0 = pending.tail
- loop(b, tail0, tail0)
+ var xc = unchanged
+ var mappedHead1: List[B] = mappedHead
+ var mappedLast1: ::[B] = mappedLast
+ while (xc ne pending) {
+ val next = new ::[B](xc.head, Nil)
+ if (mappedHead1 eq null) mappedHead1 = next
+ if (mappedLast1 ne null) mappedLast1.tl = next
+ mappedLast1 = next
+ xc = xc.tail
}
+ val next = new ::(head1, Nil)
+ if (mappedHead1 eq null) mappedHead1 = next
+ if (mappedLast1 ne null) mappedLast1.tl = next
+ mappedLast1 = next
+ val tail0 = pending.tail
+ loop(mappedHead1, mappedLast1, tail0, tail0)
+
}
- loop(null, this, this)
+ }
+ loop(null, null, this, this)
}
// Overridden methods from IterableLike and SeqLike or overloaded variants of such methods
@@ -402,6 +414,7 @@ sealed abstract class List[+A] extends AbstractSeq[A]
// Create a proxy for Java serialization that allows us to avoid mutation
// during deserialization. This is the Serialization Proxy Pattern.
protected final def writeReplace(): AnyRef = new List.SerializationProxy(this)
+
}
/** The empty list.
diff --git a/src/library/scala/collection/immutable/RedBlackTree.scala b/src/library/scala/collection/immutable/RedBlackTree.scala
index afb4c9c552..4f2e9115fe 100644
--- a/src/library/scala/collection/immutable/RedBlackTree.scala
+++ b/src/library/scala/collection/immutable/RedBlackTree.scala
@@ -516,9 +516,10 @@ object RedBlackTree {
*
* According to {@see Integer#numberOfLeadingZeros} ceil(log_2(n)) = (32 - Integer.numberOfLeadingZeros(n - 1))
*
- * We also don't store the deepest nodes in the path so the maximum path length is further reduced by one.
+ * Although we don't store the deepest nodes in the path during iteration,
+ * we potentially do so in `startFrom`.
*/
- val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2 - 1
+ val maximumHeight = 2 * (32 - Integer.numberOfLeadingZeros(root.count + 2 - 1)) - 2
new Array[Tree[A, B]](maximumHeight)
}
private[this] var index = 0
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 29382134aa..5de3dad256 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -10,6 +10,8 @@ package scala
package collection
package mutable
+import java.util
+
import scala.reflect.ClassTag
import parallel.mutable.ParArray
@@ -180,6 +182,23 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara
def seq = thisCollection
}
+/** to provide binary compat for 2.11 and 2.12 this class contains
+ * functionality that should be migrated to ArrayOps in 2.13
+ *
+ */
+private[mutable] sealed trait ArrayOpsImpl[T] extends Any with ArrayOps[T] {
+ override final def slice(from: Int, until: Int): Array[T] = {
+ val start = if (from < 0) 0 else from
+ if (until <= start || start >= repr.length)
+ return emptyImpl
+ val end = if (until > length) length else until
+ sliceImpl(start, end)
+ }
+ protected def emptyImpl: Array[T]
+ protected def sliceImpl(from: Int, until: Int): Array[T]
+
+}
+
/**
* A companion object for `ArrayOps`.
*
@@ -187,12 +206,24 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara
*/
object ArrayOps {
+ private val emptyByteArray = new Array[Byte](0)
+ private val emptyShortArray = new Array[Short](0)
+ private val emptyIntArray = new Array[Int](0)
+ private val emptyLongArray = new Array[Long](0)
+ private val emptyFloatArray = new Array[Float](0)
+ private val emptyDoubleArray = new Array[Double](0)
+ private val emptyUnitArray = new Array[Unit](0)
+ private val emptyCharArray = new Array[Char](0)
+ private val emptyBooleanArray = new Array[Boolean](0)
+
/** A subclass of `ArrayOps` for arrays containing reference types. */
- final class ofRef[T <: AnyRef](override val repr: Array[T]) extends AnyVal with ArrayOps[T] with ArrayLike[T, Array[T]] {
+ final class ofRef[T <: AnyRef](override val repr: Array[T]) extends AnyVal with ArrayOpsImpl[T] with ArrayLike[T, Array[T]] {
override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr)
override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr)
override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](repr.getClass.getComponentType))
+ protected override def emptyImpl:Array[T] = util.Arrays.copyOf[T](repr,0)
+ protected override def sliceImpl(from: Int, until: Int): Array[T] = util.Arrays.copyOfRange[T](repr, from, until)
def length: Int = repr.length
def apply(index: Int): T = repr(index)
@@ -200,11 +231,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Byte`s. */
- final class ofByte(override val repr: Array[Byte]) extends AnyVal with ArrayOps[Byte] with ArrayLike[Byte, Array[Byte]] {
+ final class ofByte(override val repr: Array[Byte]) extends AnyVal with ArrayOpsImpl[Byte] with ArrayLike[Byte, Array[Byte]] {
override protected[this] def thisCollection: WrappedArray[Byte] = new WrappedArray.ofByte(repr)
override protected[this] def toCollection(repr: Array[Byte]): WrappedArray[Byte] = new WrappedArray.ofByte(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofByte
+ protected override def emptyImpl = emptyByteArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Byte = repr(index)
@@ -212,11 +245,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Short`s. */
- final class ofShort(override val repr: Array[Short]) extends AnyVal with ArrayOps[Short] with ArrayLike[Short, Array[Short]] {
+ final class ofShort(override val repr: Array[Short]) extends AnyVal with ArrayOpsImpl[Short] with ArrayLike[Short, Array[Short]] {
override protected[this] def thisCollection: WrappedArray[Short] = new WrappedArray.ofShort(repr)
override protected[this] def toCollection(repr: Array[Short]): WrappedArray[Short] = new WrappedArray.ofShort(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofShort
+ protected override def emptyImpl = emptyShortArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Short = repr(index)
@@ -224,11 +259,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Char`s. */
- final class ofChar(override val repr: Array[Char]) extends AnyVal with ArrayOps[Char] with ArrayLike[Char, Array[Char]] {
+ final class ofChar(override val repr: Array[Char]) extends AnyVal with ArrayOpsImpl[Char] with ArrayLike[Char, Array[Char]] {
override protected[this] def thisCollection: WrappedArray[Char] = new WrappedArray.ofChar(repr)
override protected[this] def toCollection(repr: Array[Char]): WrappedArray[Char] = new WrappedArray.ofChar(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofChar
+ protected override def emptyImpl = emptyCharArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Char = repr(index)
@@ -236,11 +273,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Int`s. */
- final class ofInt(override val repr: Array[Int]) extends AnyVal with ArrayOps[Int] with ArrayLike[Int, Array[Int]] {
+ final class ofInt(override val repr: Array[Int]) extends AnyVal with ArrayOpsImpl[Int] with ArrayLike[Int, Array[Int]] {
override protected[this] def thisCollection: WrappedArray[Int] = new WrappedArray.ofInt(repr)
override protected[this] def toCollection(repr: Array[Int]): WrappedArray[Int] = new WrappedArray.ofInt(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofInt
+ protected override def emptyImpl = emptyIntArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Int = repr(index)
@@ -248,11 +287,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Long`s. */
- final class ofLong(override val repr: Array[Long]) extends AnyVal with ArrayOps[Long] with ArrayLike[Long, Array[Long]] {
+ final class ofLong(override val repr: Array[Long]) extends AnyVal with ArrayOpsImpl[Long] with ArrayLike[Long, Array[Long]] {
override protected[this] def thisCollection: WrappedArray[Long] = new WrappedArray.ofLong(repr)
override protected[this] def toCollection(repr: Array[Long]): WrappedArray[Long] = new WrappedArray.ofLong(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofLong
+ protected override def emptyImpl = emptyLongArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Long = repr(index)
@@ -260,11 +301,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Float`s. */
- final class ofFloat(override val repr: Array[Float]) extends AnyVal with ArrayOps[Float] with ArrayLike[Float, Array[Float]] {
+ final class ofFloat(override val repr: Array[Float]) extends AnyVal with ArrayOpsImpl[Float] with ArrayLike[Float, Array[Float]] {
override protected[this] def thisCollection: WrappedArray[Float] = new WrappedArray.ofFloat(repr)
override protected[this] def toCollection(repr: Array[Float]): WrappedArray[Float] = new WrappedArray.ofFloat(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofFloat
+ protected override def emptyImpl = emptyFloatArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Float = repr(index)
@@ -272,11 +315,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Double`s. */
- final class ofDouble(override val repr: Array[Double]) extends AnyVal with ArrayOps[Double] with ArrayLike[Double, Array[Double]] {
+ final class ofDouble(override val repr: Array[Double]) extends AnyVal with ArrayOpsImpl[Double] with ArrayLike[Double, Array[Double]] {
override protected[this] def thisCollection: WrappedArray[Double] = new WrappedArray.ofDouble(repr)
override protected[this] def toCollection(repr: Array[Double]): WrappedArray[Double] = new WrappedArray.ofDouble(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofDouble
+ protected override def emptyImpl = emptyDoubleArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Double = repr(index)
@@ -284,11 +329,13 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays containing `Boolean`s. */
- final class ofBoolean(override val repr: Array[Boolean]) extends AnyVal with ArrayOps[Boolean] with ArrayLike[Boolean, Array[Boolean]] {
+ final class ofBoolean(override val repr: Array[Boolean]) extends AnyVal with ArrayOpsImpl[Boolean] with ArrayLike[Boolean, Array[Boolean]] {
override protected[this] def thisCollection: WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr)
override protected[this] def toCollection(repr: Array[Boolean]): WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofBoolean
+ protected override def emptyImpl = emptyBooleanArray
+ protected override def sliceImpl(from: Int, until: Int) = util.Arrays.copyOfRange(repr, from, until)
def length: Int = repr.length
def apply(index: Int): Boolean = repr(index)
@@ -296,11 +343,18 @@ object ArrayOps {
}
/** A subclass of `ArrayOps` for arrays of `Unit` types. */
- final class ofUnit(override val repr: Array[Unit]) extends AnyVal with ArrayOps[Unit] with ArrayLike[Unit, Array[Unit]] {
+ final class ofUnit(override val repr: Array[Unit]) extends AnyVal with ArrayOpsImpl[Unit] with ArrayLike[Unit, Array[Unit]] {
override protected[this] def thisCollection: WrappedArray[Unit] = new WrappedArray.ofUnit(repr)
override protected[this] def toCollection(repr: Array[Unit]): WrappedArray[Unit] = new WrappedArray.ofUnit(repr)
override protected[this] def newBuilder = new ArrayBuilder.ofUnit
+ protected override def emptyImpl = emptyUnitArray
+ protected override def sliceImpl(from: Int, until: Int) = {
+ // cant use util.Arrays.copyOfRange[Unit](repr, from, until) - Unit is special and doesnt compile
+ val res = new Array[Unit](until-from)
+ System.arraycopy(repr, from, res, 0, res.size)
+ res
+ }
def length: Int = repr.length
def apply(index: Int): Unit = repr(index)
diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala
index 0b5ebe7e9a..d0919c4357 100644
--- a/src/library/scala/collection/mutable/WrappedArray.scala
+++ b/src/library/scala/collection/mutable/WrappedArray.scala
@@ -85,12 +85,26 @@ extends AbstractSeq[T]
*/
override protected[this] def newBuilder: Builder[T, WrappedArray[T]] =
new WrappedArrayBuilder[T](elemTag)
+}
+
+private[mutable] abstract class WrappedArrayImpl[T] extends WrappedArray[T] {
+ override def slice(from: Int, until: Int): WrappedArray[T] = {
+ val start = if (from < 0) 0 else from
+ if (until <= start || start >= repr.length)
+ return emptyImpl
+ val end = if (until > length) length else until
+ sliceImpl(start, end)
+ }
+ protected def emptyImpl: WrappedArray[T]
+
+ protected def sliceImpl(from: Int, until: Int): WrappedArray[T]
}
/** A companion object used to create instances of `WrappedArray`.
*/
object WrappedArray {
+ import java.util
// This is reused for all calls to empty.
private val EmptyWrappedArray = new ofRef[AnyRef](new Array[AnyRef](0))
def empty[T <: AnyRef]: WrappedArray[T] = EmptyWrappedArray.asInstanceOf[WrappedArray[T]]
@@ -124,7 +138,17 @@ object WrappedArray {
def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer
- final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable {
+ private val emptyWrappedByte = new ofByte(new Array[Byte](0))
+ private val emptyWrappedShort = new ofShort(new Array[Short](0))
+ private val emptyWrappedInt = new ofInt(new Array[Int](0))
+ private val emptyWrappedLong = new ofLong(new Array[Long](0))
+ private val emptyWrappedFloat = new ofFloat(new Array[Float](0))
+ private val emptyWrappedDouble = new ofDouble(new Array[Double](0))
+ private val emptyWrappedUnit = new ofUnit(new Array[Unit](0))
+ private val emptyWrappedChar = new ofChar(new Array[Char](0))
+ private val emptyWrappedBoolean = new ofBoolean(new Array[Boolean](0))
+
+ final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArrayImpl[T] with Serializable {
lazy val elemTag = ClassTag[T](array.getClass.getComponentType)
def length: Int = array.length
def apply(index: Int): T = array(index).asInstanceOf[T]
@@ -134,9 +158,11 @@ object WrappedArray {
case that: ofRef[_] => Arrays.equals(array.asInstanceOf[Array[AnyRef]], that.array.asInstanceOf[Array[AnyRef]])
case _ => super.equals(that)
}
+ protected override def emptyImpl = new ofRef(util.Arrays.copyOf[T](array,0))
+ protected override def sliceImpl(from: Int, until: Int) = new ofRef[T](util.Arrays.copyOfRange[T](array, from, until))
}
- final class ofByte(val array: Array[Byte]) extends WrappedArray[Byte] with Serializable {
+ final class ofByte(val array: Array[Byte]) extends WrappedArrayImpl[Byte] with Serializable {
def elemTag = ClassTag.Byte
def length: Int = array.length
def apply(index: Int): Byte = array(index)
@@ -146,9 +172,11 @@ object WrappedArray {
case that: ofByte => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedByte
+ protected override def sliceImpl(from: Int, until: Int) = new ofByte(util.Arrays.copyOfRange(array, from, until))
}
- final class ofShort(val array: Array[Short]) extends WrappedArray[Short] with Serializable {
+ final class ofShort(val array: Array[Short]) extends WrappedArrayImpl[Short] with Serializable {
def elemTag = ClassTag.Short
def length: Int = array.length
def apply(index: Int): Short = array(index)
@@ -158,9 +186,11 @@ object WrappedArray {
case that: ofShort => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedShort
+ protected override def sliceImpl(from: Int, until: Int) = new ofShort(util.Arrays.copyOfRange(array, from, until))
}
- final class ofChar(val array: Array[Char]) extends WrappedArray[Char] with Serializable {
+ final class ofChar(val array: Array[Char]) extends WrappedArrayImpl[Char] with Serializable {
def elemTag = ClassTag.Char
def length: Int = array.length
def apply(index: Int): Char = array(index)
@@ -170,9 +200,11 @@ object WrappedArray {
case that: ofChar => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedChar
+ protected override def sliceImpl(from: Int, until: Int) = new ofChar(util.Arrays.copyOfRange(array, from, until))
}
- final class ofInt(val array: Array[Int]) extends WrappedArray[Int] with Serializable {
+ final class ofInt(val array: Array[Int]) extends WrappedArrayImpl[Int] with Serializable {
def elemTag = ClassTag.Int
def length: Int = array.length
def apply(index: Int): Int = array(index)
@@ -182,9 +214,11 @@ object WrappedArray {
case that: ofInt => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedInt
+ protected override def sliceImpl(from: Int, until: Int) = new ofInt(util.Arrays.copyOfRange(array, from, until))
}
- final class ofLong(val array: Array[Long]) extends WrappedArray[Long] with Serializable {
+ final class ofLong(val array: Array[Long]) extends WrappedArrayImpl[Long] with Serializable {
def elemTag = ClassTag.Long
def length: Int = array.length
def apply(index: Int): Long = array(index)
@@ -194,9 +228,11 @@ object WrappedArray {
case that: ofLong => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedLong
+ protected override def sliceImpl(from: Int, until: Int) = new ofLong(util.Arrays.copyOfRange(array, from, until))
}
- final class ofFloat(val array: Array[Float]) extends WrappedArray[Float] with Serializable {
+ final class ofFloat(val array: Array[Float]) extends WrappedArrayImpl[Float] with Serializable {
def elemTag = ClassTag.Float
def length: Int = array.length
def apply(index: Int): Float = array(index)
@@ -206,9 +242,11 @@ object WrappedArray {
case that: ofFloat => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedFloat
+ protected override def sliceImpl(from: Int, until: Int) = new ofFloat(util.Arrays.copyOfRange(array, from, until))
}
- final class ofDouble(val array: Array[Double]) extends WrappedArray[Double] with Serializable {
+ final class ofDouble(val array: Array[Double]) extends WrappedArrayImpl[Double] with Serializable {
def elemTag = ClassTag.Double
def length: Int = array.length
def apply(index: Int): Double = array(index)
@@ -218,9 +256,11 @@ object WrappedArray {
case that: ofDouble => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedDouble
+ protected override def sliceImpl(from: Int, until: Int) = new ofDouble(util.Arrays.copyOfRange(array, from, until))
}
- final class ofBoolean(val array: Array[Boolean]) extends WrappedArray[Boolean] with Serializable {
+ final class ofBoolean(val array: Array[Boolean]) extends WrappedArrayImpl[Boolean] with Serializable {
def elemTag = ClassTag.Boolean
def length: Int = array.length
def apply(index: Int): Boolean = array(index)
@@ -230,9 +270,11 @@ object WrappedArray {
case that: ofBoolean => Arrays.equals(array, that.array)
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedBoolean
+ protected override def sliceImpl(from: Int, until: Int) = new ofBoolean(util.Arrays.copyOfRange(array, from, until))
}
- final class ofUnit(val array: Array[Unit]) extends WrappedArray[Unit] with Serializable {
+ final class ofUnit(val array: Array[Unit]) extends WrappedArrayImpl[Unit] with Serializable {
def elemTag = ClassTag.Unit
def length: Int = array.length
def apply(index: Int): Unit = array(index)
@@ -242,5 +284,14 @@ object WrappedArray {
case that: ofUnit => array.length == that.array.length
case _ => super.equals(that)
}
+ protected override def emptyImpl = emptyWrappedUnit
+ protected override def sliceImpl(from: Int, until: Int) = {
+ // cant use
+ // new ofUnit(util.Arrays.copyOfRange[Unit](array, from, until)) - Unit is special and doesnt compile
+ // cant use util.Arrays.copyOfRange[Unit](repr, from, until) - Unit is special and doesnt compile
+ val res = new Array[Unit](until-from)
+ System.arraycopy(repr, from, res, 0, until-from)
+ new ofUnit(res)
+ }
}
}