Created
April 28, 2022 10:26
-
-
Save user-mw/0a2d2ff24650223bc94f364998724b1f to your computer and use it in GitHub Desktop.
CoroutineContext. Whole interface.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package kotlin.coroutines | |
/** | |
* Persistent context for the coroutine. It is an indexed set of [Element] instances. | |
* An indexed set is a mix between a set and a map. | |
* Every element in this set has a unique [Key]. | |
*/ | |
@SinceKotlin("1.3") | |
public interface CoroutineContext { | |
/** | |
* Returns the element with the given [key] from this context or `null`. | |
*/ | |
public operator fun <E : Element> get(key: Key<E>): E? | |
/** | |
* Accumulates entries of this context starting with [initial] value and applying [operation] | |
* from left to right to current accumulator value and each element of this context. | |
*/ | |
public fun <R> fold(initial: R, operation: (R, Element) -> R): R | |
/** | |
* Returns a context containing elements from this context and elements from other [context]. | |
* The elements from this context with the same key as in the other one are dropped. | |
*/ | |
public operator fun plus(context: CoroutineContext): CoroutineContext = | |
if (context === EmptyCoroutineContext) this else // fast path -- avoid lambda creation | |
context.fold(this) { acc, element -> | |
val removed = acc.minusKey(element.key) | |
if (removed === EmptyCoroutineContext) element else { | |
// make sure interceptor is always last in the context (and thus is fast to get when present) | |
val interceptor = removed[ContinuationInterceptor] | |
if (interceptor == null) CombinedContext(removed, element) else { | |
val left = removed.minusKey(ContinuationInterceptor) | |
if (left === EmptyCoroutineContext) CombinedContext(element, interceptor) else | |
CombinedContext(CombinedContext(left, element), interceptor) | |
} | |
} | |
} | |
/** | |
* Returns a context containing elements from this context, but without an element with | |
* the specified [key]. | |
*/ | |
public fun minusKey(key: Key<*>): CoroutineContext | |
/** | |
* Key for the elements of [CoroutineContext]. [E] is a type of element with this key. | |
*/ | |
public interface Key<E : Element> | |
/** | |
* An element of the [CoroutineContext]. An element of the coroutine context is a singleton context by itself. | |
*/ | |
public interface Element : CoroutineContext { | |
/** | |
* A key of this coroutine context element. | |
*/ | |
public val key: Key<*> | |
public override operator fun <E : Element> get(key: Key<E>): E? = | |
@Suppress("UNCHECKED_CAST") | |
if (this.key == key) this as E else null | |
public override fun <R> fold(initial: R, operation: (R, Element) -> R): R = | |
operation(initial, this) | |
public override fun minusKey(key: Key<*>): CoroutineContext = | |
if (this.key == key) EmptyCoroutineContext else this | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment