classGeneratorIterator<T>(privateval block: suspend GeneratorScope<T>.(T) -> Unit, overrideval parameter: T) : GeneratorScope<T>(), Iterator<T>, Continuation<Any?> { var state: State
init { val coroutineBlock: suspend GeneratorScope<T>.() -> Unit = { block(parameter) } val start = coroutineBlock.createCoroutine(this, this) state = State.NotReady(start) }
overridesuspendfunyield(value: T) = suspendCoroutine<Unit> { continuation -> state = when (state) { is State.NotReady -> State.Ready(continuation, value) is State.Ready<*> -> throw IllegalStateException("Cannot yield a value while ready.") State.Done -> throw IllegalStateException("Cannot yield a value while done.") }
}
privatefunresume() { when (val currentState = state) { is State.NotReady -> currentState.continuation.resume(Unit) } }
overridefunhasNext(): Boolean { resume() return state != State.Done }
overridefunnext(): T { returnwhen (val currentState = state) { is State.NotReady -> { resume() return next() } is State.Ready<*> -> { state = State.NotReady(currentState.continuation) (currentState as State.Ready<T>).nextValue } State.Done -> throw IndexOutOfBoundsException("No value left") } }