Inline findAnyOf(chars) into indexOfAny/lastIndexOfAny

This helps to reduce allocation count

#KT-22042
This commit is contained in:
Ilya Gorbunov
2018-01-23 21:24:27 +03:00
parent 923d9f03fc
commit 2da9f12bc5
+30 -23
View File
@@ -800,24 +800,6 @@ public fun CharSequence.commonSuffixWith(other: CharSequence, ignoreCase: Boolea
// indexOfAny()
private fun CharSequence.findAnyOf(chars: CharArray, startIndex: Int, ignoreCase: Boolean, last: Boolean): Pair<Int, Char>? {
if (!ignoreCase && chars.size == 1 && this is String) {
val char = chars.single()
val index = if (!last) nativeIndexOf(char, startIndex) else nativeLastIndexOf(char, startIndex)
return if (index < 0) null else index to char
}
val indices = if (!last) startIndex.coerceAtLeast(0)..lastIndex else startIndex.coerceAtMost(lastIndex) downTo 0
for (index in indices) {
val charAtIndex = get(index)
val matchingCharIndex = chars.indexOfFirst { it.equals(charAtIndex, ignoreCase) }
if (matchingCharIndex >= 0)
return index to chars[matchingCharIndex]
}
return null
}
/**
* Finds the index of the first occurrence of any of the specified [chars] in this char sequence,
* starting from the specified [startIndex] and optionally ignoring the case.
@@ -826,8 +808,19 @@ private fun CharSequence.findAnyOf(chars: CharArray, startIndex: Int, ignoreCase
* @returns An index of the first occurrence of matched character from [chars] or -1 if none of [chars] are found.
*
*/
public fun CharSequence.indexOfAny(chars: CharArray, startIndex: Int = 0, ignoreCase: Boolean = false): Int =
findAnyOf(chars, startIndex, ignoreCase, last = false)?.first ?: -1
public fun CharSequence.indexOfAny(chars: CharArray, startIndex: Int = 0, ignoreCase: Boolean = false): Int {
if (!ignoreCase && chars.size == 1 && this is String) {
val char = chars.single()
return nativeIndexOf(char, startIndex)
}
for (index in startIndex.coerceAtLeast(0)..lastIndex) {
val charAtIndex = get(index)
if (chars.any { it.equals(charAtIndex, ignoreCase) })
return index
}
return -1
}
/**
* Finds the index of the last occurrence of any of the specified [chars] in this char sequence,
@@ -838,8 +831,21 @@ public fun CharSequence.indexOfAny(chars: CharArray, startIndex: Int = 0, ignore
* @returns An index of the last occurrence of matched character from [chars] or -1 if none of [chars] are found.
*
*/
public fun CharSequence.lastIndexOfAny(chars: CharArray, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Int =
findAnyOf(chars, startIndex, ignoreCase, last = true)?.first ?: -1
public fun CharSequence.lastIndexOfAny(chars: CharArray, startIndex: Int = lastIndex, ignoreCase: Boolean = false): Int {
if (!ignoreCase && chars.size == 1 && this is String) {
val char = chars.single()
return nativeLastIndexOf(char, startIndex)
}
for (index in startIndex.coerceAtMost(lastIndex) downTo 0) {
val charAtIndex = get(index)
if (chars.any { it.equals(charAtIndex, ignoreCase) })
return index
}
return -1
}
private fun CharSequence.indexOf(other: CharSequence, startIndex: Int, endIndex: Int, ignoreCase: Boolean, last: Boolean = false): Int {
@@ -1109,7 +1115,8 @@ private class DelimitedRangesSequence(private val input: CharSequence, private v
private fun CharSequence.rangesDelimitedBy(delimiters: CharArray, startIndex: Int = 0, ignoreCase: Boolean = false, limit: Int = 0): Sequence<IntRange> {
require(limit >= 0, { "Limit must be non-negative, but was $limit." })
return DelimitedRangesSequence(this, startIndex, limit, { startIndex -> findAnyOf(delimiters, startIndex, ignoreCase = ignoreCase, last = false)?.let { it.first to 1 } })
return DelimitedRangesSequence(this, startIndex, limit, { startIndex ->
indexOfAny(delimiters, startIndex, ignoreCase = ignoreCase).let { if (it < 0) null else it to 1 } })
}