import { create, has, ObjectLike } from '../../core/object'; import { isIterable, isArrayLike, isObject } from '../../core/traits'; //! \todo add 'symbol' here (or change to PropertyKey) when https://github.com/Microsoft/TypeScript/pull/26797 will be ready export type FastKey = number | string; /*! \class FastSet \brief Wrapper around native object with Set-like interface. */ export class FastSet { protected _entries = create(); protected _size = 0; constructor(entries?: ArrayLike | Iterable) { if (isIterable(entries)) { for (const value of entries) this.add(value); } else if (isArrayLike(entries)) { for (let i = 0; i < entries.length; i++) { const value = entries[i]; this.add(value); } } } get size() { return this._size; } add(value: FastKey) { if (!this.has(value)) this._size++; this._entries[value] = value; return this; } has(value: FastKey) { return has(this._entries, value); } delete(value: FastKey) { if (this.has(value)) { this._size--; delete this._entries[value]; return true; } return false; } clear() { for (const value of this.values()) this.delete(value); } *values() { const entries = this._entries; for (const key in entries) yield entries[key]; } *entries() { const entries = this._entries; for (const key in entries) yield [key, entries[key]] as [string, FastKey]; } forEach(callbackfn: (value: FastKey, key: string, set: FastSet) => void, thisArg?: any) { const entries = this._entries; for (const key in entries) callbackfn.call(thisArg, entries[key], key, this); } [Symbol.iterator]() { return this.values(); } reset(entries?: ObjectLike) { this.clear(); if (isObject(entries)) for (const key in entries) if (has(entries, key)) this.add(key); } }