-
Notifications
You must be signed in to change notification settings - Fork 1
/
iterable_weak_map.ts
82 lines (68 loc) · 1.74 KB
/
iterable_weak_map.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { IterableWeakSet } from "./iterable_weak_set.ts";
export class IterableWeakMap<K extends object, V>
implements WeakMap<K, V>, Map<K, V> {
#weakMap = new WeakMap<K, V>();
#set = new IterableWeakSet<K>();
constructor(entries?: readonly (readonly [K, V])[] | null);
constructor(iterable: Iterable<readonly [K, V]>);
constructor(iterable?: Iterable<readonly [K, V]> | null) {
for (const [key, value] of iterable ?? []) {
this.set(key, value);
}
}
get size(): number {
return this.#set.size;
}
clear(): void {
for (const key of this.#set) {
this.delete(key);
}
}
delete(key: K): boolean {
const ref = this.#weakMap.get(key);
if (ref) {
this.#weakMap.delete(key);
this.#set.delete(key);
return true;
}
return false;
}
get(key: K): V | undefined {
return this.#weakMap.get(key);
}
has(key: K): boolean {
return this.#weakMap.has(key);
}
set(key: K, value: V): this {
this.#weakMap.set(key, value);
this.#set.add(key);
return this;
}
get [Symbol.toStringTag](): string {
return "IterableWeakMap";
}
forEach(
callbackfn: (value: V, key: K, map: Map<K, V>) => void,
thisArg?: unknown,
): void {
for (const [key, value] of this[Symbol.iterator]()) {
callbackfn.call(thisArg, value, key, this);
}
}
*[Symbol.iterator](): IterableIterator<[K, V]> {
for (const key of this.#set) {
yield [key, this.#weakMap.get(key)!];
}
}
entries(): IterableIterator<[K, V]> {
return this[Symbol.iterator]();
}
keys(): IterableIterator<K> {
return this.#set[Symbol.iterator]();
}
*values(): IterableIterator<V> {
for (const key of this.#set) {
yield this.#weakMap.get(key)!;
}
}
}