Improve argument validation in copyOfRange
Make copyOfRange implementation non-inline in order not to expose copyOfRangeToIndexCheck implementation detail. It will be possible to make the function non-inline itself later without that JvmName trick, when apiVersion 1.2 support is discontinued. #KT-19489
This commit is contained in:
@@ -5737,48 +5737,75 @@ public expect fun CharArray.copyOf(newSize: Int): CharArray
|
|||||||
public expect fun <T> Array<T>.copyOf(newSize: Int): Array<T?>
|
public expect fun <T> Array<T>.copyOf(newSize: Int): Array<T?>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
@Suppress("NO_ACTUAL_FOR_EXPECT")
|
@Suppress("NO_ACTUAL_FOR_EXPECT")
|
||||||
public expect fun <T> Array<T>.copyOfRange(fromIndex: Int, toIndex: Int): Array<T>
|
public expect fun <T> Array<T>.copyOfRange(fromIndex: Int, toIndex: Int): Array<T>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public expect fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray
|
public expect fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public expect fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray
|
public expect fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public expect fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray
|
public expect fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public expect fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray
|
public expect fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public expect fun FloatArray.copyOfRange(fromIndex: Int, toIndex: Int): FloatArray
|
public expect fun FloatArray.copyOfRange(fromIndex: Int, toIndex: Int): FloatArray
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public expect fun DoubleArray.copyOfRange(fromIndex: Int, toIndex: Int): DoubleArray
|
public expect fun DoubleArray.copyOfRange(fromIndex: Int, toIndex: Int): DoubleArray
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public expect fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray
|
public expect fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public expect fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray
|
public expect fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray
|
||||||
|
|
||||||
|
|||||||
@@ -622,71 +622,102 @@ public actual fun <T> Array<out T>.copyOf(newSize: Int): Array<T?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
@Suppress("ACTUAL_WITHOUT_EXPECT", "NOTHING_TO_INLINE")
|
@Suppress("ACTUAL_WITHOUT_EXPECT")
|
||||||
public actual inline fun <T> Array<out T>.copyOfRange(fromIndex: Int, toIndex: Int): Array<T> {
|
public actual fun <T> Array<out T>.copyOfRange(fromIndex: Int, toIndex: Int): Array<T> {
|
||||||
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return this.asDynamic().slice(fromIndex, toIndex)
|
return this.asDynamic().slice(fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
public actual fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray {
|
||||||
public actual inline fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray {
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return this.asDynamic().slice(fromIndex, toIndex)
|
return this.asDynamic().slice(fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
public actual fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray {
|
||||||
public actual inline fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray {
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return this.asDynamic().slice(fromIndex, toIndex)
|
return this.asDynamic().slice(fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
public actual fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray {
|
||||||
public actual inline fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray {
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return this.asDynamic().slice(fromIndex, toIndex)
|
return this.asDynamic().slice(fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public actual fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray {
|
public actual fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray {
|
||||||
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return withType("LongArray", this.asDynamic().slice(fromIndex, toIndex))
|
return withType("LongArray", this.asDynamic().slice(fromIndex, toIndex))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
public actual fun FloatArray.copyOfRange(fromIndex: Int, toIndex: Int): FloatArray {
|
||||||
public actual inline fun FloatArray.copyOfRange(fromIndex: Int, toIndex: Int): FloatArray {
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return this.asDynamic().slice(fromIndex, toIndex)
|
return this.asDynamic().slice(fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
public actual fun DoubleArray.copyOfRange(fromIndex: Int, toIndex: Int): DoubleArray {
|
||||||
public actual inline fun DoubleArray.copyOfRange(fromIndex: Int, toIndex: Int): DoubleArray {
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return this.asDynamic().slice(fromIndex, toIndex)
|
return this.asDynamic().slice(fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public actual fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray {
|
public actual fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray {
|
||||||
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return withType("BooleanArray", this.asDynamic().slice(fromIndex, toIndex))
|
return withType("BooleanArray", this.asDynamic().slice(fromIndex, toIndex))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
public actual fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray {
|
public actual fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray {
|
||||||
|
AbstractList.checkRangeIndexes(fromIndex, toIndex, size)
|
||||||
return withType("CharArray", this.asDynamic().slice(fromIndex, toIndex))
|
return withType("CharArray", this.asDynamic().slice(fromIndex, toIndex))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -814,74 +814,227 @@ public actual inline fun <T> Array<T>.copyOf(newSize: Int): Array<T?> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun <T> Array<T>.copyOfRange(fromIndex: Int, toIndex: Int): Array<T> {
|
public actual inline fun <T> Array<T>.copyOfRange(fromIndex: Int, toIndex: Int): Array<T> {
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray {
|
public actual inline fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray {
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray {
|
public actual inline fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray {
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray {
|
public actual inline fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray {
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray {
|
public actual inline fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray {
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun FloatArray.copyOfRange(fromIndex: Int, toIndex: Int): FloatArray {
|
public actual inline fun FloatArray.copyOfRange(fromIndex: Int, toIndex: Int): FloatArray {
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun DoubleArray.copyOfRange(fromIndex: Int, toIndex: Int): DoubleArray {
|
public actual inline fun DoubleArray.copyOfRange(fromIndex: Int, toIndex: Int): DoubleArray {
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray {
|
public actual inline fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray {
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns new array which is a copy of range of original array.
|
* Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
*
|
||||||
|
* @param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
* @param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
*/
|
*/
|
||||||
|
@JvmName("copyOfRangeInline")
|
||||||
@kotlin.internal.InlineOnly
|
@kotlin.internal.InlineOnly
|
||||||
public actual inline fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray {
|
public actual inline fun CharArray.copyOfRange(fromIndex: Int, toIndex: Int): CharArray {
|
||||||
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: $toIndex, size: $size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun <T> Array<T>.copyOfRangeImpl(fromIndex: Int, toIndex: Int): Array<T> {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun ByteArray.copyOfRangeImpl(fromIndex: Int, toIndex: Int): ByteArray {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun ShortArray.copyOfRangeImpl(fromIndex: Int, toIndex: Int): ShortArray {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun IntArray.copyOfRangeImpl(fromIndex: Int, toIndex: Int): IntArray {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun LongArray.copyOfRangeImpl(fromIndex: Int, toIndex: Int): LongArray {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun FloatArray.copyOfRangeImpl(fromIndex: Int, toIndex: Int): FloatArray {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun DoubleArray.copyOfRangeImpl(fromIndex: Int, toIndex: Int): DoubleArray {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun BooleanArray.copyOfRangeImpl(fromIndex: Int, toIndex: Int): BooleanArray {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@PublishedApi
|
||||||
|
@JvmName("copyOfRange")
|
||||||
|
internal fun CharArray.copyOfRangeImpl(fromIndex: Int, toIndex: Int): CharArray {
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,3 +43,8 @@ internal actual fun <T> arrayOfNulls(reference: Array<T>, size: Int): Array<T> {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return java.lang.reflect.Array.newInstance(reference.javaClass.componentType, size) as Array<T>
|
return java.lang.reflect.Array.newInstance(reference.javaClass.componentType, size) as Array<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
internal fun copyOfRangeToIndexCheck(toIndex: Int, size: Int) {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex ($toIndex) is greater than size ($size).")
|
||||||
|
}
|
||||||
@@ -606,6 +606,15 @@ class ArraysTest {
|
|||||||
assertEquals(listOf<Short>(200, 100), shortArrayOf(50, 100, 200).slice(2 downTo 1))
|
assertEquals(listOf<Short>(200, 100), shortArrayOf(50, 100, 200).slice(2 downTo 1))
|
||||||
assertEquals(listOf(100L, 200L, 30L), longArrayOf(50L, 100L, 200L, 30L).slice(1..3))
|
assertEquals(listOf(100L, 200L, 30L), longArrayOf(50L, 100L, 200L, 30L).slice(1..3))
|
||||||
assertEquals(listOf(true, false, true), booleanArrayOf(true, false, true, true).slice(iter))
|
assertEquals(listOf(true, false, true), booleanArrayOf(true, false, true, true).slice(iter))
|
||||||
|
|
||||||
|
for (range in listOf(-1 until 0, 0 until 2, 2..2)) {
|
||||||
|
val bounds = "range: $range"
|
||||||
|
val exClass = IndexOutOfBoundsException::class
|
||||||
|
assertFailsWith(exClass, bounds) { arrayOf("x").slice(range) }
|
||||||
|
assertFailsWith(exClass, bounds) { intArrayOf(1).slice(range) }
|
||||||
|
assertFailsWith(exClass, bounds) { longArrayOf(1L).slice(range) }
|
||||||
|
assertFailsWith(exClass, bounds) { charArrayOf('C').slice(range) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun sliceArray() {
|
@Test fun sliceArray() {
|
||||||
@@ -625,6 +634,15 @@ class ArraysTest {
|
|||||||
// assertArrayNotSameButEquals(shortArrayOf(200, 100), shortArrayOf(50, 100, 200).sliceArray(2 downTo 1))
|
// assertArrayNotSameButEquals(shortArrayOf(200, 100), shortArrayOf(50, 100, 200).sliceArray(2 downTo 1))
|
||||||
assertArrayNotSameButEquals(longArrayOf(100L, 200L, 30L), longArrayOf(50L, 100L, 200L, 30L).sliceArray(1..3))
|
assertArrayNotSameButEquals(longArrayOf(100L, 200L, 30L), longArrayOf(50L, 100L, 200L, 30L).sliceArray(1..3))
|
||||||
assertArrayNotSameButEquals(booleanArrayOf(true, false, true), booleanArrayOf(true, false, true, true).sliceArray(coll))
|
assertArrayNotSameButEquals(booleanArrayOf(true, false, true), booleanArrayOf(true, false, true, true).sliceArray(coll))
|
||||||
|
|
||||||
|
for (range in listOf(-1 until 0, 0 until 2, 2..2)) {
|
||||||
|
val bounds = "range: $range"
|
||||||
|
val exClass = IndexOutOfBoundsException::class
|
||||||
|
assertFailsWith(exClass, bounds) { arrayOf("x").sliceArray(range) }
|
||||||
|
assertFailsWith(exClass, bounds) { intArrayOf(1).sliceArray(range) }
|
||||||
|
assertFailsWith(exClass, bounds) { longArrayOf(1L).sliceArray(range) }
|
||||||
|
assertFailsWith(exClass, bounds) { charArrayOf('C').sliceArray(range) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun iterators() {
|
@Test fun iterators() {
|
||||||
@@ -738,6 +756,7 @@ class ArraysTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test fun copyOfRange() {
|
@Test fun copyOfRange() {
|
||||||
|
assertArrayNotSameButEquals(arrayOf("b", "c"), arrayOf("a", "b", "c").copyOfRange(1, 3))
|
||||||
assertArrayNotSameButEquals(booleanArrayOf(true, false, true), booleanArrayOf(true, false, true, true).copyOfRange(0, 3))
|
assertArrayNotSameButEquals(booleanArrayOf(true, false, true), booleanArrayOf(true, false, true, true).copyOfRange(0, 3))
|
||||||
assertArrayNotSameButEquals(byteArrayOf(0, 1, 2), byteArrayOf(0, 1, 2, 3, 4, 5).copyOfRange(0, 3))
|
assertArrayNotSameButEquals(byteArrayOf(0, 1, 2), byteArrayOf(0, 1, 2, 3, 4, 5).copyOfRange(0, 3))
|
||||||
assertArrayNotSameButEquals(shortArrayOf(0, 1, 2), shortArrayOf(0, 1, 2, 3, 4, 5).copyOfRange(0, 3))
|
assertArrayNotSameButEquals(shortArrayOf(0, 1, 2), shortArrayOf(0, 1, 2, 3, 4, 5).copyOfRange(0, 3))
|
||||||
@@ -746,6 +765,22 @@ class ArraysTest {
|
|||||||
assertArrayNotSameButEquals(floatArrayOf(0F, 1F, 2F), floatArrayOf(0F, 1F, 2F, 3F, 4F, 5F).copyOfRange(0, 3))
|
assertArrayNotSameButEquals(floatArrayOf(0F, 1F, 2F), floatArrayOf(0F, 1F, 2F, 3F, 4F, 5F).copyOfRange(0, 3))
|
||||||
assertArrayNotSameButEquals(doubleArrayOf(0.0, 1.0, 2.0), doubleArrayOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0).copyOfRange(0, 3))
|
assertArrayNotSameButEquals(doubleArrayOf(0.0, 1.0, 2.0), doubleArrayOf(0.0, 1.0, 2.0, 3.0, 4.0, 5.0).copyOfRange(0, 3))
|
||||||
assertArrayNotSameButEquals(charArrayOf('0', '1', '2'), charArrayOf('0', '1', '2', '3', '4', '5').copyOfRange(0, 3))
|
assertArrayNotSameButEquals(charArrayOf('0', '1', '2'), charArrayOf('0', '1', '2', '3', '4', '5').copyOfRange(0, 3))
|
||||||
|
|
||||||
|
for (pos in 0..3) {
|
||||||
|
assertArrayNotSameButEquals(emptyArray(), arrayOf("a", "b", "c").copyOfRange(pos, pos))
|
||||||
|
assertArrayNotSameButEquals(intArrayOf(), intArrayOf(1, 2, 3).copyOfRange(pos, pos))
|
||||||
|
assertArrayNotSameButEquals(charArrayOf(), charArrayOf('a', 'b', 'c').copyOfRange(pos, pos))
|
||||||
|
assertArrayNotSameButEquals(longArrayOf(), LongArray(3) { it.toLong() }.copyOfRange(pos, pos))
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((start, end) in listOf(-1 to 0, 0 to 2, 2 to 2, 1 to 0)) {
|
||||||
|
val bounds = "start: $start, end: $end"
|
||||||
|
val exClass = if (start > end) IllegalArgumentException::class else IndexOutOfBoundsException::class
|
||||||
|
assertFailsWith(exClass, bounds) { arrayOf("x").copyOfRange(start, end) }
|
||||||
|
assertFailsWith(exClass, bounds) { intArrayOf(1).copyOfRange(start, end) }
|
||||||
|
assertFailsWith(exClass, bounds) { longArrayOf(1L).copyOfRange(start, end) }
|
||||||
|
assertFailsWith(exClass, bounds) { charArrayOf('C').copyOfRange(start, end) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,9 @@ class ListSpecificTest {
|
|||||||
@Test
|
@Test
|
||||||
fun slice() {
|
fun slice() {
|
||||||
val list = listOf('A', 'B', 'C', 'D')
|
val list = listOf('A', 'B', 'C', 'D')
|
||||||
|
|
||||||
|
assertEquals(emptyList(), list.slice(IntRange.EMPTY))
|
||||||
|
|
||||||
// ABCD
|
// ABCD
|
||||||
// 0123
|
// 0123
|
||||||
assertEquals(listOf('B', 'C', 'D'), list.slice(1..3))
|
assertEquals(listOf('B', 'C', 'D'), list.slice(1..3))
|
||||||
@@ -33,6 +36,13 @@ class ListSpecificTest {
|
|||||||
|
|
||||||
val iter = listOf(2, 0, 3)
|
val iter = listOf(2, 0, 3)
|
||||||
assertEquals(listOf('C', 'A', 'D'), list.slice(iter))
|
assertEquals(listOf('C', 'A', 'D'), list.slice(iter))
|
||||||
|
|
||||||
|
for (range in listOf(-1 until 0, 0 until 2, 2..2)) {
|
||||||
|
val bounds = "range: $range"
|
||||||
|
val exClass = IndexOutOfBoundsException::class
|
||||||
|
assertFailsWith(exClass, bounds) { listOf("x").slice(range) }
|
||||||
|
assertFailsWith(exClass, bounds) { listOf("x").slice(range.asIterable()) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
+9
@@ -1142,6 +1142,15 @@ public final class kotlin/collections/ArraysKt {
|
|||||||
public static final fun contains ([Ljava/lang/Object;Ljava/lang/Object;)Z
|
public static final fun contains ([Ljava/lang/Object;Ljava/lang/Object;)Z
|
||||||
public static final fun contains ([SS)Z
|
public static final fun contains ([SS)Z
|
||||||
public static final fun contains ([ZZ)Z
|
public static final fun contains ([ZZ)Z
|
||||||
|
public static final fun copyOfRange ([BII)[B
|
||||||
|
public static final fun copyOfRange ([CII)[C
|
||||||
|
public static final fun copyOfRange ([DII)[D
|
||||||
|
public static final fun copyOfRange ([FII)[F
|
||||||
|
public static final fun copyOfRange ([III)[I
|
||||||
|
public static final fun copyOfRange ([JII)[J
|
||||||
|
public static final fun copyOfRange ([Ljava/lang/Object;II)[Ljava/lang/Object;
|
||||||
|
public static final fun copyOfRange ([SII)[S
|
||||||
|
public static final fun copyOfRange ([ZII)[Z
|
||||||
public static final fun count ([BLkotlin/jvm/functions/Function1;)I
|
public static final fun count ([BLkotlin/jvm/functions/Function1;)I
|
||||||
public static final fun count ([CLkotlin/jvm/functions/Function1;)I
|
public static final fun count ([CLkotlin/jvm/functions/Function1;)I
|
||||||
public static final fun count ([DLkotlin/jvm/functions/Function1;)I
|
public static final fun count ([DLkotlin/jvm/functions/Function1;)I
|
||||||
|
|||||||
@@ -370,11 +370,34 @@ object ArrayOps : TemplateGroupBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val f_copyOfRangeJvmImpl = fn("copyOfRangeImpl(fromIndex: Int, toIndex: Int)") {
|
||||||
|
include(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||||
|
platforms(Platform.JVM)
|
||||||
|
} builderWith { primitive ->
|
||||||
|
since("1.3")
|
||||||
|
visibility("internal")
|
||||||
|
annotation("@PublishedApi")
|
||||||
|
annotation("""@JvmName("copyOfRange")""")
|
||||||
|
returns("SELF")
|
||||||
|
body {
|
||||||
|
"""
|
||||||
|
copyOfRangeToIndexCheck(toIndex, size)
|
||||||
|
return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val f_copyOfRange = fn("copyOfRange(fromIndex: Int, toIndex: Int)") {
|
val f_copyOfRange = fn("copyOfRange(fromIndex: Int, toIndex: Int)") {
|
||||||
include(InvariantArraysOfObjects, ArraysOfPrimitives)
|
include(InvariantArraysOfObjects, ArraysOfPrimitives)
|
||||||
} builderWith { primitive ->
|
} builderWith { primitive ->
|
||||||
doc { "Returns new array which is a copy of range of original array." }
|
doc {
|
||||||
|
"""
|
||||||
|
Returns a new array which is a copy of the specified range of the original array.
|
||||||
|
|
||||||
|
@param fromIndex the start of the range (inclusive), must be in `0..array.size`
|
||||||
|
@param toIndex the end of the range (exclusive), must be in `fromIndex..array.size`
|
||||||
|
"""
|
||||||
|
}
|
||||||
returns("SELF")
|
returns("SELF")
|
||||||
|
|
||||||
on(Platform.JS) {
|
on(Platform.JS) {
|
||||||
@@ -383,18 +406,29 @@ object ArrayOps : TemplateGroupBase() {
|
|||||||
suppress("ACTUAL_WITHOUT_EXPECT") // TODO: KT-21937
|
suppress("ACTUAL_WITHOUT_EXPECT") // TODO: KT-21937
|
||||||
returns("Array<T>")
|
returns("Array<T>")
|
||||||
}
|
}
|
||||||
when(primitive) {
|
val rangeCheck = "AbstractList.checkRangeIndexes(fromIndex, toIndex, size)"
|
||||||
|
when (primitive) {
|
||||||
PrimitiveType.Char, PrimitiveType.Boolean, PrimitiveType.Long ->
|
PrimitiveType.Char, PrimitiveType.Boolean, PrimitiveType.Long ->
|
||||||
body { "return withType(\"${primitive}Array\", this.asDynamic().slice(fromIndex, toIndex))" }
|
body { "return withType(\"${primitive}Array\", this.asDynamic().slice(fromIndex, toIndex))" }
|
||||||
else -> {
|
else -> {
|
||||||
inline(suppressWarning = true)
|
|
||||||
body { "return this.asDynamic().slice(fromIndex, toIndex)" }
|
body { "return this.asDynamic().slice(fromIndex, toIndex)" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
body { rangeCheck + "\n" + body }
|
||||||
}
|
}
|
||||||
on(Platform.JVM) {
|
on(Platform.JVM) {
|
||||||
|
annotation("""@JvmName("copyOfRangeInline")""")
|
||||||
inlineOnly()
|
inlineOnly()
|
||||||
body { "return java.util.Arrays.copyOfRange(this, fromIndex, toIndex)" }
|
body {
|
||||||
|
"""
|
||||||
|
return if (kotlin.internal.apiVersionIsAtLeast(1, 3, 0)) {
|
||||||
|
copyOfRangeImpl(fromIndex, toIndex)
|
||||||
|
} else {
|
||||||
|
if (toIndex > size) throw IndexOutOfBoundsException("toIndex: ${'$'}toIndex, size: ${'$'}size")
|
||||||
|
java.util.Arrays.copyOfRange(this, fromIndex, toIndex)
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
on(Platform.Common) {
|
on(Platform.Common) {
|
||||||
specialFor(InvariantArraysOfObjects) {
|
specialFor(InvariantArraysOfObjects) {
|
||||||
|
|||||||
Reference in New Issue
Block a user