Files
kotlin-fork/libraries/tools/kotlin-stdlib-gen/src/templates/Generators.kt
T
2020-03-31 02:04:55 +03:00

1294 lines
48 KiB
Kotlin

/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package templates
import templates.Family.*
import templates.SequenceClass.*
object Generators : TemplateGroupBase() {
init {
defaultBuilder {
specialFor(ArraysOfUnsigned) {
sinceAtLeast("1.3")
annotation("@ExperimentalUnsignedTypes")
}
}
}
val f_plusElement = fn("plusElement(element: T)") {
include(Iterables, Collections, Sets, Sequences)
} builder {
inlineOnly()
doc { "Returns a list containing all elements of the original collection and then the given [element]." }
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set and then the given [element] if it isn't already in this set.
The returned set preserves the element iteration order of the original set.
"""
}
}
specialFor(Sequences) {
doc { "Returns a sequence containing all elements of the original sequence and then the given [element]." }
}
sequenceClassification(intermediate, stateless)
returns("List<T>")
specialFor(Sets, Sequences) { returns("SELF") }
body { "return plus(element)" }
}
val f_plus = fn("plus(element: T)") {
include(Iterables, Collections, Sets, Sequences)
} builder {
operator(true)
doc { "Returns a list containing all elements of the original collection and then the given [element]." }
sequenceClassification(intermediate, stateless)
returns("List<T>")
body {
"""
if (this is Collection) return this.plus(element)
val result = ArrayList<T>()
result.addAll(this)
result.add(element)
return result
"""
}
body(Collections) {
"""
val result = ArrayList<T>(size + 1)
result.addAll(this)
result.add(element)
return result
"""
}
specialFor(Sets, Sequences) { returns("SELF") }
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set and then the given [element] if it isn't already in this set.
The returned set preserves the element iteration order of the original set.
"""
}
body {
"""
val result = LinkedHashSet<T>(mapCapacity(size + 1))
result.addAll(this)
result.add(element)
return result
"""
}
}
specialFor(Sequences) {
doc { "Returns a sequence containing all elements of the original sequence and then the given [element]." }
body {
"""
return sequenceOf(this, sequenceOf(element)).flatten()
"""
}
}
}
val f_plus_iterable = fn("plus(elements: Iterable<T>)") {
include(Iterables, Collections, Sets, Sequences)
} builder {
operator(true)
doc { "Returns a list containing all elements of the original ${f.collection} and then all elements of the given [elements] collection." }
returns("List<T>")
specialFor(Sets, Sequences) { returns("SELF") }
body {
"""
if (this is Collection) return this.plus(elements)
val result = ArrayList<T>()
result.addAll(this)
result.addAll(elements)
return result
"""
}
body(Collections) {
"""
if (elements is Collection) {
val result = ArrayList<T>(this.size + elements.size)
result.addAll(this)
result.addAll(elements)
return result
} else {
val result = ArrayList<T>(this)
result.addAll(elements)
return result
}
"""
}
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set and the given [elements] collection,
which aren't already in this set.
The returned set preserves the element iteration order of the original set.
"""
}
body {
"""
val result = LinkedHashSet<T>(mapCapacity(elements.collectionSizeOrNull()?.let { this.size + it } ?: this.size * 2))
result.addAll(this)
result.addAll(elements)
return result
"""
}
}
specialFor(Sequences) {
doc {
"""
Returns a sequence containing all elements of original sequence and then all elements of the given [elements] collection.
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.
"""
}
sequenceClassification(intermediate, stateless)
body {
"""
return sequenceOf(this, elements.asSequence()).flatten()
"""
}
}
}
val f_plus_array = fn("plus(elements: Array<out T>)") {
include(Iterables, Collections, Sets, Sequences)
} builder {
operator(true)
doc { "Returns a list containing all elements of the original collection and then all elements of the given [elements] array." }
returns("List<T>")
specialFor(Sets, Sequences) { returns("SELF") }
body {
"""
if (this is Collection) return this.plus(elements)
val result = ArrayList<T>()
result.addAll(this)
result.addAll(elements)
return result
"""
}
body(Collections) {
"""
val result = ArrayList<T>(this.size + elements.size)
result.addAll(this)
result.addAll(elements)
return result
"""
}
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set and the given [elements] array,
which aren't already in this set.
The returned set preserves the element iteration order of the original set.
"""
}
body {
"""
val result = LinkedHashSet<T>(mapCapacity(this.size + elements.size))
result.addAll(this)
result.addAll(elements)
return result
"""
}
}
specialFor(Sequences) {
doc {
"""
Returns a sequence containing all elements of original sequence and then all elements of the given [elements] array.
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.
"""
}
sequenceClassification(intermediate, stateless)
body {
"""
return this.plus(elements.asList())
"""
}
}
}
val f_plus_sequence = fn("plus(elements: Sequence<T>)") {
include(Iterables, Sets, Sequences, Collections)
} builder {
operator(true)
doc { "Returns a list containing all elements of the original collection and then all elements of the given [elements] sequence." }
returns("List<T>")
specialFor(Sets, Sequences) { returns("SELF") }
body {
"""
val result = ArrayList<T>()
result.addAll(this)
result.addAll(elements)
return result
"""
}
body(Collections) {
"""
val result = ArrayList<T>(this.size + 10)
result.addAll(this)
result.addAll(elements)
return result
"""
}
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set and the given [elements] sequence,
which aren't already in this set.
The returned set preserves the element iteration order of the original set.
"""
}
body {
"""
val result = LinkedHashSet<T>(mapCapacity(this.size * 2))
result.addAll(this)
result.addAll(elements)
return result
"""
}
}
specialFor(Sequences) {
doc {
"""
Returns a sequence containing all elements of original sequence and then all elements of the given [elements] 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.
"""
}
sequenceClassification(intermediate, stateless)
body {
"""
return sequenceOf(this, elements).flatten()
"""
}
}
}
val f_minusElement = fn("minusElement(element: T)") {
include(Iterables, Sets, Sequences)
} builder {
inline(Inline.Only)
doc { "Returns a list containing all elements of the original collection without the first occurrence of the given [element]." }
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set except the given [element].
The returned set preserves the element iteration order of the original set.
"""
}
}
specialFor(Sequences) {
doc { "Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]." }
sequenceClassification(intermediate, stateless)
}
returns("List<T>")
specialFor(Sets, Sequences) { returns("SELF") }
body { "return minus(element)" }
}
val f_minus = fn("minus(element: T)") {
include(Iterables, Sets, Sequences)
} builder {
operator(true)
doc { "Returns a list containing all elements of the original collection without the first occurrence of the given [element]." }
returns("List<T>")
body {
"""
val result = ArrayList<T>(collectionSizeOrDefault(10))
var removed = false
return this.filterTo(result) { if (!removed && it == element) { removed = true; false } else true }
"""
}
specialFor(Sets, Sequences) { returns("SELF") }
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set except the given [element].
The returned set preserves the element iteration order of the original set.
"""
}
body {
"""
val result = LinkedHashSet<T>(mapCapacity(size))
var removed = false
return this.filterTo(result) { if (!removed && it == element) { removed = true; false } else true }
"""
}
}
specialFor(Sequences) {
doc { "Returns a sequence containing all elements of the original sequence without the first occurrence of the given [element]." }
sequenceClassification(intermediate, stateless)
body {
"""
return object: Sequence<T> {
override fun iterator(): Iterator<T> {
var removed = false
return this@minus.filter { if (!removed && it == element) { removed = true; false } else true }.iterator()
}
}
"""
}
}
}
private fun elementsConversionClause(elements: Family) =
"""
The [elements] ${elements.doc.collection} may be converted to a [HashSet] to speed up the operation, thus the elements are required to have
a correct and stable implementation of `hashCode()` that doesn't change between successive invocations.
"""
val f_minus_iterable = fn("minus(elements: Iterable<T>)") {
include(Iterables, Sets, Sequences)
} builder {
operator(true)
doc { "Returns a list containing all elements of the original collection except the elements contained in the given [elements] collection.\n" }
returns("List<T>")
specialFor(Sets, Sequences) { returns("SELF") }
body {
"""
val other = elements.convertToSetForSetOperationWith(this)
if (other.isEmpty())
return this.toList()
return this.filterNot { it in other }
"""
}
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set except the elements contained in the given [elements] collection.
The returned set preserves the element iteration order of the original set.
"""
}
body {
"""
val other = elements.convertToSetForSetOperationWith(this)
if (other.isEmpty())
return this.toSet()
if (other is Set)
return this.filterNotTo(LinkedHashSet<T>()) { it in other }
val result = LinkedHashSet<T>(this)
result.removeAll(other)
return result
"""
}
}
specialFor(Sequences) {
doc {
"""
Returns a sequence containing all elements of original sequence except the elements contained in the given [elements] collection.
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.
"""
}
sequenceClassification(intermediate, stateful)
body {
"""
return object: Sequence<T> {
override fun iterator(): Iterator<T> {
val other = elements.convertToSetForSetOperation()
if (other.isEmpty())
return this@minus.iterator()
else
return this@minus.filterNot { it in other }.iterator()
}
}
"""
}
}
doc {
doc + elementsConversionClause(Iterables)
}
}
val f_minus_array = fn("minus(elements: Array<out T>)") {
include(Iterables, Sets, Sequences)
} builder {
operator(true)
doc { "Returns a list containing all elements of the original collection except the elements contained in the given [elements] array.\n" }
returns("List<T>")
specialFor(Sets, Sequences) { returns("SELF") }
body {
"""
if (elements.isEmpty()) return this.toList()
val other = elements.toHashSet()
return this.filterNot { it in other }
"""
}
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set except the elements contained in the given [elements] array.
The returned set preserves the element iteration order of the original set.
"""
}
body {
"""
val result = LinkedHashSet<T>(this)
result.removeAll(elements)
return result
"""
}
}
specialFor(Sequences) {
doc {
"""
Returns a sequence containing all elements of original sequence except the elements contained in the given [elements] array.
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.
"""
}
sequenceClassification(intermediate, stateful)
body {
"""
if (elements.isEmpty()) return this
return object: Sequence<T> {
override fun iterator(): Iterator<T> {
val other = elements.toHashSet()
return this@minus.filterNot { it in other }.iterator()
}
}
"""
}
}
doc {
doc + elementsConversionClause(ArraysOfObjects)
}
}
val f_minus_sequence = fn("minus(elements: Sequence<T>)") {
include(Iterables, Sets, Sequences)
} builder {
operator(true)
doc { "Returns a list containing all elements of the original collection except the elements contained in the given [elements] sequence.\n" }
returns("List<T>")
specialFor(Sets, Sequences) { returns("SELF") }
body {
"""
val other = elements.toHashSet()
if (other.isEmpty())
return this.toList()
return this.filterNot { it in other }
"""
}
specialFor(Sets) {
doc {
"""
Returns a set containing all elements of the original set except the elements contained in the given [elements] sequence.
The returned set preserves the element iteration order of the original set.
"""
}
body {
"""
val result = LinkedHashSet<T>(this)
result.removeAll(elements)
return result
"""
}
}
specialFor(Sequences) {
doc {
"""
Returns a sequence containing all elements of original sequence except the elements contained in the given [elements] 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.
"""
}
body {
"""
return object: Sequence<T> {
override fun iterator(): Iterator<T> {
val other = elements.toHashSet()
if (other.isEmpty())
return this@minus.iterator()
else
return this@minus.filterNot { it in other }.iterator()
}
}
"""
}
}
doc {
doc + elementsConversionClause(Sequences)
}
}
val f_partition = fn("partition(predicate: (T) -> Boolean)") {
includeDefault()
include(CharSequences, Strings)
} builder {
inline()
doc {
"""
Splits the original ${f.collection} into pair of lists,
where *first* list contains elements for which [predicate] yielded `true`,
while *second* list contains elements for which [predicate] yielded `false`.
"""
}
sample(when (family) {
CharSequences, Strings -> "samples.text.Strings.partition"
ArraysOfObjects, ArraysOfPrimitives -> "samples.collections.Arrays.Transformations.partitionArrayOfPrimitives"
Sequences -> "samples.collections.Sequences.Transformations.partition"
else -> "samples.collections.Iterables.Operations.partition"
})
sequenceClassification(terminal)
returns("Pair<List<T>, List<T>>")
body {
"""
val first = ArrayList<T>()
val second = ArrayList<T>()
for (element in this) {
if (predicate(element)) {
first.add(element)
} else {
second.add(element)
}
}
return Pair(first, second)
"""
}
specialFor(CharSequences, Strings) {
doc {
"""
Splits the original ${f.collection} into pair of ${f.collection}s,
where *first* ${f.collection} contains characters for which [predicate] yielded `true`,
while *second* ${f.collection} contains characters for which [predicate] yielded `false`.
"""
}
returns("Pair<SELF, SELF>")
}
body(CharSequences, Strings) {
val toString = if (f == Strings) ".toString()" else ""
"""
val first = StringBuilder()
val second = StringBuilder()
for (element in this) {
if (predicate(element)) {
first.append(element)
} else {
second.append(element)
}
}
return Pair(first$toString, second$toString)
"""
}
}
val f_windowed_transform = fn("windowed(size: Int, step: Int = 1, partialWindows: Boolean = false, transform: (List<T>) -> R)") {
include(Iterables, Sequences, CharSequences)
} builder {
since("1.2")
doc {
"""
Returns a ${f.mapResult} of results of applying the given [transform] function to
an each ${f.viewResult} representing a view over the window of the given [size]
sliding along this ${f.collection} with the given [step].
Note that the ${f.viewResult} passed to the [transform] function is ephemeral and is valid only inside that function.
You should not store it or allow it to escape in some way, unless you made a snapshot of it.
Several last ${f.viewResult.pluralize()} may have less ${f.element.pluralize()} than the given [size].
Both [size] and [step] must be positive and can be greater than the number of elements in this ${f.collection}.
@param size the number of elements to take in each window
@param step the number of elements to move the window forward by on an each step, by default 1
@param partialWindows controls whether or not to keep partial windows in the end if any,
by default `false` which means partial windows won't be preserved
"""
}
sample("samples.collections.Sequences.Transformations.averageWindows")
typeParam("R")
returns("List<R>")
body {
"""
checkWindowSizeStep(size, step)
if (this is RandomAccess && this is List) {
val thisSize = this.size
val resultCapacity = thisSize / step + if (thisSize % step == 0) 0 else 1
val result = ArrayList<R>(resultCapacity)
val window = MovingSubList(this)
var index = 0
while (index in 0 until thisSize) {
val windowSize = size.coerceAtMost(thisSize - index)
if (!partialWindows && windowSize < size) break
window.move(index, index + windowSize)
result.add(transform(window))
index += step
}
return result
}
val result = ArrayList<R>()
windowedIterator(iterator(), size, step, partialWindows, reuseBuffer = true).forEach {
result.add(transform(it))
}
return result
"""
}
specialFor(CharSequences) {
signature("windowed(size: Int, step: Int = 1, partialWindows: Boolean = false, transform: (CharSequence) -> R)")
}
body(CharSequences) {
"""
checkWindowSizeStep(size, step)
val thisSize = this.length
val resultCapacity = thisSize / step + if (thisSize % step == 0) 0 else 1
val result = ArrayList<R>(resultCapacity)
var index = 0
while (index in 0 until thisSize) {
val end = index + size
val coercedEnd = if (end < 0 || end > thisSize) { if (partialWindows) thisSize else break } else end
result.add(transform(subSequence(index, coercedEnd)))
index += step
}
return result
"""
}
specialFor(Sequences) { returns("Sequence<R>") }
body(Sequences) {
"""
return windowedSequence(size, step, partialWindows, reuseBuffer = true).map(transform)
"""
}
}
val f_windowed = fn("windowed(size: Int, step: Int = 1, partialWindows: Boolean = false)") {
include(Iterables, Sequences, CharSequences)
} builder {
since("1.2")
specialFor(Iterables) { returns("List<List<T>>") }
specialFor(Sequences) { returns("Sequence<List<T>>") }
specialFor(CharSequences) { returns("List<String>") }
doc {
"""
Returns a ${f.mapResult} of snapshots of the window of the given [size]
sliding along this ${f.collection} with the given [step], where each
snapshot is ${f.snapshotResult.prefixWithArticle()}.
Several last ${f.snapshotResult.pluralize()} may have less ${f.element.pluralize()} than the given [size].
Both [size] and [step] must be positive and can be greater than the number of elements in this ${f.collection}.
@param size the number of elements to take in each window
@param step the number of elements to move the window forward by on an each step, by default 1
@param partialWindows controls whether or not to keep partial windows in the end if any,
by default `false` which means partial windows won't be preserved
"""
}
sample("samples.collections.Sequences.Transformations.takeWindows")
body {
"""
checkWindowSizeStep(size, step)
if (this is RandomAccess && this is List) {
val thisSize = this.size
val resultCapacity = thisSize / step + if (thisSize % step == 0) 0 else 1
val result = ArrayList<List<T>>(resultCapacity)
var index = 0
while (index in 0 until thisSize) {
val windowSize = size.coerceAtMost(thisSize - index)
if (windowSize < size && !partialWindows) break
result.add(List(windowSize) { this[it + index] })
index += step
}
return result
}
val result = ArrayList<List<T>>()
windowedIterator(iterator(), size, step, partialWindows, reuseBuffer = false).forEach {
result.add(it)
}
return result
"""
}
body(CharSequences) { "return windowed(size, step, partialWindows) { it.toString() }" }
body(Sequences) {
"""
return windowedSequence(size, step, partialWindows, reuseBuffer = false)
"""
}
}
val f_windowedSequence_transform = fn("windowedSequence(size: Int, step: Int = 1, partialWindows: Boolean = false, transform: (CharSequence) -> R)") {
include(CharSequences)
} builder {
since("1.2")
doc {
"""
Returns a sequence of results of applying the given [transform] function to
an each ${f.viewResult} representing a view over the window of the given [size]
sliding along this ${f.collection} with the given [step].
Note that the ${f.viewResult} passed to the [transform] function is ephemeral and is valid only inside that function.
You should not store it or allow it to escape in some way, unless you made a snapshot of it.
Several last ${f.viewResult.pluralize()} may have less ${f.element.pluralize()} than the given [size].
Both [size] and [step] must be positive and can be greater than the number of elements in this ${f.collection}.
@param size the number of elements to take in each window
@param step the number of elements to move the window forward by on an each step, by default 1
@param partialWindows controls whether or not to keep partial windows in the end if any,
by default `false` which means partial windows won't be preserved
"""
}
sample("samples.collections.Sequences.Transformations.averageWindows")
typeParam("R")
returns("Sequence<R>")
body {
"""
checkWindowSizeStep(size, step)
val windows = (if (partialWindows) indices else 0 until length - size + 1) step step
return windows.asSequence().map { index ->
val end = index + size
val coercedEnd = if (end < 0 || end > length) length else end
transform(subSequence(index, coercedEnd))
}
"""
}
}
val f_windowedSequence = fn("windowedSequence(size: Int, step: Int = 1, partialWindows: Boolean = false)") {
include(CharSequences)
} builder {
since("1.2")
doc {
"""
Returns a sequence of snapshots of the window of the given [size]
sliding along this ${f.collection} with the given [step], where each
snapshot is ${f.snapshotResult.prefixWithArticle()}.
Several last ${f.snapshotResult.pluralize()} may have less ${f.element.pluralize()} than the given [size].
Both [size] and [step] must be positive and can be greater than the number of elements in this ${f.collection}.
@param size the number of elements to take in each window
@param step the number of elements to move the window forward by on an each step, by default 1
@param partialWindows controls whether or not to keep partial windows in the end if any,
by default `false` which means partial windows won't be preserved
"""
}
sample("samples.collections.Sequences.Transformations.takeWindows")
returns("Sequence<String>")
body(CharSequences) { "return windowedSequence(size, step, partialWindows) { it.toString() }" }
}
val f_chunked_transform = fn("chunked(size: Int, transform: (List<T>) -> R)") {
include(Iterables, Sequences, CharSequences)
} builder {
since("1.2")
doc {
"""
Splits this ${f.collection} into several ${f.viewResult.pluralize()} each not exceeding the given [size]
and applies the given [transform] function to an each.
@return ${f.mapResult} of results of the [transform] applied to an each ${f.viewResult}.
Note that the ${f.viewResult} passed to the [transform] function is ephemeral and is valid only inside that function.
You should not store it or allow it to escape in some way, unless you made a snapshot of it.
The last ${f.viewResult} may have less ${f.element.pluralize()} than the given [size].
@param size the number of elements to take in each ${f.viewResult}, must be positive and can be greater than the number of elements in this ${f.collection}.
"""
}
sample("samples.text.Strings.chunkedTransform")
typeParam("R")
returns("List<R>")
specialFor(CharSequences) {
signature("chunked(size: Int, transform: (CharSequence) -> R)")
}
sequenceClassification(intermediate, stateful)
specialFor(Sequences) { returns("Sequence<R>") }
body { "return windowed(size, size, partialWindows = true, transform = transform)" }
}
val f_chunked = fn("chunked(size: Int)") {
include(Iterables, Sequences, CharSequences)
} builder {
since("1.2")
doc {
"""
Splits this ${f.collection} into a ${f.mapResult} of ${f.snapshotResult.pluralize()} each not exceeding the given [size].
The last ${f.snapshotResult} in the resulting ${f.mapResult} may have less ${f.element.pluralize()} than the given [size].
@param size the number of elements to take in each ${f.snapshotResult}, must be positive and can be greater than the number of elements in this ${f.collection}.
"""
}
specialFor(Iterables, Sequences) { sample("samples.collections.Collections.Transformations.chunked") }
specialFor(CharSequences) { sample("samples.text.Strings.chunked") }
specialFor(Iterables) { returns("List<List<T>>") }
specialFor(Sequences) { returns("Sequence<List<T>>") }
specialFor(CharSequences) { returns("List<String>") }
sequenceClassification(intermediate, stateful)
body { "return windowed(size, size, partialWindows = true)" }
}
val f_chunkedSequence_transform = fn("chunkedSequence(size: Int, transform: (CharSequence) -> R)") {
include(CharSequences)
} builder {
since("1.2")
doc {
"""
Splits this ${f.collection} into several ${f.viewResult.pluralize()} each not exceeding the given [size]
and applies the given [transform] function to an each.
@return sequence of results of the [transform] applied to an each ${f.viewResult}.
Note that the ${f.viewResult} passed to the [transform] function is ephemeral and is valid only inside that function.
You should not store it or allow it to escape in some way, unless you made a snapshot of it.
The last ${f.viewResult} may have less ${f.element.pluralize()} than the given [size].
@param size the number of elements to take in each ${f.viewResult}, must be positive and can be greater than the number of elements in this ${f.collection}.
"""
}
sample("samples.text.Strings.chunkedTransformToSequence")
typeParam("R")
returns("Sequence<R>")
body {
"""
return windowedSequence(size, size, partialWindows = true, transform = transform)
"""
}
}
val f_chunkedSequence = fn("chunkedSequence(size: Int)") {
include(CharSequences)
} builder {
since("1.2")
doc {
"""
Splits this ${f.collection} into a sequence of ${f.snapshotResult.pluralize()} each not exceeding the given [size].
The last ${f.snapshotResult} in the resulting sequence may have less ${f.element.pluralize()} than the given [size].
@param size the number of elements to take in each ${f.snapshotResult}, must be positive and can be greater than the number of elements in this ${f.collection}.
"""
}
sample("samples.collections.Collections.Transformations.chunked")
returns("Sequence<String>")
body(CharSequences) { "return chunkedSequence(size) { it.toString() }" }
}
val f_zipWithNext_transform = fn("zipWithNext(transform: (a: T, b: T) -> R)") {
include(Iterables, Sequences, CharSequences)
} builder {
since("1.2")
typeParam("R")
doc {
"""
Returns a ${f.mapResult} containing the results of applying the given [transform] function
to an each pair of two adjacent ${f.element.pluralize()} in this ${f.collection}.
The returned ${f.mapResult} is empty if this ${f.collection} contains less than two ${f.element.pluralize()}.
"""
}
sample("samples.collections.Collections.Transformations.zipWithNextToFindDeltas")
returns("List<R>")
inline()
body {
"""
val iterator = iterator()
if (!iterator.hasNext()) return emptyList()
val result = mutableListOf<R>()
var current = iterator.next()
while (iterator.hasNext()) {
val next = iterator.next()
result.add(transform(current, next))
current = next
}
return result
"""
}
body(CharSequences) {
"""
val size = ${if (f == CharSequences) "length" else "size" } - 1
if (size < 1) return emptyList()
val result = ArrayList<R>(size)
for (index in 0 until size) {
result.add(transform(this[index], this[index + 1]))
}
return result
"""
}
sequenceClassification(intermediate, stateless)
specialFor(Sequences) {
inline(Inline.No)
returns("Sequence<R>")
}
body(Sequences) {
"""
return sequence result@ {
val iterator = iterator()
if (!iterator.hasNext()) return@result
var current = iterator.next()
while (iterator.hasNext()) {
val next = iterator.next()
yield(transform(current, next))
current = next
}
}
"""
}
}
val f_zipWithNext = fn("zipWithNext()") {
include(Iterables, Sequences, CharSequences)
} builder {
since("1.2")
returns("List<Pair<T, T>>")
doc {
"""
Returns a ${f.mapResult} of pairs of each two adjacent ${f.element.pluralize()} in this ${f.collection}.
The returned ${f.mapResult} is empty if this ${f.collection} contains less than two ${f.element.pluralize()}.
"""
}
sample("samples.collections.Collections.Transformations.zipWithNext")
sequenceClassification(intermediate, stateless)
specialFor(Sequences) { returns("Sequence<Pair<T, T>>") }
body {
"return zipWithNext { a, b -> a to b }"
}
}
val f_zip_transform = fn("zip(other: Iterable<R>, transform: (a: T, b: R) -> V)") {
include(Iterables, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
inline()
specialFor(ArraysOfUnsigned) { inlineOnly() }
doc {
"""
Returns a list of values built from the elements of `this` ${f.collection} and the [other] collection with the same index
using the provided [transform] function applied to each pair of elements.
The returned list has length of the shortest collection.
"""
}
sample("samples.collections.Iterables.Operations.zipIterableWithTransform")
typeParam("R")
typeParam("V")
returns("List<V>")
body {
"""
val first = iterator()
val second = other.iterator()
val list = ArrayList<V>(minOf(collectionSizeOrDefault(10), other.collectionSizeOrDefault(10)))
while (first.hasNext() && second.hasNext()) {
list.add(transform(first.next(), second.next()))
}
return list
"""
}
body(ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) {
"""
val arraySize = size
val list = ArrayList<V>(minOf(other.collectionSizeOrDefault(10), arraySize))
var i = 0
for (element in other) {
if (i >= arraySize) break
list.add(transform(this[i++], element))
}
return list
"""
}
}
val f_zip_array_transform = fn("zip(other: Array<out R>, transform: (a: T, b: R) -> V)") {
include(Iterables, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
inline()
specialFor(ArraysOfUnsigned) { inlineOnly() }
doc {
"""
Returns a list of values built from the elements of `this` ${f.collection} and the [other] array with the same index
using the provided [transform] function applied to each pair of elements.
The returned list has length of the shortest collection.
"""
}
sample("samples.collections.Iterables.Operations.zipIterableWithTransform")
typeParam("R")
typeParam("V")
returns("List<V>")
body {
"""
val arraySize = other.size
val list = ArrayList<V>(minOf(collectionSizeOrDefault(10), arraySize))
var i = 0
for (element in this) {
if (i >= arraySize) break
list.add(transform(element, other[i++]))
}
return list
"""
}
body(ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) {
"""
val size = minOf(size, other.size)
val list = ArrayList<V>(size)
for (i in 0 until size) {
list.add(transform(this[i], other[i]))
}
return list
"""
}
}
val f_zip_sameArray_transform = fn("zip(other: SELF, transform: (a: T, b: T) -> V)") {
include(ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
inline()
specialFor(ArraysOfUnsigned) { inlineOnly() }
doc {
"""
Returns a list of values built from the elements of `this` array and the [other] array with the same index
using the provided [transform] function applied to each pair of elements.
The returned list has length of the shortest array.
"""
}
sample("samples.collections.Iterables.Operations.zipIterableWithTransform")
typeParam("V")
returns("List<V>")
body {
"""
val size = minOf(size, other.size)
val list = ArrayList<V>(size)
for (i in 0 until size) {
list.add(transform(this[i], other[i]))
}
return list
"""
}
}
val f_zip_sequence_transform = fn("zip(other: Sequence<R>, transform: (a: T, b: R) -> V)") {
include(Sequences)
} builder {
doc {
"""
Returns a sequence of values built from the elements of `this` sequence and the [other] sequence with the same index
using the provided [transform] function applied to each pair of elements.
The resulting sequence ends as soon as the shortest input sequence ends.
"""
}
sample("samples.collections.Sequences.Transformations.zipWithTransform")
sequenceClassification(intermediate, stateless)
typeParam("R")
typeParam("V")
returns("Sequence<V>")
body {
"""
return MergingSequence(this, other, transform)
"""
}
}
val f_zip_charSequence_transform = fn("zip(other: CharSequence, transform: (a: Char, b: Char) -> V)") {
include(CharSequences)
} builder {
doc {
"""
Returns a list of values built from the characters of `this` and the [other] char sequences with the same index
using the provided [transform] function applied to each pair of characters.
The returned list has length of the shortest char sequence.
"""
}
sample("samples.text.Strings.zipWithTransform")
typeParam("V")
returns("List<V>")
inline()
body {
"""
val length = minOf(this.length, other.length)
val list = ArrayList<V>(length)
for (i in 0 until length) {
list.add(transform(this[i], other[i]))
}
return list
"""
}
}
val f_zip = fn("zip(other: Iterable<R>)") {
include(Iterables, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
infix(true)
doc {
"""
Returns a list of pairs built from the elements of `this` collection and [other] ${f.collection} with the same index.
The returned list has length of the shortest collection.
"""
}
sample("samples.collections.Iterables.Operations.zipIterable")
typeParam("R")
returns("List<Pair<T, R>>")
body {
"""
return zip(other) { t1, t2 -> t1 to t2 }
"""
}
}
val f_zip_charSequence = fn("zip(other: CharSequence)") {
include(CharSequences)
} builder {
infix(true)
doc {
"""
Returns a list of pairs built from the characters of `this` and the [other] char sequences with the same index
The returned list has length of the shortest char sequence.
"""
}
sample("samples.text.Strings.zip")
returns("List<Pair<Char, Char>>")
body {
"""
return zip(other) { c1, c2 -> c1 to c2 }
"""
}
}
val f_zip_array = fn("zip(other: Array<out R>)") {
include(Iterables, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
infix(true)
doc {
"""
Returns a list of pairs built from the elements of `this` ${f.collection} and the [other] array with the same index.
The returned list has length of the shortest collection.
"""
}
sample("samples.collections.Iterables.Operations.zipIterable")
typeParam("R")
returns("List<Pair<T, R>>")
body {
"""
return zip(other) { t1, t2 -> t1 to t2 }
"""
}
}
val f_zip_sameArray = fn("zip(other: SELF)") {
include(ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
infix(true)
doc {
"""
Returns a list of pairs built from the elements of `this` array and the [other] array with the same index.
The returned list has length of the shortest collection.
"""
}
sample("samples.collections.Iterables.Operations.zipIterable")
returns("List<Pair<T, T>>")
body {
"""
return zip(other) { t1, t2 -> t1 to t2 }
"""
}
}
val f_zip_sequence = fn("zip(other: Sequence<R>)") {
include(Sequences)
} builder {
infix(true)
doc {
"""
Returns a sequence of values built from the elements of `this` sequence and the [other] sequence with the same index.
The resulting sequence ends as soon as the shortest input sequence ends.
"""
}
sample("samples.collections.Sequences.Transformations.zip")
sequenceClassification(intermediate, stateless)
typeParam("R")
returns("Sequence<Pair<T, R>>")
body {
"""
return MergingSequence(this, other) { t1, t2 -> t1 to t2 }
"""
}
}
// documentation helpers
private val Family.snapshotResult: String
get() = when (this) {
CharSequences, Strings -> "string"
else -> "list"
}
private val Family.viewResult: String
get() = when (this) {
CharSequences, Strings -> "char sequence"
else -> "list"
}
}