Specialize contentDeepEquals/HashCode/ToString for arrays of unsigned types
#KT-26388
This commit is contained in:
@@ -65,3 +65,95 @@ public inline fun Array<*>?.isNullOrEmpty(): Boolean {
|
||||
@Suppress("UPPER_BOUND_CANNOT_BE_ARRAY")
|
||||
public inline fun <C, R> C.ifEmpty(defaultValue: () -> R): R where C : Array<*>, C : R =
|
||||
if (isEmpty()) defaultValue() else this
|
||||
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
@PublishedApi
|
||||
@kotlin.jvm.JvmName("contentDeepEquals")
|
||||
@kotlin.js.JsName("contentDeepEqualsImpl")
|
||||
internal fun <T> Array<out T>.contentDeepEqualsImpl(other: Array<out T>): Boolean {
|
||||
if (this === other) return true
|
||||
if (this.size != other.size) return false
|
||||
|
||||
for (i in indices) {
|
||||
val v1 = this[i]
|
||||
val v2 = other[i]
|
||||
|
||||
if (v1 === v2) {
|
||||
continue
|
||||
} else if (v1 == null || v2 == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
when {
|
||||
v1 is Array<*> && v2 is Array<*> -> if (!v1.contentDeepEquals(v2)) return false
|
||||
v1 is ByteArray && v2 is ByteArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is ShortArray && v2 is ShortArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is IntArray && v2 is IntArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is LongArray && v2 is LongArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is FloatArray && v2 is FloatArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is DoubleArray && v2 is DoubleArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is CharArray && v2 is CharArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is BooleanArray && v2 is BooleanArray -> if (!v1.contentEquals(v2)) return false
|
||||
|
||||
v1 is UByteArray && v2 is UByteArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is UShortArray && v2 is UShortArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is UIntArray && v2 is UIntArray -> if (!v1.contentEquals(v2)) return false
|
||||
v1 is ULongArray && v2 is ULongArray -> if (!v1.contentEquals(v2)) return false
|
||||
|
||||
else -> if (v1 != v2) return false
|
||||
}
|
||||
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
@PublishedApi
|
||||
@kotlin.jvm.JvmName("contentDeepToString")
|
||||
@kotlin.js.JsName("contentDeepToStringImpl")
|
||||
internal fun <T> Array<out T>.contentDeepToStringImpl(): String {
|
||||
val length = size.coerceAtMost((Int.MAX_VALUE - 2) / 5) * 5 + 2 // in order not to overflow Int.MAX_VALUE
|
||||
return buildString(length) {
|
||||
contentDeepToStringInternal(this, mutableSetOf())
|
||||
}
|
||||
}
|
||||
|
||||
@UseExperimental(ExperimentalUnsignedTypes::class)
|
||||
private fun <T> Array<out T>.contentDeepToStringInternal(result: StringBuilder, processed: MutableSet<Array<*>>) {
|
||||
if (this in processed) {
|
||||
result.append("[...]")
|
||||
return
|
||||
}
|
||||
processed.add(this)
|
||||
result.append('[')
|
||||
|
||||
for (i in indices) {
|
||||
if (i != 0) {
|
||||
result.append(", ")
|
||||
}
|
||||
val element = this[i]
|
||||
when (element) {
|
||||
null -> result.append("null")
|
||||
is Array<*> -> element.contentDeepToStringInternal(result, processed)
|
||||
is ByteArray -> result.append(element.contentToString())
|
||||
is ShortArray -> result.append(element.contentToString())
|
||||
is IntArray -> result.append(element.contentToString())
|
||||
is LongArray -> result.append(element.contentToString())
|
||||
is FloatArray -> result.append(element.contentToString())
|
||||
is DoubleArray -> result.append(element.contentToString())
|
||||
is CharArray -> result.append(element.contentToString())
|
||||
is BooleanArray -> result.append(element.contentToString())
|
||||
|
||||
is UByteArray -> result.append(element.contentToString())
|
||||
is UShortArray -> result.append(element.contentToString())
|
||||
is UIntArray -> result.append(element.contentToString())
|
||||
is ULongArray -> result.append(element.contentToString())
|
||||
|
||||
else -> result.append(element.toString())
|
||||
}
|
||||
}
|
||||
|
||||
result.append(']')
|
||||
processed.remove(this)
|
||||
}
|
||||
Reference in New Issue
Block a user