@isopodlabs/utilities 1.5.9 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/bits.d.ts +75 -45
  2. package/dist/bits.js +535 -371
  3. package/package.json +1 -1
package/dist/bits.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export declare function lowestSet32(x: number): number;
2
2
  export declare function highestSet32(x: number): number;
3
+ export declare function highestSet1024(x: number): number;
3
4
  export declare function countSet32(x: number): number;
4
5
  export declare function nthSet32(x: number, i: number): number;
5
6
  export declare function highestSet(x: bigint | number): number;
@@ -12,108 +13,137 @@ export declare function countClear(x: bigint | number): number;
12
13
  export declare function clearLowest(x: bigint): bigint;
13
14
  export declare function clearLowest(x: number): number;
14
15
  export declare function clearLowest(x: bigint | number): bigint | number;
15
- export interface immutableBitSet {
16
+ export interface ImmutableBitSet {
16
17
  test(a: number): boolean;
17
18
  countSet(): number;
18
19
  nthSet(a: number): number;
19
- complement(): this;
20
- intersect(other: this): this;
21
- union(other: this): this;
22
- xor(other: this): this;
20
+ complement(): ImmutableBitSet;
21
+ intersect(other: this): ImmutableBitSet;
22
+ union(other: this): ImmutableBitSet;
23
+ xor(other: this): ImmutableBitSet;
23
24
  contains(other: this): boolean;
24
25
  next(a: number, set: boolean): number;
25
- where(set: boolean, from?: number): {
26
+ where(set: boolean, from?: number, to?: number): {
26
27
  [Symbol.iterator](): Generator<number>;
27
28
  };
28
29
  ranges(): {
29
30
  [Symbol.iterator](): Generator<number[]>;
30
31
  };
32
+ slice(from: number, to?: number): ImmutableBitSet;
31
33
  [Symbol.iterator](): Generator<number>;
32
34
  }
33
- export interface BitSet extends immutableBitSet {
35
+ export interface BitSet extends ImmutableBitSet {
34
36
  set(a: number): void;
35
37
  clear(a: number): void;
36
38
  setRange(a: number, b: number): this;
37
39
  clearRange(a: number, b: number): this;
38
- selfComplement(): this;
40
+ selfComplement?(): this;
39
41
  selfIntersect(other: this): this;
40
42
  selfUnion(other: this): this;
41
43
  selfXor(other: this): this;
42
44
  }
43
- export declare class ImmutableSparseBits implements immutableBitSet {
45
+ export declare class ImmutableDenseBits implements ImmutableBitSet {
46
+ protected bits: bigint;
47
+ constructor(bits?: bigint);
48
+ protected create(bits?: bigint): this;
49
+ get length(): number;
50
+ test(a: number): boolean;
51
+ countSet(): number;
52
+ nthSet(a: number): number;
53
+ complement(): this;
54
+ intersect(other: ImmutableDenseBits): this;
55
+ union(other: ImmutableDenseBits): this;
56
+ xor(other: ImmutableDenseBits): this;
57
+ contains(other: this): boolean;
58
+ next(a: number, set?: boolean): number;
59
+ where(set: boolean, from?: number, to?: number): {
60
+ [Symbol.iterator](): Generator<number>;
61
+ };
62
+ ranges(): {
63
+ [Symbol.iterator](): Generator<number[]>;
64
+ };
65
+ [Symbol.iterator](): Generator<number>;
66
+ toSparse(): SparseBits2;
67
+ slice(from: number, to?: number): ImmutableBitSet;
68
+ }
69
+ export declare class DenseBits extends ImmutableDenseBits implements BitSet {
70
+ protected setMask(m: bigint): void;
71
+ protected clearMask(m: bigint): void;
72
+ set(a: number): void;
73
+ clear(a: number): void;
74
+ setRange(a: number, b: number): this;
75
+ clearRange(a: number, b: number): this;
76
+ selfComplement(): this;
77
+ selfIntersect(other: DenseBits): this;
78
+ selfUnion(other: DenseBits): this;
79
+ selfXor(other: DenseBits): this;
80
+ }
81
+ export declare class ImmutableSparseBits implements ImmutableBitSet {
44
82
  protected bits: number[];
45
- protected undef: number;
46
- static whereGenerator(bits: number[], undef: number, set: boolean, from?: number): Generator<number>;
47
- constructor(initial?: boolean);
48
- protected create(init?: boolean): this;
49
- protected copyUndefined(other: ImmutableSparseBits): this;
50
- protected flipUndefined(other: ImmutableSparseBits): this;
51
- static fromEntries<T extends ImmutableSparseBits>(this: new (initial?: boolean) => T, entries: Record<number, number> | [number, number][], initial?: boolean): T;
83
+ constructor(bits?: number[]);
84
+ protected create(bits?: number[]): this;
85
+ static fromEntries<T extends ImmutableSparseBits>(this: new (...args: any[]) => T, entries: Record<number, number> | [number, number][], ...args: any[]): T;
52
86
  keys(): number[];
53
87
  entries(): [number, number][];
54
88
  test(a: number): boolean;
55
89
  countSet(): number;
56
90
  nthSet(a: number): number;
57
- complement(): this;
91
+ complement(): ImmutableSparseBits2;
58
92
  intersect(other: ImmutableSparseBits): this;
59
93
  union(other: ImmutableSparseBits): this;
60
94
  xor(other: ImmutableSparseBits): this;
61
95
  contains(other: ImmutableSparseBits): boolean;
62
- next(a: number, set?: boolean): number;
63
- where(set: boolean, from?: number): {
64
- [Symbol.iterator]: () => Generator<number, any, any>;
96
+ next(from: number, set?: boolean): number;
97
+ where(set: boolean, from?: number, to?: number): {
98
+ [Symbol.iterator]: () => Generator<number, void, unknown>;
65
99
  };
66
100
  ranges(): {
67
- [Symbol.iterator](): Generator<number[]>;
101
+ [Symbol.iterator]: () => Generator<number[], void, unknown>;
68
102
  };
69
103
  [Symbol.iterator](): Generator<number>;
70
104
  clean(): this;
71
105
  toDense(): DenseBits;
106
+ slice(from: number, to?: number): ImmutableBitSet;
72
107
  }
73
108
  export declare class SparseBits extends ImmutableSparseBits implements BitSet {
74
- private setMask;
75
- private clearMask;
76
109
  set(a: number): void;
77
110
  clear(a: number): void;
78
111
  setRange(a: number, b: number): this;
79
112
  clearRange(a: number, b: number): this;
80
- selfComplement(): this;
81
113
  selfIntersect(other: SparseBits): this;
82
114
  selfUnion(other: SparseBits): this;
83
115
  selfXor(other: SparseBits): this;
84
116
  }
85
- export declare class ImmutableDenseBits implements immutableBitSet {
86
- protected bits: bigint;
87
- constructor(bits?: bigint);
88
- protected create(bits?: bigint): this;
89
- get length(): number;
117
+ export declare class ImmutableSparseBits2 extends ImmutableSparseBits {
118
+ protected undef: number;
119
+ constructor(bits?: number[], initial?: boolean);
120
+ protected create(bits?: number[], init?: boolean): this;
90
121
  test(a: number): boolean;
91
- countSet(): number;
92
122
  nthSet(a: number): number;
93
123
  complement(): this;
94
- intersect(other: ImmutableDenseBits): this;
95
- union(other: ImmutableDenseBits): this;
96
- xor(other: ImmutableDenseBits): this;
97
- contains(other: this): boolean;
98
- next(a: number, set?: boolean): number;
99
- where(set: boolean, from?: number): {
100
- [Symbol.iterator](): Generator<number>;
124
+ intersect(other: ImmutableSparseBits2): this;
125
+ union(other: ImmutableSparseBits2): this;
126
+ xor(other: ImmutableSparseBits2): this;
127
+ contains(other: ImmutableSparseBits2): boolean;
128
+ next(from: number, set?: boolean): number;
129
+ where(set: boolean, from?: number, to?: number): {
130
+ [Symbol.iterator]: () => Generator<number, void, unknown>;
101
131
  };
102
132
  ranges(): {
103
- [Symbol.iterator](): Generator<number[]>;
133
+ [Symbol.iterator]: () => Generator<number[], void, unknown>;
104
134
  };
105
135
  [Symbol.iterator](): Generator<number>;
106
- toSparse(): SparseBits;
136
+ clean(): this;
137
+ toDense(): DenseBits;
138
+ slice(from: number, to?: number): ImmutableBitSet;
107
139
  }
108
- export declare class DenseBits extends ImmutableDenseBits implements BitSet {
109
- protected setMask(m: bigint): void;
110
- protected clearMask(m: bigint): void;
140
+ export declare class SparseBits2 extends ImmutableSparseBits2 implements BitSet {
111
141
  set(a: number): void;
112
142
  clear(a: number): void;
113
143
  setRange(a: number, b: number): this;
114
144
  clearRange(a: number, b: number): this;
115
145
  selfComplement(): this;
116
- selfIntersect(other: DenseBits): this;
117
- selfUnion(other: DenseBits): this;
118
- selfXor(other: DenseBits): this;
146
+ selfIntersect(other: SparseBits2): this;
147
+ selfUnion(other: SparseBits2): this;
148
+ selfXor(other: SparseBits2): this;
119
149
  }
package/dist/bits.js CHANGED
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
+ //-----------------------------------------------------------------------------
3
+ // Bit twiddling functions
4
+ //-----------------------------------------------------------------------------
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DenseBits = exports.ImmutableDenseBits = exports.SparseBits = exports.ImmutableSparseBits = void 0;
6
+ exports.SparseBits2 = exports.ImmutableSparseBits2 = exports.SparseBits = exports.ImmutableSparseBits = exports.DenseBits = exports.ImmutableDenseBits = void 0;
4
7
  exports.lowestSet32 = lowestSet32;
5
8
  exports.highestSet32 = highestSet32;
9
+ exports.highestSet1024 = highestSet1024;
6
10
  exports.countSet32 = countSet32;
7
11
  exports.nthSet32 = nthSet32;
8
12
  exports.highestSet = highestSet;
@@ -13,10 +17,6 @@ exports.highestClear = highestClear;
13
17
  exports.lowestClear = lowestClear;
14
18
  exports.countClear = countClear;
15
19
  exports.clearLowest = clearLowest;
16
- const algorithm_1 = require("./algorithm");
17
- //-----------------------------------------------------------------------------
18
- // Bit twiddling functions
19
- //-----------------------------------------------------------------------------
20
20
  // Returns the index (0-31) of the lowest set bit, or 32 if none
21
21
  function lowestSet32(x) {
22
22
  return x === 0 ? 32 : 31 - Math.clz32(x & -x);
@@ -25,6 +25,10 @@ function lowestSet32(x) {
25
25
  function highestSet32(x) {
26
26
  return x ? 32 - Math.clz32(x) : 0;
27
27
  }
28
+ function highestSet1024(x) {
29
+ let b = Math.floor(Math.log2(x));
30
+ return 1n << BigInt(b) <= x ? b + 1 : b;
31
+ }
28
32
  // Returns the number of set bits
29
33
  function countSet32(x) {
30
34
  x = x - ((x >> 1) & 0x55555555);
@@ -121,45 +125,59 @@ export function bitcountCached(x: bigint): number {
121
125
  return Number(x & 0xFFFFFFFFn);
122
126
  }
123
127
  */
124
- function highestSetBig(x) {
128
+ /*
129
+ function highestSetBig32(x: bigint): number {
125
130
  let s = 0;
126
131
  let k = 0;
132
+
127
133
  for (let t = x >> 32n; t; t >>= BigInt(s)) {
128
134
  s = 32 << k++;
129
135
  x = t;
130
136
  }
137
+
131
138
  if (k) {
132
- // determine length by bisection
133
- k--;
134
- while (k--) {
135
- const b = x >> BigInt(32 << k);
139
+ while (--k) {
140
+ const b = x >> BigInt(16 << k);
136
141
  if (b) {
137
- s += 32 << k;
142
+ s += 16 << k;
138
143
  x = b;
139
144
  }
140
145
  }
141
146
  }
142
147
  return (s + 32) - Math.clz32(Number(x));
143
148
  }
149
+ */
150
+ function highestSetBig1024(x) {
151
+ let s = 0;
152
+ let k = 0;
153
+ for (let t = x >> 1024n; t; t >>= BigInt(s)) {
154
+ s = 1024 << k++;
155
+ x = t;
156
+ }
157
+ if (k) {
158
+ while (--k) {
159
+ const b = x >> BigInt(512 << k);
160
+ if (b) {
161
+ s += 512 << k;
162
+ x = b;
163
+ }
164
+ }
165
+ }
166
+ return highestSet1024(Number(x)) + s;
167
+ }
144
168
  function highestSet(x) {
145
169
  if (x < 0)
146
170
  x = ~x;
147
- if (x < 0x100000000)
148
- return highestSet32(Number(x));
149
- // For < 1024 bits, use log2
150
- if (x <= Number.MAX_VALUE) {
151
- const b = Math.floor(Math.log2(Number(x)));
152
- return (1n << BigInt(b)) <= x ? b + 1 : b;
153
- }
154
- return highestSetBig(BigInt(x));
171
+ return x < 0x100000000 ? highestSet32(Number(x))
172
+ : x <= Number.MAX_VALUE ? highestSet1024(Number(x))
173
+ : highestSetBig1024(BigInt(x));
155
174
  }
156
175
  function lowestSet(x) {
157
- if (x < 0)
158
- x = ~x;
159
- if (x < 0x100000000)
160
- return lowestSet32(Number(x));
161
- x = BigInt(x);
162
- return highestSetBig(x & -x) - 1;
176
+ if (typeof x === 'number') {
177
+ x = x < 0 ? (~x & (x + 1)) : x & -x;
178
+ return (x < 0x100000000 ? highestSet32(x) : highestSet1024(x)) - 1;
179
+ }
180
+ return highestSetBig1024(x < 0 ? (~x & (x + 1n)) : x & -x) - 1;
163
181
  }
164
182
  function countSet(x) {
165
183
  if (x < 0)
@@ -237,487 +255,633 @@ function clearLowest(x) {
237
255
  return typeof x === 'bigint' ? x & (x - 1n) : x & (x - 1);
238
256
  }
239
257
  //-----------------------------------------------------------------------------
240
- // SparseBits - a sparse bitset implementation, where each entry in the 'bits' array represents 32 bits
241
- // The 'undef' member indicates whether undefined entries are treated as 0 or 0xffffffff
258
+ // DenseBits - a dense bitset implementation using bigint
242
259
  //-----------------------------------------------------------------------------
243
- class ImmutableSparseBits {
244
- bits = []; //each entry represents 32 bits
245
- undef;
246
- static *whereGenerator(bits, undef, set, from = -1) {
247
- ++from;
248
- if (undef ? !set : set) {
249
- const keys = Object.keys(bits).map(k => +k);
250
- if (keys.length === 0)
251
- return;
252
- const i = from >> 5;
253
- let k = (0, algorithm_1.lowerBound)(keys, i);
254
- let v = bits[keys[k]] ^ undef;
255
- if (keys[k] === i)
256
- v &= -(1 << (from & 0x1f));
257
- for (;;) {
258
- const i = keys[k];
259
- while (v) {
260
- yield (i << 5) + lowestSet32(v);
261
- v = v & (v - 1);
260
+ class ImmutableDenseBits {
261
+ bits;
262
+ constructor(bits = 0n) {
263
+ this.bits = bits;
264
+ }
265
+ create(bits) {
266
+ return new this.constructor(bits);
267
+ }
268
+ get length() {
269
+ return highestSet(this.bits);
270
+ }
271
+ test(a) {
272
+ return !!(this.bits & (1n << BigInt(a)));
273
+ }
274
+ countSet() {
275
+ return countSet(this.bits);
276
+ }
277
+ nthSet(a) {
278
+ return nthSet(this.bits, a);
279
+ }
280
+ complement() {
281
+ return this.create(~this.bits);
282
+ }
283
+ intersect(other) {
284
+ return this.create(this.bits & other.bits);
285
+ }
286
+ union(other) {
287
+ return this.create(this.bits | other.bits);
288
+ }
289
+ xor(other) {
290
+ return this.create(this.bits ^ other.bits);
291
+ }
292
+ contains(other) {
293
+ return (this.bits & other.bits) === other.bits;
294
+ }
295
+ next(a, set = true) {
296
+ let s = this.bits >> BigInt(a + 1);
297
+ s = set ? s & -s : (s + 1n) & ~s;
298
+ return s ? a + highestSet(s) : -1;
299
+ }
300
+ where(set, from = -1, to) {
301
+ let bits = this.bits >> BigInt(from + 1);
302
+ if (to !== undefined)
303
+ bits &= (1n << BigInt(to - from - 1)) - 1n;
304
+ return {
305
+ *[Symbol.iterator]() {
306
+ while (bits) {
307
+ const i = highestSet(set ? bits & -bits : (bits + 1n) & ~bits);
308
+ from += i;
309
+ yield from;
310
+ bits >>= BigInt(i);
262
311
  }
263
- ++k;
264
- if (k === keys.length)
265
- return;
266
- v = bits[keys[k]] ^ undef;
267
312
  }
313
+ };
314
+ }
315
+ ranges() {
316
+ let bits = this.bits;
317
+ return {
318
+ *[Symbol.iterator]() {
319
+ let offset = 0;
320
+ while (bits) {
321
+ const i = highestSet(bits & -bits);
322
+ bits >>= BigInt(i);
323
+ const j = highestSet(~bits & (bits + 1n));
324
+ bits >>= BigInt(j);
325
+ yield [offset + i - 1, offset + i + j - 1];
326
+ offset += i + j;
327
+ }
328
+ }
329
+ };
330
+ }
331
+ *[Symbol.iterator]() {
332
+ yield* this.where(true);
333
+ }
334
+ toSparse() {
335
+ const sparse = {};
336
+ for (let bits = this.bits, i = 0; bits; bits >>= 32n, i++) {
337
+ const v = Number(bits & 0xffffffffn);
338
+ if (v)
339
+ sparse[i] = v;
340
+ }
341
+ return SparseBits2.fromEntries(sparse, false);
342
+ }
343
+ slice(from, to) {
344
+ return to === undefined
345
+ ? this.create(this.bits >> BigInt(from))
346
+ : this.create(this.bits >> BigInt(from) & ((1n << BigInt(to - from)) - 1n));
347
+ }
348
+ }
349
+ exports.ImmutableDenseBits = ImmutableDenseBits;
350
+ ;
351
+ class DenseBits extends ImmutableDenseBits {
352
+ setMask(m) {
353
+ this.bits |= m;
354
+ }
355
+ clearMask(m) {
356
+ this.bits &= ~m;
357
+ }
358
+ set(a) {
359
+ this.setMask(1n << BigInt(a));
360
+ }
361
+ clear(a) {
362
+ this.clearMask(1n << BigInt(a));
363
+ }
364
+ setRange(a, b) {
365
+ this.setMask((1n << BigInt(b)) - (1n << BigInt(a)));
366
+ return this;
367
+ }
368
+ clearRange(a, b) {
369
+ this.clearMask((1n << BigInt(b)) - (1n << BigInt(a)));
370
+ return this;
371
+ }
372
+ selfComplement() {
373
+ this.bits = ~this.bits;
374
+ return this;
375
+ }
376
+ selfIntersect(other) {
377
+ this.bits &= other.bits;
378
+ return this;
379
+ }
380
+ selfUnion(other) {
381
+ this.bits |= other.bits;
382
+ return this;
383
+ }
384
+ selfXor(other) {
385
+ this.bits ^= other.bits;
386
+ return this;
387
+ }
388
+ }
389
+ exports.DenseBits = DenseBits;
390
+ ;
391
+ //-----------------------------------------------------------------------------
392
+ // SparseBits - a sparse bitset implementation, where each entry in the 'bits' array represents 32 bits
393
+ //-----------------------------------------------------------------------------
394
+ function sparseFromEntries(entries) {
395
+ const dest = [];
396
+ if (Array.isArray(entries)) {
397
+ for (const [k, v] of entries)
398
+ dest[k] = v;
399
+ }
400
+ else {
401
+ for (const [k, v] of Object.entries(entries))
402
+ dest[+k] = v;
403
+ }
404
+ return dest;
405
+ }
406
+ function sparseCopyUndefined(bits, other, xor = 0) {
407
+ for (const i in other) {
408
+ if (bits[i] === undefined)
409
+ bits[i] = other[i] ^ xor;
410
+ }
411
+ return bits;
412
+ }
413
+ function sparseClean(bits, undef = 0) {
414
+ for (const i in bits) {
415
+ if (bits[i] === undef)
416
+ delete bits[i];
417
+ }
418
+ }
419
+ function sparseTest(bits, a, undef = 0) {
420
+ return !!((bits[a >> 5] ?? undef) & (1 << (a & 0x1f)));
421
+ }
422
+ function sparseSetMask(bits, i, m, undef = 0) {
423
+ if (bits[i] !== undefined)
424
+ bits[i] |= m;
425
+ else if (!undef)
426
+ bits[i] = m;
427
+ }
428
+ function sparseClearMask(bits, i, m, undef = 0) {
429
+ if (bits[i] !== undefined)
430
+ bits[i] &= ~m;
431
+ else if (undef)
432
+ bits[i] = ~m;
433
+ }
434
+ function sparseSetRange(bits, a, b, undef = 0) {
435
+ let i = a >> 5, j = b >> 5;
436
+ if (i === j) {
437
+ sparseSetMask(bits, i, (1 << (b & 0x1f)) - (1 << (a & 0x1f)), undef);
438
+ }
439
+ else {
440
+ sparseSetMask(bits, i++, -(1 << (a & 0x1f)), undef);
441
+ if (undef) {
442
+ while (i < j)
443
+ delete bits[i++];
444
+ }
445
+ else {
446
+ while (i < j)
447
+ bits[i++] = -1;
448
+ }
449
+ sparseSetMask(bits, i, (1 << (b & 0x1f)) - 1, undef);
450
+ }
451
+ }
452
+ function sparseClearRange(bits, a, b, undef = 0) {
453
+ let i = a >> 5, j = b >> 5;
454
+ if (i === j) {
455
+ sparseClearMask(bits, i, (1 << (b & 0x1f)) - (1 << (a & 0x1f)), undef);
456
+ }
457
+ else {
458
+ sparseClearMask(bits, i++, -(1 << (a & 0x1f)), undef);
459
+ if (!undef) {
460
+ while (i < j)
461
+ delete bits[i++];
268
462
  }
269
463
  else {
270
- let i = from >> 5;
271
- let v = ((bits[i] ?? undef) ^ ~undef) & -(1 << (from & 0x1f));
272
- for (;;) {
464
+ while (i < j)
465
+ bits[i++] = 0;
466
+ }
467
+ sparseClearMask(bits, i, (1 << (b & 0x1f)) - 1, undef);
468
+ }
469
+ }
470
+ function sparseCountSet(bits) {
471
+ let count = 0;
472
+ for (const i in bits)
473
+ count += countSet32(bits[i]);
474
+ return count;
475
+ }
476
+ function sparseNthSet(bits, a, undef = 0) {
477
+ if (undef === 0) {
478
+ for (const i in bits) {
479
+ const v = bits[i];
480
+ const n = countSet32(v);
481
+ if (a < n)
482
+ return (+i << 5) + nthSet32(v, a);
483
+ a -= n;
484
+ }
485
+ }
486
+ else {
487
+ let prev = 0;
488
+ for (const i in bits) {
489
+ const m = (+i - prev) << 5;
490
+ if (a < m)
491
+ return (prev << 5) + a;
492
+ a -= m;
493
+ const v = bits[i];
494
+ const n = countSet32(v);
495
+ if (a < n)
496
+ return (+i << 5) + nthSet32(v, a);
497
+ a -= n;
498
+ prev = +i + 1;
499
+ }
500
+ }
501
+ return -1;
502
+ }
503
+ function sparseComplement(bits) {
504
+ return bits.map(b => ~b);
505
+ }
506
+ function sparseIntersect(bits, other, undef = 0) {
507
+ return bits.map((b, i) => b & (other[i] ?? undef));
508
+ }
509
+ function sparseUnion(bits, other, undef = 0) {
510
+ return bits.map((b, i) => b | (other[i] ?? undef));
511
+ }
512
+ function sparseXor(bits, other, undef = 0) {
513
+ return bits.map((b, i) => b ^ (other[i] ?? undef));
514
+ }
515
+ function sparseSelfComplement(bits) {
516
+ for (const i in bits)
517
+ bits[i] = ~bits[i];
518
+ return bits;
519
+ }
520
+ function sparseSelfIntersect(bits, other) {
521
+ for (const i in bits)
522
+ bits[i] &= other[i];
523
+ return bits;
524
+ }
525
+ function sparseSelfUnion(bits, other) {
526
+ for (const i in bits)
527
+ bits[i] |= other[i];
528
+ return bits;
529
+ }
530
+ function sparseSelfXor(bits, other) {
531
+ for (const i in bits)
532
+ bits[i] ^= other[i];
533
+ return bits;
534
+ }
535
+ function sparseContains(bits, other, undef = 0) {
536
+ for (const i in other) {
537
+ if (other[i] & ~(bits[i] ?? undef))
538
+ return false;
539
+ }
540
+ return true;
541
+ }
542
+ function sparseNext(bits, from, set = true, undef = 0) {
543
+ ++from;
544
+ if (undef ? !set : set) {
545
+ const ai = from >> 5;
546
+ for (const i in bits) {
547
+ if (+i >= ai) {
548
+ const v = bits[i] ^ undef;
549
+ if (v)
550
+ return (+i << 5) + lowestSet32(v);
551
+ }
552
+ }
553
+ return -1;
554
+ }
555
+ else {
556
+ let i = from >> 5;
557
+ if (bits[i] === undefined)
558
+ return from;
559
+ let v = (bits[i] ^ undef) | ((1 << (from & 0x1f)) - 1);
560
+ while (!v) {
561
+ ++i;
562
+ if (bits[i] === undefined)
563
+ break;
564
+ v = bits[i] ^ undef;
565
+ }
566
+ return (i << 5) + lowestSet32(~v);
567
+ }
568
+ }
569
+ function* sparseWhere(bits, set, from = -1, to, undef = 0) {
570
+ ++from;
571
+ const from32 = from >> 5;
572
+ const to32 = to === undefined ? Infinity : to >> 5;
573
+ const fromM = 1 << (from & 0x1f);
574
+ const toM = to === undefined ? 0 : 1 << (to & 0x1f);
575
+ if (undef ? !set : set) {
576
+ for (const k in bits) {
577
+ const i = +k;
578
+ if (i >= to32)
579
+ break;
580
+ if (i >= from32) {
581
+ let v = bits[i] ^ undef;
582
+ if (i === from32)
583
+ v &= -fromM;
584
+ if (i === to32)
585
+ v &= (toM - 1);
273
586
  while (v) {
274
587
  yield (i << 5) + lowestSet32(v);
275
588
  v = v & (v - 1);
276
589
  }
277
- ++i;
278
- v = ((bits[i] ?? undef) ^ ~undef);
279
590
  }
280
591
  }
281
592
  }
282
- constructor(initial = false) {
283
- this.undef = initial ? -1 : 0;
284
- }
285
- create(init) {
286
- return new this.constructor(init);
287
- }
288
- copyUndefined(other) {
289
- for (const i in other.bits) {
290
- if (this.bits[i] === undefined)
291
- this.bits[i] = other.bits[i];
593
+ else {
594
+ if (to32 > from32) {
595
+ for (let v = ((bits[from32] ?? undef) ^ ~undef) & -fromM; v; v = v & (v - 1))
596
+ yield (from32 << 5) + lowestSet32(v);
597
+ for (let i = from32 + 1; i < to32; i++) {
598
+ for (let v = ((bits[i] ?? undef) ^ ~undef); v; v = v & (v - 1))
599
+ yield (i << 5) + lowestSet32(v);
600
+ }
601
+ for (let v = ((bits[to32] ?? undef) ^ ~undef) & (toM - 1); v; v = v & (v - 1))
602
+ yield (to32 << 5) + lowestSet32(v);
292
603
  }
293
- return this;
294
- }
295
- flipUndefined(other) {
296
- for (const i in other.bits) {
297
- if (this.bits[i] === undefined)
298
- this.bits[i] = ~other.bits[i];
604
+ else if (to32 === from32) {
605
+ for (let v = ((bits[from32] ?? undef) ^ ~undef) & (toM - fromM); v; v = v & (v - 1))
606
+ yield (from32 << 5) + lowestSet32(v);
299
607
  }
300
- return this;
301
608
  }
302
- static fromEntries(entries, initial = false) {
303
- const r = new this(initial);
304
- if (Array.isArray(entries)) {
305
- for (const [k, v] of entries)
306
- r.bits[k] = v;
609
+ }
610
+ function* sparseRanges(bits, undef = 0) {
611
+ let start = -1, end = 0;
612
+ for (const i in bits) {
613
+ let b = bits[i] ^ undef;
614
+ const c0 = +i * 32;
615
+ while ((start < 0 ? b : ~b) !== 0) {
616
+ if (start === -1) {
617
+ start = c0 + lowestSet32(b);
618
+ if (undef)
619
+ yield [end, start];
620
+ end = -1;
621
+ b = b | (b - 1);
622
+ }
623
+ else {
624
+ end = c0 + lowestSet32(~b);
625
+ if (!undef)
626
+ yield [start, end];
627
+ start = -1;
628
+ b = b & (b + 1);
629
+ }
307
630
  }
308
- else {
309
- for (const [k, v] of Object.entries(entries))
310
- r.bits[+k] = v;
631
+ if (start >= 0 && bits[+i + 1] === undefined) {
632
+ if (!undef)
633
+ yield [start, c0 + 32];
634
+ start = -1;
311
635
  }
636
+ }
637
+ if (undef)
638
+ yield [end, Infinity];
639
+ }
640
+ function sparseSlice(bits, from, to) {
641
+ const from32 = from >> 5;
642
+ const to32 = to === undefined ? Infinity : to >> 5;
643
+ const fromBit = from & 0x1f;
644
+ const toBit = to === undefined ? 0 : to & 0x1f;
645
+ const result = [];
646
+ for (const i in bits) {
647
+ const idx = +i;
648
+ if (idx < from32 || idx > to32)
649
+ continue;
650
+ let b = bits[i];
651
+ // Mask start bits
652
+ if (idx === from32)
653
+ b &= -(1 << fromBit);
654
+ // Mask end bits
655
+ if (idx === to32 && to !== undefined)
656
+ b &= (1 << toBit) - 1;
657
+ if (b !== 0)
658
+ result[i] = b;
659
+ }
660
+ return result;
661
+ }
662
+ class ImmutableSparseBits {
663
+ bits;
664
+ constructor(bits = []) {
665
+ this.bits = bits;
666
+ }
667
+ create(bits = []) {
668
+ return new this.constructor(bits);
669
+ }
670
+ static fromEntries(entries, ...args) {
671
+ const r = new this(...args);
672
+ r.bits = sparseFromEntries(entries);
312
673
  return r;
313
674
  }
314
675
  keys() {
315
676
  return Object.keys(this.bits).map(k => +k);
316
677
  }
317
678
  entries() {
318
- //return this.bits;
319
679
  return Object.entries(this.bits).map(([k, v]) => [+k, v]);
320
680
  }
321
681
  test(a) {
322
- return !!((this.bits[a >> 5] ?? this.undef) & (1 << (a & 0x1f)));
682
+ return sparseTest(this.bits, a);
323
683
  }
324
684
  countSet() {
325
- let count = 0;
326
- for (const i in this.bits)
327
- count += countSet32(this.bits[i]);
328
- return count;
685
+ return sparseCountSet(this.bits);
329
686
  }
330
687
  nthSet(a) {
331
- if (this.undef === 0) {
332
- for (const i in this.bits) {
333
- const v = this.bits[i];
334
- const n = countSet32(v);
335
- if (a < n)
336
- return (+i << 5) + nthSet32(v, a);
337
- a -= n;
338
- }
339
- }
340
- else {
341
- let prev = 0;
342
- for (const i in this.bits) {
343
- const m = (+i - prev) << 5;
344
- if (a < m)
345
- return (prev << 5) + a;
346
- a -= m;
347
- const v = this.bits[i];
348
- const n = countSet32(v);
349
- if (a < n)
350
- return (+i << 5) + nthSet32(v, a);
351
- a -= n;
352
- prev = +i + 1;
353
- }
354
- }
355
- return -1;
688
+ return sparseNthSet(this.bits, a);
356
689
  }
357
690
  complement() {
358
- const result = this.create(this.undef === 0);
359
- for (const i in this.bits)
360
- result.bits[i] = ~this.bits[i];
361
- return result;
691
+ return new ImmutableSparseBits2(sparseComplement(this.bits), true);
362
692
  }
363
693
  intersect(other) {
364
- const result = this.create(!!(this.undef & other.undef));
365
- for (const i in this.bits)
366
- result.bits[i] = this.bits[i] & other.bits[i];
367
- return this.undef ? result.copyUndefined(other) : result;
694
+ return this.create(sparseIntersect(this.bits, other.bits));
368
695
  }
369
696
  union(other) {
370
- const result = this.create(!!(this.undef | other.undef));
371
- for (const i in other.bits)
372
- result.bits[i] = this.bits[i] | other.bits[i];
373
- return this.undef ? result : result.copyUndefined(other);
697
+ return this.create(sparseCopyUndefined(sparseUnion(this.bits, other.bits), other.bits));
374
698
  }
375
699
  xor(other) {
376
- const result = this.create(!!(this.undef ^ other.undef));
377
- for (const i in this.bits)
378
- result.bits[i] = this.bits[i] ^ other.bits[i];
379
- return this.undef ? result.flipUndefined(other) : result.copyUndefined(other);
700
+ return this.create(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits));
380
701
  }
381
702
  contains(other) {
382
- if (other.undef && !this.undef)
383
- return false;
384
- for (const i in other.bits) {
385
- if (other.bits[i] & ~(this.bits[i] ?? this.undef))
386
- return false;
387
- }
388
- return true;
703
+ return sparseContains(this.bits, other.bits);
389
704
  }
390
- next(a, set = true) {
391
- ++a;
392
- const xor = this.undef;
393
- if (xor)
394
- set = !set;
395
- if (set) {
396
- const keys = Object.keys(this.bits).map(k => +k);
397
- if (keys.length === 0)
398
- return -1;
399
- const ai = a >> 5;
400
- let i = (0, algorithm_1.lowerBound)(keys, ai);
401
- let v = this.bits[keys[i]] ^ xor;
402
- if (keys[i] === ai)
403
- v &= -(1 << (a & 0x1f));
404
- while (!v) {
405
- ++i;
406
- if (i === keys.length)
407
- return -1;
408
- v = this.bits[keys[i]] ^ xor;
409
- }
410
- return (keys[i] << 5) + lowestSet32(v);
411
- }
412
- else {
413
- let i = a >> 5;
414
- if (this.bits[i] === undefined)
415
- return a;
416
- let v = (this.bits[i] ^ xor) | ((1 << (a & 0x1f)) - 1);
417
- while (!v) {
418
- ++i;
419
- if (this.bits[i] === undefined)
420
- break;
421
- v = this.bits[i] ^ xor;
422
- }
423
- return (i << 5) + lowestSet32(~v);
424
- }
705
+ next(from, set = true) {
706
+ return sparseNext(this.bits, from, set);
425
707
  }
426
- where(set, from = -1) {
708
+ where(set, from = -1, to) {
427
709
  return {
428
- [Symbol.iterator]: () => ImmutableSparseBits.whereGenerator(this.bits, this.undef, set, from)
710
+ [Symbol.iterator]: () => sparseWhere(this.bits, set, from, to)
429
711
  };
430
712
  }
431
713
  ranges() {
432
- const bits = this.bits;
433
- const undef = this.undef;
434
714
  return {
435
- *[Symbol.iterator]() {
436
- let start = -1, end = 0;
437
- for (const i in bits) {
438
- let b = bits[i] ^ undef;
439
- const c0 = +i * 32;
440
- while ((start < 0 ? b : ~b) !== 0) {
441
- if (start === -1) {
442
- start = c0 + lowestSet32(b);
443
- if (undef)
444
- yield [end, start];
445
- end = -1;
446
- b = b | (b - 1);
447
- }
448
- else {
449
- end = c0 + lowestSet32(~b);
450
- if (!undef)
451
- yield [start, end];
452
- start = -1;
453
- b = b & (b + 1);
454
- }
455
- }
456
- if (start >= 0 && bits[+i + 1] === undefined) {
457
- if (!undef)
458
- yield [start, c0 + 32];
459
- start = -1;
460
- }
461
- }
462
- if (undef)
463
- yield [end, Infinity];
464
- }
715
+ [Symbol.iterator]: () => sparseRanges(this.bits)
465
716
  };
466
717
  }
467
718
  *[Symbol.iterator]() {
468
- yield* ImmutableSparseBits.whereGenerator(this.bits, this.undef, true, -1);
469
- //for (let i = this.next(-1); i !== -1; i = this.next(i))
470
- // yield i;
719
+ yield* sparseWhere(this.bits, true, -1);
471
720
  }
472
721
  clean() {
473
- for (const i in this.bits) {
474
- if (this.bits[i] === this.undef)
475
- delete this.bits[i];
476
- }
722
+ sparseClean(this.bits);
477
723
  return this;
478
724
  }
479
725
  toDense() {
480
726
  let bits = 0n;
481
- if (this.undef) {
482
- for (const i in this.bits)
483
- bits |= BigInt(~this.bits[i]) << BigInt(+i * 32);
484
- bits = ~bits;
485
- }
486
- else {
487
- for (const i in this.bits)
488
- bits |= BigInt(this.bits[i]) << BigInt(+i * 32);
489
- }
727
+ for (const i in this.bits)
728
+ bits |= BigInt(this.bits[i]) << BigInt(+i * 32);
490
729
  return new DenseBits(bits);
491
730
  }
731
+ slice(from, to) {
732
+ return this.create(sparseSlice(this.bits, from, to));
733
+ }
492
734
  }
493
735
  exports.ImmutableSparseBits = ImmutableSparseBits;
494
736
  class SparseBits extends ImmutableSparseBits {
495
- setMask(i, m) {
496
- if (this.bits[i] !== undefined)
497
- this.bits[i] |= m;
498
- else if (!this.undef)
499
- this.bits[i] = m;
500
- }
501
- clearMask(i, m) {
502
- if (this.bits[i] !== undefined)
503
- this.bits[i] &= ~m;
504
- else if (this.undef)
505
- this.bits[i] = ~m;
506
- }
507
737
  set(a) {
508
- this.setMask(a >> 5, 1 << (a & 0x1f));
738
+ sparseSetMask(this.bits, a >> 5, 1 << (a & 0x1f));
509
739
  }
510
740
  clear(a) {
511
- this.clearMask(a >> 5, 1 << (a & 0x1f));
741
+ sparseClearMask(this.bits, a >> 5, 1 << (a & 0x1f));
512
742
  }
513
743
  setRange(a, b) {
514
- let i = a >> 5, j = b >> 5;
515
- if (i === j) {
516
- this.setMask(i, (1 << (b & 0x1f)) - (1 << (a & 0x1f)));
517
- }
518
- else {
519
- this.setMask(i++, -(1 << (a & 0x1f)));
520
- if (this.undef) {
521
- while (i < j)
522
- delete this.bits[i++];
523
- }
524
- else {
525
- while (i < j)
526
- this.bits[i++] = -1;
527
- }
528
- this.setMask(i, (1 << (b & 0x1f)) - 1);
529
- }
744
+ sparseSetRange(this.bits, a, b);
530
745
  return this;
531
746
  }
532
747
  clearRange(a, b) {
533
- let i = a >> 5, j = b >> 5;
534
- if (i === j) {
535
- this.clearMask(i, (1 << (b & 0x1f)) - (1 << (a & 0x1f)));
536
- }
537
- else {
538
- this.clearMask(i++, -(1 << (a & 0x1f)));
539
- if (!this.undef) {
540
- while (i < j)
541
- delete this.bits[i++];
542
- }
543
- else {
544
- while (i < j)
545
- this.bits[i++] = 0;
546
- }
547
- this.clearMask(i, (1 << (b & 0x1f)) - 1);
548
- }
549
- return this;
550
- }
551
- selfComplement() {
552
- this.undef = ~this.undef;
553
- for (const i in this.bits)
554
- this.bits[i] = ~this.bits[i];
748
+ sparseClearRange(this.bits, a, b);
555
749
  return this;
556
750
  }
557
751
  selfIntersect(other) {
558
- for (const i in this.bits)
559
- this.bits[i] &= other.bits[i];
560
- if (this.undef)
561
- this.copyUndefined(other);
562
- this.undef &= other.undef;
752
+ sparseSelfIntersect(this.bits, other.bits);
563
753
  return this;
564
754
  }
565
755
  selfUnion(other) {
566
- for (const i in other.bits)
567
- this.bits[i] |= other.bits[i];
568
- if (!this.undef)
569
- this.copyUndefined(other);
570
- this.undef |= other.undef;
756
+ sparseCopyUndefined(sparseSelfUnion(this.bits, other.bits), other.bits);
571
757
  return this;
572
758
  }
573
759
  selfXor(other) {
574
- for (const i in this.bits)
575
- this.bits[i] ^= other.bits[i];
576
- if (this.undef)
577
- this.flipUndefined(other);
578
- else
579
- this.copyUndefined(other);
580
- this.undef &= other.undef;
760
+ sparseCopyUndefined(sparseSelfXor(this.bits, other.bits), other.bits);
581
761
  return this;
582
762
  }
583
763
  }
584
764
  exports.SparseBits = SparseBits;
585
765
  ;
586
766
  //-----------------------------------------------------------------------------
587
- // DenseBits - a dense bitset implementation using bigint
767
+ // SparseBits2 as above, with an 'undef' member indicating whether undefined entries are treated as 0 or 0xffffffff
588
768
  //-----------------------------------------------------------------------------
589
- class ImmutableDenseBits {
590
- bits;
591
- constructor(bits = 0n) {
592
- this.bits = bits;
593
- }
594
- create(bits) {
595
- return new this.constructor(bits);
769
+ class ImmutableSparseBits2 extends ImmutableSparseBits {
770
+ undef;
771
+ constructor(bits = [], initial = false) {
772
+ super(bits);
773
+ this.undef = initial ? -1 : 0;
596
774
  }
597
- get length() {
598
- return highestSet(this.bits);
775
+ create(bits = [], init) {
776
+ return new this.constructor(bits, init);
599
777
  }
600
778
  test(a) {
601
- return !!(this.bits & (1n << BigInt(a)));
602
- }
603
- countSet() {
604
- return countSet(this.bits);
779
+ return sparseTest(this.bits, a, this.undef);
605
780
  }
606
781
  nthSet(a) {
607
- return nthSet(this.bits, a);
782
+ return sparseNthSet(this.bits, a, this.undef);
608
783
  }
609
784
  complement() {
610
- return this.create(~this.bits);
785
+ return this.create(sparseComplement(this.bits), this.undef === 0);
611
786
  }
612
787
  intersect(other) {
613
- return this.create(this.bits & other.bits);
788
+ if (this.undef)
789
+ return this.create(sparseCopyUndefined(sparseIntersect(this.bits, other.bits, other.undef), other.bits), !!other.undef);
790
+ return this.create(sparseIntersect(this.bits, other.bits), false);
614
791
  }
615
792
  union(other) {
616
- return this.create(this.bits | other.bits);
793
+ if (this.undef)
794
+ return this.create(sparseUnion(this.bits, other.bits), true);
795
+ return this.create(sparseCopyUndefined(sparseUnion(this.bits, other.bits), other.bits), !!other.undef);
617
796
  }
618
797
  xor(other) {
619
- return this.create(this.bits ^ other.bits);
798
+ return this.create(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits, this.undef), !!(this.undef ^ other.undef));
620
799
  }
621
800
  contains(other) {
622
- return (this.bits & other.bits) === other.bits;
801
+ if (other.undef && !this.undef)
802
+ return false;
803
+ return sparseContains(this.bits, other.bits, this.undef);
623
804
  }
624
- next(a, set = true) {
625
- let s = this.bits >> BigInt(a + 1);
626
- s = set ? s & -s : (s + 1n) & ~s;
627
- return s ? a + highestSet(s) : -1;
805
+ next(from, set = true) {
806
+ return sparseNext(this.bits, from, set, this.undef);
628
807
  }
629
- where(set, from = -1) {
630
- let bits = this.bits >> BigInt(from + 1);
631
- return {
632
- *[Symbol.iterator]() {
633
- while (bits) {
634
- const i = highestSet(set ? bits & -bits : (bits + 1n) & ~bits);
635
- from += i;
636
- yield from;
637
- bits >>= BigInt(i);
638
- }
639
- }
640
- };
641
- /*
642
- const self = this;
808
+ where(set, from = -1, to) {
643
809
  return {
644
- *[Symbol.iterator](): Generator<number> {
645
- for (let i = self.next(-1, set); i !== -1; i = self.next(i, set))
646
- yield i;
647
- }
810
+ [Symbol.iterator]: () => sparseWhere(this.bits, set, from, to, this.undef)
648
811
  };
649
- */
650
812
  }
651
813
  ranges() {
652
- let bits = this.bits;
653
814
  return {
654
- *[Symbol.iterator]() {
655
- let offset = 0;
656
- while (bits) {
657
- const i = highestSet(bits & -bits);
658
- bits >>= BigInt(i);
659
- const j = highestSet(~bits & (bits + 1n));
660
- bits >>= BigInt(j);
661
- yield [offset + i - 1, offset + i + j - 1];
662
- offset += i + j;
663
- }
664
- }
815
+ [Symbol.iterator]: () => sparseRanges(this.bits, this.undef)
665
816
  };
666
817
  }
667
818
  *[Symbol.iterator]() {
668
- yield* this.where(true);
669
- //for (let i = this.next(-1); i !== -1; i = this.next(i))
670
- // yield i;
819
+ yield* sparseWhere(this.bits, true, -1, undefined, this.undef);
671
820
  }
672
- toSparse() {
673
- const sparse = {};
674
- for (let bits = this.bits, i = 0; bits; bits >>= 32n, i++) {
675
- const v = Number(bits & 0xffffffffn);
676
- if (v)
677
- sparse[i] = v;
678
- }
679
- return SparseBits.fromEntries(sparse, false);
821
+ clean() {
822
+ sparseClean(this.bits, this.undef);
823
+ return this;
680
824
  }
681
- }
682
- exports.ImmutableDenseBits = ImmutableDenseBits;
683
- ;
684
- class DenseBits extends ImmutableDenseBits {
685
- setMask(m) {
686
- this.bits |= m;
825
+ toDense() {
826
+ let bits = 0n;
827
+ if (this.undef) {
828
+ for (const i in this.bits)
829
+ bits |= BigInt(~this.bits[i]) << BigInt(+i * 32);
830
+ bits = ~bits;
831
+ }
832
+ else {
833
+ for (const i in this.bits)
834
+ bits |= BigInt(this.bits[i]) << BigInt(+i * 32);
835
+ }
836
+ return new DenseBits(bits);
687
837
  }
688
- clearMask(m) {
689
- this.bits &= ~m;
838
+ slice(from, to) {
839
+ return this.create(sparseSlice(this.bits, from, to), !!this.undef);
690
840
  }
841
+ }
842
+ exports.ImmutableSparseBits2 = ImmutableSparseBits2;
843
+ class SparseBits2 extends ImmutableSparseBits2 {
691
844
  set(a) {
692
- this.setMask(1n << BigInt(a));
845
+ sparseSetMask(this.bits, a >> 5, 1 << (a & 0x1f), this.undef);
693
846
  }
694
847
  clear(a) {
695
- this.clearMask(1n << BigInt(a));
848
+ sparseClearMask(this.bits, a >> 5, 1 << (a & 0x1f), this.undef);
696
849
  }
697
850
  setRange(a, b) {
698
- this.setMask((1n << BigInt(b)) - (1n << BigInt(a)));
851
+ sparseSetRange(this.bits, a, b, this.undef);
699
852
  return this;
700
853
  }
701
854
  clearRange(a, b) {
702
- this.clearMask((1n << BigInt(b)) - (1n << BigInt(a)));
855
+ sparseClearRange(this.bits, a, b, this.undef);
703
856
  return this;
704
857
  }
705
858
  selfComplement() {
706
- this.bits = ~this.bits;
859
+ this.undef = ~this.undef;
860
+ sparseSelfComplement(this.bits);
707
861
  return this;
708
862
  }
709
863
  selfIntersect(other) {
710
- this.bits &= other.bits;
864
+ sparseSelfIntersect(this.bits, other.bits);
865
+ if (this.undef) {
866
+ sparseCopyUndefined(this.bits, other.bits);
867
+ this.undef = other.undef;
868
+ }
711
869
  return this;
712
870
  }
713
871
  selfUnion(other) {
714
- this.bits |= other.bits;
872
+ sparseSelfUnion(this.bits, other.bits);
873
+ if (!this.undef) {
874
+ sparseCopyUndefined(this.bits, other.bits);
875
+ this.undef = other.undef;
876
+ }
715
877
  return this;
716
878
  }
717
879
  selfXor(other) {
718
- this.bits ^= other.bits;
880
+ sparseSelfXor(this.bits, other.bits);
881
+ sparseCopyUndefined(this.bits, other.bits, this.undef);
882
+ this.undef ^= other.undef;
719
883
  return this;
720
884
  }
721
885
  }
722
- exports.DenseBits = DenseBits;
886
+ exports.SparseBits2 = SparseBits2;
723
887
  ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isopodlabs/utilities",
3
- "version": "1.5.9",
3
+ "version": "1.6.0",
4
4
  "description": "Various typescript helpers.",
5
5
  "repository": {
6
6
  "type": "git",