More stdlib: sorting, better Appendable, other minor changes. (#245)

This commit is contained in:
Nikolay Igotti
2017-02-16 17:00:37 +03:00
committed by GitHub
parent f0a99963a7
commit 38c6b5e9ad
8 changed files with 312 additions and 54 deletions
+5
View File
@@ -526,6 +526,11 @@ task array2(type: RunKonanTest) {
source = "runtime/collections/array2.kt"
}
task sort0(type: RunKonanTest) {
goldValue = "[a, b, x]\n[-1, 0, 42, 239, 100500]\n"
source = "runtime/collections/sort0.kt"
}
task if_else(type: RunKonanTest) {
source = "codegen/branching/if_else.kt"
}
@@ -0,0 +1,4 @@
fun main(a: Array<String>) {
println(arrayOf("x", "a", "b").sorted().toString())
println(intArrayOf(239, 42, -1, 100500, 0).sorted().toString());
}
+18 -18
View File
@@ -45,8 +45,8 @@ void Kotlin_Array_set(KRef thiz, KInt index, KConstRef value) {
OBJ_GETTER(Kotlin_Array_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
array->type_info(), array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
for (int index = 0; index < array->count_; index++) {
SetGlobalRef(
ArrayAddressOfElementAt(result, index), *ArrayAddressOfElementAt(array, index));
@@ -109,8 +109,8 @@ void Kotlin_ByteArray_set(KRef thiz, KInt index, KByte value) {
OBJ_GETTER(Kotlin_ByteArray_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
theByteArrayTypeInfo, array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
memcpy(
ByteArrayAddressOfElementAt(result, 0),
ByteArrayAddressOfElementAt(array, 0),
@@ -141,8 +141,8 @@ void Kotlin_CharArray_set(KRef thiz, KInt index, KChar value) {
OBJ_GETTER(Kotlin_CharArray_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
theCharArrayTypeInfo, array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
memcpy(
PrimitiveArrayAddressOfElementAt<KChar>(result, 0),
PrimitiveArrayAddressOfElementAt<KChar>(array, 0),
@@ -185,8 +185,8 @@ void Kotlin_ShortArray_set(KRef thiz, KInt index, KShort value) {
OBJ_GETTER(Kotlin_ShortArray_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
theShortArrayTypeInfo, array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
memcpy(
PrimitiveArrayAddressOfElementAt<KShort>(result, 0),
PrimitiveArrayAddressOfElementAt<KShort>(array, 0),
@@ -217,8 +217,8 @@ void Kotlin_IntArray_set(KRef thiz, KInt index, KInt value) {
OBJ_GETTER(Kotlin_IntArray_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
theIntArrayTypeInfo, array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
memcpy(
PrimitiveArrayAddressOfElementAt<KInt>(result, 0),
PrimitiveArrayAddressOfElementAt<KInt>(array, 0),
@@ -300,8 +300,8 @@ void Kotlin_LongArray_set(KRef thiz, KInt index, KLong value) {
OBJ_GETTER(Kotlin_LongArray_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
theLongArrayTypeInfo, array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
memcpy(
PrimitiveArrayAddressOfElementAt<KLong>(result, 0),
PrimitiveArrayAddressOfElementAt<KLong>(array, 0),
@@ -332,8 +332,8 @@ void Kotlin_FloatArray_set(KRef thiz, KInt index, KFloat value) {
OBJ_GETTER(Kotlin_FloatArray_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
theFloatArrayTypeInfo, array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
memcpy(
PrimitiveArrayAddressOfElementAt<KFloat>(result, 0),
PrimitiveArrayAddressOfElementAt<KFloat>(array, 0),
@@ -364,8 +364,8 @@ void Kotlin_DoubleArray_set(KRef thiz, KInt index, KDouble value) {
OBJ_GETTER(Kotlin_DoubleArray_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
theDoubleArrayTypeInfo, array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
memcpy(
PrimitiveArrayAddressOfElementAt<KDouble>(result, 0),
PrimitiveArrayAddressOfElementAt<KDouble>(array, 0),
@@ -396,8 +396,8 @@ void Kotlin_BooleanArray_set(KRef thiz, KInt index, KBoolean value) {
OBJ_GETTER(Kotlin_BooleanArray_clone, KConstRef thiz) {
const ArrayHeader* array = thiz->array();
ArrayHeader* result = ArrayContainer(
theBooleanArrayTypeInfo, array->count_).GetPlace();
ArrayHeader* result = AllocArrayInstance(
array->type_info(), array->count_, OBJ_RESULT)->array();
memcpy(
PrimitiveArrayAddressOfElementAt<KBoolean>(result, 0),
PrimitiveArrayAddressOfElementAt<KBoolean>(array, 0),
+181 -2
View File
@@ -2,7 +2,8 @@ package kotlin
import kotlin.collections.*
import kotlin.internal.PureReifiable
import kotlin.util.sortArrayComparable
import kotlin.util.sortArrayWith
// TODO: make all iterator() methods inline.
/**
@@ -782,6 +783,25 @@ public inline fun CharArray.isNotEmpty(): Boolean {
public val <T> Array<out T>.lastIndex: Int
get() = size - 1
/**
* Returns last index of [element], or -1 if the array does not contain element.
*/
public fun <@kotlin.internal.OnlyInputTypes T> Array<out T>.lastIndexOf(element: T): Int {
if (element == null) {
for (index in indices.reversed()) {
if (this[index] == null) {
return index
}
}
} else {
for (index in indices.reversed()) {
if (element == this[index]) {
return index
}
}
}
return -1
}
/**
* Returns the last valid index for the array.
@@ -921,6 +941,24 @@ public fun <C : MutableCollection<in Char>> CharArray.toCollection(destination:
return destination
}
/**
* Returns a [List] containing all elements.
*/
public fun <T> Array<out T>.toList(): List<T> {
return when (size) {
0 -> emptyList()
1 -> listOf(this[0])
else -> this.toMutableList()
}
}
/**
* Returns a [MutableList] filled with all elements of this array.
*/
public fun <T> Array<out T>.toMutableList(): MutableList<T> {
return ArrayList(this.asCollection())
}
/**
* Returns a [HashSet] of all elements.
*/
@@ -984,6 +1022,135 @@ public fun CharArray.toHashSet(): HashSet<Char> {
return toCollection(HashSet<Char>(mapCapacity(size)))
}
/**
* Returns new array which is a copy of the original array.
*/
@kotlin.internal.InlineOnly
public inline fun <T> Array<T>.copyOf(): Array<T> {
return this.copyOfUninitializedElements(size)
}
/**
* Sorts the array in-place according to the order specified by the given [comparator].
*/
public fun <T> Array<out T>.sortWith(comparator: Comparator<in T>): Unit {
if (size > 1) {
sortArrayWith(this, 0, size - 1, comparator)
}
}
/**
* Sorts elements in the array in-place according to natural sort order of the value returned by specified [selector] function.
*/
public inline fun <T, R : Comparable<R>> Array<out T>.sortBy(crossinline selector: (T) -> R?): Unit {
if (size > 1) sortWith(compareBy(selector))
}
/**
* Sorts elements in the array in-place descending according to natural sort order of the value returned by specified [selector] function.
*/
public inline fun <T, R : Comparable<R>> Array<out T>.sortByDescending(crossinline selector: (T) -> R?): Unit {
if (size > 1) sortWith(compareByDescending(selector))
}
/**
* Sorts elements in the array in-place descending according to their natural sort order.
*/
public fun <T : Comparable<T>> Array<out T>.sortDescending(): Unit {
sortWith(reverseOrder())
}
/**
* Returns a list of all elements sorted according to their natural sort order.
*/
public fun <T : Comparable<T>> Array<out T>.sorted(): List<T> {
return sortedArray().asList()
}
/**
* Returns a list of all elements sorted according to their natural sort order.
*/
public fun IntArray.sorted(): List<Int> {
return toTypedArray().apply { sort() }.asList()
}
/**
* Returns an array with all elements of this array sorted according to their natural sort order.
*/
public fun <T : Comparable<T>> Array<T>.sortedArray(): Array<T> {
if (isEmpty()) return this
return this.copyOf().apply { sort() }
}
/**
* Returns an array with all elements of this array sorted descending according to their natural sort order.
*/
public fun <T : Comparable<T>> Array<T>.sortedArrayDescending(): Array<T> {
if (isEmpty()) return this
return this.copyOf().apply { sortWith(reverseOrder()) }
}
/**
* Returns a list of all elements sorted according to natural sort order of the value returned by specified [selector] function.
*/
public inline fun <T, R : Comparable<R>> Array<out T>.sortedBy(crossinline selector: (T) -> R?): List<T> {
return sortedWith(compareBy(selector))
}
/**
* Returns a list of all elements sorted descending according to natural sort order of the value returned by specified [selector] function.
*/
public inline fun <T, R : Comparable<R>> Array<out T>.sortedByDescending(crossinline selector: (T) -> R?): List<T> {
return sortedWith(compareByDescending(selector))
}
/**
* Returns a list of all elements sorted descending according to their natural sort order.
*/
public fun <T : Comparable<T>> Array<out T>.sortedDescending(): List<T> {
return sortedWith(reverseOrder())
}
/**
* Sorts the array in-place according to the natural order of its elements.
*
* @throws ClassCastException if any element of the array is not [Comparable].
*/
public fun <T> Array<out T>.sort(): Unit {
if (size > 1) sortArrayComparable(this)
}
public fun <T> Array<out T>.sortWith(comparator: Comparator<in T>, fromIndex: Int = 0, toIndex: Int = size): Unit {
sortArrayWith(this, fromIndex, toIndex, comparator)
}
/**
* Returns a *typed* object array containing all of the elements of this primitive array.
*/
public fun IntArray.toTypedArray(): Array<Int> {
val result = arrayOfNulls<Int>(size)
for (index in indices)
result[index] = this[index]
@Suppress("UNCHECKED_CAST")
return result as Array<Int>
}
/**
* Returns a list of all elements sorted according to the specified [comparator].
*/
public fun <T> Array<out T>.sortedWith(comparator: Comparator<in T>): List<T> {
return sortedArrayWith(comparator).asList()
}
/**
* Returns an array with all elements of this array sorted according the specified [comparator].
*/
public fun <T> Array<out T>.sortedArrayWith(comparator: Comparator<in T>): Array<out T> {
if (isEmpty()) return this
return this.copyOf().apply { sortWith(comparator) }
}
// From Library.kt.
/**
* Returns an array of objects of the given type with the given [size], initialized with null values.
@@ -992,6 +1159,19 @@ public inline fun <reified @PureReifiable T> arrayOfNulls(size: Int): Array<T?>
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
arrayOfUninitializedElements<T?>(size)
/**
* Returns a *typed* array containing all of the elements of this collection.
*
* Allocates an array of runtime type `T` having its size equal to the size of this collection
* and populates the array with the elements of this collection.
*/
public inline fun <reified T> Collection<T>.toTypedArray(): Array<T> {
val result = arrayOfNulls<T>(size)
var index = 0
for (element in this) result[index++] = element
return result as Array<T>
}
/**
* Returns an array containing the specified elements.
*/
@@ -1000,7 +1180,6 @@ public inline fun <reified @PureReifiable T> arrayOf(vararg elements: T): Array<
/**
* Returns an array containing the specified [Double] numbers.
*/
public inline fun doubleArrayOf(vararg elements: Double) = elements
/**
@@ -12,8 +12,7 @@ public abstract class AbstractCollection<out E> protected constructor() : Collec
override fun isEmpty(): Boolean = size == 0
@Fixme
override fun toString(): String = TODO() // joinToString(", ", "[", "]") {
// if (it === this) "(this Collection)" else it.toString()
// }
override fun toString(): String = joinToString(", ", "[", "]") {
if (it === this) "(this Collection)" else it.toString()
}
}
@@ -149,17 +149,6 @@ public interface MutableIterable<out T> : Iterable<T> {
override fun iterator(): MutableIterator<T>
}
@Fixme
fun <E> Array<E>.asList(): List<E> {
// TODO: consider making lighter list over an array.
val result = ArrayList<E>(this.size)
for (e in this) {
result.add(e)
}
return result
}
/* TODO: use this one!
public fun <T> Array<out T>.asList(): List<T> {
return object : AbstractList<T>() {
override val size: Int get() = this@asList.size
@@ -169,7 +158,7 @@ public fun <T> Array<out T>.asList(): List<T> {
override fun indexOf(element: T): Int = this@asList.indexOf(element)
override fun lastIndexOf(element: T): Int = this@asList.lastIndexOf(element)
}
} */
}
fun <E> Array<E>.toSet(): Set<E> {
val result = HashSet<E>(this.size)
@@ -1009,15 +998,13 @@ public fun <T : Comparable<T>> MutableList<T>.sortDescending(): Unit {
/**
* Returns a list of all elements sorted according to their natural sort order.
*/
@FixmeSorting
public fun <T : Comparable<T>> Iterable<T>.sorted(): List<T> {
TODO()
//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() }
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() }
}
/**
@@ -1044,15 +1031,13 @@ public fun <T : Comparable<T>> Iterable<T>.sortedDescending(): List<T> {
/**
* Returns a list of all elements sorted according to the specified [comparator].
*/
@FixmeSorting
public fun <T> Iterable<T>.sortedWith(comparator: Comparator<in T>): List<T> {
TODO()
//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) }
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) }
}
/**
@@ -1568,6 +1553,7 @@ public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean {
}
/**
* Returns the number of elements in this collection.
* Returns the number of elements in this collection.
*/
public fun <T> Iterable<T>.count(): Int {
@@ -64,9 +64,21 @@ class StringBuilder private constructor (
return this
}
override fun append(csq: CharSequence?): Appendable = TODO()
override fun append(csq: CharSequence?): Appendable {
// TODO: how to treat nulls properly?
if (csq == null) return this
return append(csq, 0, csq.length)
}
override fun append(csq: CharSequence?, start: Int, end: Int): Appendable = TODO()
override fun append(csq: CharSequence?, start: Int, end: Int): Appendable {
// TODO: how to treat nulls properly?
if (csq == null) return this
ensureExtraCapacity(end - start)
var index = start
while (index < end)
array[length++] = csq[index++]
return this
}
fun append(it: CharArray) {
ensureExtraCapacity(it.size)
@@ -0,0 +1,73 @@
package kotlin.util
import kotlin.comparisons.*
// Yes, rather naive qsort for now.
private fun <T> partition(array: Array<T>, left: Int, right: Int): Int {
var i = left
var j = right
val pivot = array[(left + right) / 2] as Comparable<T>
while (i <= j) {
while (pivot.compareTo(array[i]) > 0) {
i++
}
while (pivot.compareTo(array[j]) < 0) {
j--
}
if (i <= j) {
val tmp = array[i]
array[i] = array[j]
array[j] = tmp
i++
j--
}
}
return i
}
private fun <T> quickSort(array: Array<T>, left: Int, right: Int) {
val index = partition(array, left, right)
if (left < index - 1)
quickSort(array, left, index - 1)
if (index < right)
quickSort(array, index, right)
}
private fun <T> partition(
array: Array<T>, left: Int, right: Int, comparator: Comparator<T>): Int {
var i = left
var j = right
val pivot = array[(left + right) / 2]
while (i <= j) {
while (comparator.compare(array[i], pivot) < 0)
i++
while (comparator.compare(array[j], pivot) > 0)
j--
if (i <= j) {
val tmp = array[i]
array[i] = array[j]
array[j] = tmp
i++
j--
}
}
return i
}
private fun <T> quickSort(
array: Array<T>, left: Int, right: Int, comparator: Comparator<T>) {
val index = partition(array, left, right, comparator)
if (left < index - 1)
quickSort(array, left, index - 1, comparator)
if (index < right)
quickSort(array, index, right, comparator)
}
internal fun <T> sortArrayWith(
array: Array<out T>, fromIndex: Int, toIndex: Int, comparator: Comparator<T>) {
quickSort(array as Array<T>, fromIndex, toIndex, comparator)
}
internal fun <T> sortArrayComparable(array: Array<out T>) {
quickSort(array as Array<T>, 0, array.size - 1)
}