/* MIT License http://www.opensource.org/licenses/mit-license.php Author Ivan Kopeykin @vankop */ "use strict"; /** * @template T */ class AppendOnlyStackedSet { /** * @param {Set[]} sets an optional array of sets */ constructor(sets = []) { /** @type {Set[]} */ this._sets = sets; /** @type {Set | undefined} */ this._current = undefined; } /** * @param {T} el element */ add(el) { if (!this._current) { this._current = new Set(); this._sets.push(this._current); } this._current.add(el); } /** * @param {T} el element * @returns {boolean} result */ has(el) { for (const set of this._sets) { if (set.has(el)) return true; } return false; } clear() { this._sets = []; if (this._current) { this._current = undefined; } } /** * @returns {AppendOnlyStackedSet} child */ createChild() { return new AppendOnlyStackedSet(this._sets.length ? [...this._sets] : []); } /** * @returns {Iterator} iterable iterator */ [Symbol.iterator]() { const iterators = this._sets.map((map) => map[Symbol.iterator]()); let current = iterators.pop(); return { next() { if (!current) return { done: true, value: undefined }; let result = current.next(); while (result.done && iterators.length > 0) { current = /** @type {SetIterator} */ (iterators.pop()); result = current.next(); } return result; } }; } } module.exports = AppendOnlyStackedSet;