• 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.SparseArray
20 
21 typealias IntMap<T> = SparseArray<T>
22 
23 inline fun <T> IntMap<T>.allIndexed(predicate: (Int, Int, T) -> 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 <T> IntMap<T>.anyIndexed(predicate: (Int, Int, T) -> 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 <T> IntMap<T>.copy(copyValue: (T) -> T): IntMap<T> =
42     this.clone().apply {
43         forEachValueIndexed { index, value ->
44             setValueAt(index, copyValue(value))
45         }
46     }
47 
firstNotNullOfOrNullIndexednull48 inline fun <T, R> IntMap<T>.firstNotNullOfOrNullIndexed(transform: (Int, Int, T) -> R): R? {
49     forEachIndexed { index, key, value ->
50         transform(index, key, value)?.let { return it }
51     }
52     return null
53 }
54 
forEachIndexednull55 inline fun <T> IntMap<T>.forEachIndexed(action: (Int, Int, T) -> Unit) {
56     for (index in 0 until size) {
57         action(index, keyAt(index), valueAt(index))
58     }
59 }
60 
forEachKeyIndexednull61 inline fun <T> IntMap<T>.forEachKeyIndexed(action: (Int, Int) -> Unit) {
62     for (index in 0 until size) {
63         action(index, keyAt(index))
64     }
65 }
66 
forEachReversedIndexednull67 inline fun <T> IntMap<T>.forEachReversedIndexed(action: (Int, Int, T) -> Unit) {
68     for (index in lastIndex downTo 0) {
69         action(index, keyAt(index), valueAt(index))
70     }
71 }
72 
forEachValueIndexednull73 inline fun <T> IntMap<T>.forEachValueIndexed(action: (Int, T) -> Unit) {
74     for (index in 0 until size) {
75         action(index, valueAt(index))
76     }
77 }
78 
getOrPutnull79 inline fun <T> IntMap<T>.getOrPut(key: Int, defaultValue: () -> T): T {
80     get(key)?.let { return it }
81     return defaultValue().also { put(key, it) }
82 }
83 
84 @Suppress("NOTHING_TO_INLINE")
getWithDefaultnull85 inline fun <T> IntMap<T>?.getWithDefault(key: Int, defaultValue: T): T {
86     this ?: return defaultValue
87     val index = indexOfKey(key)
88     return if (index >= 0) valueAt(index) else defaultValue
89 }
90 
91 inline val <T> IntMap<T>.lastIndex: Int
92     get() = size - 1
93 
94 @Suppress("NOTHING_TO_INLINE")
minusAssignnull95 inline operator fun <T> IntMap<T>.minusAssign(key: Int) {
96     remove(key)
97 }
98 
noneIndexednull99 inline fun <T> IntMap<T>.noneIndexed(predicate: (Int, Int, T) -> 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 <T> IntMap<T>.putWithDefault(key: Int, value: T, defaultValue: T): T {
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 
129 // SparseArray.removeReturnOld() is @hide, so a backup once we move to APIs.
removeReturnOldnull130 fun <T> IntMap<T>.removeReturnOld(key: Int): T? {
131     val index = indexOfKey(key)
132     return if (index >= 0) {
133         val oldValue = valueAt(index)
134         removeAt(index)
135         oldValue
136     } else {
137         null
138     }
139 }
140 
removeAllIndexednull141 inline fun <T> IntMap<T>.removeAllIndexed(predicate: (Int, Int, T) -> Boolean): Boolean {
142     var isChanged = false
143     forEachReversedIndexed { index, key, value ->
144         if (predicate(index, key, value)) {
145             removeAt(index)
146             isChanged = true
147         }
148     }
149     return isChanged
150 }
151 
retainAllIndexednull152 inline fun <T> IntMap<T>.retainAllIndexed(predicate: (Int, Int, T) -> Boolean): Boolean {
153     var isChanged = false
154     forEachReversedIndexed { index, key, value ->
155         if (!predicate(index, key, value)) {
156             removeAt(index)
157             isChanged = true
158         }
159     }
160     return isChanged
161 }
162 
163 inline val <T> IntMap<T>.size: Int
164     get() = size()
165