commonMain.androidx.compose.runtime.snapshots.ListUtils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of runtime Show documentation
Show all versions of runtime Show documentation
Tree composition support for code generated by the Compose compiler plugin and corresponding public API
The newest version!
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.runtime.snapshots
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
/**
* Iterates through a [List] using the index and calls [action] for each item.
* This does not allocate an iterator like [Iterable.forEach].
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@Suppress("BanInlineOptIn") // Treat Kotlin Contracts as non-experimental.
@OptIn(ExperimentalContracts::class)
internal inline fun List.fastForEach(action: (T) -> Unit) {
contract { callsInPlace(action) }
for (index in indices) {
val item = get(index)
action(item)
}
}
/**
* Returns a [Set] of all elements.
*
* The returned set preserves the element iteration order of the original collection.
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
internal fun List.fastToSet(): Set = HashSet(size).also { set ->
fastForEach { item -> set.add(item) }
}
/**
* Iterates through a [List] using the index and calls [action] for each item.
* This does not allocate an iterator like [Iterable.forEachIndexed].
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@Suppress("BanInlineOptIn") // Treat Kotlin Contracts as non-experimental.
@OptIn(ExperimentalContracts::class)
internal inline fun List.fastForEachIndexed(action: (Int, T) -> Unit) {
contract { callsInPlace(action) }
for (index in indices) {
val item = get(index)
action(index, item)
}
}
/**
* Returns a list containing the results of applying the given [transform] function
* to each element in the original collection.
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@Suppress("BanInlineOptIn") // Treat Kotlin Contracts as non-experimental.
@OptIn(ExperimentalContracts::class)
internal inline fun List.fastMap(transform: (T) -> R): List {
contract { callsInPlace(transform) }
val target = ArrayList(size)
fastForEach {
target += transform(it)
}
return target
}
@Suppress("BanInlineOptIn") // Treat Kotlin Contracts as non-experimental.
@OptIn(ExperimentalContracts::class)
internal inline fun List.fastAny(predicate: (T) -> Boolean): Boolean {
contract { callsInPlace(predicate) }
fastForEach {
if (predicate(it)) return true
}
return false
}
/**
* Returns `true` if all elements match the given [predicate].
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@Suppress("BanInlineOptIn") // Treat Kotlin Contracts as non-experimental.
@OptIn(ExperimentalContracts::class)
internal inline fun List.fastAll(predicate: (T) -> Boolean): Boolean {
contract { callsInPlace(predicate) }
fastForEach { if (!predicate(it)) return false }
return true
}
@Suppress("BanInlineOptIn") // Treat Kotlin Contracts as non-experimental.
@OptIn(ExperimentalContracts::class)
internal inline fun List.fastGroupBy(
keySelector: (T) -> K
): Map> {
contract { callsInPlace(keySelector) }
val destination = HashMap>(size)
fastForEach {
val key = keySelector(it)
val list = destination.getOrPut(key) { ArrayList() }
list.add(it)
}
return destination
}
/**
* Creates a string from all the elements separated using [separator] and using the given [prefix]
* and [postfix] if supplied.
*
* If the collection could be huge, you can specify a non-negative value of [limit], in which case
* only the first [limit] elements will be appended, followed by the [truncated] string (which
* defaults to "...").
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
internal fun List.fastJoinToString(
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((T) -> CharSequence)? = null
): String {
return fastJoinTo(StringBuilder(), separator, prefix, postfix, limit, truncated, transform)
.toString()
}
/**
* Appends the string from all the elements separated using [separator] and using the given
* [prefix] and [postfix] if supplied.
*
* If the collection could be huge, you can specify a non-negative value of [limit], in which
* case only the first [limit] elements will be appended, followed by the [truncated] string
* (which defaults to "...").
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
private fun List.fastJoinTo(
buffer: A,
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((T) -> CharSequence)? = null
): A {
buffer.append(prefix)
var count = 0
for (index in indices) {
val element = get(index)
if (++count > 1) buffer.append(separator)
if (limit < 0 || count <= limit) {
buffer.appendElement(element, transform)
} else break
}
if (limit >= 0 && count > limit) buffer.append(truncated)
buffer.append(postfix)
return buffer
}
/**
* Copied from Appendable.kt
*/
private fun Appendable.appendElement(element: T, transform: ((T) -> CharSequence)?) {
when {
transform != null -> append(transform(element))
element is CharSequence? -> append(element)
element is Char -> append(element)
else -> append(element.toString())
}
}
/**
* Returns a list containing the results of applying the given [transform] function
* to each element in the original collection.
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@Suppress("BanInlineOptIn") // Treat Kotlin Contracts as non-experimental.
@OptIn(ExperimentalContracts::class)
internal inline fun List.fastMapNotNull(transform: (T) -> R?): List {
contract { callsInPlace(transform) }
val target = ArrayList(size)
fastForEach { e ->
transform(e)?.let { target += it }
}
return target
}
/**
* Returns a list containing only elements matching the given [predicate].
* @param [predicate] function that takes the index of an element and the element itself
* and returns the result of predicate evaluation on the element.
*
* **Do not use for collections that come from public APIs**, since they may not support random
* access in an efficient way, and this method may actually be a lot slower. Only use for
* collections that are created by code we control and are known to support random access.
*/
@Suppress("BanInlineOptIn") // Treat Kotlin Contracts as non-experimental.
@OptIn(ExperimentalContracts::class)
internal inline fun List.fastFilterIndexed(predicate: (index: Int, T) -> Boolean): List {
contract { callsInPlace(predicate) }
val target = ArrayList(size)
fastForEachIndexed { index, e ->
if (predicate(index, e)) target += e
}
return target
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy