copyInto: copying elements between two arrays

#KT-25874 Fixed
This commit is contained in:
Ilya Gorbunov
2018-08-21 08:56:17 +03:00
parent 58e6f910bc
commit ea37a65178
8 changed files with 900 additions and 0 deletions
@@ -407,6 +407,222 @@ public actual fun CharArray.contentToString(): String {
definedExternally
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun <T> Array<out T>.copyInto(destination: Array<T>, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): Array<T> {
arrayCopy(this, destination, destinationOffset, startIndex, endIndex)
return destination
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun ByteArray.copyInto(destination: ByteArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): ByteArray {
arrayCopy(this.unsafeCast<Array<Byte>>(), destination.unsafeCast<Array<Byte>>(), destinationOffset, startIndex, endIndex)
return destination
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun ShortArray.copyInto(destination: ShortArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): ShortArray {
arrayCopy(this.unsafeCast<Array<Short>>(), destination.unsafeCast<Array<Short>>(), destinationOffset, startIndex, endIndex)
return destination
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun IntArray.copyInto(destination: IntArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): IntArray {
arrayCopy(this.unsafeCast<Array<Int>>(), destination.unsafeCast<Array<Int>>(), destinationOffset, startIndex, endIndex)
return destination
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun LongArray.copyInto(destination: LongArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): LongArray {
arrayCopy(this.unsafeCast<Array<Long>>(), destination.unsafeCast<Array<Long>>(), destinationOffset, startIndex, endIndex)
return destination
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun FloatArray.copyInto(destination: FloatArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): FloatArray {
arrayCopy(this.unsafeCast<Array<Float>>(), destination.unsafeCast<Array<Float>>(), destinationOffset, startIndex, endIndex)
return destination
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun DoubleArray.copyInto(destination: DoubleArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): DoubleArray {
arrayCopy(this.unsafeCast<Array<Double>>(), destination.unsafeCast<Array<Double>>(), destinationOffset, startIndex, endIndex)
return destination
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun BooleanArray.copyInto(destination: BooleanArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): BooleanArray {
arrayCopy(this.unsafeCast<Array<Boolean>>(), destination.unsafeCast<Array<Boolean>>(), destinationOffset, startIndex, endIndex)
return destination
}
/**
* Copies this array or its subrange into the [destination] array and returns that array.
*
* It's allowed to pass the same array in the [destination] and even specify the subrange so that it overlaps with the destination range.
*
* @param destination the array to copy to.
* @param destinationOffset the position in the [destination] array to copy to, 0 by default.
* @param startIndex the beginning (inclusive) of the subrange to copy, 0 by default.
* @param endIndex the end (exclusive) of the subrange to copy, size of this array by default.
*
* @throws IndexOutOfBoundsException or [IllegalArgumentException] when [startIndex] or [endIndex] is out of range of this array indices or when `startIndex > endIndex`.
* @throws IndexOutOfBoundsException when the subrange doesn't fit into the [destination] array starting at the specified [destinationIndex],
* or when that index is out of the [destination] array indices range.
*
* @return the [destination] array.
*/
@SinceKotlin("1.3")
@kotlin.internal.InlineOnly
@Suppress("ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS")
public actual inline fun CharArray.copyInto(destination: CharArray, destinationOffset: Int = 0, startIndex: Int = 0, endIndex: Int = size): CharArray {
arrayCopy(this.unsafeCast<Array<Char>>(), destination.unsafeCast<Array<Char>>(), destinationOffset, startIndex, endIndex)
return destination
}
/**
* Returns new array which is a copy of the original array.
*
@@ -126,6 +126,27 @@ internal actual fun <T> arrayOfNulls(reference: Array<T>, size: Int): Array<T> {
return arrayOfNulls<Any>(size).unsafeCast<Array<T>>()
}
@SinceKotlin("1.3")
@PublishedApi
@JsName("arrayCopy")
internal fun <T> arrayCopy(source: Array<out T>, destination: Array<in T>, destinationOffset: Int, startIndex: Int, endIndex: Int) {
@Suppress("NAME_SHADOWING")
val endIndex = if (endIndex == -1) source.size else endIndex // TODO: Remove when default value from expect is fixed
AbstractList.checkRangeIndexes(startIndex, endIndex, source.size)
val rangeSize = endIndex - startIndex
AbstractList.checkRangeIndexes(destinationOffset, destinationOffset + rangeSize, destination.size)
if (source !== destination || destinationOffset <= startIndex) {
for (index in 0 until rangeSize) {
destination[destinationOffset + index] = source[startIndex + index]
}
} else {
for (index in rangeSize - 1 downTo 0) {
destination[destinationOffset + index] = source[startIndex + index]
}
}
}
// no singleton map implementation in js, return map as is
@Suppress("NOTHING_TO_INLINE")
internal actual inline fun <K, V> Map<K, V>.toSingletonMapOrSelf(): Map<K, V> = this