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

Commit 7b2b9e1

Browse files
committed
First cut at porting to Scala 2.13
1 parent f832409 commit 7b2b9e1

File tree

2 files changed

+72
-47
lines changed

2 files changed

+72
-47
lines changed

collections/src/main/scala/strawman/collection/Iterator.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ trait Iterator[+A] extends IterableOnce[A] { self =>
5959
* @note Reuse: $preservesIterator
6060
*/
6161
def isEmpty: Boolean = !hasNext
62+
63+
def nonEmpty: Boolean = !isEmpty
6264

6365
/** Wraps the value of `next()` in an option.
6466
*

collections/src/main/scala/strawman/collection/mutable/ArrayDeque.scala

Lines changed: 70 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package strawman
2-
package collection.mutable
2+
package collection
3+
package mutable
34

4-
import scala.{Int, Option, None, inline, Serializable, Unit, Array, StringContext, Iterator, Boolean, Some, AnyRef, IndexOutOfBoundsException, SerialVersionUID}
5-
import scala.collection.{generic, mutable}
5+
import scala.{Int, Option, None, inline, Serializable, Unit, Array, StringContext, Boolean, Some, AnyRef, IndexOutOfBoundsException, SerialVersionUID}
66
import scala.reflect.ClassTag
77
import scala.Predef.{assert, require}
88

9+
import strawman.collection.{IndexedSeq, IndexedSeqOps, Iterator, StrictOptimizedSeqOps}
10+
911
import java.lang.Math
1012
import java.util.NoSuchElementException
1113

@@ -39,13 +41,11 @@ class ArrayDeque[A] private[ArrayDeque](
3941
private[ArrayDeque] var array: Array[AnyRef],
4042
private[ArrayDeque] var start: Int,
4143
private[ArrayDeque] var end: Int
42-
) extends mutable.AbstractBuffer[A]
43-
with mutable.Buffer[A]
44-
with generic.GenericTraversableTemplate[A, ArrayDeque]
45-
with mutable.BufferLike[A, ArrayDeque[A]]
46-
with mutable.IndexedSeq[A]
47-
with mutable.IndexedSeqOptimized[A, ArrayDeque[A]]
48-
with mutable.Builder[A, ArrayDeque[A]]
44+
) extends Buffer[A]
45+
with IndexedSeq[A]
46+
with IndexedSeqOps[A, ArrayDeque, ArrayDeque[A]]
47+
with IndexedOptimizedSeq[A]
48+
with StrictOptimizedSeqOps[A, ArrayDeque, ArrayDeque[A]]
4949
with Serializable {
5050

5151
reset(array, start, end)
@@ -71,13 +71,13 @@ class ArrayDeque[A] private[ArrayDeque](
7171
_set(idx, elem)
7272
}
7373

74-
override def +=(elem: A) = {
75-
sizeHint(length + 1)
74+
override def add(elem: A) = {
75+
ensureSize(length + 1)
7676
appendAssumingCapacity(elem)
7777
}
7878

79-
override def +=:(elem: A) = {
80-
sizeHint(length + 1)
79+
override def prepend(elem: A) = {
80+
ensureSize(length + 1)
8181
prependAssumingCapacity(elem)
8282
}
8383

@@ -93,12 +93,14 @@ class ArrayDeque[A] private[ArrayDeque](
9393
this
9494
}
9595

96-
override def ++=:(elems: scala.collection.TraversableOnce[A]) = {
97-
if (elems.nonEmpty) {
96+
override def prependAll(elems: IterableOnce[A]) = {
97+
val it = elems.iterator
98+
if (it.nonEmpty) {
9899
val n = length
99100
// The following code resizes the current collection atmost once and traverses elems atmost twice
100-
ArrayDeque.knownSize(elems) match {
101+
elems.knownSize match {
101102
// Size is too expensive to compute AND we can traverse it only once - can't do much but retry with an IndexedSeq
103+
102104
case srcLength if srcLength < 0 && !elems.isTraversableAgain => elems.toIndexedSeq ++=: this
103105

104106
// We know for sure we need to resize to hold everything, might as well resize and memcopy upfront
@@ -111,11 +113,10 @@ class ArrayDeque[A] private[ArrayDeque](
111113

112114
// Just fill up from (start - srcLength) to (start - 1) and move back start
113115
case _srcLength =>
114-
val srcLength = if (_srcLength < 0) elems.size else _srcLength
115-
sizeHint(srcLength + n)
116+
val srcLength = if (_srcLength < 0) elems.length else _srcLength
117+
ensureSize(srcLength + n)
116118
// Optimized version of `elems.zipWithIndex.foreach((elem, i) => _set(i - srcLength, elem))`
117119
var i = 0
118-
val it = elems.toIterator
119120
while(it.hasNext) {
120121
_set(i - srcLength, it.next())
121122
i += 1
@@ -126,27 +127,27 @@ class ArrayDeque[A] private[ArrayDeque](
126127
this
127128
}
128129

129-
override def ++=(elems: scala.collection.TraversableOnce[A]) = {
130-
if (elems.nonEmpty) {
131-
ArrayDeque.knownSize(elems) match {
130+
override def addAll(elems: IterableOnce[A]) = {
131+
if (elems.iterator.nonEmpty) {
132+
elems.knownSize match {
132133
case srcLength if srcLength >= 0 =>
133-
sizeHint(srcLength + length)
134+
ensureSize(srcLength + length)
134135
elems.foreach(appendAssumingCapacity)
135136
case _ => elems.foreach(+=)
136137
}
137138
}
138139
this
139140
}
140141

141-
override def insertAll(idx: Int, elems: scala.collection.Traversable[A]) = {
142+
override def insertAll(idx: Int, elems: IterableOnce[A]) = {
142143
requireBounds(idx)
143144
val n = length
144145
if (idx == 0) {
145-
elems ++=: this
146+
prependAll(elems)
146147
} else if (idx == n - 1) {
147148
this ++= elems
148-
} else if (elems.nonEmpty) {
149-
val srcLength = elems.size
149+
} else if (elems.iterator.nonEmpty) {
150+
val srcLength = elems.length
150151
val finalLength = srcLength + n
151152
// Either we resize right away or move prefix left or suffix right
152153
if (isResizeNecessary(finalLength)) {
@@ -162,7 +163,7 @@ class ArrayDeque[A] private[ArrayDeque](
162163
i -= 1
163164
}
164165
end = end_+(srcLength)
165-
val it = elems.toIterator
166+
val it = elems.iterator
166167
while(it.hasNext) {
167168
i += 1
168169
_set(i, it.next())
@@ -174,7 +175,7 @@ class ArrayDeque[A] private[ArrayDeque](
174175
i += 1
175176
}
176177
start = start_-(srcLength)
177-
val it = elems.toIterator
178+
val it = elems.iterator
178179
while(it.hasNext) {
179180
_set(i, it.next())
180181
i += 1
@@ -222,6 +223,12 @@ class ArrayDeque[A] private[ArrayDeque](
222223
elem
223224
}
224225

226+
override def subtract(elem: A) = {
227+
val idx = indexOf(elem)
228+
if (idx != -1) remove(idx)
229+
this
230+
}
231+
225232
/**
226233
*
227234
* @param resizeInternalRepr If this is set, resize the internal representation to reclaim space once in a while
@@ -282,7 +289,7 @@ class ArrayDeque[A] private[ArrayDeque](
282289
*/
283290
def removeAll(): scala.collection.Seq[A] = {
284291
val elems = scala.collection.Seq.newBuilder[A]
285-
elems.sizeHint(length)
292+
elems.ensureSize(length)
286293
while(nonEmpty) {
287294
elems += removeHeadAssumingNonEmpty()
288295
}
@@ -329,7 +336,7 @@ class ArrayDeque[A] private[ArrayDeque](
329336
Iterator.tabulate(n)(i => this(n - i - 1))
330337
}
331338

332-
override def reverseMap[B, That](f: (A) => B)(implicit bf: generic.CanBuildFrom[ArrayDeque[A], B, That]) = reverse.map(f)
339+
//override def reverseMap[B, That](f: (A) => B)(implicit bf: generic.CanBuildFrom[ArrayDeque[A], B, That]) = reverse.map(f)
333340

334341
override def reverse = {
335342
val n = length
@@ -342,16 +349,28 @@ class ArrayDeque[A] private[ArrayDeque](
342349
new ArrayDeque(arr, start = 0, end = n)
343350
}
344351

345-
@inline override def sizeHint(hint: Int) = if (hint > length && isResizeNecessary(hint)) resize(hint + 1)
352+
@inline override def ensureSize(hint: Int) = if (hint > length && isResizeNecessary(hint)) resize(hint + 1)
346353

347354
override def length = end_-(start)
348355

356+
override def knowSize = length
357+
349358
override def isEmpty = start == end
350359

351360
override def nonEmpty = start != end
352361

353362
override def clone() = new ArrayDeque(array.clone(), start = start, end = end)
354363

364+
override def view: ArrayDequeView[A] = new ArrayDequeView(this)
365+
366+
override def iterableFactory: SeqFactory[ArrayDeque] = ArrayDeque
367+
368+
protected[this] def fromSpecificIterable(coll: collection.Iterable[A]): ArrayDeque[A] =
369+
fromIterable(coll)
370+
371+
protected[this] def newSpecificBuilder(): Builder[A, ArrayDeque[A]] =
372+
ArrayBuffer.newBuilder()
373+
355374
/**
356375
* Note: This does not actually resize the internal representation.
357376
* See clearAndShrink if you want to also resize internally
@@ -399,11 +418,7 @@ class ArrayDeque[A] private[ArrayDeque](
399418
override def copyToArray[B >: A](dest: Array[B], destStart: Int, len: Int) =
400419
copySliceToArray(srcStart = 0, dest = dest, destStart = destStart, maxItems = len)
401420

402-
override def companion = ArrayDeque
403-
404-
override def result() = this
405-
406-
override def stringPrefix = "ArrayDeque"
421+
override def className = "ArrayDeque"
407422

408423
override def toArray[B >: A: ClassTag] =
409424
copySliceToArray(srcStart = 0, dest = new Array[B](length), destStart = 0, maxItems = length)
@@ -462,11 +477,24 @@ class ArrayDeque[A] private[ArrayDeque](
462477
if (idx < 0 || until <= idx) throw new IndexOutOfBoundsException(idx.toString)
463478
}
464479

465-
object ArrayDeque extends generic.SeqFactory[ArrayDeque] {
466-
implicit def canBuildFrom[A]: generic.CanBuildFrom[Coll, A, ArrayDeque[A]] =
467-
ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
480+
class ArrayDequeView[A](val parent: ArrayDeque[A]) extends IndexedView[A] {
481+
482+
override def apply(idx: Int) = parent(idx)
483+
484+
override def className = "ArrayDequeView"
485+
}
486+
487+
object ArrayDeque extends StrictOptimizedSeqFactory[ArrayDeque] {
488+
/** Avoid reallocation of buffer if length is known. */
489+
def from[B](coll: collection.IterableOnce[B]): ArrayDeque[B] =
490+
empty[B].addAll(coll) //TODO: Can be optimized based on coll.size?
491+
492+
def newBuilder[A](): Builder[A, ArrayDeque[A]] =
493+
new GrowableBuilder[A, ArrayDeque[A]](empty) {
494+
override def sizeHint(size: Int): Unit = elems.ensureSize(size)
495+
}
468496

469-
override def newBuilder[A]: mutable.Builder[A, ArrayDeque[A]] = new ArrayDeque[A]()
497+
def empty[A]: ArrayDeque[A] = new ArrayDeque[A]()
470498

471499
final val DefaultInitialSize = 16
472500

@@ -475,11 +503,6 @@ object ArrayDeque extends generic.SeqFactory[ArrayDeque] {
475503
*/
476504
private[ArrayDeque] final val StableSize = 256
477505

478-
private[ArrayDeque] def knownSize[A](coll: scala.collection.TraversableOnce[A]) = {
479-
//TODO: Remove this temporary util when we switch to strawman .sizeHintIfCheap is now .knownSize
480-
if (coll.isInstanceOf[scala.List[_]] || coll.isInstanceOf[scala.Stream[_]] || coll.isInstanceOf[scala.Iterator[_]] || !coll.isTraversableAgain) -1 else coll.size
481-
}
482-
483506
/**
484507
* Allocates an array whose size is next power of 2 > $len
485508
* Largest possible len is 1<<30 - 1

0 commit comments

Comments
 (0)