* When a def starts with if and is not a oneliner the if should be on a new line. * The reason is that it might be easy to miss the if when reading the code.
55 lines
1.8 KiB
Scala
55 lines
1.8 KiB
Scala
/**
|
|
* Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
|
|
*/
|
|
|
|
package akka.util
|
|
|
|
import scala.collection.immutable
|
|
import scala.annotation.tailrec
|
|
|
|
/**
|
|
* INTERNAL API
|
|
*/
|
|
private[akka] object Collections {
|
|
|
|
case object EmptyImmutableSeq extends immutable.Seq[Nothing] {
|
|
override final def iterator = Iterator.empty
|
|
override final def apply(idx: Int): Nothing = throw new java.lang.IndexOutOfBoundsException(idx.toString)
|
|
override final def length: Int = 0
|
|
}
|
|
|
|
abstract class PartialImmutableValuesIterable[From, To] extends immutable.Iterable[To] {
|
|
def isDefinedAt(from: From): Boolean
|
|
def apply(from: From): To
|
|
def valuesIterator: Iterator[From]
|
|
final def iterator: Iterator[To] = {
|
|
val superIterator = valuesIterator
|
|
new Iterator[To] {
|
|
private[this] var _next: To = _
|
|
private[this] var _hasNext = false
|
|
|
|
@tailrec override final def hasNext: Boolean =
|
|
if (!_hasNext && superIterator.hasNext) { // If we need and are able to look for the next value
|
|
val potentiallyNext = superIterator.next()
|
|
if (isDefinedAt(potentiallyNext)) {
|
|
_next = apply(potentiallyNext)
|
|
_hasNext = true
|
|
true
|
|
} else hasNext //Attempt to find the next
|
|
} else _hasNext // Return if we found one
|
|
|
|
override final def next(): To =
|
|
if (hasNext) {
|
|
val ret = _next
|
|
_next = null.asInstanceOf[To] // Mark as consumed (nice to the GC, don't leak the last returned value)
|
|
_hasNext = false // Mark as consumed (we need to look for the next value)
|
|
ret
|
|
} else throw new java.util.NoSuchElementException("next")
|
|
}
|
|
}
|
|
|
|
override lazy val size: Int = iterator.size
|
|
override def foreach[C](f: To ⇒ C) = iterator foreach f
|
|
}
|
|
|
|
}
|