1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.compose.runtime.collection
18 
19 import androidx.collection.MutableObjectList
20 import androidx.collection.ObjectList
21 
fastMapnull22 internal inline fun <T, R> ObjectList<T>.fastMap(transform: (T) -> R): ObjectList<R> {
23     val target = MutableObjectList<R>(size)
24     forEach { target += transform(it) }
25     return target
26 }
27 
fastFilternull28 internal inline fun <T> ObjectList<T>.fastFilter(predicate: (T) -> Boolean): ObjectList<T> {
29     if (all(predicate)) return this
30     val target = MutableObjectList<T>()
31     forEach { if (predicate(it)) target += it }
32     return target
33 }
34 
allnull35 internal inline fun <T> ObjectList<T>.all(predicate: (T) -> Boolean): Boolean {
36     forEach { if (!predicate(it)) return false }
37     return true
38 }
39 
toMutableObjectListnull40 internal fun <T> ObjectList<T>.toMutableObjectList(): MutableObjectList<T> {
41     val target = MutableObjectList<T>(size)
42     forEach { target += it }
43     return target
44 }
45 
sortedBynull46 internal fun <T, K : Comparable<K>> ObjectList<T>.sortedBy(selector: (T) -> K?): ObjectList<T> =
47     if (isSorted(selector)) this else toMutableObjectList().also { it.sortBy(selector) }
48 
isSortednull49 internal fun <T, K : Comparable<K>> ObjectList<T>.isSorted(selector: (T) -> K?): Boolean {
50     if (size <= 1) return true
51     val previousValue = get(0)
52     var previousKey = selector(previousValue) ?: return false
53     for (i in 1 until size) {
54         val value = get(i)
55         val key = selector(value) ?: return false
56         if (previousKey > key) return false
57         previousKey = key
58     }
59     return true
60 }
61 
sortBynull62 internal fun <T, K : Comparable<K>> MutableObjectList<T>.sortBy(selector: (T) -> K?) {
63     @Suppress("AsCollectionCall") // Needed to call sortBy
64     asMutableList().sortBy(selector)
65 }
66 
removeLastnull67 internal fun <T> MutableObjectList<T>.removeLast(): T {
68     if (isEmpty()) throw NoSuchElementException("List is empty.")
69     val last = size - 1
70     return this[last].also { removeAt(last) }
71 }
72