stdlib: Rewrite deep content operations for Arrays
This commit is contained in:
@@ -11450,36 +11450,44 @@ public inline fun <T> Array<out T>.subarrayContentToString(offset: Int, length:
|
|||||||
*/
|
*/
|
||||||
@SinceKotlin("1.1")
|
@SinceKotlin("1.1")
|
||||||
public infix fun <T> Array<out T>.contentDeepEquals(other: Array<out T>): Boolean {
|
public infix fun <T> Array<out T>.contentDeepEquals(other: Array<out T>): Boolean {
|
||||||
if (this === other)
|
if (this === other) {
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
if (size != other.size)
|
if (this.size != other.size) {
|
||||||
return false
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
for (i in indices) {
|
for (i in indices) {
|
||||||
val e1 = this[i]
|
val v1 = this[i]
|
||||||
val e2 = other[i]
|
val v2 = other[i]
|
||||||
|
|
||||||
if (e1 === e2)
|
if (v1 == null || v2 == null) {
|
||||||
continue
|
if (v1 == v2) {
|
||||||
if (e1 == null)
|
continue
|
||||||
return false
|
} else {
|
||||||
|
return false
|
||||||
// Figure out whether the two elements are equal
|
}
|
||||||
val eq = when {
|
}
|
||||||
e1 is Array<*> && e2 is Array<*> -> e1 contentDeepEquals e2
|
|
||||||
e1 is ByteArray && e2 is ByteArray -> e1 contentEquals e2
|
// TODO: Do a typecheck like if(v1.class == v2.class) return false
|
||||||
e1 is ShortArray && e2 is ShortArray -> e1 contentEquals e2
|
// Cases:
|
||||||
e1 is IntArray && e2 is IntArray -> e1 contentEquals e2
|
// Array<T>
|
||||||
e1 is LongArray && e2 is LongArray -> e1 contentEquals e2
|
// Primitive array
|
||||||
e1 is CharArray && e2 is CharArray -> e1 contentEquals e2
|
// Some value (not an array)
|
||||||
e1 is FloatArray && e2 is FloatArray -> e1 contentEquals e2
|
|
||||||
e1 is DoubleArray && e2 is DoubleArray -> e1 contentEquals e2
|
when {
|
||||||
e1 is BooleanArray && e2 is BooleanArray -> e1 contentEquals e2
|
v1 is Array<*> && v2 is Array<*> -> if (!v1.contentDeepEquals(v2)) return false
|
||||||
else -> e1 == e2
|
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
|
||||||
|
else -> if (v1 != v2) return false
|
||||||
}
|
}
|
||||||
if (!eq)
|
|
||||||
return false
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -11515,56 +11523,42 @@ public fun <T> Array<out T>.contentDeepHashCode(): Int {
|
|||||||
*/
|
*/
|
||||||
@SinceKotlin("1.1")
|
@SinceKotlin("1.1")
|
||||||
public fun <T> Array<out T>.contentDeepToString(): String {
|
public fun <T> Array<out T>.contentDeepToString(): String {
|
||||||
var bufLen = 20 * size
|
val length = if (size * 5 + 2 > 0) size * 5 + 2 else Int.MAX_VALUE
|
||||||
if (size != 0 && bufLen <= 0)
|
val result = StringBuilder(length)
|
||||||
bufLen = Int.MAX_VALUE
|
contentDeepToStringInternal(result, mutableSetOf())
|
||||||
val buf = StringBuilder(bufLen)
|
return result.toString()
|
||||||
contentDeepToString(buf, mutableSetOf())
|
|
||||||
return buf.toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private fun <T> Array<out T>.contentDeepToStringInternal(result: StringBuilder, processed: MutableSet<Array<*>>) {
|
||||||
* Internal recursive function to build a string for [contentDeepToString].
|
if (this in processed) {
|
||||||
*/
|
result.append("[...]")
|
||||||
private fun <T> Array<out T>.contentDeepToString(buf: StringBuilder, dejaVu: MutableSet<Array<Any?>>) {
|
|
||||||
if (size == 0) {
|
|
||||||
buf.append("[]")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
processed.add(this)
|
||||||
|
result.append('[')
|
||||||
|
|
||||||
val iMax = size - 1
|
for (i in indices) {
|
||||||
@Suppress("UNCHECKED_CAST")
|
if (i != 0) {
|
||||||
dejaVu.add(this as Array<Any?>) // TODO: Is the cast correct?
|
result.append(", ")
|
||||||
buf.append('[')
|
}
|
||||||
var i = 0
|
val element = this[i]
|
||||||
while (true) {
|
when (element) {
|
||||||
val element = this[i]
|
null -> result.append("null")
|
||||||
when {
|
is Array<*> -> element.contentDeepToStringInternal(result, processed)
|
||||||
element is Array<*> -> {
|
is ByteArray -> result.append(element.contentToString())
|
||||||
@Suppress("UNCHECKED_CAST")
|
is ShortArray -> result.append(element.contentToString())
|
||||||
if (dejaVu.contains(element as Array<Any?>)) {
|
is IntArray -> result.append(element.contentToString())
|
||||||
buf.append("[...]")
|
is LongArray -> result.append(element.contentToString())
|
||||||
} else {
|
is FloatArray -> result.append(element.contentToString())
|
||||||
element.contentDeepToString(buf, dejaVu)
|
is DoubleArray -> result.append(element.contentToString())
|
||||||
}
|
is CharArray -> result.append(element.contentToString())
|
||||||
}
|
is BooleanArray -> result.append(element.contentToString())
|
||||||
element is ByteArray -> buf.append(element.contentToString())
|
else -> result.append(element.toString())
|
||||||
element is ShortArray -> buf.append(element.contentToString())
|
|
||||||
element is IntArray -> buf.append(element.contentToString())
|
|
||||||
element is LongArray -> buf.append(element.contentToString())
|
|
||||||
element is CharArray -> buf.append(element.contentToString())
|
|
||||||
element is FloatArray -> buf.append(element.contentToString())
|
|
||||||
element is DoubleArray -> buf.append(element.contentToString())
|
|
||||||
element is BooleanArray -> buf.append(element.contentToString())
|
|
||||||
else -> buf.append(element.toString())
|
|
||||||
}
|
}
|
||||||
if (i == iMax)
|
|
||||||
break
|
|
||||||
buf.append(", ")
|
|
||||||
i++
|
|
||||||
}
|
}
|
||||||
buf.append(']')
|
|
||||||
dejaVu.remove(this)
|
result.append(']')
|
||||||
|
processed.remove(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user