UNPKG

enumset32

Version:

High-performance, typesafe, small ordered set implemented in TypeScript

192 lines 5.29 kB
/*! * Copyright (c) 2019 Justin Johansson */ export class _UniversalEnumset32 { constructor(enumObject) { let e = Object.create(null); let m = Object.create(null); let u = 0 | 0; let names = Object.getOwnPropertyNames(enumObject); for (let i = 0; i < names.length; ++i) { let n = names[i]; let v = enumObject[n]; if (typeof v === 'number') { e[(e[n] = v)] = n; let mv = 1 << v; m[n] = mv; u |= mv; } } this.Enum = Object.freeze(e); this.Member = Object.freeze(m); this._univ = u; } static create(enumObject) { return Object.freeze(new _UniversalEnumset32(enumObject)); } get Empty() { return (0 | 0); } set() { let res = 0; let i; for (i = 0; i < arguments.length; ++i) { res |= 1 << arguments[i]; } return res & this._univ; } add(set, member) { let s = set & this._univ; let m = +member; return (s | (1 << m)) & this._univ; } addAll(set1, set2, ...sets) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; let res = s1 | s2; for (let i = 0; i < sets.length; ++i) { res |= sets[i]; } return res & this._univ; } complement(set) { let s = set & this._univ; return ~s & this._univ; } retain(set, member) { let s = set & this._univ; let m = +member; return s & (1 << m) & this._univ; } retainAll(set1, set2, ...sets) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; let res = s1 & s2; for (let i = 0; i < sets.length; ++i) { res &= sets[i]; } return res & this._univ; } remove(set, member) { let s = set & this._univ; let m = +member; return s & ~(1 << m) & this._univ; } removeAll(set1, set2, ...sets) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; let res = s1 & ~s2; for (let i = 0; i < sets.length; ++i) { res &= ~sets[i]; } return res & this._univ; } toggle(set, member) { let s = set & this._univ; let m = +member; return (s ^ (1 << m)) & this._univ; } toggleAll(set1, set2, ...sets) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; let res = s1 ^ s2; for (let i = 0; i < sets.length; ++i) { res ^= sets[i]; } return res & this._univ; } empty(set) { let s = set & this._univ; return s === 0; } excludes(set, member) { let s = set & this._univ; let m = +member; return this.excludesEvery(s, (1 << m)); } excludesEvery(set1, set2) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; return (s1 & s2) === 0; } excludesSome(set1, set2) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; return (s1 & s2) !== s2; } includes(set, member) { let s = set & this._univ; let m = +member; return this.includesEvery(s, (1 << m)); } includesEvery(set1, set2) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; return (s1 & s2) === s2; } includesSome(set1, set2) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; return (s1 & s2) !== 0; } count(set) { let s = set & this._univ; if (s >= 0) { let card = s - ((s >> 1) & 0o33333333333) - ((s >> 2) & 0o11111111111); return ((card + (card >> 3)) & 0o30707070707) % 0o77; } return this.count((set & 0o17777777777)) + 1; } enumEntries(set) { let s = set & this._univ; let entries = []; for (let i = 0; i < 32; ++i) { if (s & (1 << i)) { entries.push([this.Enum[i], i]); } } return entries; } enumKeys(set) { let s = set & this._univ; let keys = []; for (let i = 0; i < 32; ++i) { if (s & (1 << i)) { keys.push(this.Enum[i]); } } return keys; } enumValues(set) { let s = set & this._univ; let values = []; for (let i = 0; i < 32; ++i) { if (s & (1 << i)) { values.push(i); } } return values; } equal(set1, set2) { let s1 = set1 & this._univ; let s2 = set2 & this._univ; return s1 === s2; } isEnumKey(key) { return typeof key === 'string' && typeof this.Enum[key] === 'number'; } isEnumValue(value) { return typeof value === 'number' && typeof this.Enum[value] === 'string'; } toDigitString(set, radix) { let s = set & this._univ; return (s >>> 0).toString(radix); } valueOf() { return (this._univ | 0); } } export function UniversalEnumset32(enumObject) { return _UniversalEnumset32.create(enumObject); } //# sourceMappingURL=index.js.map