1/* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16package escompat; 17 18export interface ReadonlySet<T> extends Iterable<T> { 19 /** 20 * Checks if a value is in the Set 21 * 22 * @param v the value to find in the Set 23 * 24 * @returns true if the value is in the Set 25 */ 26 27 has(value: T): boolean; 28 29 /** 30 * Returns number of unique elements in the Set 31 * 32 * @returns number of unique elements in the Set 33 */ 34 get size(): number; 35 36 /** 37 * Executes a provided function once per each value in the Set object, in insertion order 38 * 39 * @param callbackfn to apply 40 */ 41 forEach(callbackfn: () => void): void; 42 43 /** 44 * Executes a provided function once per each value in the Set object, in insertion order 45 * 46 * @param callbackfn to apply 47 */ 48 forEach(callbackfn: (value: T) => void): void; 49 50 /** 51 * Executes a provided function once per each value in the Set object, in insertion order 52 * 53 * @param callbackfn to apply; value2 is always same as value1 54 */ 55 forEach(callbackfn: (value: T, value2: T) => void): void; 56 57 /** 58 * Executes a provided function once per each value in the Set object, in insertion order 59 * 60 * @param callbackfn to apply; value2 is always same as value1 61 */ 62 forEach(callbackfn: (value: T, value2: T, set: ReadonlySet<T>) => void): void; 63 64 /** 65 * Despite name, returns elements from the Set 66 * @returns an iterable of the values in the set 67 */ 68 keys(): IterableIterator<T>; 69 70 /** 71 * Returns elements from the Set 72 * 73 * @returns an iterable of the values in the set 74 */ 75 values(): IterableIterator<T>; 76 77 /** 78 * @returns an iterable of [v,v] pairs for every value `v` in the set. 79 */ 80 entries(): IterableIterator<[T, T]>; 81} 82 83/** 84 * Set implementation 85 */ 86export final class Set<K> implements ReadonlySet<K> { 87 private readonly elements: Map<K, K> = new Map<K, K>() 88 89 /** 90 * Constructs a Set from collection 91 * @param elements initial collection 92 */ 93 constructor(elements?: ArrayLike<K> | Iterable<K> | null) { 94 if (elements != null) { 95 const elementsIter = elements.$_iterator() 96 97 iteratorForEach<K>(elements.$_iterator(), (elem: K) => { 98 this.elements.set(elem, elem) 99 }) 100 } 101 } 102 103 private toStringVals(): String { 104 const strBuf = new StringBuilder() 105 106 const valsIter = this.values() 107 let valsIterRes = valsIter.next() 108 while (!valsIterRes.done) { 109 strBuf.append(`${valsIterRes.value}`) 110 111 valsIterRes = valsIter.next() 112 if (!valsIterRes.done) { 113 strBuf.append(",") 114 } 115 } 116 117 return strBuf.toString() 118 } 119 120 override toString(): String { 121 return "Set[" + this.toStringVals() + "]" 122 } 123 124 /** 125 * Puts a value into the Set 126 * 127 * @param val the value to put into the Set 128 * @returns this 129 */ 130 add(val: K): this { 131 this.elements.set(val, val) 132 return this 133 } 134 135 /** 136 * Checks if a value is in the Set 137 * 138 * @param val the value to find in the Set 139 * 140 * @returns true if the value is in the Set 141 */ 142 override has(val: K): boolean { 143 return this.elements.has(val) 144 } 145 146 /** 147 * Returns number of unique elements in the Set 148 * 149 * @returns number of unique elements in the Set 150 */ 151 override get size(): number { 152 return this.elements.size; 153 } 154 155 /** 156 * Removes a value from the Set 157 * 158 * @param val the value to remove 159 */ 160 delete(val: K): boolean { 161 return this.elements.delete(val) 162 } 163 164 /** 165 * Deletes all elements from the Set 166 */ 167 clear(): void { 168 this.elements.clear() 169 } 170 171 /** 172 * Despite name, returns elements from the Set 173 * @returns an iterable of the values in the set 174 */ 175 override keys(): IterableIterator<K> { 176 return this.elements.keys() 177 } 178 179 /** 180 * Returns elements from the Set 181 * 182 * @returns an iterable of the values in the set 183 */ 184 override values(): IterableIterator<K> { 185 return this.elements.keys() 186 } 187 188 override $_iterator(): IterableIterator<K> { 189 return this.values(); 190 } 191 192 /** 193 * @returns an iterable of [v,v] pairs for every value `v` in the set. 194 */ 195 override entries(): IterableIterator<[K, K]> { 196 return this.elements.entries() 197 } 198 199 /** 200 * Executes a provided function once per each value in the Set object, in insertion order 201 * 202 * @param callbackfn to apply 203 */ 204 override forEach(callbackfn: () => void): void { 205 iteratorForEach<K>(this.keys(), (elem: K) => callbackfn()) 206 } 207 208 /** 209 * Executes a provided function once per each value in the Set object, in insertion order 210 * 211 * @param callbackfn to apply 212 */ 213 override forEach(callbackfn: (k: K) => void): void { 214 iteratorForEach<K>(this.keys(), callbackfn) 215 } 216 217 /** 218 * Executes a provided function once per each value in the Set object, in insertion order 219 * 220 * @param callbackfn to apply 221 */ 222 override forEach(callbackfn: (k: K, v: K) => void): void { 223 iteratorForEach<K>(this.keys(), (x: K): void => callbackfn(x, x)) 224 } 225 226 /** 227 * Executes a provided function once per each value in the Set object, in insertion order 228 * 229 * @param callbackfn to apply 230 */ 231 override forEach(callbackfn: (k: K, v: K, set: Set<K>) => void): void { 232 iteratorForEach<K>(this.keys(), (x: K): void => callbackfn(x, x, this)) 233 } 234} 235