
org.opalj.collection.LongIterator.scala Maven / Gradle / Ivy
The newest version!
/* BSD 2-Clause License - see OPAL/LICENSE for details. */
package org.opalj.collection
import java.util.function.LongPredicate
import java.util.function.LongConsumer
import scala.collection.AbstractIterator
import org.opalj.collection.immutable.LongTrieSet
/**
* Iterator over a collection of longs; basically all methods are overridden to avoid
* (un)boxing operations.
*
* @author Michael Eichberg
*/
abstract class LongIterator extends AbstractIterator[Long] { self ⇒
def ++(other: LongIterator): LongIterator = {
new LongIterator {
private[this] var it = self
override def hasNext = it != null
override def next: Long = {
val v = it.next
if (!it.hasNext) {
it = if (it eq self) other else null
}
v
}
}
}
/**
* Returns the next value if `hasNext` has returned `true`; if hasNext has returned `false`
* and `next` is called, the result is undefined. The method may throw an
* `UnsupportedOperationException` or just return the last value; however, the behavior
* is undefined and subject to change without notice!
*/
def next(): Long
override def exists(p: Long ⇒ Boolean): Boolean = {
while (this.hasNext) { if (p(this.next())) return true; }
false
}
override def forall(p: Long ⇒ Boolean): Boolean = {
while (this.hasNext) { if (!p(this.next())) return false; }
true
}
def contains(i: Long): Boolean = {
while (this.hasNext) { if (i == this.next()) return true; }
false
}
override def foldLeft[B](start: B)(f: (B, Long) ⇒ B): B = {
var c = start
while (this.hasNext) { c = f(c, next()) }
c
}
def foreachWhile(p: LongPredicate)(f: LongConsumer): Unit = {
while (this.hasNext && {
val c = this.next()
if (p.test(c)) {
f.accept(c)
true
} else {
false
}
}) { /*empty*/ }
}
def map(f: Long ⇒ Long): LongIterator = {
new LongIterator {
def hasNext: Boolean = self.hasNext
def next(): Long = f(self.next())
}
}
override def take(n: Int): LongIterator = {
new LongIterator {
private[this] var i: Int = 0
def hasNext: Boolean = self.hasNext && i < n
def next(): Long = { i += 1; self.next() }
}
}
def map(f: Long ⇒ Int): IntIterator = new IntIterator {
def hasNext: Boolean = self.hasNext
def next(): Int = f(self.next())
}
override def map[X](m: Long ⇒ X): RefIterator[X] = new RefIterator[X] {
def hasNext: Boolean = self.hasNext
def next: X = m(self.next())
}
override def foreach[U](f: Long ⇒ U): Unit = while (hasNext) f(next())
def flatMap(f: Long ⇒ LongIterator): LongIterator = {
new LongIterator {
private[this] var it: LongIterator = LongIterator.empty
private[this] def advanceIterator(): Unit = {
while (!it.hasNext) {
if (self.hasNext) {
it = f(self.next())
} else {
it = null
return ;
}
}
}
advanceIterator()
def hasNext: Boolean = it != null
def next(): Long = { val e = it.next(); advanceIterator(); e }
}
}
override def withFilter(p: Long ⇒ Boolean): LongIterator = filter(p)
override def filter(p: Long ⇒ Boolean): LongIterator = new LongIterator {
private[this] var hasNextValue: Boolean = true
private[this] var v: Long = 0
private[this] def goToNextValue(): Unit = {
while (self.hasNext) {
v = self.next()
if (p(v)) return ;
}
hasNextValue = false
}
goToNextValue()
def hasNext: Boolean = hasNextValue
def next(): Long = { val v = this.v; goToNextValue(); v }
}
def toArray: Array[Long] = {
var asLength = 8
var as = new Array[Long](asLength)
var i = 0
while (hasNext) {
if (i == asLength) {
val newAS = new Array[Long](Math.min(asLength * 2, asLength + 512))
Array.copy(as, 0, newAS, 0, asLength)
as = newAS
asLength = as.length
}
val v = next()
as(i) = v
i += 1
}
if (i == asLength)
as
else {
val resultAs = new Array[Long](i)
Array.copy(as, 0, resultAs, 0, i)
resultAs
}
}
def toSet: LongSet = {
var s = LongTrieSet.empty
while (hasNext) { s += next() }
s
}
/**
* Copies all elements to a target array of the given size. The size has to be
* at least the size of elements of this iterator.
*/
private[opalj] def toArray(size: Int): Array[Long] = {
val as = new Array[Long](size)
var i = 0
while (hasNext) {
val v = next()
as(i) = v
i += 1
}
as
}
/**
* Compares the returned values to check if the iteration order is the same.
*
* Both iterators may be consumed up to an arbitrary point.
*/
def sameValues(that: LongIterator): Boolean = {
while (this.hasNext) {
if (!that.hasNext || this.next() != that.next())
return false;
}
!that.hasNext
}
}
object LongIterator {
final val empty: LongIterator = new LongIterator {
def hasNext: Boolean = false
def next(): Nothing = throw new UnsupportedOperationException
override def toArray: Array[Long] = new Array[Long](0)
override def toSet: LongTrieSet = LongTrieSet.empty
}
def apply(i: Long): LongIterator = new LongIterator {
private[this] var returned = false
def hasNext: Boolean = !returned
def next(): Long = { returned = true; i }
override def toArray: Array[Long] = { val as = new Array[Long](1); as(0) = i; as }
override def toSet: LongTrieSet = LongTrieSet(i)
}
def apply(i1: Long, i2: Long): LongIterator = new LongIterator {
private[this] var nextId: Int = 0
def hasNext: Boolean = nextId < 2
def next(): Long = { if (nextId == 0) { nextId = 1; i1 } else { nextId = 2; i2 } }
override def toArray: Array[Long] = {
val as = new Array[Long](2)
as(0) = i1
as(1) = i2
as
}
override def toSet: LongTrieSet = LongTrieSet(i1, i2)
}
def apply(i1: Long, i2: Long, i3: Long): LongIterator = new LongIterator {
private[this] var nextId: Int = 0
def hasNext: Boolean = nextId < 3
def next(): Long = { nextId += 1; if (nextId == 1) i1 else if (nextId == 2) i2 else i3 }
override def toArray: Array[Long] = {
val as = new Array[Long](3)
as(0) = i1
as(1) = i2
as(2) = i3
as
}
override def toSet: LongTrieSet = LongTrieSet(i1, i2, i3)
}
def apply(i1: Long, i2: Long, i3: Long, i4: Long): LongIterator = new LongIterator {
private[this] var nextId: Int = 0
def hasNext: Boolean = nextId < 4
def next(): Long = {
nextId += 1
nextId match {
case 1 ⇒ i1
case 2 ⇒ i2
case 3 ⇒ i3
case _ ⇒ i4
}
}
override def toArray: Array[Long] = {
val as = new Array[Long](3)
as(0) = i1
as(1) = i2
as(2) = i3
as(3) = i4
as
}
override def toSet: LongTrieSet = LongTrieSet(i1, i2, i3, i4)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy