From 4018db680e3fa4880cf71ee030ce1d6de2d08fe2 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Tue, 21 Mar 2017 16:23:04 +0300 Subject: [PATCH] Sequence operation classification regarding their statefulness and laziness. #KT-16994 Fixed --- .../src/core/generated/_SequencesJs.kt | 250 +++++++++++++++++ .../stdlib/common/src/generated/_Sequences.kt | 250 +++++++++++++++++ libraries/stdlib/src/Module.md | 15 ++ libraries/stdlib/src/generated/_Sequences.kt | 254 ++++++++++++++++++ .../src/kotlin/collections/Sequences.kt | 9 + .../src/templates/Aggregates.kt | 8 + .../src/templates/Elements.kt | 2 + .../src/templates/Filtering.kt | 13 + .../src/templates/Generators.kt | 15 ++ .../kotlin-stdlib-gen/src/templates/Guards.kt | 2 + .../src/templates/Mapping.kt | 12 + .../src/templates/Numeric.kt | 2 + .../src/templates/Ordering.kt | 7 + .../kotlin-stdlib-gen/src/templates/Sets.kt | 4 + .../src/templates/Snapshots.kt | 2 + .../src/templates/Strings.kt | 3 + .../src/templates/engine/Engine.kt | 17 ++ 17 files changed, 865 insertions(+) diff --git a/js/js.libraries/src/core/generated/_SequencesJs.kt b/js/js.libraries/src/core/generated/_SequencesJs.kt index 67823eca9e2..f09ab663dd9 100644 --- a/js/js.libraries/src/core/generated/_SequencesJs.kt +++ b/js/js.libraries/src/core/generated/_SequencesJs.kt @@ -13,6 +13,8 @@ import kotlin.comparisons.* /** * Returns `true` if [element] is found in the sequence. + * + * The operation is _terminal_. */ public operator fun <@kotlin.internal.OnlyInputTypes T> Sequence.contains(element: T): Boolean { return indexOf(element) >= 0 @@ -20,6 +22,8 @@ public operator fun <@kotlin.internal.OnlyInputTypes T> Sequence.contains(ele /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public fun Sequence.elementAt(index: Int): T { return elementAtOrElse(index) { throw IndexOutOfBoundsException("Sequence doesn't contain element at index $index.") } @@ -27,6 +31,8 @@ public fun Sequence.elementAt(index: Int): T { /** * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public fun Sequence.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T { if (index < 0) @@ -43,6 +49,8 @@ public fun Sequence.elementAtOrElse(index: Int, defaultValue: (Int) -> T) /** * Returns an element at the given [index] or `null` if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public fun Sequence.elementAtOrNull(index: Int): T? { if (index < 0) @@ -59,6 +67,8 @@ public fun Sequence.elementAtOrNull(index: Int): T? { /** * Returns the first element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ @kotlin.internal.InlineOnly public inline fun Sequence.find(predicate: (T) -> Boolean): T? { @@ -67,6 +77,8 @@ public inline fun Sequence.find(predicate: (T) -> Boolean): T? { /** * Returns the last element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ @kotlin.internal.InlineOnly public inline fun Sequence.findLast(predicate: (T) -> Boolean): T? { @@ -76,6 +88,8 @@ public inline fun Sequence.findLast(predicate: (T) -> Boolean): T? { /** * Returns first element. * @throws [NoSuchElementException] if the sequence is empty. + * + * The operation is _terminal_. */ public fun Sequence.first(): T { val iterator = iterator() @@ -87,6 +101,8 @@ public fun Sequence.first(): T { /** * Returns the first element matching the given [predicate]. * @throws [NoSuchElementException] if no such element is found. + * + * The operation is _terminal_. */ public inline fun Sequence.first(predicate: (T) -> Boolean): T { for (element in this) if (predicate(element)) return element @@ -95,6 +111,8 @@ public inline fun Sequence.first(predicate: (T) -> Boolean): T { /** * Returns the first element, or `null` if the sequence is empty. + * + * The operation is _terminal_. */ public fun Sequence.firstOrNull(): T? { val iterator = iterator() @@ -105,6 +123,8 @@ public fun Sequence.firstOrNull(): T? { /** * Returns the first element matching the given [predicate], or `null` if element was not found. + * + * The operation is _terminal_. */ public inline fun Sequence.firstOrNull(predicate: (T) -> Boolean): T? { for (element in this) if (predicate(element)) return element @@ -113,6 +133,8 @@ public inline fun Sequence.firstOrNull(predicate: (T) -> Boolean): T? { /** * Returns first index of [element], or -1 if the sequence does not contain element. + * + * The operation is _terminal_. */ public fun <@kotlin.internal.OnlyInputTypes T> Sequence.indexOf(element: T): Int { var index = 0 @@ -126,6 +148,8 @@ public fun <@kotlin.internal.OnlyInputTypes T> Sequence.indexOf(element: T): /** * Returns index of the first element matching the given [predicate], or -1 if the sequence does not contain such element. + * + * The operation is _terminal_. */ public inline fun Sequence.indexOfFirst(predicate: (T) -> Boolean): Int { var index = 0 @@ -139,6 +163,8 @@ public inline fun Sequence.indexOfFirst(predicate: (T) -> Boolean): Int { /** * Returns index of the last element matching the given [predicate], or -1 if the sequence does not contain such element. + * + * The operation is _terminal_. */ public inline fun Sequence.indexOfLast(predicate: (T) -> Boolean): Int { var lastIndex = -1 @@ -154,6 +180,8 @@ public inline fun Sequence.indexOfLast(predicate: (T) -> Boolean): Int { /** * Returns the last element. * @throws [NoSuchElementException] if the sequence is empty. + * + * The operation is _terminal_. */ public fun Sequence.last(): T { val iterator = iterator() @@ -168,6 +196,8 @@ public fun Sequence.last(): T { /** * Returns the last element matching the given [predicate]. * @throws [NoSuchElementException] if no such element is found. + * + * The operation is _terminal_. */ public inline fun Sequence.last(predicate: (T) -> Boolean): T { var last: T? = null @@ -184,6 +214,8 @@ public inline fun Sequence.last(predicate: (T) -> Boolean): T { /** * Returns last index of [element], or -1 if the sequence does not contain element. + * + * The operation is _terminal_. */ public fun <@kotlin.internal.OnlyInputTypes T> Sequence.lastIndexOf(element: T): Int { var lastIndex = -1 @@ -198,6 +230,8 @@ public fun <@kotlin.internal.OnlyInputTypes T> Sequence.lastIndexOf(element: /** * Returns the last element, or `null` if the sequence is empty. + * + * The operation is _terminal_. */ public fun Sequence.lastOrNull(): T? { val iterator = iterator() @@ -211,6 +245,8 @@ public fun Sequence.lastOrNull(): T? { /** * Returns the last element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ public inline fun Sequence.lastOrNull(predicate: (T) -> Boolean): T? { var last: T? = null @@ -224,6 +260,8 @@ public inline fun Sequence.lastOrNull(predicate: (T) -> Boolean): T? { /** * Returns the single element, or throws an exception if the sequence is empty or has more than one element. + * + * The operation is _terminal_. */ public fun Sequence.single(): T { val iterator = iterator() @@ -237,6 +275,8 @@ public fun Sequence.single(): T { /** * Returns the single element matching the given [predicate], or throws exception if there is no or more than one matching element. + * + * The operation is _terminal_. */ public inline fun Sequence.single(predicate: (T) -> Boolean): T { var single: T? = null @@ -254,6 +294,8 @@ public inline fun Sequence.single(predicate: (T) -> Boolean): T { /** * Returns single element, or `null` if the sequence is empty or has more than one element. + * + * The operation is _terminal_. */ public fun Sequence.singleOrNull(): T? { val iterator = iterator() @@ -267,6 +309,8 @@ public fun Sequence.singleOrNull(): T? { /** * Returns the single element matching the given [predicate], or `null` if element was not found or more than one element was found. + * + * The operation is _terminal_. */ public inline fun Sequence.singleOrNull(predicate: (T) -> Boolean): T? { var single: T? = null @@ -284,6 +328,8 @@ public inline fun Sequence.singleOrNull(predicate: (T) -> Boolean): T? { /** * Returns a sequence containing all elements except first [n] elements. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.drop(n: Int): Sequence { require(n >= 0) { "Requested element count $n is less than zero." } @@ -296,6 +342,8 @@ public fun Sequence.drop(n: Int): Sequence { /** * Returns a sequence containing all elements except first elements that satisfy the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.dropWhile(predicate: (T) -> Boolean): Sequence { return DropWhileSequence(this, predicate) @@ -303,6 +351,8 @@ public fun Sequence.dropWhile(predicate: (T) -> Boolean): Sequence { /** * Returns a sequence containing only elements matching the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.filter(predicate: (T) -> Boolean): Sequence { return FilteringSequence(this, true, predicate) @@ -312,6 +362,8 @@ public fun Sequence.filter(predicate: (T) -> Boolean): Sequence { * Returns a sequence containing only elements matching the given [predicate]. * @param [predicate] function that takes the index of an element and the element itself * and returns the result of predicate evaluation on the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.filterIndexed(predicate: (index: Int, T) -> Boolean): Sequence { // TODO: Rewrite with generalized MapFilterIndexingSequence @@ -322,6 +374,8 @@ public fun Sequence.filterIndexed(predicate: (index: Int, T) -> Boolean): * Appends all elements matching the given [predicate] to the given [destination]. * @param [predicate] function that takes the index of an element and the element itself * and returns the result of predicate evaluation on the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public inline fun > Sequence.filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C { forEachIndexed { index, element -> @@ -332,6 +386,8 @@ public inline fun > Sequence.filterIndexedTo(d /** * Returns a sequence containing all elements that are instances of specified type parameter R. + * + * The operation is _intermediate_ and _stateless_. */ public inline fun Sequence<*>.filterIsInstance(): Sequence<@kotlin.internal.NoInfer R> { @Suppress("UNCHECKED_CAST") @@ -340,6 +396,8 @@ public inline fun Sequence<*>.filterIsInstance(): Sequence<@kotlin.i /** * Appends all elements that are instances of specified type parameter R to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public inline fun > Sequence<*>.filterIsInstanceTo(destination: C): C { for (element in this) if (element is R) destination.add(element) @@ -348,6 +406,8 @@ public inline fun > Sequence<*>.filterIsI /** * Returns a sequence containing all elements not matching the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.filterNot(predicate: (T) -> Boolean): Sequence { return FilteringSequence(this, false, predicate) @@ -355,6 +415,8 @@ public fun Sequence.filterNot(predicate: (T) -> Boolean): Sequence { /** * Returns a sequence containing all elements that are not `null`. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.filterNotNull(): Sequence { @Suppress("UNCHECKED_CAST") @@ -363,6 +425,8 @@ public fun Sequence.filterNotNull(): Sequence { /** * Appends all elements that are not `null` to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public fun , T : Any> Sequence.filterNotNullTo(destination: C): C { for (element in this) if (element != null) destination.add(element) @@ -371,6 +435,8 @@ public fun , T : Any> Sequence.filterNotNullTo(d /** * Appends all elements not matching the given [predicate] to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public inline fun > Sequence.filterNotTo(destination: C, predicate: (T) -> Boolean): C { for (element in this) if (!predicate(element)) destination.add(element) @@ -379,6 +445,8 @@ public inline fun > Sequence.filterNotTo(desti /** * Appends all elements matching the given [predicate] to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public inline fun > Sequence.filterTo(destination: C, predicate: (T) -> Boolean): C { for (element in this) if (predicate(element)) destination.add(element) @@ -387,6 +455,8 @@ public inline fun > Sequence.filterTo(destinat /** * Returns a sequence containing first [n] elements. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.take(n: Int): Sequence { require(n >= 0) { "Requested element count $n is less than zero." } @@ -399,6 +469,8 @@ public fun Sequence.take(n: Int): Sequence { /** * Returns a sequence containing first elements satisfying the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.takeWhile(predicate: (T) -> Boolean): Sequence { return TakeWhileSequence(this, predicate) @@ -406,6 +478,8 @@ public fun Sequence.takeWhile(predicate: (T) -> Boolean): Sequence { /** * Returns a sequence that yields elements of this sequence sorted according to their natural sort order. + * + * The operation is _intermediate_ and _stateful_. */ public fun > Sequence.sorted(): Sequence { return object : Sequence { @@ -419,6 +493,8 @@ public fun > Sequence.sorted(): Sequence { /** * Returns a sequence that yields elements of this sequence sorted according to natural sort order of the value returned by specified [selector] function. + * + * The operation is _intermediate_ and _stateful_. */ public inline fun > Sequence.sortedBy(crossinline selector: (T) -> R?): Sequence { return sortedWith(compareBy(selector)) @@ -426,6 +502,8 @@ public inline fun > Sequence.sortedBy(crossinline select /** * Returns a sequence that yields elements of this sequence sorted descending according to natural sort order of the value returned by specified [selector] function. + * + * The operation is _intermediate_ and _stateful_. */ public inline fun > Sequence.sortedByDescending(crossinline selector: (T) -> R?): Sequence { return sortedWith(compareByDescending(selector)) @@ -433,6 +511,8 @@ public inline fun > Sequence.sortedByDescending(crossinl /** * Returns a sequence that yields elements of this sequence sorted descending according to their natural sort order. + * + * The operation is _intermediate_ and _stateful_. */ public fun > Sequence.sortedDescending(): Sequence { return sortedWith(reverseOrder()) @@ -440,6 +520,8 @@ public fun > Sequence.sortedDescending(): Sequence { /** * Returns a sequence that yields elements of this sequence sorted according to the specified [comparator]. + * + * The operation is _intermediate_ and _stateful_. */ public fun Sequence.sortedWith(comparator: Comparator): Sequence { return object : Sequence { @@ -458,6 +540,8 @@ public fun Sequence.sortedWith(comparator: Comparator): Sequence * If any of two pairs would have the same key the last one gets added to the map. * * The returned map preserves the entry iteration order of the original sequence. + * + * The operation is _terminal_. */ public inline fun Sequence.associate(transform: (T) -> Pair): Map { return associateTo(LinkedHashMap(), transform) @@ -470,6 +554,8 @@ public inline fun Sequence.associate(transform: (T) -> Pair): * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. * * The returned map preserves the entry iteration order of the original sequence. + * + * The operation is _terminal_. */ public inline fun Sequence.associateBy(keySelector: (T) -> K): Map { return associateByTo(LinkedHashMap(), keySelector) @@ -481,6 +567,8 @@ public inline fun Sequence.associateBy(keySelector: (T) -> K): Map Sequence.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map { return associateByTo(LinkedHashMap(), keySelector, valueTransform) @@ -492,6 +580,8 @@ public inline fun Sequence.associateBy(keySelector: (T) -> K, value * and value is the element itself. * * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. + * + * The operation is _terminal_. */ public inline fun > Sequence.associateByTo(destination: M, keySelector: (T) -> K): M { for (element in this) { @@ -506,6 +596,8 @@ public inline fun > Sequence.associateByTo(d * and value is provided by the [valueTransform] function applied to elements of the given sequence. * * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. + * + * The operation is _terminal_. */ public inline fun > Sequence.associateByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V): M { for (element in this) { @@ -519,6 +611,8 @@ public inline fun > Sequence.associateByT * provided by [transform] function applied to each element of the given sequence. * * If any of two pairs would have the same key the last one gets added to the map. + * + * The operation is _terminal_. */ public inline fun > Sequence.associateTo(destination: M, transform: (T) -> Pair): M { for (element in this) { @@ -529,6 +623,8 @@ public inline fun > Sequence.associateTo( /** * Appends all elements to the given [destination] collection. + * + * The operation is _terminal_. */ public fun > Sequence.toCollection(destination: C): C { for (item in this) { @@ -539,6 +635,8 @@ public fun > Sequence.toCollection(destination /** * Returns a [HashSet] of all elements. + * + * The operation is _terminal_. */ public fun Sequence.toHashSet(): HashSet { return toCollection(HashSet()) @@ -546,6 +644,8 @@ public fun Sequence.toHashSet(): HashSet { /** * Returns a [List] containing all elements. + * + * The operation is _terminal_. */ public fun Sequence.toList(): List { return this.toMutableList().optimizeReadOnlyList() @@ -553,6 +653,8 @@ public fun Sequence.toList(): List { /** * Returns a [MutableList] filled with all elements of this sequence. + * + * The operation is _terminal_. */ public fun Sequence.toMutableList(): MutableList { return toCollection(ArrayList()) @@ -562,6 +664,8 @@ public fun Sequence.toMutableList(): MutableList { * Returns a [Set] of all elements. * * The returned set preserves the element iteration order of the original sequence. + * + * The operation is _terminal_. */ public fun Sequence.toSet(): Set { return toCollection(LinkedHashSet()).optimizeReadOnlySet() @@ -569,6 +673,8 @@ public fun Sequence.toSet(): Set { /** * Returns a single sequence of all elements from results of [transform] function being invoked on each element of original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.flatMap(transform: (T) -> Sequence): Sequence { return FlatteningSequence(this, transform, { it.iterator() }) @@ -576,6 +682,8 @@ public fun Sequence.flatMap(transform: (T) -> Sequence): Sequence> Sequence.flatMapTo(destination: C, transform: (T) -> Sequence): C { for (element in this) { @@ -592,6 +700,8 @@ public inline fun > Sequence.flatMapTo(dest * The returned map preserves the entry iteration order of the keys produced from the original sequence. * * @sample samples.collections.Collections.Transformations.groupBy + * + * The operation is _terminal_ and _stateful_. */ public inline fun Sequence.groupBy(keySelector: (T) -> K): Map> { return groupByTo(LinkedHashMap>(), keySelector) @@ -605,6 +715,8 @@ public inline fun Sequence.groupBy(keySelector: (T) -> K): Map Sequence.groupBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map> { return groupByTo(LinkedHashMap>(), keySelector, valueTransform) @@ -617,6 +729,8 @@ public inline fun Sequence.groupBy(keySelector: (T) -> K, valueTran * @return The [destination] map. * * @sample samples.collections.Collections.Transformations.groupBy + * + * The operation is _terminal_ and _stateful_. */ public inline fun >> Sequence.groupByTo(destination: M, keySelector: (T) -> K): M { for (element in this) { @@ -635,6 +749,8 @@ public inline fun >> Sequence.group * @return The [destination] map. * * @sample samples.collections.Collections.Transformations.groupByKeysAndValues + * + * The operation is _terminal_ and _stateful_. */ public inline fun >> Sequence.groupByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V): M { for (element in this) { @@ -650,6 +766,8 @@ public inline fun >> Sequence.gr * using the specified [keySelector] function to extract a key from each element. * * @sample samples.collections.Collections.Transformations.groupingByEachCount + * + * The operation is _intermediate_ and _stateless_. */ @SinceKotlin("1.1") public inline fun Sequence.groupingBy(crossinline keySelector: (T) -> K): Grouping { @@ -662,6 +780,8 @@ public inline fun Sequence.groupingBy(crossinline keySelector: (T) -> /** * Returns a sequence containing the results of applying the given [transform] function * to each element in the original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.map(transform: (T) -> R): Sequence { return TransformingSequence(this, transform) @@ -672,6 +792,8 @@ public fun Sequence.map(transform: (T) -> R): Sequence { * to each element and its index in the original sequence. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.mapIndexed(transform: (index: Int, T) -> R): Sequence { return TransformingIndexedSequence(this, transform) @@ -682,6 +804,8 @@ public fun Sequence.mapIndexed(transform: (index: Int, T) -> R): Seque * to each element and its index in the original sequence. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.mapIndexedNotNull(transform: (index: Int, T) -> R?): Sequence { return TransformingIndexedSequence(this, transform).filterNotNull() @@ -692,6 +816,8 @@ public fun Sequence.mapIndexedNotNull(transform: (index: Int, T) * and appends only the non-null results to the given [destination]. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public inline fun > Sequence.mapIndexedNotNullTo(destination: C, transform: (index: Int, T) -> R?): C { forEachIndexed { index, element -> transform(index, element)?.let { destination.add(it) } } @@ -703,6 +829,8 @@ public inline fun > Sequence.mapIndex * and appends the results to the given [destination]. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public inline fun > Sequence.mapIndexedTo(destination: C, transform: (index: Int, T) -> R): C { var index = 0 @@ -714,6 +842,8 @@ public inline fun > Sequence.mapIndexedTo(d /** * Returns a sequence containing only the non-null results of applying the given [transform] function * to each element in the original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.mapNotNull(transform: (T) -> R?): Sequence { return TransformingSequence(this, transform).filterNotNull() @@ -722,6 +852,8 @@ public fun Sequence.mapNotNull(transform: (T) -> R?): Sequence> Sequence.mapNotNullTo(destination: C, transform: (T) -> R?): C { forEach { element -> transform(element)?.let { destination.add(it) } } @@ -731,6 +863,8 @@ public inline fun > Sequence.mapNotNu /** * Applies the given [transform] function to each element of the original sequence * and appends the results to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public inline fun > Sequence.mapTo(destination: C, transform: (T) -> R): C { for (item in this) @@ -740,6 +874,8 @@ public inline fun > Sequence.mapTo(destinat /** * Returns a sequence of [IndexedValue] for each element of the original sequence. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.withIndex(): Sequence> { return IndexingSequence(this) @@ -749,6 +885,8 @@ public fun Sequence.withIndex(): Sequence> { * Returns a sequence containing only distinct elements from the given sequence. * * The elements in the resulting sequence are in the same order as they were in the source sequence. + * + * The operation is _intermediate_ and _stateful_. */ public fun Sequence.distinct(): Sequence { return this.distinctBy { it } @@ -759,6 +897,8 @@ public fun Sequence.distinct(): Sequence { * having distinct keys returned by the given [selector] function. * * The elements in the resulting sequence are in the same order as they were in the source sequence. + * + * The operation is _intermediate_ and _stateful_. */ public fun Sequence.distinctBy(selector: (T) -> K): Sequence { return DistinctSequence(this, selector) @@ -768,6 +908,8 @@ public fun Sequence.distinctBy(selector: (T) -> K): Sequence { * Returns a mutable set containing all distinct elements from the given sequence. * * The returned set preserves the element iteration order of the original sequence. + * + * The operation is _terminal_. */ public fun Sequence.toMutableSet(): MutableSet { val set = LinkedHashSet() @@ -777,6 +919,8 @@ public fun Sequence.toMutableSet(): MutableSet { /** * Returns `true` if all elements match the given [predicate]. + * + * The operation is _terminal_. */ public inline fun Sequence.all(predicate: (T) -> Boolean): Boolean { for (element in this) if (!predicate(element)) return false @@ -785,6 +929,8 @@ public inline fun Sequence.all(predicate: (T) -> Boolean): Boolean { /** * Returns `true` if sequence has at least one element. + * + * The operation is _terminal_. */ public fun Sequence.any(): Boolean { for (element in this) return true @@ -793,6 +939,8 @@ public fun Sequence.any(): Boolean { /** * Returns `true` if at least one element matches the given [predicate]. + * + * The operation is _terminal_. */ public inline fun Sequence.any(predicate: (T) -> Boolean): Boolean { for (element in this) if (predicate(element)) return true @@ -801,6 +949,8 @@ public inline fun Sequence.any(predicate: (T) -> Boolean): Boolean { /** * Returns the number of elements in this sequence. + * + * The operation is _terminal_. */ public fun Sequence.count(): Int { var count = 0 @@ -810,6 +960,8 @@ public fun Sequence.count(): Int { /** * Returns the number of elements matching the given [predicate]. + * + * The operation is _terminal_. */ public inline fun Sequence.count(predicate: (T) -> Boolean): Int { var count = 0 @@ -819,6 +971,8 @@ public inline fun Sequence.count(predicate: (T) -> Boolean): Int { /** * Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element. + * + * The operation is _terminal_. */ public inline fun Sequence.fold(initial: R, operation: (acc: R, T) -> R): R { var accumulator = initial @@ -831,6 +985,8 @@ public inline fun Sequence.fold(initial: R, operation: (acc: R, T) -> * to current accumulator value and each element with its index in the original sequence. * @param [operation] function that takes the index of an element, current accumulator value * and the element itself, and calculates the next accumulator value. + * + * The operation is _terminal_. */ public inline fun Sequence.foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R { var index = 0 @@ -841,6 +997,8 @@ public inline fun Sequence.foldIndexed(initial: R, operation: (index: /** * Performs the given [action] on each element. + * + * The operation is _terminal_. */ public inline fun Sequence.forEach(action: (T) -> Unit): Unit { for (element in this) action(element) @@ -850,6 +1008,8 @@ public inline fun Sequence.forEach(action: (T) -> Unit): Unit { * Performs the given [action] on each element, providing sequential index with the element. * @param [action] function that takes the index of an element and the element itself * and performs the desired action on the element. + * + * The operation is _terminal_. */ public inline fun Sequence.forEachIndexed(action: (index: Int, T) -> Unit): Unit { var index = 0 @@ -860,6 +1020,8 @@ public inline fun Sequence.forEachIndexed(action: (index: Int, T) -> Unit * Returns the largest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public fun Sequence.max(): Double? { @@ -879,6 +1041,8 @@ public fun Sequence.max(): Double? { * Returns the largest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public fun Sequence.max(): Float? { @@ -896,6 +1060,8 @@ public fun Sequence.max(): Float? { /** * Returns the largest element or `null` if there are no elements. + * + * The operation is _terminal_. */ public fun > Sequence.max(): T? { val iterator = iterator() @@ -910,6 +1076,8 @@ public fun > Sequence.max(): T? { /** * Returns the first element yielding the largest value of the given function or `null` if there are no elements. + * + * The operation is _terminal_. */ public inline fun > Sequence.maxBy(selector: (T) -> R): T? { val iterator = iterator() @@ -929,6 +1097,8 @@ public inline fun > Sequence.maxBy(selector: (T) -> R): /** * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. + * + * The operation is _terminal_. */ public fun Sequence.maxWith(comparator: Comparator): T? { val iterator = iterator() @@ -945,6 +1115,8 @@ public fun Sequence.maxWith(comparator: Comparator): T? { * Returns the smallest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public fun Sequence.min(): Double? { @@ -964,6 +1136,8 @@ public fun Sequence.min(): Double? { * Returns the smallest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public fun Sequence.min(): Float? { @@ -981,6 +1155,8 @@ public fun Sequence.min(): Float? { /** * Returns the smallest element or `null` if there are no elements. + * + * The operation is _terminal_. */ public fun > Sequence.min(): T? { val iterator = iterator() @@ -995,6 +1171,8 @@ public fun > Sequence.min(): T? { /** * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. + * + * The operation is _terminal_. */ public inline fun > Sequence.minBy(selector: (T) -> R): T? { val iterator = iterator() @@ -1014,6 +1192,8 @@ public inline fun > Sequence.minBy(selector: (T) -> R): /** * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. + * + * The operation is _terminal_. */ public fun Sequence.minWith(comparator: Comparator): T? { val iterator = iterator() @@ -1028,6 +1208,8 @@ public fun Sequence.minWith(comparator: Comparator): T? { /** * Returns `true` if the sequence has no elements. + * + * The operation is _terminal_. */ public fun Sequence.none(): Boolean { for (element in this) return false @@ -1036,6 +1218,8 @@ public fun Sequence.none(): Boolean { /** * Returns `true` if no elements match the given [predicate]. + * + * The operation is _terminal_. */ public inline fun Sequence.none(predicate: (T) -> Boolean): Boolean { for (element in this) if (predicate(element)) return false @@ -1044,6 +1228,8 @@ public inline fun Sequence.none(predicate: (T) -> Boolean): Boolean { /** * Returns a sequence which performs the given [action] on each element of the original sequence as they pass though it. + * + * The operation is _intermediate_ and _stateless_. */ @SinceKotlin("1.1") public fun Sequence.onEach(action: (T) -> Unit): Sequence { @@ -1055,6 +1241,8 @@ public fun Sequence.onEach(action: (T) -> Unit): Sequence { /** * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. + * + * The operation is _terminal_. */ public inline fun Sequence.reduce(operation: (acc: S, T) -> S): S { val iterator = this.iterator() @@ -1071,6 +1259,8 @@ public inline fun Sequence.reduce(operation: (acc: S, T) -> S): S { * to current accumulator value and each element with its index in the original sequence. * @param [operation] function that takes the index of an element, current accumulator value * and the element itself and calculates the next accumulator value. + * + * The operation is _terminal_. */ public inline fun Sequence.reduceIndexed(operation: (index: Int, acc: S, T) -> S): S { val iterator = this.iterator() @@ -1085,6 +1275,8 @@ public inline fun Sequence.reduceIndexed(operation: (index: Int, ac /** * Returns the sum of all values produced by [selector] function applied to each element in the sequence. + * + * The operation is _terminal_. */ public inline fun Sequence.sumBy(selector: (T) -> Int): Int { var sum: Int = 0 @@ -1096,6 +1288,8 @@ public inline fun Sequence.sumBy(selector: (T) -> Int): Int { /** * Returns the sum of all values produced by [selector] function applied to each element in the sequence. + * + * The operation is _terminal_. */ public inline fun Sequence.sumByDouble(selector: (T) -> Double): Double { var sum: Double = 0.0 @@ -1107,6 +1301,8 @@ public inline fun Sequence.sumByDouble(selector: (T) -> Double): Double { /** * Returns an original collection containing all the non-`null` elements, throwing an [IllegalArgumentException] if there are any `null` elements. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.requireNoNulls(): Sequence { return map { it ?: throw IllegalArgumentException("null element found in $this.") } @@ -1114,6 +1310,8 @@ public fun Sequence.requireNoNulls(): Sequence { /** * Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]. + * + * The operation is _intermediate_ and _nearly stateless_. */ public operator fun Sequence.minus(element: T): Sequence { return object: Sequence { @@ -1129,6 +1327,8 @@ public operator fun Sequence.minus(element: T): Sequence { * * Note that the source sequence and the array being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateful_. */ public operator fun Sequence.minus(elements: Array): Sequence { if (elements.isEmpty()) return this @@ -1145,6 +1345,8 @@ public operator fun Sequence.minus(elements: Array): Sequence { * * Note that the source sequence and the collection being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateful_. */ public operator fun Sequence.minus(elements: Iterable): Sequence { return object: Sequence { @@ -1163,6 +1365,8 @@ public operator fun Sequence.minus(elements: Iterable): Sequence { * * Note that the source sequence and the sequence being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ for this sequence and _terminal_ and _stateful_ for the [elements] sequence. */ public operator fun Sequence.minus(elements: Sequence): Sequence { return object: Sequence { @@ -1178,6 +1382,8 @@ public operator fun Sequence.minus(elements: Sequence): Sequence { /** * Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]. + * + * The operation is _intermediate_ and _nearly stateless_. */ @kotlin.internal.InlineOnly public inline fun Sequence.minusElement(element: T): Sequence { @@ -1188,6 +1394,8 @@ public inline fun Sequence.minusElement(element: T): Sequence { * Splits the original sequence into pair of lists, * where *first* list contains elements for which [predicate] yielded `true`, * while *second* list contains elements for which [predicate] yielded `false`. + * + * The operation is _terminal_. */ public inline fun Sequence.partition(predicate: (T) -> Boolean): Pair, List> { val first = ArrayList() @@ -1204,6 +1412,8 @@ public inline fun Sequence.partition(predicate: (T) -> Boolean): Pair Sequence.plus(element: T): Sequence { return sequenceOf(this, sequenceOf(element)).flatten() @@ -1214,6 +1424,8 @@ public operator fun Sequence.plus(element: T): Sequence { * * Note that the source sequence and the array being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public operator fun Sequence.plus(elements: Array): Sequence { return this.plus(elements.asList()) @@ -1224,6 +1436,8 @@ public operator fun Sequence.plus(elements: Array): Sequence { * * Note that the source sequence and the collection being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public operator fun Sequence.plus(elements: Iterable): Sequence { return sequenceOf(this, elements.asSequence()).flatten() @@ -1234,6 +1448,8 @@ public operator fun Sequence.plus(elements: Iterable): Sequence { * * Note that the source sequence and the sequence being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public operator fun Sequence.plus(elements: Sequence): Sequence { return sequenceOf(this, elements).flatten() @@ -1241,6 +1457,8 @@ public operator fun Sequence.plus(elements: Sequence): Sequence { /** * Returns a sequence containing all elements of the original sequence and then the given [element]. + * + * The operation is _intermediate_ and _stateless_. */ @kotlin.internal.InlineOnly public inline fun Sequence.plusElement(element: T): Sequence { @@ -1250,6 +1468,8 @@ public inline fun Sequence.plusElement(element: T): Sequence { /** * Returns a sequence of pairs built from elements of both sequences with same indexes. * Resulting sequence has length of shortest input sequence. + * + * The operation is _intermediate_ and _stateless_. */ public infix fun Sequence.zip(other: Sequence): Sequence> { return MergingSequence(this, other) { t1, t2 -> t1 to t2 } @@ -1257,6 +1477,8 @@ public infix fun Sequence.zip(other: Sequence): Sequence /** * Returns a sequence of values built from elements of both collections with same indexes using provided [transform]. Resulting sequence has length of shortest input sequences. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.zip(other: Sequence, transform: (a: T, b: R) -> V): Sequence { return MergingSequence(this, other, transform) @@ -1267,6 +1489,8 @@ public fun Sequence.zip(other: Sequence, transform: (a: T, b: R) * * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). + * + * The operation is _terminal_. */ public fun Sequence.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): A { buffer.append(prefix) @@ -1287,6 +1511,8 @@ public fun Sequence.joinTo(buffer: A, separator: CharSequ * * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). + * + * The operation is _terminal_. */ public fun Sequence.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): String { return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() @@ -1309,6 +1535,8 @@ public inline fun Sequence.asSequence(): Sequence { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfByte") public fun Sequence.average(): Double { @@ -1323,6 +1551,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfShort") public fun Sequence.average(): Double { @@ -1337,6 +1567,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfInt") public fun Sequence.average(): Double { @@ -1351,6 +1583,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfLong") public fun Sequence.average(): Double { @@ -1365,6 +1599,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfFloat") public fun Sequence.average(): Double { @@ -1379,6 +1615,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfDouble") public fun Sequence.average(): Double { @@ -1393,6 +1631,8 @@ public fun Sequence.average(): Double { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfByte") public fun Sequence.sum(): Int { @@ -1405,6 +1645,8 @@ public fun Sequence.sum(): Int { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfShort") public fun Sequence.sum(): Int { @@ -1417,6 +1659,8 @@ public fun Sequence.sum(): Int { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfInt") public fun Sequence.sum(): Int { @@ -1429,6 +1673,8 @@ public fun Sequence.sum(): Int { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfLong") public fun Sequence.sum(): Long { @@ -1441,6 +1687,8 @@ public fun Sequence.sum(): Long { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfFloat") public fun Sequence.sum(): Float { @@ -1453,6 +1701,8 @@ public fun Sequence.sum(): Float { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfDouble") public fun Sequence.sum(): Double { diff --git a/libraries/stdlib/common/src/generated/_Sequences.kt b/libraries/stdlib/common/src/generated/_Sequences.kt index 2e1791d78d9..b5534366b03 100644 --- a/libraries/stdlib/common/src/generated/_Sequences.kt +++ b/libraries/stdlib/common/src/generated/_Sequences.kt @@ -12,32 +12,44 @@ import kotlin.comparisons.* /** * Returns `true` if [element] is found in the sequence. + * + * The operation is _terminal_. */ public header operator fun <@kotlin.internal.OnlyInputTypes T> Sequence.contains(element: T): Boolean /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public header fun Sequence.elementAt(index: Int): T /** * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public header fun Sequence.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T /** * Returns an element at the given [index] or `null` if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public header fun Sequence.elementAtOrNull(index: Int): T? /** * Returns the first element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ @kotlin.internal.InlineOnly public header inline fun Sequence.find(predicate: (T) -> Boolean): T? /** * Returns the last element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ @kotlin.internal.InlineOnly public header inline fun Sequence.findLast(predicate: (T) -> Boolean): T? @@ -45,99 +57,137 @@ public header inline fun Sequence.findLast(predicate: (T) -> Boolean): T? /** * Returns first element. * @throws [NoSuchElementException] if the sequence is empty. + * + * The operation is _terminal_. */ public header fun Sequence.first(): T /** * Returns the first element matching the given [predicate]. * @throws [NoSuchElementException] if no such element is found. + * + * The operation is _terminal_. */ public header inline fun Sequence.first(predicate: (T) -> Boolean): T /** * Returns the first element, or `null` if the sequence is empty. + * + * The operation is _terminal_. */ public header fun Sequence.firstOrNull(): T? /** * Returns the first element matching the given [predicate], or `null` if element was not found. + * + * The operation is _terminal_. */ public header inline fun Sequence.firstOrNull(predicate: (T) -> Boolean): T? /** * Returns first index of [element], or -1 if the sequence does not contain element. + * + * The operation is _terminal_. */ public header fun <@kotlin.internal.OnlyInputTypes T> Sequence.indexOf(element: T): Int /** * Returns index of the first element matching the given [predicate], or -1 if the sequence does not contain such element. + * + * The operation is _terminal_. */ public header inline fun Sequence.indexOfFirst(predicate: (T) -> Boolean): Int /** * Returns index of the last element matching the given [predicate], or -1 if the sequence does not contain such element. + * + * The operation is _terminal_. */ public header inline fun Sequence.indexOfLast(predicate: (T) -> Boolean): Int /** * Returns the last element. * @throws [NoSuchElementException] if the sequence is empty. + * + * The operation is _terminal_. */ public header fun Sequence.last(): T /** * Returns the last element matching the given [predicate]. * @throws [NoSuchElementException] if no such element is found. + * + * The operation is _terminal_. */ public header inline fun Sequence.last(predicate: (T) -> Boolean): T /** * Returns last index of [element], or -1 if the sequence does not contain element. + * + * The operation is _terminal_. */ public header fun <@kotlin.internal.OnlyInputTypes T> Sequence.lastIndexOf(element: T): Int /** * Returns the last element, or `null` if the sequence is empty. + * + * The operation is _terminal_. */ public header fun Sequence.lastOrNull(): T? /** * Returns the last element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ public header inline fun Sequence.lastOrNull(predicate: (T) -> Boolean): T? /** * Returns the single element, or throws an exception if the sequence is empty or has more than one element. + * + * The operation is _terminal_. */ public header fun Sequence.single(): T /** * Returns the single element matching the given [predicate], or throws exception if there is no or more than one matching element. + * + * The operation is _terminal_. */ public header inline fun Sequence.single(predicate: (T) -> Boolean): T /** * Returns single element, or `null` if the sequence is empty or has more than one element. + * + * The operation is _terminal_. */ public header fun Sequence.singleOrNull(): T? /** * Returns the single element matching the given [predicate], or `null` if element was not found or more than one element was found. + * + * The operation is _terminal_. */ public header inline fun Sequence.singleOrNull(predicate: (T) -> Boolean): T? /** * Returns a sequence containing all elements except first [n] elements. + * + * The operation is _intermediate_ and _nearly stateless_. */ public header fun Sequence.drop(n: Int): Sequence /** * Returns a sequence containing all elements except first elements that satisfy the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.dropWhile(predicate: (T) -> Boolean): Sequence /** * Returns a sequence containing only elements matching the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.filter(predicate: (T) -> Boolean): Sequence @@ -145,6 +195,8 @@ public header fun Sequence.filter(predicate: (T) -> Boolean): Sequence * Returns a sequence containing only elements matching the given [predicate]. * @param [predicate] function that takes the index of an element and the element itself * and returns the result of predicate evaluation on the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public header fun Sequence.filterIndexed(predicate: (index: Int, T) -> Boolean): Sequence @@ -152,76 +204,106 @@ public header fun Sequence.filterIndexed(predicate: (index: Int, T) -> Bo * Appends all elements matching the given [predicate] to the given [destination]. * @param [predicate] function that takes the index of an element and the element itself * and returns the result of predicate evaluation on the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public header inline fun > Sequence.filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C /** * Returns a sequence containing all elements that are instances of specified type parameter R. + * + * The operation is _intermediate_ and _stateless_. */ public header inline fun Sequence<*>.filterIsInstance(): Sequence<@kotlin.internal.NoInfer R> /** * Appends all elements that are instances of specified type parameter R to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public header inline fun > Sequence<*>.filterIsInstanceTo(destination: C): C /** * Returns a sequence containing all elements not matching the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.filterNot(predicate: (T) -> Boolean): Sequence /** * Returns a sequence containing all elements that are not `null`. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.filterNotNull(): Sequence /** * Appends all elements that are not `null` to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public header fun , T : Any> Sequence.filterNotNullTo(destination: C): C /** * Appends all elements not matching the given [predicate] to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public header inline fun > Sequence.filterNotTo(destination: C, predicate: (T) -> Boolean): C /** * Appends all elements matching the given [predicate] to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public header inline fun > Sequence.filterTo(destination: C, predicate: (T) -> Boolean): C /** * Returns a sequence containing first [n] elements. + * + * The operation is _intermediate_ and _nearly stateless_. */ public header fun Sequence.take(n: Int): Sequence /** * Returns a sequence containing first elements satisfying the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.takeWhile(predicate: (T) -> Boolean): Sequence /** * Returns a sequence that yields elements of this sequence sorted according to their natural sort order. + * + * The operation is _intermediate_ and _stateful_. */ public header fun > Sequence.sorted(): Sequence /** * Returns a sequence that yields elements of this sequence sorted according to natural sort order of the value returned by specified [selector] function. + * + * The operation is _intermediate_ and _stateful_. */ public header inline fun > Sequence.sortedBy(crossinline selector: (T) -> R?): Sequence /** * Returns a sequence that yields elements of this sequence sorted descending according to natural sort order of the value returned by specified [selector] function. + * + * The operation is _intermediate_ and _stateful_. */ public header inline fun > Sequence.sortedByDescending(crossinline selector: (T) -> R?): Sequence /** * Returns a sequence that yields elements of this sequence sorted descending according to their natural sort order. + * + * The operation is _intermediate_ and _stateful_. */ public header fun > Sequence.sortedDescending(): Sequence /** * Returns a sequence that yields elements of this sequence sorted according to the specified [comparator]. + * + * The operation is _intermediate_ and _stateful_. */ public header fun Sequence.sortedWith(comparator: Comparator): Sequence @@ -232,6 +314,8 @@ public header fun Sequence.sortedWith(comparator: Comparator): Sequ * If any of two pairs would have the same key the last one gets added to the map. * * The returned map preserves the entry iteration order of the original sequence. + * + * The operation is _terminal_. */ public header inline fun Sequence.associate(transform: (T) -> Pair): Map @@ -242,6 +326,8 @@ public header inline fun Sequence.associate(transform: (T) -> Pair< * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. * * The returned map preserves the entry iteration order of the original sequence. + * + * The operation is _terminal_. */ public header inline fun Sequence.associateBy(keySelector: (T) -> K): Map @@ -251,6 +337,8 @@ public header inline fun Sequence.associateBy(keySelector: (T) -> K): * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. * * The returned map preserves the entry iteration order of the original sequence. + * + * The operation is _terminal_. */ public header inline fun Sequence.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map @@ -260,6 +348,8 @@ public header inline fun Sequence.associateBy(keySelector: (T) -> K * and value is the element itself. * * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. + * + * The operation is _terminal_. */ public header inline fun > Sequence.associateByTo(destination: M, keySelector: (T) -> K): M @@ -269,6 +359,8 @@ public header inline fun > Sequence.associat * and value is provided by the [valueTransform] function applied to elements of the given sequence. * * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. + * + * The operation is _terminal_. */ public header inline fun > Sequence.associateByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V): M @@ -277,26 +369,36 @@ public header inline fun > Sequence.assoc * provided by [transform] function applied to each element of the given sequence. * * If any of two pairs would have the same key the last one gets added to the map. + * + * The operation is _terminal_. */ public header inline fun > Sequence.associateTo(destination: M, transform: (T) -> Pair): M /** * Appends all elements to the given [destination] collection. + * + * The operation is _terminal_. */ public header fun > Sequence.toCollection(destination: C): C /** * Returns a [HashSet] of all elements. + * + * The operation is _terminal_. */ public header fun Sequence.toHashSet(): HashSet /** * Returns a [List] containing all elements. + * + * The operation is _terminal_. */ public header fun Sequence.toList(): List /** * Returns a [MutableList] filled with all elements of this sequence. + * + * The operation is _terminal_. */ public header fun Sequence.toMutableList(): MutableList @@ -304,16 +406,22 @@ public header fun Sequence.toMutableList(): MutableList * Returns a [Set] of all elements. * * The returned set preserves the element iteration order of the original sequence. + * + * The operation is _terminal_. */ public header fun Sequence.toSet(): Set /** * Returns a single sequence of all elements from results of [transform] function being invoked on each element of original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.flatMap(transform: (T) -> Sequence): Sequence /** * Appends all elements yielded from results of [transform] function being invoked on each element of original sequence, to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public header inline fun > Sequence.flatMapTo(destination: C, transform: (T) -> Sequence): C @@ -324,6 +432,8 @@ public header inline fun > Sequence.flatMap * The returned map preserves the entry iteration order of the keys produced from the original sequence. * * @sample samples.collections.Collections.Transformations.groupBy + * + * The operation is _terminal_ and _stateful_. */ public header inline fun Sequence.groupBy(keySelector: (T) -> K): Map> @@ -335,6 +445,8 @@ public header inline fun Sequence.groupBy(keySelector: (T) -> K): Map< * The returned map preserves the entry iteration order of the keys produced from the original sequence. * * @sample samples.collections.Collections.Transformations.groupByKeysAndValues + * + * The operation is _terminal_ and _stateful_. */ public header inline fun Sequence.groupBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map> @@ -345,6 +457,8 @@ public header inline fun Sequence.groupBy(keySelector: (T) -> K, va * @return The [destination] map. * * @sample samples.collections.Collections.Transformations.groupBy + * + * The operation is _terminal_ and _stateful_. */ public header inline fun >> Sequence.groupByTo(destination: M, keySelector: (T) -> K): M @@ -356,6 +470,8 @@ public header inline fun >> Sequence>> Sequence.groupByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V): M @@ -364,6 +480,8 @@ public header inline fun >> Sequenc * using the specified [keySelector] function to extract a key from each element. * * @sample samples.collections.Collections.Transformations.groupingByEachCount + * + * The operation is _intermediate_ and _stateless_. */ @SinceKotlin("1.1") public header inline fun Sequence.groupingBy(crossinline keySelector: (T) -> K): Grouping @@ -371,6 +489,8 @@ public header inline fun Sequence.groupingBy(crossinline keySelector: /** * Returns a sequence containing the results of applying the given [transform] function * to each element in the original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.map(transform: (T) -> R): Sequence @@ -379,6 +499,8 @@ public header fun Sequence.map(transform: (T) -> R): Sequence * to each element and its index in the original sequence. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public header fun Sequence.mapIndexed(transform: (index: Int, T) -> R): Sequence @@ -387,6 +509,8 @@ public header fun Sequence.mapIndexed(transform: (index: Int, T) -> R) * to each element and its index in the original sequence. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public header fun Sequence.mapIndexedNotNull(transform: (index: Int, T) -> R?): Sequence @@ -395,6 +519,8 @@ public header fun Sequence.mapIndexedNotNull(transform: (index: * and appends only the non-null results to the given [destination]. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public header inline fun > Sequence.mapIndexedNotNullTo(destination: C, transform: (index: Int, T) -> R?): C @@ -403,29 +529,39 @@ public header inline fun > Sequence.m * and appends the results to the given [destination]. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public header inline fun > Sequence.mapIndexedTo(destination: C, transform: (index: Int, T) -> R): C /** * Returns a sequence containing only the non-null results of applying the given [transform] function * to each element in the original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.mapNotNull(transform: (T) -> R?): Sequence /** * Applies the given [transform] function to each element in the original sequence * and appends only the non-null results to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public header inline fun > Sequence.mapNotNullTo(destination: C, transform: (T) -> R?): C /** * Applies the given [transform] function to each element of the original sequence * and appends the results to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public header inline fun > Sequence.mapTo(destination: C, transform: (T) -> R): C /** * Returns a sequence of [IndexedValue] for each element of the original sequence. + * + * The operation is _intermediate_ and _nearly stateless_. */ public header fun Sequence.withIndex(): Sequence> @@ -433,6 +569,8 @@ public header fun Sequence.withIndex(): Sequence> * Returns a sequence containing only distinct elements from the given sequence. * * The elements in the resulting sequence are in the same order as they were in the source sequence. + * + * The operation is _intermediate_ and _stateful_. */ public header fun Sequence.distinct(): Sequence @@ -441,6 +579,8 @@ public header fun Sequence.distinct(): Sequence * having distinct keys returned by the given [selector] function. * * The elements in the resulting sequence are in the same order as they were in the source sequence. + * + * The operation is _intermediate_ and _stateful_. */ public header fun Sequence.distinctBy(selector: (T) -> K): Sequence @@ -448,36 +588,50 @@ public header fun Sequence.distinctBy(selector: (T) -> K): Sequence * Returns a mutable set containing all distinct elements from the given sequence. * * The returned set preserves the element iteration order of the original sequence. + * + * The operation is _terminal_. */ public header fun Sequence.toMutableSet(): MutableSet /** * Returns `true` if all elements match the given [predicate]. + * + * The operation is _terminal_. */ public header inline fun Sequence.all(predicate: (T) -> Boolean): Boolean /** * Returns `true` if sequence has at least one element. + * + * The operation is _terminal_. */ public header fun Sequence.any(): Boolean /** * Returns `true` if at least one element matches the given [predicate]. + * + * The operation is _terminal_. */ public header inline fun Sequence.any(predicate: (T) -> Boolean): Boolean /** * Returns the number of elements in this sequence. + * + * The operation is _terminal_. */ public header fun Sequence.count(): Int /** * Returns the number of elements matching the given [predicate]. + * + * The operation is _terminal_. */ public header inline fun Sequence.count(predicate: (T) -> Boolean): Int /** * Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element. + * + * The operation is _terminal_. */ public header inline fun Sequence.fold(initial: R, operation: (acc: R, T) -> R): R @@ -486,11 +640,15 @@ public header inline fun Sequence.fold(initial: R, operation: (acc: R, * to current accumulator value and each element with its index in the original sequence. * @param [operation] function that takes the index of an element, current accumulator value * and the element itself, and calculates the next accumulator value. + * + * The operation is _terminal_. */ public header inline fun Sequence.foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R /** * Performs the given [action] on each element. + * + * The operation is _terminal_. */ public header inline fun Sequence.forEach(action: (T) -> Unit): Unit @@ -498,6 +656,8 @@ public header inline fun Sequence.forEach(action: (T) -> Unit): Unit * Performs the given [action] on each element, providing sequential index with the element. * @param [action] function that takes the index of an element and the element itself * and performs the desired action on the element. + * + * The operation is _terminal_. */ public header inline fun Sequence.forEachIndexed(action: (index: Int, T) -> Unit): Unit @@ -505,6 +665,8 @@ public header inline fun Sequence.forEachIndexed(action: (index: Int, T) * Returns the largest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public header fun Sequence.max(): Double? @@ -513,22 +675,30 @@ public header fun Sequence.max(): Double? * Returns the largest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public header fun Sequence.max(): Float? /** * Returns the largest element or `null` if there are no elements. + * + * The operation is _terminal_. */ public header fun > Sequence.max(): T? /** * Returns the first element yielding the largest value of the given function or `null` if there are no elements. + * + * The operation is _terminal_. */ public header inline fun > Sequence.maxBy(selector: (T) -> R): T? /** * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. + * + * The operation is _terminal_. */ public header fun Sequence.maxWith(comparator: Comparator): T? @@ -536,6 +706,8 @@ public header fun Sequence.maxWith(comparator: Comparator): T? * Returns the smallest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public header fun Sequence.min(): Double? @@ -544,43 +716,59 @@ public header fun Sequence.min(): Double? * Returns the smallest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public header fun Sequence.min(): Float? /** * Returns the smallest element or `null` if there are no elements. + * + * The operation is _terminal_. */ public header fun > Sequence.min(): T? /** * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. + * + * The operation is _terminal_. */ public header inline fun > Sequence.minBy(selector: (T) -> R): T? /** * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. + * + * The operation is _terminal_. */ public header fun Sequence.minWith(comparator: Comparator): T? /** * Returns `true` if the sequence has no elements. + * + * The operation is _terminal_. */ public header fun Sequence.none(): Boolean /** * Returns `true` if no elements match the given [predicate]. + * + * The operation is _terminal_. */ public header inline fun Sequence.none(predicate: (T) -> Boolean): Boolean /** * Returns a sequence which performs the given [action] on each element of the original sequence as they pass though it. + * + * The operation is _intermediate_ and _stateless_. */ @SinceKotlin("1.1") public header fun Sequence.onEach(action: (T) -> Unit): Sequence /** * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. + * + * The operation is _terminal_. */ public header inline fun Sequence.reduce(operation: (acc: S, T) -> S): S @@ -589,26 +777,36 @@ public header inline fun Sequence.reduce(operation: (acc: S, T) -> * to current accumulator value and each element with its index in the original sequence. * @param [operation] function that takes the index of an element, current accumulator value * and the element itself and calculates the next accumulator value. + * + * The operation is _terminal_. */ public header inline fun Sequence.reduceIndexed(operation: (index: Int, acc: S, T) -> S): S /** * Returns the sum of all values produced by [selector] function applied to each element in the sequence. + * + * The operation is _terminal_. */ public header inline fun Sequence.sumBy(selector: (T) -> Int): Int /** * Returns the sum of all values produced by [selector] function applied to each element in the sequence. + * + * The operation is _terminal_. */ public header inline fun Sequence.sumByDouble(selector: (T) -> Double): Double /** * Returns an original collection containing all the non-`null` elements, throwing an [IllegalArgumentException] if there are any `null` elements. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.requireNoNulls(): Sequence /** * Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]. + * + * The operation is _intermediate_ and _nearly stateless_. */ public header operator fun Sequence.minus(element: T): Sequence @@ -617,6 +815,8 @@ public header operator fun Sequence.minus(element: T): Sequence * * Note that the source sequence and the array being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateful_. */ public header operator fun Sequence.minus(elements: Array): Sequence @@ -625,6 +825,8 @@ public header operator fun Sequence.minus(elements: Array): Sequen * * Note that the source sequence and the collection being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateful_. */ public header operator fun Sequence.minus(elements: Iterable): Sequence @@ -633,11 +835,15 @@ public header operator fun Sequence.minus(elements: Iterable): Sequenc * * Note that the source sequence and the sequence being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ for this sequence and _terminal_ and _stateful_ for the [elements] sequence. */ public header operator fun Sequence.minus(elements: Sequence): Sequence /** * Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]. + * + * The operation is _intermediate_ and _nearly stateless_. */ @kotlin.internal.InlineOnly public header inline fun Sequence.minusElement(element: T): Sequence @@ -646,11 +852,15 @@ public header inline fun Sequence.minusElement(element: T): Sequence * Splits the original sequence into pair of lists, * where *first* list contains elements for which [predicate] yielded `true`, * while *second* list contains elements for which [predicate] yielded `false`. + * + * The operation is _terminal_. */ public header inline fun Sequence.partition(predicate: (T) -> Boolean): Pair, List> /** * Returns a sequence containing all elements of the original sequence and then the given [element]. + * + * The operation is _intermediate_ and _stateless_. */ public header operator fun Sequence.plus(element: T): Sequence @@ -659,6 +869,8 @@ public header operator fun Sequence.plus(element: T): Sequence * * Note that the source sequence and the array being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public header operator fun Sequence.plus(elements: Array): Sequence @@ -667,6 +879,8 @@ public header operator fun Sequence.plus(elements: Array): Sequenc * * Note that the source sequence and the collection being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public header operator fun Sequence.plus(elements: Iterable): Sequence @@ -675,11 +889,15 @@ public header operator fun Sequence.plus(elements: Iterable): Sequence * * Note that the source sequence and the sequence being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public header operator fun Sequence.plus(elements: Sequence): Sequence /** * Returns a sequence containing all elements of the original sequence and then the given [element]. + * + * The operation is _intermediate_ and _stateless_. */ @kotlin.internal.InlineOnly public header inline fun Sequence.plusElement(element: T): Sequence @@ -687,11 +905,15 @@ public header inline fun Sequence.plusElement(element: T): Sequence /** * Returns a sequence of pairs built from elements of both sequences with same indexes. * Resulting sequence has length of shortest input sequence. + * + * The operation is _intermediate_ and _stateless_. */ public header infix fun Sequence.zip(other: Sequence): Sequence> /** * Returns a sequence of values built from elements of both collections with same indexes using provided [transform]. Resulting sequence has length of shortest input sequences. + * + * The operation is _intermediate_ and _stateless_. */ public header fun Sequence.zip(other: Sequence, transform: (a: T, b: R) -> V): Sequence @@ -700,6 +922,8 @@ public header fun Sequence.zip(other: Sequence, transform: (a: T * * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). + * + * The operation is _terminal_. */ public fun Sequence.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): A { buffer.append(prefix) @@ -720,6 +944,8 @@ public fun Sequence.joinTo(buffer: A, separator: CharSequ * * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). + * + * The operation is _terminal_. */ public fun Sequence.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): String { return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() @@ -738,72 +964,96 @@ public header inline fun Sequence.asSequence(): Sequence /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfByte") public header fun Sequence.average(): Double /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfShort") public header fun Sequence.average(): Double /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfInt") public header fun Sequence.average(): Double /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfLong") public header fun Sequence.average(): Double /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfFloat") public header fun Sequence.average(): Double /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfDouble") public header fun Sequence.average(): Double /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfByte") public header fun Sequence.sum(): Int /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfShort") public header fun Sequence.sum(): Int /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfInt") public header fun Sequence.sum(): Int /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfLong") public header fun Sequence.sum(): Long /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfFloat") public header fun Sequence.sum(): Float /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfDouble") public header fun Sequence.sum(): Double diff --git a/libraries/stdlib/src/Module.md b/libraries/stdlib/src/Module.md index 2aa8ea683f6..9f213f27def 100644 --- a/libraries/stdlib/src/Module.md +++ b/libraries/stdlib/src/Module.md @@ -89,6 +89,21 @@ Java reflection provided by `kotlin-reflect` library. [Sequence][kotlin.sequences.Sequence] type that represents lazily evaluated collections. Top-level functions for instantiating sequences and extension functions for sequences. +## Classification of sequences + +The sequence operations can be classified into the following groups regarding their state requirements: + + - _stateless_ – operations like [kotlin.sequences.Sequence.map], [kotlin.sequences.Sequence.filter], which process each element independently; + - _nearly stateless_ – operations which require a small constant amount of state to process an element, for example [kotlin.sequences.Sequence.take] or [kotlin.sequences.Sequence.drop]; + - _stateful_ – operations which require a significant amount of state, usually proportional to the number of elements in a sequence. + +If the sequence operation returns another sequence, which is produced lazily, it's called _intermediate_, and otherwise the operation is _terminal_. +Examples of terminal operations are [kotlin.sequences.Sequence.toList], [kotlin.sequences.Sequence.max]. + +Sequences can be iterated multiple times, however some sequence implementations might constrain themselves +to be iterated only once. That is mentioned specifically in their documentation (e.g. [kotlin.sequences.generateSequence] overload). +The latter sequences throw an exception on an attempt to iterate them the second time. + # Package kotlin.streams Utility functions for working with Java 8 [streams](https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html). diff --git a/libraries/stdlib/src/generated/_Sequences.kt b/libraries/stdlib/src/generated/_Sequences.kt index 97f4a34cdee..70c9792a464 100644 --- a/libraries/stdlib/src/generated/_Sequences.kt +++ b/libraries/stdlib/src/generated/_Sequences.kt @@ -13,6 +13,8 @@ import kotlin.comparisons.* /** * Returns `true` if [element] is found in the sequence. + * + * The operation is _terminal_. */ public operator fun <@kotlin.internal.OnlyInputTypes T> Sequence.contains(element: T): Boolean { return indexOf(element) >= 0 @@ -20,6 +22,8 @@ public operator fun <@kotlin.internal.OnlyInputTypes T> Sequence.contains(ele /** * Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public fun Sequence.elementAt(index: Int): T { return elementAtOrElse(index) { throw IndexOutOfBoundsException("Sequence doesn't contain element at index $index.") } @@ -27,6 +31,8 @@ public fun Sequence.elementAt(index: Int): T { /** * Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public fun Sequence.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T { if (index < 0) @@ -43,6 +49,8 @@ public fun Sequence.elementAtOrElse(index: Int, defaultValue: (Int) -> T) /** * Returns an element at the given [index] or `null` if the [index] is out of bounds of this sequence. + * + * The operation is _terminal_. */ public fun Sequence.elementAtOrNull(index: Int): T? { if (index < 0) @@ -59,6 +67,8 @@ public fun Sequence.elementAtOrNull(index: Int): T? { /** * Returns the first element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ @kotlin.internal.InlineOnly public inline fun Sequence.find(predicate: (T) -> Boolean): T? { @@ -67,6 +77,8 @@ public inline fun Sequence.find(predicate: (T) -> Boolean): T? { /** * Returns the last element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ @kotlin.internal.InlineOnly public inline fun Sequence.findLast(predicate: (T) -> Boolean): T? { @@ -76,6 +88,8 @@ public inline fun Sequence.findLast(predicate: (T) -> Boolean): T? { /** * Returns first element. * @throws [NoSuchElementException] if the sequence is empty. + * + * The operation is _terminal_. */ public fun Sequence.first(): T { val iterator = iterator() @@ -87,6 +101,8 @@ public fun Sequence.first(): T { /** * Returns the first element matching the given [predicate]. * @throws [NoSuchElementException] if no such element is found. + * + * The operation is _terminal_. */ public inline fun Sequence.first(predicate: (T) -> Boolean): T { for (element in this) if (predicate(element)) return element @@ -95,6 +111,8 @@ public inline fun Sequence.first(predicate: (T) -> Boolean): T { /** * Returns the first element, or `null` if the sequence is empty. + * + * The operation is _terminal_. */ public fun Sequence.firstOrNull(): T? { val iterator = iterator() @@ -105,6 +123,8 @@ public fun Sequence.firstOrNull(): T? { /** * Returns the first element matching the given [predicate], or `null` if element was not found. + * + * The operation is _terminal_. */ public inline fun Sequence.firstOrNull(predicate: (T) -> Boolean): T? { for (element in this) if (predicate(element)) return element @@ -113,6 +133,8 @@ public inline fun Sequence.firstOrNull(predicate: (T) -> Boolean): T? { /** * Returns first index of [element], or -1 if the sequence does not contain element. + * + * The operation is _terminal_. */ public fun <@kotlin.internal.OnlyInputTypes T> Sequence.indexOf(element: T): Int { var index = 0 @@ -126,6 +148,8 @@ public fun <@kotlin.internal.OnlyInputTypes T> Sequence.indexOf(element: T): /** * Returns index of the first element matching the given [predicate], or -1 if the sequence does not contain such element. + * + * The operation is _terminal_. */ public inline fun Sequence.indexOfFirst(predicate: (T) -> Boolean): Int { var index = 0 @@ -139,6 +163,8 @@ public inline fun Sequence.indexOfFirst(predicate: (T) -> Boolean): Int { /** * Returns index of the last element matching the given [predicate], or -1 if the sequence does not contain such element. + * + * The operation is _terminal_. */ public inline fun Sequence.indexOfLast(predicate: (T) -> Boolean): Int { var lastIndex = -1 @@ -154,6 +180,8 @@ public inline fun Sequence.indexOfLast(predicate: (T) -> Boolean): Int { /** * Returns the last element. * @throws [NoSuchElementException] if the sequence is empty. + * + * The operation is _terminal_. */ public fun Sequence.last(): T { val iterator = iterator() @@ -168,6 +196,8 @@ public fun Sequence.last(): T { /** * Returns the last element matching the given [predicate]. * @throws [NoSuchElementException] if no such element is found. + * + * The operation is _terminal_. */ public inline fun Sequence.last(predicate: (T) -> Boolean): T { var last: T? = null @@ -184,6 +214,8 @@ public inline fun Sequence.last(predicate: (T) -> Boolean): T { /** * Returns last index of [element], or -1 if the sequence does not contain element. + * + * The operation is _terminal_. */ public fun <@kotlin.internal.OnlyInputTypes T> Sequence.lastIndexOf(element: T): Int { var lastIndex = -1 @@ -198,6 +230,8 @@ public fun <@kotlin.internal.OnlyInputTypes T> Sequence.lastIndexOf(element: /** * Returns the last element, or `null` if the sequence is empty. + * + * The operation is _terminal_. */ public fun Sequence.lastOrNull(): T? { val iterator = iterator() @@ -211,6 +245,8 @@ public fun Sequence.lastOrNull(): T? { /** * Returns the last element matching the given [predicate], or `null` if no such element was found. + * + * The operation is _terminal_. */ public inline fun Sequence.lastOrNull(predicate: (T) -> Boolean): T? { var last: T? = null @@ -224,6 +260,8 @@ public inline fun Sequence.lastOrNull(predicate: (T) -> Boolean): T? { /** * Returns the single element, or throws an exception if the sequence is empty or has more than one element. + * + * The operation is _terminal_. */ public fun Sequence.single(): T { val iterator = iterator() @@ -237,6 +275,8 @@ public fun Sequence.single(): T { /** * Returns the single element matching the given [predicate], or throws exception if there is no or more than one matching element. + * + * The operation is _terminal_. */ public inline fun Sequence.single(predicate: (T) -> Boolean): T { var single: T? = null @@ -254,6 +294,8 @@ public inline fun Sequence.single(predicate: (T) -> Boolean): T { /** * Returns single element, or `null` if the sequence is empty or has more than one element. + * + * The operation is _terminal_. */ public fun Sequence.singleOrNull(): T? { val iterator = iterator() @@ -267,6 +309,8 @@ public fun Sequence.singleOrNull(): T? { /** * Returns the single element matching the given [predicate], or `null` if element was not found or more than one element was found. + * + * The operation is _terminal_. */ public inline fun Sequence.singleOrNull(predicate: (T) -> Boolean): T? { var single: T? = null @@ -284,6 +328,8 @@ public inline fun Sequence.singleOrNull(predicate: (T) -> Boolean): T? { /** * Returns a sequence containing all elements except first [n] elements. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.drop(n: Int): Sequence { require(n >= 0) { "Requested element count $n is less than zero." } @@ -296,6 +342,8 @@ public fun Sequence.drop(n: Int): Sequence { /** * Returns a sequence containing all elements except first elements that satisfy the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.dropWhile(predicate: (T) -> Boolean): Sequence { return DropWhileSequence(this, predicate) @@ -303,6 +351,8 @@ public fun Sequence.dropWhile(predicate: (T) -> Boolean): Sequence { /** * Returns a sequence containing only elements matching the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.filter(predicate: (T) -> Boolean): Sequence { return FilteringSequence(this, true, predicate) @@ -312,6 +362,8 @@ public fun Sequence.filter(predicate: (T) -> Boolean): Sequence { * Returns a sequence containing only elements matching the given [predicate]. * @param [predicate] function that takes the index of an element and the element itself * and returns the result of predicate evaluation on the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.filterIndexed(predicate: (index: Int, T) -> Boolean): Sequence { // TODO: Rewrite with generalized MapFilterIndexingSequence @@ -322,6 +374,8 @@ public fun Sequence.filterIndexed(predicate: (index: Int, T) -> Boolean): * Appends all elements matching the given [predicate] to the given [destination]. * @param [predicate] function that takes the index of an element and the element itself * and returns the result of predicate evaluation on the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public inline fun > Sequence.filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C { forEachIndexed { index, element -> @@ -332,6 +386,8 @@ public inline fun > Sequence.filterIndexedTo(d /** * Returns a sequence containing all elements that are instances of specified type parameter R. + * + * The operation is _intermediate_ and _stateless_. */ public inline fun Sequence<*>.filterIsInstance(): Sequence<@kotlin.internal.NoInfer R> { @Suppress("UNCHECKED_CAST") @@ -340,6 +396,8 @@ public inline fun Sequence<*>.filterIsInstance(): Sequence<@kotlin.i /** * Appends all elements that are instances of specified type parameter R to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public inline fun > Sequence<*>.filterIsInstanceTo(destination: C): C { for (element in this) if (element is R) destination.add(element) @@ -348,6 +406,8 @@ public inline fun > Sequence<*>.filterIsI /** * Returns a sequence containing all elements not matching the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.filterNot(predicate: (T) -> Boolean): Sequence { return FilteringSequence(this, false, predicate) @@ -355,6 +415,8 @@ public fun Sequence.filterNot(predicate: (T) -> Boolean): Sequence { /** * Returns a sequence containing all elements that are not `null`. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.filterNotNull(): Sequence { @Suppress("UNCHECKED_CAST") @@ -363,6 +425,8 @@ public fun Sequence.filterNotNull(): Sequence { /** * Appends all elements that are not `null` to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public fun , T : Any> Sequence.filterNotNullTo(destination: C): C { for (element in this) if (element != null) destination.add(element) @@ -371,6 +435,8 @@ public fun , T : Any> Sequence.filterNotNullTo(d /** * Appends all elements not matching the given [predicate] to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public inline fun > Sequence.filterNotTo(destination: C, predicate: (T) -> Boolean): C { for (element in this) if (!predicate(element)) destination.add(element) @@ -379,6 +445,8 @@ public inline fun > Sequence.filterNotTo(desti /** * Appends all elements matching the given [predicate] to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public inline fun > Sequence.filterTo(destination: C, predicate: (T) -> Boolean): C { for (element in this) if (predicate(element)) destination.add(element) @@ -387,6 +455,8 @@ public inline fun > Sequence.filterTo(destinat /** * Returns a sequence containing first [n] elements. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.take(n: Int): Sequence { require(n >= 0) { "Requested element count $n is less than zero." } @@ -399,6 +469,8 @@ public fun Sequence.take(n: Int): Sequence { /** * Returns a sequence containing first elements satisfying the given [predicate]. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.takeWhile(predicate: (T) -> Boolean): Sequence { return TakeWhileSequence(this, predicate) @@ -406,6 +478,8 @@ public fun Sequence.takeWhile(predicate: (T) -> Boolean): Sequence { /** * Returns a sequence that yields elements of this sequence sorted according to their natural sort order. + * + * The operation is _intermediate_ and _stateful_. */ public fun > Sequence.sorted(): Sequence { return object : Sequence { @@ -419,6 +493,8 @@ public fun > Sequence.sorted(): Sequence { /** * Returns a sequence that yields elements of this sequence sorted according to natural sort order of the value returned by specified [selector] function. + * + * The operation is _intermediate_ and _stateful_. */ public inline fun > Sequence.sortedBy(crossinline selector: (T) -> R?): Sequence { return sortedWith(compareBy(selector)) @@ -426,6 +502,8 @@ public inline fun > Sequence.sortedBy(crossinline select /** * Returns a sequence that yields elements of this sequence sorted descending according to natural sort order of the value returned by specified [selector] function. + * + * The operation is _intermediate_ and _stateful_. */ public inline fun > Sequence.sortedByDescending(crossinline selector: (T) -> R?): Sequence { return sortedWith(compareByDescending(selector)) @@ -433,6 +511,8 @@ public inline fun > Sequence.sortedByDescending(crossinl /** * Returns a sequence that yields elements of this sequence sorted descending according to their natural sort order. + * + * The operation is _intermediate_ and _stateful_. */ public fun > Sequence.sortedDescending(): Sequence { return sortedWith(reverseOrder()) @@ -440,6 +520,8 @@ public fun > Sequence.sortedDescending(): Sequence { /** * Returns a sequence that yields elements of this sequence sorted according to the specified [comparator]. + * + * The operation is _intermediate_ and _stateful_. */ public fun Sequence.sortedWith(comparator: Comparator): Sequence { return object : Sequence { @@ -458,6 +540,8 @@ public fun Sequence.sortedWith(comparator: Comparator): Sequence * If any of two pairs would have the same key the last one gets added to the map. * * The returned map preserves the entry iteration order of the original sequence. + * + * The operation is _terminal_. */ public inline fun Sequence.associate(transform: (T) -> Pair): Map { return associateTo(LinkedHashMap(), transform) @@ -470,6 +554,8 @@ public inline fun Sequence.associate(transform: (T) -> Pair): * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. * * The returned map preserves the entry iteration order of the original sequence. + * + * The operation is _terminal_. */ public inline fun Sequence.associateBy(keySelector: (T) -> K): Map { return associateByTo(LinkedHashMap(), keySelector) @@ -481,6 +567,8 @@ public inline fun Sequence.associateBy(keySelector: (T) -> K): Map Sequence.associateBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map { return associateByTo(LinkedHashMap(), keySelector, valueTransform) @@ -492,6 +580,8 @@ public inline fun Sequence.associateBy(keySelector: (T) -> K, value * and value is the element itself. * * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. + * + * The operation is _terminal_. */ public inline fun > Sequence.associateByTo(destination: M, keySelector: (T) -> K): M { for (element in this) { @@ -506,6 +596,8 @@ public inline fun > Sequence.associateByTo(d * and value is provided by the [valueTransform] function applied to elements of the given sequence. * * If any two elements would have the same key returned by [keySelector] the last one gets added to the map. + * + * The operation is _terminal_. */ public inline fun > Sequence.associateByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V): M { for (element in this) { @@ -519,6 +611,8 @@ public inline fun > Sequence.associateByT * provided by [transform] function applied to each element of the given sequence. * * If any of two pairs would have the same key the last one gets added to the map. + * + * The operation is _terminal_. */ public inline fun > Sequence.associateTo(destination: M, transform: (T) -> Pair): M { for (element in this) { @@ -529,6 +623,8 @@ public inline fun > Sequence.associateTo( /** * Appends all elements to the given [destination] collection. + * + * The operation is _terminal_. */ public fun > Sequence.toCollection(destination: C): C { for (item in this) { @@ -539,6 +635,8 @@ public fun > Sequence.toCollection(destination /** * Returns a [HashSet] of all elements. + * + * The operation is _terminal_. */ public fun Sequence.toHashSet(): HashSet { return toCollection(HashSet()) @@ -546,6 +644,8 @@ public fun Sequence.toHashSet(): HashSet { /** * Returns a [List] containing all elements. + * + * The operation is _terminal_. */ public fun Sequence.toList(): List { return this.toMutableList().optimizeReadOnlyList() @@ -553,6 +653,8 @@ public fun Sequence.toList(): List { /** * Returns a [MutableList] filled with all elements of this sequence. + * + * The operation is _terminal_. */ public fun Sequence.toMutableList(): MutableList { return toCollection(ArrayList()) @@ -562,6 +664,8 @@ public fun Sequence.toMutableList(): MutableList { * Returns a [Set] of all elements. * * The returned set preserves the element iteration order of the original sequence. + * + * The operation is _terminal_. */ public fun Sequence.toSet(): Set { return toCollection(LinkedHashSet()).optimizeReadOnlySet() @@ -569,6 +673,8 @@ public fun Sequence.toSet(): Set { /** * Returns a [SortedSet] of all elements. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmVersion public fun > Sequence.toSortedSet(): SortedSet { @@ -579,6 +685,8 @@ public fun > Sequence.toSortedSet(): SortedSet { * Returns a [SortedSet] of all elements. * * Elements in the set returned are sorted according to the given [comparator]. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmVersion public fun Sequence.toSortedSet(comparator: Comparator): SortedSet { @@ -587,6 +695,8 @@ public fun Sequence.toSortedSet(comparator: Comparator): SortedSet< /** * Returns a single sequence of all elements from results of [transform] function being invoked on each element of original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.flatMap(transform: (T) -> Sequence): Sequence { return FlatteningSequence(this, transform, { it.iterator() }) @@ -594,6 +704,8 @@ public fun Sequence.flatMap(transform: (T) -> Sequence): Sequence> Sequence.flatMapTo(destination: C, transform: (T) -> Sequence): C { for (element in this) { @@ -610,6 +722,8 @@ public inline fun > Sequence.flatMapTo(dest * The returned map preserves the entry iteration order of the keys produced from the original sequence. * * @sample samples.collections.Collections.Transformations.groupBy + * + * The operation is _terminal_ and _stateful_. */ public inline fun Sequence.groupBy(keySelector: (T) -> K): Map> { return groupByTo(LinkedHashMap>(), keySelector) @@ -623,6 +737,8 @@ public inline fun Sequence.groupBy(keySelector: (T) -> K): Map Sequence.groupBy(keySelector: (T) -> K, valueTransform: (T) -> V): Map> { return groupByTo(LinkedHashMap>(), keySelector, valueTransform) @@ -635,6 +751,8 @@ public inline fun Sequence.groupBy(keySelector: (T) -> K, valueTran * @return The [destination] map. * * @sample samples.collections.Collections.Transformations.groupBy + * + * The operation is _terminal_ and _stateful_. */ public inline fun >> Sequence.groupByTo(destination: M, keySelector: (T) -> K): M { for (element in this) { @@ -653,6 +771,8 @@ public inline fun >> Sequence.group * @return The [destination] map. * * @sample samples.collections.Collections.Transformations.groupByKeysAndValues + * + * The operation is _terminal_ and _stateful_. */ public inline fun >> Sequence.groupByTo(destination: M, keySelector: (T) -> K, valueTransform: (T) -> V): M { for (element in this) { @@ -668,6 +788,8 @@ public inline fun >> Sequence.gr * using the specified [keySelector] function to extract a key from each element. * * @sample samples.collections.Collections.Transformations.groupingByEachCount + * + * The operation is _intermediate_ and _stateless_. */ @SinceKotlin("1.1") public inline fun Sequence.groupingBy(crossinline keySelector: (T) -> K): Grouping { @@ -680,6 +802,8 @@ public inline fun Sequence.groupingBy(crossinline keySelector: (T) -> /** * Returns a sequence containing the results of applying the given [transform] function * to each element in the original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.map(transform: (T) -> R): Sequence { return TransformingSequence(this, transform) @@ -690,6 +814,8 @@ public fun Sequence.map(transform: (T) -> R): Sequence { * to each element and its index in the original sequence. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.mapIndexed(transform: (index: Int, T) -> R): Sequence { return TransformingIndexedSequence(this, transform) @@ -700,6 +826,8 @@ public fun Sequence.mapIndexed(transform: (index: Int, T) -> R): Seque * to each element and its index in the original sequence. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.mapIndexedNotNull(transform: (index: Int, T) -> R?): Sequence { return TransformingIndexedSequence(this, transform).filterNotNull() @@ -710,6 +838,8 @@ public fun Sequence.mapIndexedNotNull(transform: (index: Int, T) * and appends only the non-null results to the given [destination]. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public inline fun > Sequence.mapIndexedNotNullTo(destination: C, transform: (index: Int, T) -> R?): C { forEachIndexed { index, element -> transform(index, element)?.let { destination.add(it) } } @@ -721,6 +851,8 @@ public inline fun > Sequence.mapIndex * and appends the results to the given [destination]. * @param [transform] function that takes the index of an element and the element itself * and returns the result of the transform applied to the element. + * + * The operation is _terminal_ and _nearly stateless_. */ public inline fun > Sequence.mapIndexedTo(destination: C, transform: (index: Int, T) -> R): C { var index = 0 @@ -732,6 +864,8 @@ public inline fun > Sequence.mapIndexedTo(d /** * Returns a sequence containing only the non-null results of applying the given [transform] function * to each element in the original sequence. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.mapNotNull(transform: (T) -> R?): Sequence { return TransformingSequence(this, transform).filterNotNull() @@ -740,6 +874,8 @@ public fun Sequence.mapNotNull(transform: (T) -> R?): Sequence> Sequence.mapNotNullTo(destination: C, transform: (T) -> R?): C { forEach { element -> transform(element)?.let { destination.add(it) } } @@ -749,6 +885,8 @@ public inline fun > Sequence.mapNotNu /** * Applies the given [transform] function to each element of the original sequence * and appends the results to the given [destination]. + * + * The operation is _terminal_ and _stateless_. */ public inline fun > Sequence.mapTo(destination: C, transform: (T) -> R): C { for (item in this) @@ -758,6 +896,8 @@ public inline fun > Sequence.mapTo(destinat /** * Returns a sequence of [IndexedValue] for each element of the original sequence. + * + * The operation is _intermediate_ and _nearly stateless_. */ public fun Sequence.withIndex(): Sequence> { return IndexingSequence(this) @@ -767,6 +907,8 @@ public fun Sequence.withIndex(): Sequence> { * Returns a sequence containing only distinct elements from the given sequence. * * The elements in the resulting sequence are in the same order as they were in the source sequence. + * + * The operation is _intermediate_ and _stateful_. */ public fun Sequence.distinct(): Sequence { return this.distinctBy { it } @@ -777,6 +919,8 @@ public fun Sequence.distinct(): Sequence { * having distinct keys returned by the given [selector] function. * * The elements in the resulting sequence are in the same order as they were in the source sequence. + * + * The operation is _intermediate_ and _stateful_. */ public fun Sequence.distinctBy(selector: (T) -> K): Sequence { return DistinctSequence(this, selector) @@ -786,6 +930,8 @@ public fun Sequence.distinctBy(selector: (T) -> K): Sequence { * Returns a mutable set containing all distinct elements from the given sequence. * * The returned set preserves the element iteration order of the original sequence. + * + * The operation is _terminal_. */ public fun Sequence.toMutableSet(): MutableSet { val set = LinkedHashSet() @@ -795,6 +941,8 @@ public fun Sequence.toMutableSet(): MutableSet { /** * Returns `true` if all elements match the given [predicate]. + * + * The operation is _terminal_. */ public inline fun Sequence.all(predicate: (T) -> Boolean): Boolean { for (element in this) if (!predicate(element)) return false @@ -803,6 +951,8 @@ public inline fun Sequence.all(predicate: (T) -> Boolean): Boolean { /** * Returns `true` if sequence has at least one element. + * + * The operation is _terminal_. */ public fun Sequence.any(): Boolean { for (element in this) return true @@ -811,6 +961,8 @@ public fun Sequence.any(): Boolean { /** * Returns `true` if at least one element matches the given [predicate]. + * + * The operation is _terminal_. */ public inline fun Sequence.any(predicate: (T) -> Boolean): Boolean { for (element in this) if (predicate(element)) return true @@ -819,6 +971,8 @@ public inline fun Sequence.any(predicate: (T) -> Boolean): Boolean { /** * Returns the number of elements in this sequence. + * + * The operation is _terminal_. */ public fun Sequence.count(): Int { var count = 0 @@ -828,6 +982,8 @@ public fun Sequence.count(): Int { /** * Returns the number of elements matching the given [predicate]. + * + * The operation is _terminal_. */ public inline fun Sequence.count(predicate: (T) -> Boolean): Int { var count = 0 @@ -837,6 +993,8 @@ public inline fun Sequence.count(predicate: (T) -> Boolean): Int { /** * Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element. + * + * The operation is _terminal_. */ public inline fun Sequence.fold(initial: R, operation: (acc: R, T) -> R): R { var accumulator = initial @@ -849,6 +1007,8 @@ public inline fun Sequence.fold(initial: R, operation: (acc: R, T) -> * to current accumulator value and each element with its index in the original sequence. * @param [operation] function that takes the index of an element, current accumulator value * and the element itself, and calculates the next accumulator value. + * + * The operation is _terminal_. */ public inline fun Sequence.foldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): R { var index = 0 @@ -859,6 +1019,8 @@ public inline fun Sequence.foldIndexed(initial: R, operation: (index: /** * Performs the given [action] on each element. + * + * The operation is _terminal_. */ public inline fun Sequence.forEach(action: (T) -> Unit): Unit { for (element in this) action(element) @@ -868,6 +1030,8 @@ public inline fun Sequence.forEach(action: (T) -> Unit): Unit { * Performs the given [action] on each element, providing sequential index with the element. * @param [action] function that takes the index of an element and the element itself * and performs the desired action on the element. + * + * The operation is _terminal_. */ public inline fun Sequence.forEachIndexed(action: (index: Int, T) -> Unit): Unit { var index = 0 @@ -878,6 +1042,8 @@ public inline fun Sequence.forEachIndexed(action: (index: Int, T) -> Unit * Returns the largest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public fun Sequence.max(): Double? { @@ -897,6 +1063,8 @@ public fun Sequence.max(): Double? { * Returns the largest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public fun Sequence.max(): Float? { @@ -914,6 +1082,8 @@ public fun Sequence.max(): Float? { /** * Returns the largest element or `null` if there are no elements. + * + * The operation is _terminal_. */ public fun > Sequence.max(): T? { val iterator = iterator() @@ -928,6 +1098,8 @@ public fun > Sequence.max(): T? { /** * Returns the first element yielding the largest value of the given function or `null` if there are no elements. + * + * The operation is _terminal_. */ public inline fun > Sequence.maxBy(selector: (T) -> R): T? { val iterator = iterator() @@ -947,6 +1119,8 @@ public inline fun > Sequence.maxBy(selector: (T) -> R): /** * Returns the first element having the largest value according to the provided [comparator] or `null` if there are no elements. + * + * The operation is _terminal_. */ public fun Sequence.maxWith(comparator: Comparator): T? { val iterator = iterator() @@ -963,6 +1137,8 @@ public fun Sequence.maxWith(comparator: Comparator): T? { * Returns the smallest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public fun Sequence.min(): Double? { @@ -982,6 +1158,8 @@ public fun Sequence.min(): Double? { * Returns the smallest element or `null` if there are no elements. * * If any of elements is `NaN` returns `NaN`. + * + * The operation is _terminal_. */ @SinceKotlin("1.1") public fun Sequence.min(): Float? { @@ -999,6 +1177,8 @@ public fun Sequence.min(): Float? { /** * Returns the smallest element or `null` if there are no elements. + * + * The operation is _terminal_. */ public fun > Sequence.min(): T? { val iterator = iterator() @@ -1013,6 +1193,8 @@ public fun > Sequence.min(): T? { /** * Returns the first element yielding the smallest value of the given function or `null` if there are no elements. + * + * The operation is _terminal_. */ public inline fun > Sequence.minBy(selector: (T) -> R): T? { val iterator = iterator() @@ -1032,6 +1214,8 @@ public inline fun > Sequence.minBy(selector: (T) -> R): /** * Returns the first element having the smallest value according to the provided [comparator] or `null` if there are no elements. + * + * The operation is _terminal_. */ public fun Sequence.minWith(comparator: Comparator): T? { val iterator = iterator() @@ -1046,6 +1230,8 @@ public fun Sequence.minWith(comparator: Comparator): T? { /** * Returns `true` if the sequence has no elements. + * + * The operation is _terminal_. */ public fun Sequence.none(): Boolean { for (element in this) return false @@ -1054,6 +1240,8 @@ public fun Sequence.none(): Boolean { /** * Returns `true` if no elements match the given [predicate]. + * + * The operation is _terminal_. */ public inline fun Sequence.none(predicate: (T) -> Boolean): Boolean { for (element in this) if (predicate(element)) return false @@ -1062,6 +1250,8 @@ public inline fun Sequence.none(predicate: (T) -> Boolean): Boolean { /** * Returns a sequence which performs the given [action] on each element of the original sequence as they pass though it. + * + * The operation is _intermediate_ and _stateless_. */ @SinceKotlin("1.1") public fun Sequence.onEach(action: (T) -> Unit): Sequence { @@ -1073,6 +1263,8 @@ public fun Sequence.onEach(action: (T) -> Unit): Sequence { /** * Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. + * + * The operation is _terminal_. */ public inline fun Sequence.reduce(operation: (acc: S, T) -> S): S { val iterator = this.iterator() @@ -1089,6 +1281,8 @@ public inline fun Sequence.reduce(operation: (acc: S, T) -> S): S { * to current accumulator value and each element with its index in the original sequence. * @param [operation] function that takes the index of an element, current accumulator value * and the element itself and calculates the next accumulator value. + * + * The operation is _terminal_. */ public inline fun Sequence.reduceIndexed(operation: (index: Int, acc: S, T) -> S): S { val iterator = this.iterator() @@ -1103,6 +1297,8 @@ public inline fun Sequence.reduceIndexed(operation: (index: Int, ac /** * Returns the sum of all values produced by [selector] function applied to each element in the sequence. + * + * The operation is _terminal_. */ public inline fun Sequence.sumBy(selector: (T) -> Int): Int { var sum: Int = 0 @@ -1114,6 +1310,8 @@ public inline fun Sequence.sumBy(selector: (T) -> Int): Int { /** * Returns the sum of all values produced by [selector] function applied to each element in the sequence. + * + * The operation is _terminal_. */ public inline fun Sequence.sumByDouble(selector: (T) -> Double): Double { var sum: Double = 0.0 @@ -1125,6 +1323,8 @@ public inline fun Sequence.sumByDouble(selector: (T) -> Double): Double { /** * Returns an original collection containing all the non-`null` elements, throwing an [IllegalArgumentException] if there are any `null` elements. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.requireNoNulls(): Sequence { return map { it ?: throw IllegalArgumentException("null element found in $this.") } @@ -1132,6 +1332,8 @@ public fun Sequence.requireNoNulls(): Sequence { /** * Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]. + * + * The operation is _intermediate_ and _nearly stateless_. */ public operator fun Sequence.minus(element: T): Sequence { return object: Sequence { @@ -1147,6 +1349,8 @@ public operator fun Sequence.minus(element: T): Sequence { * * Note that the source sequence and the array being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateful_. */ public operator fun Sequence.minus(elements: Array): Sequence { if (elements.isEmpty()) return this @@ -1163,6 +1367,8 @@ public operator fun Sequence.minus(elements: Array): Sequence { * * Note that the source sequence and the collection being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateful_. */ public operator fun Sequence.minus(elements: Iterable): Sequence { return object: Sequence { @@ -1181,6 +1387,8 @@ public operator fun Sequence.minus(elements: Iterable): Sequence { * * Note that the source sequence and the sequence being subtracted are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ for this sequence and _terminal_ and _stateful_ for the [elements] sequence. */ public operator fun Sequence.minus(elements: Sequence): Sequence { return object: Sequence { @@ -1196,6 +1404,8 @@ public operator fun Sequence.minus(elements: Sequence): Sequence { /** * Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]. + * + * The operation is _intermediate_ and _nearly stateless_. */ @kotlin.internal.InlineOnly public inline fun Sequence.minusElement(element: T): Sequence { @@ -1206,6 +1416,8 @@ public inline fun Sequence.minusElement(element: T): Sequence { * Splits the original sequence into pair of lists, * where *first* list contains elements for which [predicate] yielded `true`, * while *second* list contains elements for which [predicate] yielded `false`. + * + * The operation is _terminal_. */ public inline fun Sequence.partition(predicate: (T) -> Boolean): Pair, List> { val first = ArrayList() @@ -1222,6 +1434,8 @@ public inline fun Sequence.partition(predicate: (T) -> Boolean): Pair Sequence.plus(element: T): Sequence { return sequenceOf(this, sequenceOf(element)).flatten() @@ -1232,6 +1446,8 @@ public operator fun Sequence.plus(element: T): Sequence { * * Note that the source sequence and the array being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public operator fun Sequence.plus(elements: Array): Sequence { return this.plus(elements.asList()) @@ -1242,6 +1458,8 @@ public operator fun Sequence.plus(elements: Array): Sequence { * * Note that the source sequence and the collection being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public operator fun Sequence.plus(elements: Iterable): Sequence { return sequenceOf(this, elements.asSequence()).flatten() @@ -1252,6 +1470,8 @@ public operator fun Sequence.plus(elements: Iterable): Sequence { * * Note that the source sequence and the sequence being added are iterated only when an `iterator` is requested from * the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + * + * The operation is _intermediate_ and _stateless_. */ public operator fun Sequence.plus(elements: Sequence): Sequence { return sequenceOf(this, elements).flatten() @@ -1259,6 +1479,8 @@ public operator fun Sequence.plus(elements: Sequence): Sequence { /** * Returns a sequence containing all elements of the original sequence and then the given [element]. + * + * The operation is _intermediate_ and _stateless_. */ @kotlin.internal.InlineOnly public inline fun Sequence.plusElement(element: T): Sequence { @@ -1268,6 +1490,8 @@ public inline fun Sequence.plusElement(element: T): Sequence { /** * Returns a sequence of pairs built from elements of both sequences with same indexes. * Resulting sequence has length of shortest input sequence. + * + * The operation is _intermediate_ and _stateless_. */ public infix fun Sequence.zip(other: Sequence): Sequence> { return MergingSequence(this, other) { t1, t2 -> t1 to t2 } @@ -1275,6 +1499,8 @@ public infix fun Sequence.zip(other: Sequence): Sequence /** * Returns a sequence of values built from elements of both collections with same indexes using provided [transform]. Resulting sequence has length of shortest input sequences. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence.zip(other: Sequence, transform: (a: T, b: R) -> V): Sequence { return MergingSequence(this, other, transform) @@ -1285,6 +1511,8 @@ public fun Sequence.zip(other: Sequence, transform: (a: T, b: R) * * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). + * + * The operation is _terminal_. */ public fun Sequence.joinTo(buffer: A, separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): A { buffer.append(prefix) @@ -1305,6 +1533,8 @@ public fun Sequence.joinTo(buffer: A, separator: CharSequ * * If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first [limit] * elements will be appended, followed by the [truncated] string (which defaults to "..."). + * + * The operation is _terminal_. */ public fun Sequence.joinToString(separator: CharSequence = ", ", prefix: CharSequence = "", postfix: CharSequence = "", limit: Int = -1, truncated: CharSequence = "...", transform: ((T) -> CharSequence)? = null): String { return joinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform).toString() @@ -1327,6 +1557,8 @@ public inline fun Sequence.asSequence(): Sequence { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfByte") public fun Sequence.average(): Double { @@ -1341,6 +1573,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfShort") public fun Sequence.average(): Double { @@ -1355,6 +1589,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfInt") public fun Sequence.average(): Double { @@ -1369,6 +1605,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfLong") public fun Sequence.average(): Double { @@ -1383,6 +1621,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfFloat") public fun Sequence.average(): Double { @@ -1397,6 +1637,8 @@ public fun Sequence.average(): Double { /** * Returns an average value of elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("averageOfDouble") public fun Sequence.average(): Double { @@ -1411,6 +1653,8 @@ public fun Sequence.average(): Double { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfByte") public fun Sequence.sum(): Int { @@ -1423,6 +1667,8 @@ public fun Sequence.sum(): Int { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfShort") public fun Sequence.sum(): Int { @@ -1435,6 +1681,8 @@ public fun Sequence.sum(): Int { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfInt") public fun Sequence.sum(): Int { @@ -1447,6 +1695,8 @@ public fun Sequence.sum(): Int { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfLong") public fun Sequence.sum(): Long { @@ -1459,6 +1709,8 @@ public fun Sequence.sum(): Long { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfFloat") public fun Sequence.sum(): Float { @@ -1471,6 +1723,8 @@ public fun Sequence.sum(): Float { /** * Returns the sum of all elements in the sequence. + * + * The operation is _terminal_. */ @kotlin.jvm.JvmName("sumOfDouble") public fun Sequence.sum(): Double { diff --git a/libraries/stdlib/src/kotlin/collections/Sequences.kt b/libraries/stdlib/src/kotlin/collections/Sequences.kt index 132aa920bdc..28537115b44 100644 --- a/libraries/stdlib/src/kotlin/collections/Sequences.kt +++ b/libraries/stdlib/src/kotlin/collections/Sequences.kt @@ -49,11 +49,15 @@ private object EmptySequence : Sequence, DropTakeSequence { /** * Returns a sequence of all elements from all sequences in this sequence. + * + * The operation is _intermediate_ and _stateless_. */ public fun Sequence>.flatten(): Sequence = flatten { it.iterator() } /** * Returns a sequence of all elements from all iterables in this sequence. + * + * The operation is _intermediate_ and _stateless_. */ @kotlin.jvm.JvmName("flattenSequenceOfIterable") public fun Sequence>.flatten(): Sequence = flatten { it.iterator() } @@ -69,6 +73,8 @@ private fun Sequence.flatten(iterator: (T) -> Iterator): Sequence Sequence>.unzip(): Pair, List> { val listT = ArrayList() @@ -532,7 +538,10 @@ private class GeneratorSequence(private val getInitialValue: () -> T?, p /** * Returns a wrapper sequence that provides values of this sequence, but ensures it can be iterated only one time. * + * The operation is _intermediate_ and _stateless_. + * * [IllegalStateException] is thrown on iterating the returned sequence from the second time. + * */ public fun Sequence.constrainOnce(): Sequence { // as? does not work in js diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt index c7df78beaa4..23fa64a8cec 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt @@ -1,6 +1,7 @@ package templates import templates.Family.* +import templates.SequenceClass.* fun aggregates(): List { val templates = arrayListOf() @@ -749,6 +750,7 @@ fun aggregates(): List { Returns a sequence which performs the given [action] on each ${f.element} of the original sequence as they pass though it. """ } + sequenceClassification(intermediate, stateless) body(Sequences) { """ return map { @@ -791,5 +793,11 @@ fun aggregates(): List { } } + templates.forEach { + if (it.sequenceClassification.isEmpty()) { + it.sequenceClassification(terminal) + } + } + return templates } \ No newline at end of file diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt index 2142a914023..59d26b58f64 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Elements.kt @@ -1,6 +1,7 @@ package templates import templates.Family.* +import templates.SequenceClass.* fun elements(): List { val templates = arrayListOf() @@ -753,5 +754,6 @@ fun elements(): List { } } + templates.forEach { it.sequenceClassification(terminal) } return templates } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt index 12eee5be962..42fa46fb8d2 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Filtering.kt @@ -17,6 +17,7 @@ package templates import templates.Family.* +import templates.SequenceClass.* fun filtering(): List { val templates = arrayListOf() @@ -36,6 +37,7 @@ fun filtering(): List { templates add f("drop(n: Int)") { val n = "\$n" doc { "Returns a list containing all elements except first [n] elements." } + sequenceClassification(nearly_stateless) returns("List") body { """ @@ -106,6 +108,7 @@ fun filtering(): List { templates add f("take(n: Int)") { val n = "\$n" doc { "Returns a list containing first [n] elements." } + sequenceClassification(nearly_stateless) returns("List") body { """ @@ -763,5 +766,15 @@ fun filtering(): List { } } + + val terminalOperationPattern = Regex("^\\w+To") + templates.forEach { with (it) { + if (sequenceClassification.isEmpty()) { + sequenceClassification(if (signature.contains("index", ignoreCase = true)) nearly_stateless else stateless) + } + sequenceClassification.add(0, if (terminalOperationPattern in signature) terminal else intermediate) + } } + + return templates } \ No newline at end of file diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt index 3c8c48c8deb..da82e28ffbd 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt @@ -1,6 +1,7 @@ package templates import templates.Family.* +import templates.SequenceClass.* fun generators(): List { val templates = arrayListOf() @@ -18,6 +19,7 @@ fun generators(): List { """ } doc(Sequences) { "Returns a sequence containing all elements of the original sequence and then the given [element]." } + sequenceClassification(intermediate, stateless) returns("List") returns("SELF", Sets, Sequences) @@ -29,6 +31,7 @@ fun generators(): List { only(Iterables, Collections, Sets, Sequences) doc { "Returns a list containing all elements of the original collection and then the given [element]." } + sequenceClassification(intermediate, stateless) returns("List") body { """ @@ -130,6 +133,7 @@ fun generators(): List { the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. """ } + sequenceClassification(intermediate, stateless) body(Sequences) { """ return sequenceOf(this, elements.asSequence()).flatten() @@ -185,6 +189,7 @@ fun generators(): List { the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. """ } + sequenceClassification(intermediate, stateless) body(Sequences) { """ return this.plus(elements.asList()) @@ -243,6 +248,7 @@ fun generators(): List { the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. """ } + sequenceClassification(intermediate, stateless) body(Sequences) { """ return sequenceOf(this, elements).flatten() @@ -263,6 +269,7 @@ fun generators(): List { """ } doc(Sequences) { "Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]." } + sequenceClassification(intermediate, nearly_stateless) returns("List") returns("SELF", Sets, Sequences) @@ -301,6 +308,7 @@ fun generators(): List { doc(Sequences) { "Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]." } + sequenceClassification(intermediate, nearly_stateless) body(Sequences) { """ return object: Sequence { @@ -360,6 +368,7 @@ fun generators(): List { the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. """ } + sequenceClassification(intermediate, stateful) body(Sequences) { """ return object: Sequence { @@ -412,6 +421,7 @@ fun generators(): List { the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. """ } + sequenceClassification(intermediate, stateful) body(Sequences) { """ if (elements.isEmpty()) return this @@ -462,6 +472,8 @@ fun generators(): List { Note that the source sequence and the sequence being subtracted are iterated only when an `iterator` is requested from the resulting sequence. Changing any of them between successive calls to `iterator` may affect the result. + + The operation is _intermediate_ for this sequence and _terminal_ and _stateful_ for the [elements] sequence. """ } body(Sequences) { @@ -489,6 +501,7 @@ fun generators(): List { while *second* list contains elements for which [predicate] yielded `false`. """ } + sequenceClassification(terminal) returns("Pair, List>") body { """ @@ -631,6 +644,7 @@ fun generators(): List { Returns a sequence of values built from elements of both collections with same indexes using provided [transform]. Resulting sequence has length of shortest input sequences. """ } + sequenceClassification(intermediate, stateless) typeParam("R") typeParam("V") returns("Sequence") @@ -740,6 +754,7 @@ fun generators(): List { Resulting sequence has length of shortest input sequence. """ } + sequenceClassification(intermediate, stateless) typeParam("R") returns("Sequence>") body { diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Guards.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Guards.kt index 2e5f834dfc9..84506f5113d 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Guards.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Guards.kt @@ -1,6 +1,7 @@ package templates import templates.Family.* +import templates.SequenceClass.* fun guards(): List { val THIS = "\$this" @@ -10,6 +11,7 @@ fun guards(): List { templates add f("requireNoNulls()") { only(Iterables, Sequences, InvariantArraysOfObjects, Lists) doc { "Returns an original collection containing all the non-`null` elements, throwing an [IllegalArgumentException] if there are any `null` elements." } + sequenceClassification(intermediate, stateless) typeParam("T : Any") toNullableT = true returns("SELF") diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Mapping.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Mapping.kt index f8084f2f932..1c6f37a9d3d 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Mapping.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Mapping.kt @@ -1,6 +1,7 @@ package templates import templates.Family.* +import templates.SequenceClass.* fun mapping(): List { val templates = arrayListOf() @@ -300,6 +301,7 @@ fun mapping(): List { @sample samples.collections.Collections.Transformations.groupBy """ } + sequenceClassification(terminal, stateful) typeParam("K") returns("Map>") body { "return groupByTo(LinkedHashMap>(), keySelector)" } @@ -321,6 +323,7 @@ fun mapping(): List { @sample samples.collections.Collections.Transformations.groupBy """ } + sequenceClassification(terminal, stateful) returns("M") body { """ @@ -349,6 +352,7 @@ fun mapping(): List { @sample samples.collections.Collections.Transformations.groupByKeysAndValues """ } + sequenceClassification(terminal, stateful) typeParam("K") typeParam("V") returns("Map>") @@ -375,6 +379,7 @@ fun mapping(): List { @sample samples.collections.Collections.Transformations.groupByKeysAndValues """ } + sequenceClassification(terminal, stateful) returns("M") body { """ @@ -417,5 +422,12 @@ fun mapping(): List { } } + val terminalOperationPattern = Regex("^\\w+To") + templates.forEach { with (it) { + if (sequenceClassification.isEmpty()) { + sequenceClassification(if (terminalOperationPattern in signature) terminal else intermediate) + sequenceClassification(if (signature.contains("index", ignoreCase = true)) nearly_stateless else stateless) + } + } } return templates } \ No newline at end of file diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Numeric.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Numeric.kt index 9cc18682b41..7721f9aea85 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Numeric.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Numeric.kt @@ -41,5 +41,7 @@ fun numeric(): List { } } + templates.forEach { it.sequenceClassification(SequenceClass.terminal) } + return templates } diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt index 5c9569f6847..abe375bfc49 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Ordering.kt @@ -1,6 +1,8 @@ package templates import templates.Family.* +import templates.SequenceClass.intermediate +import templates.SequenceClass.stateful fun ordering(): List { val templates = arrayListOf() @@ -123,6 +125,7 @@ fun ordering(): List { doc(Sequences) { "Returns a sequence that yields elements of this sequence sorted according to their natural sort order." } + sequenceClassification(intermediate, stateful) body(Sequences) { """ return object : Sequence { @@ -196,6 +199,7 @@ fun ordering(): List { doc(Sequences) { "Returns a sequence that yields elements of this sequence sorted descending according to their natural sort order." } + sequenceClassification(intermediate, stateful) } templates add f("sortedArrayDescending()") { @@ -253,6 +257,7 @@ fun ordering(): List { doc(Sequences) { "Returns a sequence that yields elements of this sequence sorted according to the specified [comparator]." } + sequenceClassification(intermediate, stateful) body(Sequences) { """ return object : Sequence { @@ -306,6 +311,7 @@ fun ordering(): List { doc(Sequences) { "Returns a sequence that yields elements of this sequence sorted according to natural sort order of the value returned by specified [selector] function." } + sequenceClassification(intermediate, stateful) body { "return sortedWith(compareBy(selector))" @@ -339,6 +345,7 @@ fun ordering(): List { doc(Sequences) { "Returns a sequence that yields elements of this sequence sorted descending according to natural sort order of the value returned by specified [selector] function." } + sequenceClassification(intermediate, stateful) body { "return sortedWith(compareByDescending(selector))" diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Sets.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Sets.kt index 83818824a5e..690ed798368 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Sets.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Sets.kt @@ -1,6 +1,7 @@ package templates import templates.Family.* +import templates.SequenceClass.* fun sets(): List { val templates = arrayListOf() @@ -14,6 +15,7 @@ fun sets(): List { The returned set preserves the element iteration order of the original ${f.collection}. """ } + sequenceClassification(terminal) returns("MutableSet") body { """ @@ -51,6 +53,7 @@ fun sets(): List { returns("List") body { "return this.toMutableSet().toList()" } + sequenceClassification(intermediate, stateful) returns(Sequences) { "Sequence" } body(Sequences) { "return this.distinctBy { it }" } } @@ -84,6 +87,7 @@ fun sets(): List { inline(false, Sequences) returns(Sequences) { "Sequence" } + sequenceClassification(intermediate, stateful) body(Sequences) { """ return DistinctSequence(this, selector) diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Snapshots.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Snapshots.kt index d4565484d4d..85e8a93307d 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Snapshots.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Snapshots.kt @@ -373,5 +373,7 @@ fun snapshots(): List { } } + templates.forEach { it.sequenceClassification(SequenceClass.terminal) } + return templates } \ No newline at end of file diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Strings.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Strings.kt index 3df60f1eaaf..d5566d7d342 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Strings.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Strings.kt @@ -1,6 +1,7 @@ package templates import templates.Family.* +import templates.SequenceClass.* fun strings(): List { val templates = arrayListOf() @@ -14,6 +15,7 @@ fun strings(): List { elements will be appended, followed by the [truncated] string (which defaults to "..."). """ } + sequenceClassification(terminal) typeParam("A : Appendable") returns { "A" } body { @@ -61,6 +63,7 @@ fun strings(): List { elements will be appended, followed by the [truncated] string (which defaults to "..."). """ } + sequenceClassification(terminal) exclude(Strings) returns("String") diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/engine/Engine.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/engine/Engine.kt index 86a6c834979..463e4d5ea9b 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/engine/Engine.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/engine/Engine.kt @@ -76,6 +76,14 @@ enum class Platform { JS } +enum class SequenceClass { + terminal, + intermediate, + stateless, + nearly_stateless, + stateful +} + data class Deprecation(val message: String, val replaceWith: String? = null, val level: DeprecationLevel = DeprecationLevel.WARNING) val forBinaryCompatibility = Deprecation("Provided for binary compatibility", level = DeprecationLevel.HIDDEN) @@ -213,6 +221,7 @@ class GenericFunction(val signature: String, val keyword: String = "fun") { val customPrimitiveBodies = HashMap, String>() val annotations = PlatformFamilyProperty() val sourceFile = FamilyProperty() + val sequenceClassification = mutableListOf() fun bodyForTypes(family: Family, vararg primitiveTypes: PrimitiveType, b: (PrimitiveType) -> String) { include(family) @@ -225,6 +234,10 @@ class GenericFunction(val signature: String, val keyword: String = "fun") { typeParams.add(t) } + fun sequenceClassification(vararg sequenceClass: SequenceClass) { + sequenceClassification.addAll(sequenceClass) + } + fun exclude(vararg families: Family) { buildFamilies(buildFamilies.default!! - families) } @@ -442,6 +455,10 @@ class GenericFunction(val signature: String, val keyword: String = "fun") { StringReader(methodDoc.trim()).forEachLine { line -> builder.append(" * ").append(line.trim()).append("\n") } + if (f == Sequences && sequenceClassification.isNotEmpty()) { + builder.append(" *\n") + builder.append(" * The operation is ${sequenceClassification.joinToString(" and ") { "_${it.toString().replace('_', ' ')}_" }}.\n") + } builder.append(" */\n") }