kotlin.coroutines.experimental.SequenceBuilder.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of lightstep-opentelemetry-auto-exporter Show documentation
Show all versions of lightstep-opentelemetry-auto-exporter Show documentation
Lightstep OpenTelemetry Auto Exporter
The newest version!
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:kotlin.jvm.JvmMultifileClass
@file:kotlin.jvm.JvmName("SequenceBuilderKt")
@file:UseExperimental(ExperimentalTypeInference::class)
package kotlin.coroutines.experimental
import kotlin.coroutines.experimental.intrinsics.*
import kotlin.experimental.ExperimentalTypeInference
/**
* Builds a [Sequence] lazily yielding values one by one.
*
* Since Kotlin 1.3 use [kotlin.sequences.sequence] instead.
*
* @see kotlin.sequences.generateSequence
* @see kotlin.sequences.sequence
*/
@SinceKotlin("1.1")
public fun buildSequence(@BuilderInference builderAction: suspend SequenceBuilder.() -> Unit): Sequence = Sequence { buildIterator(builderAction) }
/**
* Builds an [Iterator] lazily yielding values one by one.
*
* Since Kotlin 1.3 use [kotlin.sequences.iterator] instead.
*
* @see kotlin.sequences.iterator
*/
@SinceKotlin("1.1")
public fun buildIterator(@BuilderInference builderAction: suspend SequenceBuilder.() -> Unit): Iterator {
val iterator = SequenceBuilderIterator()
iterator.nextStep = builderAction.createCoroutineUnchecked(receiver = iterator, completion = iterator)
return iterator
}
/**
* Builder for a [Sequence] or an [Iterator], provides [yield] and [yieldAll] suspension functions.
*
* Since Kotlin 1.3 use [kotlin.sequences.SequenceScope] instead.
*
* @see buildSequence
* @see buildIterator
* @see kotlin.sequences.SequenceScope
*/
@RestrictsSuspension
@SinceKotlin("1.1")
public abstract class SequenceBuilder internal constructor() {
/**
* Yields a value to the [Iterator] being built.
*/
public abstract suspend fun yield(value: T)
/**
* Yields all values from the `iterator` to the [Iterator] being built.
*
* The sequence of values returned by the given iterator can be potentially infinite.
*/
public abstract suspend fun yieldAll(iterator: Iterator)
/**
* Yields a collections of values to the [Iterator] being built.
*/
public suspend fun yieldAll(elements: Iterable) {
if (elements is Collection && elements.isEmpty()) return
return yieldAll(elements.iterator())
}
/**
* Yields potentially infinite sequence of values to the [Iterator] being built.
*
* The sequence can be potentially infinite.
*/
public suspend fun yieldAll(sequence: Sequence) = yieldAll(sequence.iterator())
}
private typealias State = Int
private const val State_NotReady: State = 0
private const val State_ManyNotReady: State = 1
private const val State_ManyReady: State = 2
private const val State_Ready: State = 3
private const val State_Done: State = 4
private const val State_Failed: State = 5
private class SequenceBuilderIterator : SequenceBuilder(), Iterator, Continuation {
private var state = State_NotReady
private var nextValue: T? = null
private var nextIterator: Iterator? = null
var nextStep: Continuation? = null
override fun hasNext(): Boolean {
while (true) {
when (state) {
State_NotReady -> {}
State_ManyNotReady ->
if (nextIterator!!.hasNext()) {
state = State_ManyReady
return true
} else {
nextIterator = null
}
State_Done -> return false
State_Ready, State_ManyReady -> return true
else -> throw exceptionalState()
}
state = State_Failed
val step = nextStep!!
nextStep = null
step.resume(Unit)
}
}
override fun next(): T {
when (state) {
State_NotReady, State_ManyNotReady -> return nextNotReady()
State_ManyReady -> {
state = State_ManyNotReady
return nextIterator!!.next()
}
State_Ready -> {
state = State_NotReady
@Suppress("UNCHECKED_CAST")
val result = nextValue as T
nextValue = null
return result
}
else -> throw exceptionalState()
}
}
private fun nextNotReady(): T {
if (!hasNext()) throw NoSuchElementException() else return next()
}
private fun exceptionalState(): Throwable = when (state) {
State_Done -> NoSuchElementException()
State_Failed -> IllegalStateException("Iterator has failed.")
else -> IllegalStateException("Unexpected state of the iterator: $state")
}
suspend override fun yield(value: T) {
nextValue = value
state = State_Ready
return suspendCoroutineOrReturn { c ->
nextStep = c
COROUTINE_SUSPENDED
}
}
suspend override fun yieldAll(iterator: Iterator) {
if (!iterator.hasNext()) return
nextIterator = iterator
state = State_ManyReady
return suspendCoroutineOrReturn { c ->
nextStep = c
COROUTINE_SUSPENDED
}
}
// Completion continuation implementation
override fun resume(value: Unit) {
state = State_Done
}
override fun resumeWithException(exception: Throwable) {
throw exception // just rethrow
}
override val context: CoroutineContext
get() = EmptyCoroutineContext
}