• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2021 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.collection
18 
19 import android.util.ArrayMap
20 
21 typealias IndexedMap<K, V> = ArrayMap<K, V>
22 
23 inline fun <K, V> IndexedMap<K, V>.allIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
24     forEachIndexed { index, key, value ->
25         if (!predicate(index, key, value)) {
26             return false
27         }
28     }
29     return true
30 }
31 
anyIndexednull32 inline fun <K, V> IndexedMap<K, V>.anyIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
33     forEachIndexed { index, key, value ->
34         if (predicate(index, key, value)) {
35             return true
36         }
37     }
38     return false
39 }
40 
copynull41 inline fun <K, V> IndexedMap<K, V>.copy(copyValue: (V) -> V): IndexedMap<K, V> =
42     IndexedMap(this).apply {
43         forEachValueIndexed { index, value ->
44             setValueAt(index, copyValue(value))
45         }
46     }
47 
firstNotNullOfOrNullIndexednull48 inline fun <K, V, R> IndexedMap<K, V>.firstNotNullOfOrNullIndexed(transform: (Int, K, V) -> R): R? {
49     forEachIndexed { index, key, value ->
50         transform(index, key, value)?.let { return it }
51     }
52     return null
53 }
54 
forEachIndexednull55 inline fun <K, V> IndexedMap<K, V>.forEachIndexed(action: (Int, K, V) -> Unit) {
56     for (index in 0 until size) {
57         action(index, keyAt(index), valueAt(index))
58     }
59 }
60 
forEachKeyIndexednull61 inline fun <K, V> IndexedMap<K, V>.forEachKeyIndexed(action: (Int, K) -> Unit) {
62     for (index in 0 until size) {
63         action(index, keyAt(index))
64     }
65 }
66 
forEachReversedIndexednull67 inline fun <K, V> IndexedMap<K, V>.forEachReversedIndexed(action: (Int, K, V) -> Unit) {
68     for (index in lastIndex downTo 0) {
69         action(index, keyAt(index), valueAt(index))
70     }
71 }
72 
forEachValueIndexednull73 inline fun <K, V> IndexedMap<K, V>.forEachValueIndexed(action: (Int, V) -> Unit) {
74     for (index in 0 until size) {
75         action(index, valueAt(index))
76     }
77 }
78 
getOrPutnull79 inline fun <K, V> IndexedMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
80     get(key)?.let { return it }
81     return defaultValue().also { put(key, it) }
82 }
83 
84 @Suppress("NOTHING_TO_INLINE")
getWithDefaultnull85 inline fun <K, V> IndexedMap<K, V>?.getWithDefault(key: K, defaultValue: V): V {
86     this ?: return defaultValue
87     val index = indexOfKey(key)
88     return if (index >= 0) valueAt(index) else defaultValue
89 }
90 
91 inline val <K, V> IndexedMap<K, V>.lastIndex: Int
92     get() = size - 1
93 
94 @Suppress("NOTHING_TO_INLINE")
minusAssignnull95 inline operator fun <K, V> IndexedMap<K, V>.minusAssign(key: K) {
96     remove(key)
97 }
98 
noneIndexednull99 inline fun <K, V> IndexedMap<K, V>.noneIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
100     forEachIndexed { index, key, value ->
101         if (predicate(index, key, value)) {
102             return false
103         }
104     }
105     return true
106 }
107 
108 @Suppress("NOTHING_TO_INLINE")
putWithDefaultnull109 inline fun <K, V> IndexedMap<K, V>.putWithDefault(key: K, value: V, defaultValue: V): V {
110     val index = indexOfKey(key)
111     if (index >= 0) {
112         val oldValue = valueAt(index)
113         if (value != oldValue) {
114             if (value == defaultValue) {
115                 removeAt(index)
116             } else {
117                 setValueAt(index, value)
118             }
119         }
120         return oldValue
121     } else {
122         if (value != defaultValue) {
123             put(key, value)
124         }
125         return defaultValue
126     }
127 }
128 
removeAllIndexednull129 inline fun <K, V> IndexedMap<K, V>.removeAllIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
130     var isChanged = false
131     forEachReversedIndexed { index, key, value ->
132         if (predicate(index, key, value)) {
133             removeAt(index)
134             isChanged = true
135         }
136     }
137     return isChanged
138 }
139 
retainAllIndexednull140 inline fun <K, V> IndexedMap<K, V>.retainAllIndexed(predicate: (Int, K, V) -> Boolean): Boolean {
141     var isChanged = false
142     forEachReversedIndexed { index, key, value ->
143         if (!predicate(index, key, value)) {
144             removeAt(index)
145             isChanged = true
146         }
147     }
148     return isChanged
149 }
150 
mapIndexednull151 inline fun <K, V, R> IndexedMap<K, V>.mapIndexed(transform: (Int, K, V) -> R): IndexedList<R> =
152     IndexedList<R>().also { destination ->
153         forEachIndexed { index, key, value ->
154             transform(index, key, value).let { destination += it }
155         }
156     }
157 
mapNotNullIndexednull158 inline fun <K, V, R> IndexedMap<K, V>.mapNotNullIndexed(
159     transform: (Int, K, V) -> R?
160 ): IndexedList<R> =
161     IndexedList<R>().also { destination ->
162         forEachIndexed { index, key, value ->
163             transform(index, key, value)?.let { destination += it }
164         }
165     }
166 
mapNotNullIndexedToSetnull167 inline fun <K, V, R> IndexedMap<K, V>.mapNotNullIndexedToSet(
168     transform: (Int, K, V) -> R?
169 ): IndexedSet<R> =
170     IndexedSet<R>().also { destination ->
171         forEachIndexed { index, key, value ->
172             transform(index, key, value)?.let { destination += it }
173         }
174     }
175 
176 @Suppress("NOTHING_TO_INLINE")
setnull177 inline operator fun <K, V> IndexedMap<K, V>.set(key: K, value: V) {
178     put(key, value)
179 }
180