From 7b7840f8b43aa9eca9f506f52e99582b8133dde8 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Thu, 9 Mar 2017 16:04:42 +0300 Subject: [PATCH] stdlib: Add AbstractIterator class Fix: external_codegen_blackbox_regressions/objectCaptureOuterConstructorProperty.kt --- .../kotlin/collections/AbstractIterator.kt | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 runtime/src/main/kotlin/kotlin/collections/AbstractIterator.kt diff --git a/runtime/src/main/kotlin/kotlin/collections/AbstractIterator.kt b/runtime/src/main/kotlin/kotlin/collections/AbstractIterator.kt new file mode 100644 index 00000000000..7f30b156c70 --- /dev/null +++ b/runtime/src/main/kotlin/kotlin/collections/AbstractIterator.kt @@ -0,0 +1,68 @@ +package kotlin.collections + + +private enum class State { + Ready, + NotReady, + Done, + Failed +} + +/** + * A base class to simplify implementing iterators so that implementations only have to implement [computeNext] + * to implement the iterator, calling [done] when the iteration is complete. + */ +public abstract class AbstractIterator: Iterator { + private var state = State.NotReady + private var nextValue: T? = null + + override fun hasNext(): Boolean { + require(state != State.Failed) + return when (state) { + State.Done -> false + State.Ready -> true + else -> tryToComputeNext() + } + } + + override fun next(): T { + if (!hasNext()) throw NoSuchElementException() + state = State.NotReady + return nextValue as T + } + + private fun tryToComputeNext(): Boolean { + state = State.Failed + computeNext() + return state == State.Ready + } + + /** + * Computes the next item in the iterator. + * + * This callback method should call one of these two methods: + * + * * [setNext] with the next value of the iteration + * * [done] to indicate there are no more elements + * + * Failure to call either method will result in the iteration terminating with a failed state + */ + abstract protected fun computeNext(): Unit + + /** + * Sets the next value in the iteration, called from the [computeNext] function + */ + protected fun setNext(value: T): Unit { + nextValue = value + state = State.Ready + } + + /** + * Sets the state to done so that the iteration terminates. + */ + protected fun done() { + state = State.Done + } +} + +