| /* |
| * 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]) |
| } |
| """ |
| } |
| } |
| } |
| } |