blob: bd78ab397525b52308f14830e095fd8742c1bcd6 [file] [log] [blame]
/*
* Copyright 2010-2020 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.ArrayOps.rangeDoc
import templates.Family.*
import templates.SequenceClass.*
object Ordering : TemplateGroupBase() {
init {
defaultBuilder {
specialFor(ArraysOfUnsigned) {
sinceAtLeast("1.3")
annotation("@ExperimentalUnsignedTypes")
}
}
}
val f_reverse = fn("reverse()") {
include(Lists, InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
doc { "Reverses ${f.element.pluralize()} in the ${f.collection} in-place." }
returns("Unit")
body {
"""
val midPoint = (size / 2) - 1
if (midPoint < 0) return
var reverseIndex = lastIndex
for (index in 0..midPoint) {
val tmp = this[index]
this[index] = this[reverseIndex]
this[reverseIndex] = tmp
reverseIndex--
}
"""
}
specialFor(ArraysOfUnsigned) {
inlineOnly()
body {
"""
storage.reverse()
"""
}
}
specialFor(Lists) {
receiver("MutableList<T>")
on(Platform.JVM) {
body { """java.util.Collections.reverse(this)""" }
}
}
}
val f_reverse_range = fn("reverse(fromIndex: Int, toIndex: Int)") {
include(InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
since("1.4")
doc {
"""
Reverses elements of the ${f.collection} in the specified range in-place.
${rangeDoc(hasDefault = false, action = "reverse")}
"""
}
returns("Unit")
body {
"""
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
val midPoint = (fromIndex + toIndex) / 2
if (fromIndex == midPoint) return
var reverseIndex = toIndex - 1
for (index in fromIndex until midPoint) {
val tmp = this[index]
this[index] = this[reverseIndex]
this[reverseIndex] = tmp
reverseIndex--
}
"""
}
specialFor(ArraysOfUnsigned) {
inlineOnly()
body { """storage.reverse(fromIndex, toIndex)""" }
}
}
val f_reversed = fn("reversed()") {
include(Iterables, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences, Strings)
} builder {
doc { "Returns a list with elements in reversed order." }
returns("List<T>")
body {
"""
if (this is Collection && size <= 1) return toList()
val list = toMutableList()
list.reverse()
return list
"""
}
body(ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned) {
"""
if (isEmpty()) return emptyList()
val list = toMutableList()
list.reverse()
return list
"""
}
specialFor(CharSequences, Strings) {
returns("SELF")
doc { "Returns a ${f.collection} with characters in reversed order." }
}
body(CharSequences) { "return StringBuilder(this).reverse()" }
specialFor(Strings) { inlineOnly() }
body(Strings) { "return (this as CharSequence).reversed().toString()" }
}
val f_reversedArray = fn("reversedArray()") {
include(InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
doc { "Returns an array with elements of this array in reversed order." }
returns("SELF")
body(InvariantArraysOfObjects) {
"""
if (isEmpty()) return this
val result = arrayOfNulls(this, size)
val lastIndex = lastIndex
for (i in 0..lastIndex)
result[lastIndex - i] = this[i]
return result
"""
}
body(ArraysOfPrimitives) {
"""
if (isEmpty()) return this
val result = SELF(size)
val lastIndex = lastIndex
for (i in 0..lastIndex)
result[lastIndex - i] = this[i]
return result
"""
}
specialFor(ArraysOfUnsigned) {
inlineOnly()
body {
"""
return SELF(storage.reversedArray())
"""
}
}
}
val stableSortNote =
"The sort is _stable_. It means that equal elements preserve their order relative to each other after sorting."
fun MemberBuilder.appendStableSortNote() {
doc {
doc.orEmpty().trimIndent() + "\n\n" + stableSortNote
}
}
val f_sorted = fn("sorted()") {
includeDefault()
exclude(PrimitiveType.Boolean)
include(ArraysOfUnsigned)
} builder {
doc {
"""
Returns a list of all elements sorted according to their natural sort order.
"""
}
if (f != ArraysOfPrimitives && f != ArraysOfUnsigned) {
appendStableSortNote()
}
returns("List<T>")
typeParam("T : Comparable<T>")
body {
"""
if (this is Collection) {
if (size <= 1) return this.toList()
@Suppress("UNCHECKED_CAST")
return (toTypedArray<Comparable<T>>() as Array<T>).apply { sort() }.asList()
}
return toMutableList().apply { sort() }
"""
}
body(ArraysOfPrimitives) {
"""
return toTypedArray().apply { sort() }.asList()
"""
}
body(ArraysOfUnsigned) {
"""
return copyOf().apply { sort() }.asList()
"""
}
body(ArraysOfObjects) {
"""
return sortedArray().asList()
"""
}
specialFor(Sequences) {
returns("SELF")
doc {
"Returns a sequence that yields elements of this sequence sorted according to their natural sort order."
}
appendStableSortNote()
sequenceClassification(intermediate, stateful)
}
body(Sequences) {
"""
return object : Sequence<T> {
override fun iterator(): Iterator<T> {
val sortedList = this@sorted.toMutableList()
sortedList.sort()
return sortedList.iterator()
}
}
"""
}
}
val f_sortedArray = fn("sortedArray()") {
include(InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
exclude(PrimitiveType.Boolean)
} builder {
doc {
"Returns an array with all elements of this array sorted according to their natural sort order."
}
specialFor(InvariantArraysOfObjects) {
appendStableSortNote()
}
typeParam("T : Comparable<T>")
returns("SELF")
body {
"""
if (isEmpty()) return this
return this.copyOf().apply { sort() }
"""
}
}
val f_sortDescending = fn("sortDescending()") {
include(Lists, ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
exclude(PrimitiveType.Boolean)
} builder {
doc { """Sorts elements in the ${f.collection} in-place descending according to their natural sort order.""" }
if (f != ArraysOfPrimitives && f != ArraysOfUnsigned) {
appendStableSortNote()
}
returns("Unit")
typeParam("T : Comparable<T>")
specialFor(Lists) {
receiver("MutableList<T>")
}
body { """sortWith(reverseOrder())""" }
body(ArraysOfPrimitives, ArraysOfUnsigned) {
"""
if (size > 1) {
sort()
reverse()
}
"""
}
}
val f_sortedDescending = fn("sortedDescending()") {
includeDefault()
exclude(PrimitiveType.Boolean)
include(ArraysOfUnsigned)
} builder {
doc {
"""
Returns a list of all elements sorted descending according to their natural sort order.
"""
}
if (f != ArraysOfPrimitives) {
appendStableSortNote()
}
returns("List<T>")
typeParam("T : Comparable<T>")
body {
"""
return sortedWith(reverseOrder())
"""
}
body(ArraysOfPrimitives, ArraysOfUnsigned) {
"""
return copyOf().apply { sort() }.reversed()
"""
}
specialFor(Sequences) {
returns("SELF")
doc {
"Returns a sequence that yields elements of this sequence sorted descending according to their natural sort order."
}
appendStableSortNote()
sequenceClassification(intermediate, stateful)
}
}
val f_sortedArrayDescending = fn("sortedArrayDescending()") {
include(InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
exclude(PrimitiveType.Boolean)
} builder {
doc {
"Returns an array with all elements of this array sorted descending according to their natural sort order."
}
specialFor(InvariantArraysOfObjects) {
appendStableSortNote()
}
typeParam("T : Comparable<T>")
returns("SELF")
body(InvariantArraysOfObjects) {
"""
if (isEmpty()) return this
return this.copyOf().apply { sortWith(reverseOrder()) }
"""
}
body(ArraysOfPrimitives, ArraysOfUnsigned) {
"""
if (isEmpty()) return this
return this.copyOf().apply { sortDescending() }
"""
}
}
val f_sortedWith = fn("sortedWith(comparator: Comparator<in T>)") {
includeDefault()
} builder {
returns("List<T>")
doc {
"""
Returns a list of all elements sorted according to the specified [comparator].
"""
}
if (f != ArraysOfPrimitives) {
appendStableSortNote()
}
body {
"""
if (this is Collection) {
if (size <= 1) return this.toList()
@Suppress("UNCHECKED_CAST")
return (toTypedArray<Any?>() as Array<T>).apply { sortWith(comparator) }.asList()
}
return toMutableList().apply { sortWith(comparator) }
"""
}
body(ArraysOfPrimitives) {
"""
return toTypedArray().apply { sortWith(comparator) }.asList()
"""
}
body(ArraysOfObjects) {
"""
return sortedArrayWith(comparator).asList()
"""
}
specialFor(Sequences) {
returns("SELF")
doc {
"Returns a sequence that yields elements of this sequence sorted according to the specified [comparator]."
}
appendStableSortNote()
sequenceClassification(intermediate, stateful)
}
body(Sequences) {
"""
return object : Sequence<T> {
override fun iterator(): Iterator<T> {
val sortedList = this@sortedWith.toMutableList()
sortedList.sortWith(comparator)
return sortedList.iterator()
}
}
"""
}
}
val f_sortedArrayWith = fn("sortedArrayWith(comparator: Comparator<in T>)") {
include(ArraysOfObjects)
} builder {
doc {
"Returns an array with all elements of this array sorted according the specified [comparator]."
}
appendStableSortNote()
returns("SELF")
body {
"""
if (isEmpty()) return this
return this.copyOf().apply { sortWith(comparator) }
"""
}
}
val f_sortBy = fn("sortBy(crossinline selector: (T) -> R?)") {
include(Lists, ArraysOfObjects)
} builder {
inline()
doc { """Sorts elements in the ${f.collection} in-place according to natural sort order of the value returned by specified [selector] function.""" }
appendStableSortNote()
returns("Unit")
typeParam("R : Comparable<R>")
specialFor(Lists) { receiver("MutableList<T>") }
body { """if (size > 1) sortWith(compareBy(selector))""" }
}
val f_sortedBy = fn("sortedBy(crossinline selector: (T) -> R?)") {
includeDefault()
} builder {
inline()
returns("List<T>")
typeParam("R : Comparable<R>")
doc {
"""
Returns a list of all elements sorted according to natural sort order of the value returned by specified [selector] function.
"""
}
if (f != ArraysOfPrimitives) {
appendStableSortNote()
}
specialFor(Sequences) {
returns("SELF")
doc {
"Returns a sequence that yields elements of this sequence sorted according to natural sort order of the value returned by specified [selector] function."
}
appendStableSortNote()
sequenceClassification(intermediate, stateful)
}
sample("samples.collections.Collections.Sorting.sortedBy")
body {
"return sortedWith(compareBy(selector))"
}
}
val f_sortByDescending = fn("sortByDescending(crossinline selector: (T) -> R?)") {
include(Lists, ArraysOfObjects)
} builder {
inline()
doc { """Sorts elements in the ${f.collection} in-place descending according to natural sort order of the value returned by specified [selector] function.""" }
appendStableSortNote()
returns("Unit")
typeParam("R : Comparable<R>")
specialFor(Lists) { receiver("MutableList<T>") }
body {
"""if (size > 1) sortWith(compareByDescending(selector))""" }
}
val f_sortedByDescending = fn("sortedByDescending(crossinline selector: (T) -> R?)") {
includeDefault()
} builder {
inline()
returns("List<T>")
typeParam("R : Comparable<R>")
doc {
"""
Returns a list of all elements sorted descending according to natural sort order of the value returned by specified [selector] function.
"""
}
if (f != ArraysOfPrimitives) {
appendStableSortNote()
}
specialFor(Sequences) {
returns("SELF")
doc {
"Returns a sequence that yields elements of this sequence sorted descending according to natural sort order of the value returned by specified [selector] function."
}
appendStableSortNote()
sequenceClassification(intermediate, stateful)
}
body {
"return sortedWith(compareByDescending(selector))"
}
}
val f_shuffle = fn("shuffle()") {
include(InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
since("1.4")
returns("Unit")
doc {
"""
Randomly shuffles elements in this ${f.collection} in-place.
"""
}
body {
"shuffle(Random)"
}
}
val f_shuffleRandom = fn("shuffle(random: Random)") {
include(Lists, InvariantArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
since("1.4")
returns("Unit")
doc {
"""
Randomly shuffles elements in this ${f.collection} in-place using the specified [random] instance as the source of randomness.
See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
"""
}
specialFor(Lists) {
since("1.3")
receiver("MutableList<T>")
}
body {
"""
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
val copy = this[i]
this[i] = this[j]
this[j] = copy
}
"""
}
specialFor(Lists) {
body {
"""
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
this[j] = this.set(i, this[j])
}
"""
}
}
}
}