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 class IndexedListSet<T> private constructor(
20 private val list: ArrayList<T>
21 ) : MutableSet<T> {
22 constructor() : this(ArrayList())
23
24 override val size: Int
25 get() = list.size
26
27 override fun contains(element: T): Boolean = list.contains(element)
28
29 override fun isEmpty(): Boolean = list.isEmpty()
30
31 override fun iterator(): MutableIterator<T> = list.iterator()
32
33 override fun containsAll(elements: Collection<T>): Boolean {
34 throw NotImplementedError()
35 }
36
37 fun elementAt(index: Int): T = list[index]
38
39 fun indexOf(element: T): Int = list.indexOf(element)
40
41 override fun add(element: T): Boolean =
42 if (list.contains(element)) {
43 false
44 } else {
45 list.add(element)
46 true
47 }
48
49 override fun remove(element: T): Boolean = list.remove(element)
50
51 override fun clear() {
52 list.clear()
53 }
54
55 override fun addAll(elements: Collection<T>): Boolean {
56 throw NotImplementedError()
57 }
58
59 override fun removeAll(elements: Collection<T>): Boolean {
60 throw NotImplementedError()
61 }
62
63 override fun retainAll(elements: Collection<T>): Boolean {
64 throw NotImplementedError()
65 }
66
67 fun removeAt(index: Int): T? = list.removeAt(index)
68
69 fun copy(): IndexedListSet<T> = IndexedListSet(ArrayList(list))
70 }
71
allIndexednull72 inline fun <T> IndexedListSet<T>.allIndexed(predicate: (Int, T) -> Boolean): Boolean {
73 forEachIndexed { index, element ->
74 if (!predicate(index, element)) {
75 return false
76 }
77 }
78 return true
79 }
80
anyIndexednull81 inline fun <T> IndexedListSet<T>.anyIndexed(predicate: (Int, T) -> Boolean): Boolean {
82 forEachIndexed { index, element ->
83 if (predicate(index, element)) {
84 return true
85 }
86 }
87 return false
88 }
89
forEachIndexednull90 inline fun <T> IndexedListSet<T>.forEachIndexed(action: (Int, T) -> Unit) {
91 for (index in indices) {
92 action(index, elementAt(index))
93 }
94 }
95
forEachReversedIndexednull96 inline fun <T> IndexedListSet<T>.forEachReversedIndexed(action: (Int, T) -> Unit) {
97 for (index in lastIndex downTo 0) {
98 action(index, elementAt(index))
99 }
100 }
101
102 inline val <T> IndexedListSet<T>.lastIndex: Int
103 get() = size - 1
104
105 @Suppress("NOTHING_TO_INLINE")
minusnull106 inline operator fun <T> IndexedListSet<T>.minus(element: T): IndexedListSet<T> =
107 copy().apply { this -= element }
108
109 @Suppress("NOTHING_TO_INLINE")
minusAssignnull110 inline operator fun <T> IndexedListSet<T>.minusAssign(element: T) {
111 remove(element)
112 }
113
noneIndexednull114 inline fun <T> IndexedListSet<T>.noneIndexed(predicate: (Int, T) -> Boolean): Boolean {
115 forEachIndexed { index, element ->
116 if (predicate(index, element)) {
117 return false
118 }
119 }
120 return true
121 }
122
123 @Suppress("NOTHING_TO_INLINE")
plusnull124 inline operator fun <T> IndexedListSet<T>.plus(element: T): IndexedListSet<T> =
125 copy().apply { this += element }
126
127 @Suppress("NOTHING_TO_INLINE")
plusAssignnull128 inline operator fun <T> IndexedListSet<T>.plusAssign(element: T) {
129 add(element)
130 }
131
removeAllIndexednull132 inline fun <T> IndexedListSet<T>.removeAllIndexed(predicate: (Int, T) -> Boolean): Boolean {
133 var isChanged = false
134 forEachReversedIndexed { index, element ->
135 if (predicate(index, element)) {
136 removeAt(index)
137 isChanged = true
138 }
139 }
140 return isChanged
141 }
142
retainAllIndexednull143 inline fun <T> IndexedListSet<T>.retainAllIndexed(predicate: (Int, T) -> Boolean): Boolean {
144 var isChanged = false
145 forEachReversedIndexed { index, element ->
146 if (!predicate(index, element)) {
147 removeAt(index)
148 isChanged = true
149 }
150 }
151 return isChanged
152 }
153