1 /*
<lambda>null2  * Copyright (C) 2023 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 com.android.server.permission.access.immutable
18 
19 inline fun <K, V> IndexedMap<K, V>.allIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
20     forEachIndexed { index, key, value ->
21         if (!predicate(index, key, value)) {
22             return false
23         }
24     }
25     return true
26 }
27 
anyIndexednull28 inline fun <K, V> IndexedMap<K, V>.anyIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
29     forEachIndexed { index, key, value ->
30         if (predicate(index, key, value)) {
31             return true
32         }
33     }
34     return false
35 }
36 
firstNotNullOfOrNullIndexednull37 inline fun <K, V, R> IndexedMap<K, V>.firstNotNullOfOrNullIndexed(transform: (Int, K, V) -> R): R? {
38     forEachIndexed { index, key, value ->
39         transform(index, key, value)?.let {
40             return it
41         }
42     }
43     return null
44 }
45 
forEachIndexednull46 inline fun <K, V> IndexedMap<K, V>.forEachIndexed(action: (Int, K, V) -> Unit) {
47     for (index in 0 until size) {
48         action(index, keyAt(index), valueAt(index))
49     }
50 }
51 
forEachReversedIndexednull52 inline fun <K, V> IndexedMap<K, V>.forEachReversedIndexed(action: (Int, K, V) -> Unit) {
53     for (index in lastIndex downTo 0) {
54         action(index, keyAt(index), valueAt(index))
55     }
56 }
57 
getWithDefaultnull58 fun <K, V> IndexedMap<K, V>?.getWithDefault(key: K, defaultValue: V): V {
59     this ?: return defaultValue
60     val index = indexOfKey(key)
61     return if (index >= 0) valueAt(index) else defaultValue
62 }
63 
64 inline val <K, V> IndexedMap<K, V>.lastIndex: Int
65     get() = size - 1
66 
noneIndexednull67 inline fun <K, V> IndexedMap<K, V>.noneIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
68     forEachIndexed { index, key, value ->
69         if (predicate(index, key, value)) {
70             return false
71         }
72     }
73     return true
74 }
75 
mapIndexedTonull76 inline fun <K, V, R, C : MutableCollection<R>> IndexedMap<K, V>.mapIndexedTo(
77     destination: C,
78     transform: (Int, K, V) -> R,
79 ): C {
80     forEachIndexed { index, key, value -> transform(index, key, value).let { destination += it } }
81     return destination
82 }
83 
mapNotNullIndexedTonull84 inline fun <K, V, R, C : MutableCollection<R>> IndexedMap<K, V>.mapNotNullIndexedTo(
85     destination: C,
86     transform: (Int, K, V) -> R?
87 ): C {
88     forEachIndexed { index, key, value -> transform(index, key, value)?.let { destination += it } }
89     return destination
90 }
91 
getOrPutnull92 inline fun <K, V> MutableIndexedMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
93     get(key)?.let {
94         return it
95     }
96     return defaultValue().also { put(key, it) }
97 }
98 
99 @Suppress("NOTHING_TO_INLINE")
minusAssignnull100 inline operator fun <K, V> MutableIndexedMap<K, V>.minusAssign(key: K) {
101     remove(key)
102 }
103 
putWithDefaultnull104 fun <K, V> MutableIndexedMap<K, V>.putWithDefault(key: K, value: V, defaultValue: V): V {
105     val index = indexOfKey(key)
106     if (index >= 0) {
107         val oldValue = valueAt(index)
108         if (value != oldValue) {
109             if (value == defaultValue) {
110                 removeAt(index)
111             } else {
112                 putAt(index, value)
113             }
114         }
115         return oldValue
116     } else {
117         if (value != defaultValue) {
118             put(key, value)
119         }
120         return defaultValue
121     }
122 }
123 
124 @Suppress("NOTHING_TO_INLINE")
setnull125 inline operator fun <K, V> MutableIndexedMap<K, V>.set(key: K, value: V) {
126     put(key, value)
127 }
128