![JAR search and dependency download from the Maven repository](/logo.png)
scala.collection.convert.impl.TableStepper.scala Maven / Gradle / Ivy
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/
package scala.collection.convert
package impl
import scala.collection.Stepper.EfficientSplit
import scala.collection._
private[collection] abstract class TableStepperBase[A, I >: Null <: AnyRef, Sub >: Null, Semi <: Sub with TableStepperBase[A, I, _, _]](
protected var maxLength: Int, protected val table: Array[I], protected var i0: Int, protected val iN: Int
)
extends EfficientSplit {
// Always holds table(i0); if `null` it is time to switch to the next element
protected var myCurrent: I = if (i0 < iN) table(i0) else null
// Only call this when `myCurrent` is null (meaning we need to advance)
@annotation.tailrec
protected final def findNextCurrent(): Boolean =
if (i0 < iN) {
i0 += 1
if (i0 >= iN) false
else {
myCurrent = table(i0)
if (myCurrent eq null) findNextCurrent()
else true
}
}
else false
protected def semiclone(half: Int): Semi
def characteristics: Int = 0
def estimateSize: Long = if (!hasStep) { maxLength = 0; 0 } else maxLength
def hasStep: Boolean = (myCurrent ne null) || findNextCurrent()
def trySplit(): Sub = {
if (iN-1 > i0 && maxLength > 0) {
val half = (i0 + iN) >>> 1
val ans = semiclone(half)
ans.myCurrent = myCurrent
myCurrent = table(half)
var inLeft = if (ans.myCurrent ne null) 1 else 0
var inRight = if (myCurrent ne null) 1 else 0
if (iN - i0 < 32) {
var i = i0+1
while (i < half && (table(i) ne null)) { i += 1; inLeft += 1 }
i = half+1
while (i < iN && (table(i) ne null)) { i += 1; inRight += 1 }
}
maxLength -= inLeft
ans.maxLength -= inRight
i0 = half
ans
}
else null
}
}
private[collection] final class AnyTableStepper[A, I >: Null <: AnyRef](
_maxLength: Int, _table: Array[I], iterate: I => I, extract: I => A, _i0: Int, _iN: Int
)
extends TableStepperBase[A, I, AnyStepper[A], AnyTableStepper[A, I]](_maxLength, _table, _i0, _iN)
with AnyStepper[A] {
def nextStep(): A =
if (hasStep) {
val ans = extract(myCurrent)
myCurrent = iterate(myCurrent)
ans
}
else Stepper.throwNSEE()
def semiclone(half: Int): AnyTableStepper[A, I] = new AnyTableStepper[A, I](maxLength, table, iterate, extract, i0, half)
}
private[collection] final class DoubleTableStepper[I >: Null <: AnyRef](
_maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Double, _i0: Int, _iN: Int
)
extends TableStepperBase[Double, I, DoubleStepper, DoubleTableStepper[I]](_maxLength, _table, _i0, _iN)
with DoubleStepper {
def nextStep(): Double =
if (hasStep) {
val ans = extract(myCurrent)
myCurrent = iterate(myCurrent)
ans
}
else Stepper.throwNSEE()
def semiclone(half: Int): DoubleTableStepper[I] = new DoubleTableStepper[I](maxLength, table, iterate, extract, i0, half)
}
private[collection] final class IntTableStepper[I >: Null <: AnyRef](
_maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Int, _i0: Int, _iN: Int
)
extends TableStepperBase[Int, I, IntStepper, IntTableStepper[I]](_maxLength, _table, _i0, _iN)
with IntStepper {
def nextStep(): Int =
if (hasStep) {
val ans = extract(myCurrent)
myCurrent = iterate(myCurrent)
ans
}
else Stepper.throwNSEE()
def semiclone(half: Int): IntTableStepper[I] = new IntTableStepper[I](maxLength, table, iterate, extract, i0, half)
}
private[collection] final class LongTableStepper[I >: Null <: AnyRef](
_maxLength: Int, _table: Array[I], iterate: I => I, extract: I => Long, _i0: Int, _iN: Int
)
extends TableStepperBase[Long, I, LongStepper, LongTableStepper[I]](_maxLength, _table, _i0, _iN)
with LongStepper {
def nextStep(): Long =
if (hasStep) {
val ans = extract(myCurrent)
myCurrent = iterate(myCurrent)
ans
}
else Stepper.throwNSEE()
def semiclone(half: Int): LongTableStepper[I] = new LongTableStepper[I](maxLength, table, iterate, extract, i0, half)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy