From ec64fd0477e38f6a013f9fd3d1c71c67062406e5 Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Wed, 12 Apr 2017 13:44:49 +0700 Subject: [PATCH] stdlib: Make toIndex exclusive in sortArrayWith method This patch makes toIndex parameter exclusive in sortArrayWith method in order to make this method corresponding to the other ones (e.g. copyOfRange, Array.sortWith extension etc). It also improves the external sortBy test in order to use it with different sort algorithms. --- .../collections/ArraysTest/sortByInPlace.kt | 60 ++++++++----------- runtime/src/main/kotlin/kotlin/Arrays.kt | 6 +- runtime/src/main/kotlin/kotlin/util/Sort.kt | 15 ++++- 3 files changed, 40 insertions(+), 41 deletions(-) diff --git a/backend.native/tests/external/stdlib/collections/ArraysTest/sortByInPlace.kt b/backend.native/tests/external/stdlib/collections/ArraysTest/sortByInPlace.kt index e145aa909af..6a35c3a217f 100644 --- a/backend.native/tests/external/stdlib/collections/ArraysTest/sortByInPlace.kt +++ b/backend.native/tests/external/stdlib/collections/ArraysTest/sortByInPlace.kt @@ -1,49 +1,39 @@ import kotlin.test.* -fun assertArrayNotSameButEquals(expected: Array, actual: Array, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) +fun > assertSorted(array: Array, message: String = "") = assertSorted(array, message, { it }) + +inline fun > assertSorted(array: Array, message: String = "", crossinline selector: (T) -> R) { + if (array.isEmpty() || array.size == 1) { + return + } + var prev = selector(array[0]) + for (i in 1..array.lastIndex) { + val cur = selector(array[i]) + assertTrue(prev.compareTo(cur) <= 0, message) + prev = cur + } } -fun assertArrayNotSameButEquals(expected: IntArray, actual: IntArray, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) -} - -fun assertArrayNotSameButEquals(expected: LongArray, actual: LongArray, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) -} - -fun assertArrayNotSameButEquals(expected: ShortArray, actual: ShortArray, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) -} - -fun assertArrayNotSameButEquals(expected: ByteArray, actual: ByteArray, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) -} - -fun assertArrayNotSameButEquals(expected: DoubleArray, actual: DoubleArray, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) -} - -fun assertArrayNotSameButEquals(expected: FloatArray, actual: FloatArray, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) -} - -fun assertArrayNotSameButEquals(expected: CharArray, actual: CharArray, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) -} - -fun assertArrayNotSameButEquals(expected: BooleanArray, actual: BooleanArray, message: String = "") { - assertTrue(expected !== actual && expected contentEquals actual, message) +inline fun > assertSortedDescending(array: Array, message: String = "", crossinline selector: (T) -> R) { + if (array.isEmpty() || array.size == 1) { + return + } + var prev = selector(array[0]) + for (i in 1..array.lastIndex) { + val cur = selector(array[i]) + assertTrue(prev.compareTo(cur) >= 0, message) + prev = cur + } } fun box() { val data = arrayOf("aa" to 20, "ab" to 3, "aa" to 3) data.sortBy { it.second } - assertArrayNotSameButEquals(arrayOf("ab" to 3, "aa" to 3, "aa" to 20), data) + assertSorted(data) { it.second } data.sortBy { it.first } - assertArrayNotSameButEquals(arrayOf("aa" to 3, "aa" to 20, "ab" to 3), data) + assertSorted(data) { it.first } data.sortByDescending { (it.first + it.second).length } - assertArrayNotSameButEquals(arrayOf("aa" to 20, "aa" to 3, "ab" to 3), data) + assertSortedDescending(data) { (it.first + it.second).length } } diff --git a/runtime/src/main/kotlin/kotlin/Arrays.kt b/runtime/src/main/kotlin/kotlin/Arrays.kt index f3928687b9d..1f1669c0913 100644 --- a/runtime/src/main/kotlin/kotlin/Arrays.kt +++ b/runtime/src/main/kotlin/kotlin/Arrays.kt @@ -15,7 +15,7 @@ */ // TODO: Add SortedSed class and implement toSortedSet extensions -// TODO: Add sort and binary search for primitive arrays +// TODO: Add fill and binary search methods for primitive arrays (with tests) package kotlin @@ -10559,9 +10559,7 @@ public inline fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray * Sorts the array in-place according to the order specified by the given [comparator]. */ public fun Array.sortWith(comparator: Comparator): Unit { - if (size > 1) { - sortArrayWith(this, 0, size - 1, comparator) - } + if (size > 1) sortArrayWith(this, 0, size, comparator) } /** diff --git a/runtime/src/main/kotlin/kotlin/util/Sort.kt b/runtime/src/main/kotlin/kotlin/util/Sort.kt index 9d58b81fc3b..3eeff31c476 100644 --- a/runtime/src/main/kotlin/kotlin/util/Sort.kt +++ b/runtime/src/main/kotlin/kotlin/util/Sort.kt @@ -332,17 +332,28 @@ private fun quickSort( } // Interfaces ============================================================================= +/** + * Sorts the subarray specified by [fromIndex] (inclusive) and [toIndex] (exclusive) parameters + * using the qsort algorithm with the given [comparator]. + */ internal fun sortArrayWith( - array: Array, fromIndex: Int, toIndex: Int, comparator: Comparator) { + array: Array, fromIndex: Int = 0, toIndex: Int = array.size, comparator: Comparator) { @Suppress("UNCHECKED_CAST") - quickSort(array as Array, fromIndex, toIndex, comparator) + quickSort(array as Array, fromIndex, toIndex - 1, comparator) } +/** + * Sorts a subarray of [Comparable] elements specified by [fromIndex] (inclusive) and + * [toIndex] (exclusive) parameters using the qsort algorithm. + */ internal fun sortArrayComparable(array: Array) { @Suppress("UNCHECKED_CAST") quickSort(array as Array, 0, array.size - 1) } +/** + * Sorts the given array using qsort algorithm. + */ internal fun sortArray(array: ByteArray) = quickSort(array, 0, array.size - 1) internal fun sortArray(array: ShortArray) = quickSort(array, 0, array.size - 1) internal fun sortArray(array: IntArray) = quickSort(array, 0, array.size - 1)