• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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