@isopodlabs/utilities 1.6.0 → 1.7.1

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 +111 -49
  2. package/dist/bits.js +554 -114
  3. package/package.json +1 -1
package/dist/bits.d.ts CHANGED
@@ -3,36 +3,40 @@ export declare function highestSet32(x: number): number;
3
3
  export declare function highestSet1024(x: number): number;
4
4
  export declare function countSet32(x: number): number;
5
5
  export declare function nthSet32(x: number, i: number): number;
6
+ export declare function reverse32(x: number): number;
6
7
  export declare function highestSet(x: bigint | number): number;
7
8
  export declare function lowestSet(x: number | bigint): number;
8
9
  export declare function countSet(x: bigint | number): number;
9
10
  export declare function nthSet(x: bigint | number, i: number): number;
11
+ export declare function reverse(x: number): number;
12
+ export declare function reverse(x: bigint): bigint;
10
13
  export declare function highestClear(x: number | bigint): number;
11
14
  export declare function lowestClear(x: number | bigint): number;
12
15
  export declare function countClear(x: bigint | number): number;
13
16
  export declare function clearLowest(x: bigint): bigint;
14
17
  export declare function clearLowest(x: number): number;
15
18
  export declare function clearLowest(x: bigint | number): bigint | number;
16
- export interface ImmutableBitSet {
19
+ export interface BitSet {
17
20
  test(a: number): boolean;
21
+ equals(other: this): boolean;
22
+ contains(other: this): boolean;
23
+ intersects(other: this): boolean;
18
24
  countSet(): number;
19
25
  nthSet(a: number): number;
20
- complement(): ImmutableBitSet;
21
- intersect(other: this): ImmutableBitSet;
22
- union(other: this): ImmutableBitSet;
23
- xor(other: this): ImmutableBitSet;
24
- contains(other: this): boolean;
26
+ complement(): BitSet;
27
+ intersect(other: this): BitSet;
28
+ union(other: this): BitSet;
29
+ xor(other: this): BitSet;
30
+ difference(other: this): BitSet;
25
31
  next(a: number, set: boolean): number;
26
32
  where(set: boolean, from?: number, to?: number): {
27
33
  [Symbol.iterator](): Generator<number>;
28
34
  };
29
- ranges(): {
30
- [Symbol.iterator](): Generator<number[]>;
35
+ ranges(set?: boolean): {
36
+ [Symbol.iterator](): Generator<[number, number]>;
31
37
  };
32
- slice(from: number, to?: number): ImmutableBitSet;
38
+ slice(from: number, to?: number): BitSet;
33
39
  [Symbol.iterator](): Generator<number>;
34
- }
35
- export interface BitSet extends ImmutableBitSet {
36
40
  set(a: number): void;
37
41
  clear(a: number): void;
38
42
  setRange(a: number, b: number): this;
@@ -41,32 +45,35 @@ export interface BitSet extends ImmutableBitSet {
41
45
  selfIntersect(other: this): this;
42
46
  selfUnion(other: this): this;
43
47
  selfXor(other: this): this;
48
+ selfDifference(other: this): this;
44
49
  }
45
- export declare class ImmutableDenseBits implements ImmutableBitSet {
50
+ export declare class DenseBits implements BitSet {
46
51
  protected bits: bigint;
47
52
  constructor(bits?: bigint);
48
53
  protected create(bits?: bigint): this;
54
+ static fromIndices<C extends new (bits: bigint, ...args: any[]) => any>(this: C, ...indices: number[]): InstanceType<C>;
49
55
  get length(): number;
50
56
  test(a: number): boolean;
57
+ equals(other: this): boolean;
58
+ contains(other: this): boolean;
59
+ intersects(other: this): boolean;
51
60
  countSet(): number;
52
61
  nthSet(a: number): number;
53
62
  complement(): this;
54
- intersect(other: ImmutableDenseBits): this;
55
- union(other: ImmutableDenseBits): this;
56
- xor(other: ImmutableDenseBits): this;
57
- contains(other: this): boolean;
63
+ intersect(other: DenseBits): this;
64
+ union(other: DenseBits): this;
65
+ xor(other: DenseBits): this;
66
+ difference(other: DenseBits): this;
58
67
  next(a: number, set?: boolean): number;
59
68
  where(set: boolean, from?: number, to?: number): {
60
69
  [Symbol.iterator](): Generator<number>;
61
70
  };
62
- ranges(): {
63
- [Symbol.iterator](): Generator<number[]>;
71
+ ranges(set?: boolean): {
72
+ [Symbol.iterator](): Generator<[number, number]>;
64
73
  };
65
74
  [Symbol.iterator](): Generator<number>;
66
- toSparse(): SparseBits2;
67
- slice(from: number, to?: number): ImmutableBitSet;
68
- }
69
- export declare class DenseBits extends ImmutableDenseBits implements BitSet {
75
+ toSparse(): SparseBits;
76
+ slice(from: number, to?: number): BitSet;
70
77
  protected setMask(m: bigint): void;
71
78
  protected clearMask(m: bigint): void;
72
79
  set(a: number): void;
@@ -77,35 +84,84 @@ export declare class DenseBits extends ImmutableDenseBits implements BitSet {
77
84
  selfIntersect(other: DenseBits): this;
78
85
  selfUnion(other: DenseBits): this;
79
86
  selfXor(other: DenseBits): this;
87
+ selfDifference(other: DenseBits): this;
80
88
  }
81
- export declare class ImmutableSparseBits implements ImmutableBitSet {
82
- protected bits: number[];
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;
89
+ export declare class DenseBits32 implements BitSet {
90
+ protected bits: Uint32Array;
91
+ constructor(bits?: Uint32Array);
92
+ protected create(bits?: Uint32Array): this;
93
+ static fromIndices<C extends new (bits: Uint32Array, ...args: any[]) => any>(this: C, ...indices: number[]): InstanceType<C>;
94
+ get length(): number;
95
+ test(a: number): boolean;
96
+ equals(other: this): boolean;
97
+ contains(other: this): boolean;
98
+ intersects(other: this): boolean;
99
+ countSet(): number;
100
+ nthSet(a: number): number;
101
+ complement(): this;
102
+ intersect(other: DenseBits32): this;
103
+ union(other: DenseBits32): this;
104
+ xor(other: DenseBits32): this;
105
+ difference(other: DenseBits32): this;
106
+ next(a: number, set?: boolean): number;
107
+ where(set: boolean, from?: number, to?: number): {
108
+ [Symbol.iterator](): Generator<number>;
109
+ };
110
+ ranges(set?: boolean): {
111
+ [Symbol.iterator](): Generator<[number, number]>;
112
+ };
113
+ [Symbol.iterator](): Generator<number>;
114
+ toSparse(): SparseBits;
115
+ slice(from: number, to?: number): BitSet;
116
+ protected setMask(i: number, m: number): void;
117
+ protected clearMask(i: number, m: number): void;
118
+ set(a: number): void;
119
+ clear(a: number): void;
120
+ setRange(a: number, b: number): this;
121
+ clearRange(a: number, b: number): this;
122
+ selfComplement(): this;
123
+ selfIntersect(other: DenseBits32): this;
124
+ selfUnion(other: DenseBits32): this;
125
+ selfXor(other: DenseBits32): this;
126
+ selfDifference(other: DenseBits32): this;
127
+ clean(): this;
128
+ }
129
+ type sparsebits = Record<number, number>;
130
+ type SparseNumberArray = number[] | sparsebits;
131
+ type ExtraParams<T> = T extends new (bits: SparseNumberArray, ...args: infer P) => any ? P : never;
132
+ export declare class SparseBits implements BitSet {
133
+ protected bits: sparsebits;
134
+ constructor(bits?: SparseNumberArray);
135
+ protected create(bits?: SparseNumberArray): this;
136
+ static fromEntries<C extends new (bits: SparseNumberArray, ...args: any[]) => any>(this: C, entries: sparsebits | [number, number][], ...extra: ExtraParams<C>): InstanceType<C>;
137
+ static fromIndices<C extends new (bits: SparseNumberArray, ...args: any[]) => any>(this: C, ...indices: number[]): InstanceType<C>;
138
+ static fromIndices<C extends new (bits: SparseNumberArray, ...args: any[]) => any>(this: C, indices: number[], ...extra: ExtraParams<C>): InstanceType<C>;
139
+ copy(): this;
140
+ empty(): boolean;
86
141
  keys(): number[];
87
142
  entries(): [number, number][];
88
143
  test(a: number): boolean;
144
+ equals(other: this): boolean;
145
+ contains(other: SparseBits): boolean;
146
+ intersects(other: SparseBits): boolean;
89
147
  countSet(): number;
90
148
  nthSet(a: number): number;
91
- complement(): ImmutableSparseBits2;
92
- intersect(other: ImmutableSparseBits): this;
93
- union(other: ImmutableSparseBits): this;
94
- xor(other: ImmutableSparseBits): this;
95
- contains(other: ImmutableSparseBits): boolean;
149
+ complement(): SparseBits2;
150
+ intersect(other: SparseBits): this;
151
+ union(other: SparseBits): this;
152
+ xor(other: SparseBits): this;
153
+ difference(other: this): BitSet;
96
154
  next(from: number, set?: boolean): number;
97
155
  where(set: boolean, from?: number, to?: number): {
98
156
  [Symbol.iterator]: () => Generator<number, void, unknown>;
99
157
  };
100
- ranges(): {
101
- [Symbol.iterator]: () => Generator<number[], void, unknown>;
158
+ ranges(set?: boolean): {
159
+ [Symbol.iterator]: () => Generator<[number, number], any, any>;
102
160
  };
103
161
  [Symbol.iterator](): Generator<number>;
104
162
  clean(): this;
105
163
  toDense(): DenseBits;
106
- slice(from: number, to?: number): ImmutableBitSet;
107
- }
108
- export declare class SparseBits extends ImmutableSparseBits implements BitSet {
164
+ slice(from: number, to?: number): BitSet;
109
165
  set(a: number): void;
110
166
  clear(a: number): void;
111
167
  setRange(a: number, b: number): this;
@@ -113,31 +169,35 @@ export declare class SparseBits extends ImmutableSparseBits implements BitSet {
113
169
  selfIntersect(other: SparseBits): this;
114
170
  selfUnion(other: SparseBits): this;
115
171
  selfXor(other: SparseBits): this;
172
+ selfDifference(other: this): this;
116
173
  }
117
- export declare class ImmutableSparseBits2 extends ImmutableSparseBits {
174
+ export declare class SparseBits2 extends SparseBits {
118
175
  protected undef: number;
119
- constructor(bits?: number[], initial?: boolean);
120
- protected create(bits?: number[], init?: boolean): this;
176
+ constructor(bits?: SparseNumberArray, initial?: boolean);
177
+ protected create(bits?: SparseNumberArray, initial?: boolean): this;
178
+ copy(): this;
179
+ empty(): boolean;
121
180
  test(a: number): boolean;
181
+ equals(other: this): boolean;
182
+ contains(other: SparseBits2): boolean;
183
+ intersects(other: SparseBits2): boolean;
122
184
  nthSet(a: number): number;
123
185
  complement(): this;
124
- intersect(other: ImmutableSparseBits2): this;
125
- union(other: ImmutableSparseBits2): this;
126
- xor(other: ImmutableSparseBits2): this;
127
- contains(other: ImmutableSparseBits2): boolean;
186
+ intersect(other: SparseBits2): this;
187
+ union(other: SparseBits2): this;
188
+ xor(other: SparseBits2): this;
189
+ difference(other: SparseBits2): BitSet;
128
190
  next(from: number, set?: boolean): number;
129
191
  where(set: boolean, from?: number, to?: number): {
130
192
  [Symbol.iterator]: () => Generator<number, void, unknown>;
131
193
  };
132
- ranges(): {
133
- [Symbol.iterator]: () => Generator<number[], void, unknown>;
194
+ ranges(set?: boolean): {
195
+ [Symbol.iterator]: () => Generator<[number, number], any, any>;
134
196
  };
135
197
  [Symbol.iterator](): Generator<number>;
136
198
  clean(): this;
137
199
  toDense(): DenseBits;
138
- slice(from: number, to?: number): ImmutableBitSet;
139
- }
140
- export declare class SparseBits2 extends ImmutableSparseBits2 implements BitSet {
200
+ slice(from: number, to?: number): BitSet;
141
201
  set(a: number): void;
142
202
  clear(a: number): void;
143
203
  setRange(a: number, b: number): this;
@@ -146,4 +206,6 @@ export declare class SparseBits2 extends ImmutableSparseBits2 implements BitSet
146
206
  selfIntersect(other: SparseBits2): this;
147
207
  selfUnion(other: SparseBits2): this;
148
208
  selfXor(other: SparseBits2): this;
209
+ selfDifference(other: this): this;
149
210
  }
211
+ export {};
package/dist/bits.js CHANGED
@@ -3,16 +3,18 @@
3
3
  // Bit twiddling functions
4
4
  //-----------------------------------------------------------------------------
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SparseBits2 = exports.ImmutableSparseBits2 = exports.SparseBits = exports.ImmutableSparseBits = exports.DenseBits = exports.ImmutableDenseBits = void 0;
6
+ exports.SparseBits2 = exports.SparseBits = exports.DenseBits32 = exports.DenseBits = void 0;
7
7
  exports.lowestSet32 = lowestSet32;
8
8
  exports.highestSet32 = highestSet32;
9
9
  exports.highestSet1024 = highestSet1024;
10
10
  exports.countSet32 = countSet32;
11
11
  exports.nthSet32 = nthSet32;
12
+ exports.reverse32 = reverse32;
12
13
  exports.highestSet = highestSet;
13
14
  exports.lowestSet = lowestSet;
14
15
  exports.countSet = countSet;
15
16
  exports.nthSet = nthSet;
17
+ exports.reverse = reverse;
16
18
  exports.highestClear = highestClear;
17
19
  exports.lowestClear = lowestClear;
18
20
  exports.countClear = countClear;
@@ -65,6 +67,13 @@ function nthSet32(x, i) {
65
67
  ++n;
66
68
  return n;
67
69
  }
70
+ function reverse32(x) {
71
+ x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
72
+ x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
73
+ x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4);
74
+ x = ((x >> 8) & 0x00FF00FF) | ((x & 0x00FF00FF) << 8);
75
+ return (x >> 16) | (x << 16);
76
+ }
68
77
  /*
69
78
  const testersShift: bigint[] = []; //32 << i
70
79
  const testers: bigint[] = []; //1 << (32 << i)
@@ -239,6 +248,38 @@ function nthSet(x, i) {
239
248
  }
240
249
  return n;
241
250
  }
251
+ function reverse(x) {
252
+ if (typeof x === 'number')
253
+ return reverse32(Number(x));
254
+ let k = 5;
255
+ for (let t = x >> 32n; t;)
256
+ t >>= BigInt(1 << k++);
257
+ let n = 1 << k;
258
+ let s = 0;
259
+ if (k === 5) {
260
+ s += highestSet32(Number(x));
261
+ }
262
+ else {
263
+ let t = x;
264
+ while (k >= 10) {
265
+ --k;
266
+ const b = t >> BigInt(1 << k);
267
+ if (b) {
268
+ s += 1 << k;
269
+ t = b;
270
+ }
271
+ }
272
+ s += highestSet1024(Number(t));
273
+ }
274
+ const shift = n - s;
275
+ let mask = (1n << BigInt(n)) - 1n;
276
+ while (n >>= 1) {
277
+ const nb = BigInt(n);
278
+ mask ^= (mask << nb);
279
+ x = ((x >> nb) & mask) | ((x << nb) & ~mask);
280
+ }
281
+ return x >> BigInt(shift);
282
+ }
242
283
  // Returns the index of the highest clear bit
243
284
  function highestClear(x) {
244
285
  return highestSet(~x);
@@ -257,7 +298,7 @@ function clearLowest(x) {
257
298
  //-----------------------------------------------------------------------------
258
299
  // DenseBits - a dense bitset implementation using bigint
259
300
  //-----------------------------------------------------------------------------
260
- class ImmutableDenseBits {
301
+ class DenseBits {
261
302
  bits;
262
303
  constructor(bits = 0n) {
263
304
  this.bits = bits;
@@ -265,12 +306,27 @@ class ImmutableDenseBits {
265
306
  create(bits) {
266
307
  return new this.constructor(bits);
267
308
  }
309
+ static fromIndices(...indices) {
310
+ let bits = 0n;
311
+ for (const i of indices)
312
+ bits |= 1n << BigInt(i);
313
+ return new this(bits);
314
+ }
268
315
  get length() {
269
316
  return highestSet(this.bits);
270
317
  }
271
318
  test(a) {
272
319
  return !!(this.bits & (1n << BigInt(a)));
273
320
  }
321
+ equals(other) {
322
+ return this.bits === other.bits;
323
+ }
324
+ contains(other) {
325
+ return (this.bits & other.bits) === other.bits;
326
+ }
327
+ intersects(other) {
328
+ return (this.bits & other.bits) !== 0n;
329
+ }
274
330
  countSet() {
275
331
  return countSet(this.bits);
276
332
  }
@@ -289,8 +345,8 @@ class ImmutableDenseBits {
289
345
  xor(other) {
290
346
  return this.create(this.bits ^ other.bits);
291
347
  }
292
- contains(other) {
293
- return (this.bits & other.bits) === other.bits;
348
+ difference(other) {
349
+ return this.create(this.bits & ~other.bits);
294
350
  }
295
351
  next(a, set = true) {
296
352
  let s = this.bits >> BigInt(a + 1);
@@ -312,17 +368,20 @@ class ImmutableDenseBits {
312
368
  }
313
369
  };
314
370
  }
315
- ranges() {
371
+ ranges(set = true) {
316
372
  let bits = this.bits;
317
373
  return {
318
374
  *[Symbol.iterator]() {
319
375
  let offset = 0;
320
376
  while (bits) {
321
377
  const i = highestSet(bits & -bits);
378
+ if (!set && offset + i > 1)
379
+ yield [offset ? offset - 1 : 0, offset + i - 1];
322
380
  bits >>= BigInt(i);
323
381
  const j = highestSet(~bits & (bits + 1n));
324
382
  bits >>= BigInt(j);
325
- yield [offset + i - 1, offset + i + j - 1];
383
+ if (set)
384
+ yield [offset + i - 1, offset + i + j - 1];
326
385
  offset += i + j;
327
386
  }
328
387
  }
@@ -332,23 +391,20 @@ class ImmutableDenseBits {
332
391
  yield* this.where(true);
333
392
  }
334
393
  toSparse() {
335
- const sparse = {};
394
+ const sparse = [];
336
395
  for (let bits = this.bits, i = 0; bits; bits >>= 32n, i++) {
337
396
  const v = Number(bits & 0xffffffffn);
338
397
  if (v)
339
398
  sparse[i] = v;
340
399
  }
341
- return SparseBits2.fromEntries(sparse, false);
400
+ return new SparseBits(sparse);
342
401
  }
343
402
  slice(from, to) {
344
403
  return to === undefined
345
404
  ? this.create(this.bits >> BigInt(from))
346
405
  : this.create(this.bits >> BigInt(from) & ((1n << BigInt(to - from)) - 1n));
347
406
  }
348
- }
349
- exports.ImmutableDenseBits = ImmutableDenseBits;
350
- ;
351
- class DenseBits extends ImmutableDenseBits {
407
+ // mutating methods
352
408
  setMask(m) {
353
409
  this.bits |= m;
354
410
  }
@@ -385,23 +441,272 @@ class DenseBits extends ImmutableDenseBits {
385
441
  this.bits ^= other.bits;
386
442
  return this;
387
443
  }
444
+ selfDifference(other) {
445
+ this.bits &= ~other.bits;
446
+ return this;
447
+ }
388
448
  }
389
449
  exports.DenseBits = DenseBits;
390
450
  ;
391
451
  //-----------------------------------------------------------------------------
392
- // SparseBits - a sparse bitset implementation, where each entry in the 'bits' array represents 32 bits
452
+ // DenseBits32 - a dense bitset implementation using Uint32Array
393
453
  //-----------------------------------------------------------------------------
394
- function sparseFromEntries(entries) {
395
- const dest = [];
396
- if (Array.isArray(entries)) {
397
- for (const [k, v] of entries)
398
- dest[k] = v;
454
+ class DenseBits32 {
455
+ bits;
456
+ constructor(bits = new Uint32Array(1)) {
457
+ this.bits = bits;
399
458
  }
400
- else {
401
- for (const [k, v] of Object.entries(entries))
402
- dest[+k] = v;
459
+ create(bits) {
460
+ return new this.constructor(bits);
461
+ }
462
+ static fromIndices(...indices) {
463
+ const max = Math.max(...indices);
464
+ const bits = new Uint32Array(Math.ceil((max + 1) / 32));
465
+ for (const i of indices)
466
+ bits[i >>> 5] |= 1 << (i & 31);
467
+ return new this(bits);
468
+ }
469
+ get length() {
470
+ const n = this.bits.length;
471
+ return highestSet32(this.bits[n - 1]) + (n - 1) * 32;
472
+ }
473
+ test(a) {
474
+ return !!(this.bits[a >>> 5] & (1 << (a & 31)));
475
+ }
476
+ equals(other) {
477
+ if (this.bits.length !== other.bits.length)
478
+ return false;
479
+ for (let i = 0; i < this.bits.length; i++) {
480
+ if (this.bits[i] !== other.bits[i])
481
+ return false;
482
+ }
483
+ return true;
484
+ }
485
+ contains(other) {
486
+ return other.bits.every((b, i) => (b & this.bits[i]) === b);
487
+ }
488
+ intersects(other) {
489
+ return this.bits.some((b, i) => (b & other.bits[i]) !== 0);
490
+ }
491
+ countSet() {
492
+ return this.bits.reduce((a, b) => a + countSet32(b), 0);
493
+ }
494
+ nthSet(a) {
495
+ for (let i = 0; i < this.bits.length; i++) {
496
+ const c = countSet32(this.bits[i]);
497
+ if (a < c)
498
+ return i * 32 + nthSet32(this.bits[i], a);
499
+ a -= c;
500
+ }
501
+ return -1;
502
+ }
503
+ complement() {
504
+ return this.create(this.bits.map(b => ~b));
505
+ }
506
+ intersect(other) {
507
+ return this.create(this.bits.map((b, i) => b & other.bits[i]));
508
+ }
509
+ union(other) {
510
+ if (other.bits.length > this.bits.length)
511
+ return this.create(other.bits.map((b, i) => b | this.bits[i]));
512
+ return this.create(this.bits.map((b, i) => b | other.bits[i]));
513
+ }
514
+ xor(other) {
515
+ if (other.bits.length > this.bits.length)
516
+ return this.create(other.bits.map((b, i) => b ^ this.bits[i]));
517
+ return this.create(this.bits.map((b, i) => b ^ other.bits[i]));
518
+ }
519
+ difference(other) {
520
+ return this.create(this.bits.map((b, i) => b & ~other.bits[i]));
521
+ }
522
+ next(a, set = true) {
523
+ ++a;
524
+ const xor = set ? 0 : -1;
525
+ for (let i = a >>> 5; i < this.bits.length; i++) {
526
+ let b = this.bits[i] ^ xor;
527
+ if (b) {
528
+ if (i === (a >>> 5)) {
529
+ b &= -(1 << (a & 31));
530
+ if (!b)
531
+ continue;
532
+ }
533
+ return i * 32 + lowestSet32(b);
534
+ }
535
+ }
536
+ return -1;
537
+ }
538
+ where(set, from = -1, to) {
539
+ const bits = this.bits;
540
+ ++from;
541
+ to = to === undefined ? bits.length * 32 : Math.min(to, bits.length * 32);
542
+ return {
543
+ *[Symbol.iterator]() {
544
+ const xor = set ? 0 : -1;
545
+ const end = (to + 31) >>> 5;
546
+ for (let i = from >>> 5; i < end; i++) {
547
+ let b = bits[i] ^ xor;
548
+ if (i === (from >>> 5))
549
+ b &= -(1 << (from & 31));
550
+ if (i === end - 1)
551
+ b &= (1 << (to & 31)) - 1;
552
+ while (b) {
553
+ yield i * 32 + lowestSet32(b);
554
+ b = b & (b - 1);
555
+ }
556
+ }
557
+ }
558
+ };
559
+ }
560
+ ranges(set = true) {
561
+ const bits = this.bits;
562
+ return {
563
+ *[Symbol.iterator]() {
564
+ let start = -1, end = 0;
565
+ for (let i = 0; i < bits.length; i++) {
566
+ let b = bits[i];
567
+ const c0 = +i * 32;
568
+ while ((start < 0 ? b : ~b) !== 0) {
569
+ if (start === -1) {
570
+ start = c0 + lowestSet32(b);
571
+ if (!set && end != start)
572
+ yield [end, start];
573
+ end = -1;
574
+ b = b | (b - 1);
575
+ }
576
+ else {
577
+ end = c0 + lowestSet32(~b);
578
+ if (set)
579
+ yield [start, end];
580
+ start = -1;
581
+ b = b & (b + 1);
582
+ }
583
+ }
584
+ }
585
+ if (set) {
586
+ if (start >= 0)
587
+ yield [start, bits.length * 32];
588
+ }
589
+ else {
590
+ yield [end, Infinity];
591
+ }
592
+ }
593
+ };
594
+ }
595
+ *[Symbol.iterator]() {
596
+ yield* this.where(true);
597
+ }
598
+ toSparse() {
599
+ const sparse = [];
600
+ for (let i = 0; i < this.bits.length; i++) {
601
+ const v = this.bits[i];
602
+ if (v)
603
+ sparse[i] = v;
604
+ }
605
+ return new SparseBits(sparse);
606
+ }
607
+ slice(from, to) {
608
+ to = to === undefined ? this.bits.length * 32 : Math.min(to, this.bits.length * 32);
609
+ const fromi = from >>> 5, toi = (to + 31) >>> 5;
610
+ const shift = from & 31;
611
+ const bits = shift === 0
612
+ ? this.bits.slice(fromi, toi)
613
+ : this.bits.subarray(fromi, toi).map((b, i) => (b >>> shift) | (this.bits[fromi + i + 1] << (32 - shift)));
614
+ const maskBits = (to - from) & 31;
615
+ if (maskBits)
616
+ bits[bits.length - 1] &= (1 << maskBits) - 1;
617
+ return this.create(bits);
618
+ }
619
+ // mutating methods
620
+ setMask(i, m) {
621
+ if (i >= this.bits.length) {
622
+ const bits = new Uint32Array(i + 1);
623
+ bits.set(this.bits);
624
+ this.bits = bits;
625
+ }
626
+ this.bits[i] |= m;
627
+ }
628
+ clearMask(i, m) {
629
+ if (i < this.bits.length)
630
+ this.bits[i] &= ~m;
631
+ }
632
+ set(a) {
633
+ this.setMask(a >>> 5, 1 << (a & 31));
634
+ }
635
+ clear(a) {
636
+ this.clearMask(a >>> 5, 1 << (a & 31));
637
+ }
638
+ setRange(a, b) {
639
+ const ai = a >>> 5, bi = b >>> 5;
640
+ if (ai === bi) {
641
+ this.setMask(ai, (1 << (b & 31)) - (1 << (a & 31)));
642
+ }
643
+ else {
644
+ this.setMask(bi, (1 << (b & 31)) - 1);
645
+ this.setMask(ai, -(1 << (a & 31)));
646
+ for (let i = ai + 1; i < bi; i++)
647
+ this.bits[i] = -1;
648
+ }
649
+ return this;
650
+ }
651
+ clearRange(a, b) {
652
+ const ai = a >>> 5, bi = b >>> 5;
653
+ if (ai < this.bits.length) {
654
+ if (ai === bi) {
655
+ this.clearMask(ai, (1 << (b & 31)) - (1 << (a & 31)));
656
+ }
657
+ else {
658
+ this.clearMask(ai, -(1 << (a & 31)));
659
+ if (bi >= this.bits.length) {
660
+ this.bits = this.bits.slice(0, ai + 1);
661
+ }
662
+ else {
663
+ for (let i = ai + 1; i < bi; i++)
664
+ this.bits[i] = 0;
665
+ this.clearMask(bi, (1 << (b & 31)) - 1);
666
+ }
667
+ }
668
+ }
669
+ return this;
670
+ }
671
+ selfComplement() {
672
+ this.bits = this.bits.map(b => ~b);
673
+ return this;
674
+ }
675
+ selfIntersect(other) {
676
+ this.bits = this.bits.map((b, i) => b & other.bits[i]);
677
+ return this;
678
+ }
679
+ selfUnion(other) {
680
+ this.bits = other.bits.length > this.bits.length
681
+ ? other.bits.map((b, i) => b | this.bits[i])
682
+ : this.bits.map((b, i) => b | other.bits[i]);
683
+ return this;
684
+ }
685
+ selfXor(other) {
686
+ this.bits = other.bits.length > this.bits.length
687
+ ? other.bits.map((b, i) => b ^ this.bits[i])
688
+ : this.bits.map((b, i) => b ^ other.bits[i]);
689
+ return this;
690
+ }
691
+ selfDifference(other) {
692
+ this.bits = this.bits.map((b, i) => b & ~other.bits[i]);
693
+ return this;
694
+ }
695
+ clean() {
696
+ let i = this.bits.length;
697
+ while (i-- && this.bits[i] === 0)
698
+ ;
699
+ this.bits = this.bits.slice(0, i + 1);
700
+ return this;
403
701
  }
404
- return dest;
702
+ }
703
+ exports.DenseBits32 = DenseBits32;
704
+ ;
705
+ function sparseFromIndices(indices) {
706
+ const bits = {};
707
+ for (const i of indices)
708
+ bits[i >> 5] |= 1 << (i & 0x1f);
709
+ return bits;
405
710
  }
406
711
  function sparseCopyUndefined(bits, other, xor = 0) {
407
712
  for (const i in other) {
@@ -410,6 +715,13 @@ function sparseCopyUndefined(bits, other, xor = 0) {
410
715
  }
411
716
  return bits;
412
717
  }
718
+ function sparseDeleteUndefined(bits, other) {
719
+ for (const i in bits) {
720
+ if (other[i] === undefined)
721
+ delete bits[i];
722
+ }
723
+ return bits;
724
+ }
413
725
  function sparseClean(bits, undef = 0) {
414
726
  for (const i in bits) {
415
727
  if (bits[i] === undef)
@@ -501,16 +813,46 @@ function sparseNthSet(bits, a, undef = 0) {
501
813
  return -1;
502
814
  }
503
815
  function sparseComplement(bits) {
504
- return bits.map(b => ~b);
816
+ const result = [];
817
+ for (const i in bits)
818
+ result[i] = ~bits[i];
819
+ return result;
820
+ }
821
+ function sparseIntersect(bits, other) {
822
+ const result = [];
823
+ for (const i in bits) {
824
+ if (other[i] !== undefined) {
825
+ result[i] = bits[i] & other[i];
826
+ }
827
+ }
828
+ return result;
505
829
  }
506
- function sparseIntersect(bits, other, undef = 0) {
507
- return bits.map((b, i) => b & (other[i] ?? undef));
830
+ function sparseUnion(bits, other) {
831
+ const result = [];
832
+ for (const i in bits) {
833
+ if (other[i] !== undefined) {
834
+ result[i] = bits[i] | other[i];
835
+ }
836
+ }
837
+ return result;
508
838
  }
509
- function sparseUnion(bits, other, undef = 0) {
510
- return bits.map((b, i) => b | (other[i] ?? undef));
839
+ function sparseXor(bits, other) {
840
+ const result = [];
841
+ for (const i in bits) {
842
+ if (other[i] !== undefined) {
843
+ result[i] = bits[i] ^ other[i];
844
+ }
845
+ }
846
+ return result;
511
847
  }
512
- function sparseXor(bits, other, undef = 0) {
513
- return bits.map((b, i) => b ^ (other[i] ?? undef));
848
+ function sparseDifference(bits, other) {
849
+ const result = [];
850
+ for (const i in bits) {
851
+ if (other[i] !== undefined) {
852
+ result[i] = bits[i] & ~other[i];
853
+ }
854
+ }
855
+ return result;
514
856
  }
515
857
  function sparseSelfComplement(bits) {
516
858
  for (const i in bits)
@@ -519,19 +861,45 @@ function sparseSelfComplement(bits) {
519
861
  }
520
862
  function sparseSelfIntersect(bits, other) {
521
863
  for (const i in bits)
522
- bits[i] &= other[i];
864
+ if (other[i] !== undefined)
865
+ bits[i] &= other[i];
523
866
  return bits;
524
867
  }
525
868
  function sparseSelfUnion(bits, other) {
526
869
  for (const i in bits)
527
- bits[i] |= other[i];
870
+ if (other[i] !== undefined)
871
+ bits[i] |= other[i];
528
872
  return bits;
529
873
  }
530
874
  function sparseSelfXor(bits, other) {
531
875
  for (const i in bits)
532
- bits[i] ^= other[i];
876
+ if (other[i] !== undefined)
877
+ bits[i] ^= other[i];
878
+ return bits;
879
+ }
880
+ function sparseSelfDifference(bits, other) {
881
+ for (const i in bits)
882
+ if (other[i] !== undefined)
883
+ bits[i] &= ~other[i];
533
884
  return bits;
534
885
  }
886
+ function sparseEquals(bits, other) {
887
+ const ka = Object.keys(bits), kb = Object.keys(other);
888
+ if (ka.length !== kb.length)
889
+ return false;
890
+ for (const k of ka) {
891
+ if (bits[+k] !== other[+k])
892
+ return false;
893
+ }
894
+ return true;
895
+ }
896
+ function sparseIntersects(bits, other, undef = 0) {
897
+ for (const i in bits) {
898
+ if ((bits[i] & (other[i] ?? undef)))
899
+ return true;
900
+ }
901
+ return false;
902
+ }
535
903
  function sparseContains(bits, other, undef = 0) {
536
904
  for (const i in other) {
537
905
  if (other[i] & ~(bits[i] ?? undef))
@@ -541,11 +909,12 @@ function sparseContains(bits, other, undef = 0) {
541
909
  }
542
910
  function sparseNext(bits, from, set = true, undef = 0) {
543
911
  ++from;
912
+ const from32 = from >> 5;
913
+ const fromM = 1 << (from & 0x1f);
544
914
  if (undef ? !set : set) {
545
- const ai = from >> 5;
546
915
  for (const i in bits) {
547
- if (+i >= ai) {
548
- const v = bits[i] ^ undef;
916
+ if (+i >= from32) {
917
+ const v = (bits[i] ^ undef) & (+i === from32 ? -fromM : -1);
549
918
  if (v)
550
919
  return (+i << 5) + lowestSet32(v);
551
920
  }
@@ -553,13 +922,12 @@ function sparseNext(bits, from, set = true, undef = 0) {
553
922
  return -1;
554
923
  }
555
924
  else {
556
- let i = from >> 5;
557
- if (bits[i] === undefined)
925
+ if (bits[from32] === undefined)
558
926
  return from;
559
- let v = (bits[i] ^ undef) | ((1 << (from & 0x1f)) - 1);
927
+ let i = from32;
928
+ let v = (bits[i] ^ undef) | (fromM - 1);
560
929
  while (!v) {
561
- ++i;
562
- if (bits[i] === undefined)
930
+ if (bits[++i] === undefined)
563
931
  break;
564
932
  v = bits[i] ^ undef;
565
933
  }
@@ -572,105 +940,119 @@ function* sparseWhere(bits, set, from = -1, to, undef = 0) {
572
940
  const to32 = to === undefined ? Infinity : to >> 5;
573
941
  const fromM = 1 << (from & 0x1f);
574
942
  const toM = to === undefined ? 0 : 1 << (to & 0x1f);
943
+ function* block(i, v) {
944
+ while (v) {
945
+ yield (i << 5) + lowestSet32(v);
946
+ v &= v - 1;
947
+ }
948
+ }
575
949
  if (undef ? !set : set) {
576
950
  for (const k in bits) {
577
951
  const i = +k;
578
- if (i >= to32)
579
- break;
580
952
  if (i >= from32) {
953
+ if (i >= to32)
954
+ break;
581
955
  let v = bits[i] ^ undef;
582
956
  if (i === from32)
583
957
  v &= -fromM;
584
958
  if (i === to32)
585
959
  v &= (toM - 1);
586
- while (v) {
587
- yield (i << 5) + lowestSet32(v);
588
- v = v & (v - 1);
589
- }
960
+ yield* block(i, v);
590
961
  }
591
962
  }
592
963
  }
593
964
  else {
594
965
  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);
966
+ yield* block(from32, ((bits[from32] ?? undef) ^ ~undef) & -fromM);
967
+ for (let i = from32 + 1; i < to32; i++)
968
+ yield* block(i, (bits[i] ?? undef) ^ ~undef);
969
+ yield* block(to32, ((bits[to32] ?? undef) ^ ~undef) & (toM - 1));
603
970
  }
604
971
  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);
972
+ yield* block(from32, ((bits[from32] ?? undef) ^ ~undef) & (-fromM & (toM - 1)));
607
973
  }
608
974
  }
609
975
  }
610
- function* sparseRanges(bits, undef = 0) {
976
+ function* sparseRanges(bits, set, undef = 0) {
611
977
  let start = -1, end = 0;
978
+ let other = undef ? set : !set;
612
979
  for (const i in bits) {
613
980
  let b = bits[i] ^ undef;
614
981
  const c0 = +i * 32;
615
982
  while ((start < 0 ? b : ~b) !== 0) {
616
983
  if (start === -1) {
617
984
  start = c0 + lowestSet32(b);
618
- if (undef)
985
+ if (other && end != start)
619
986
  yield [end, start];
620
987
  end = -1;
621
988
  b = b | (b - 1);
622
989
  }
623
990
  else {
624
991
  end = c0 + lowestSet32(~b);
625
- if (!undef)
992
+ if (!other)
626
993
  yield [start, end];
627
994
  start = -1;
628
995
  b = b & (b + 1);
629
996
  }
630
997
  }
631
998
  if (start >= 0 && bits[+i + 1] === undefined) {
632
- if (!undef)
999
+ if (!other)
633
1000
  yield [start, c0 + 32];
634
1001
  start = -1;
635
1002
  }
636
1003
  }
637
- if (undef)
1004
+ if (other)
638
1005
  yield [end, Infinity];
639
1006
  }
640
1007
  function sparseSlice(bits, from, to) {
641
1008
  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;
1009
+ const fromM = 1 << (from & 0x1f);
1010
+ const to32 = to !== undefined ? to >> 5 : Infinity;
1011
+ const toM = to !== undefined ? 1 << (to & 0x1f) : 0;
645
1012
  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;
1013
+ for (const k in bits) {
1014
+ const i = +k;
1015
+ if (i >= from32) {
1016
+ let b = bits[k];
1017
+ if (i === from32)
1018
+ b &= -fromM;
1019
+ if (i === to32) {
1020
+ b &= toM - 1;
1021
+ if (b !== 0)
1022
+ result[k] = b;
1023
+ break;
1024
+ }
1025
+ if (b !== 0)
1026
+ result[k] = b;
1027
+ }
659
1028
  }
660
1029
  return result;
661
1030
  }
662
- class ImmutableSparseBits {
1031
+ class SparseBits {
663
1032
  bits;
664
1033
  constructor(bits = []) {
665
- this.bits = bits;
1034
+ this.bits = bits; // as Record<number, number>;
666
1035
  }
667
1036
  create(bits = []) {
668
1037
  return new this.constructor(bits);
669
1038
  }
670
- static fromEntries(entries, ...args) {
671
- const r = new this(...args);
672
- r.bits = sparseFromEntries(entries);
673
- return r;
1039
+ static fromEntries(entries, ...extra) {
1040
+ return new this(Array.isArray(entries) ? Object.fromEntries(entries) : entries, ...extra);
1041
+ }
1042
+ static fromIndices(indicesOrFirst, ...rest) {
1043
+ return Array.isArray(indicesOrFirst)
1044
+ ? new this(sparseFromIndices(indicesOrFirst), ...rest)
1045
+ : new this(sparseFromIndices([indicesOrFirst, ...rest]));
1046
+ }
1047
+ copy() {
1048
+ return this.create({ ...this.bits });
1049
+ }
1050
+ empty() {
1051
+ for (const i in this.bits) {
1052
+ if (this.bits[i] !== 0)
1053
+ return false;
1054
+ }
1055
+ return true;
674
1056
  }
675
1057
  keys() {
676
1058
  return Object.keys(this.bits).map(k => +k);
@@ -681,6 +1063,15 @@ class ImmutableSparseBits {
681
1063
  test(a) {
682
1064
  return sparseTest(this.bits, a);
683
1065
  }
1066
+ equals(other) {
1067
+ return sparseEquals(this.bits, other.bits);
1068
+ }
1069
+ contains(other) {
1070
+ return sparseContains(this.bits, other.bits);
1071
+ }
1072
+ intersects(other) {
1073
+ return sparseIntersects(this.bits, other.bits);
1074
+ }
684
1075
  countSet() {
685
1076
  return sparseCountSet(this.bits);
686
1077
  }
@@ -688,19 +1079,19 @@ class ImmutableSparseBits {
688
1079
  return sparseNthSet(this.bits, a);
689
1080
  }
690
1081
  complement() {
691
- return new ImmutableSparseBits2(sparseComplement(this.bits), true);
1082
+ return new SparseBits2(sparseComplement(this.bits), true);
692
1083
  }
693
1084
  intersect(other) {
694
1085
  return this.create(sparseIntersect(this.bits, other.bits));
695
1086
  }
696
1087
  union(other) {
697
- return this.create(sparseCopyUndefined(sparseUnion(this.bits, other.bits), other.bits));
1088
+ return this.create(sparseCopyUndefined(sparseCopyUndefined(sparseUnion(this.bits, other.bits), other.bits), this.bits));
698
1089
  }
699
1090
  xor(other) {
700
- return this.create(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits));
1091
+ return this.create(sparseCopyUndefined(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits, -1), this.bits, -1));
701
1092
  }
702
- contains(other) {
703
- return sparseContains(this.bits, other.bits);
1093
+ difference(other) {
1094
+ return this.create(sparseCopyUndefined(sparseDifference(this.bits, other.bits), this.bits));
704
1095
  }
705
1096
  next(from, set = true) {
706
1097
  return sparseNext(this.bits, from, set);
@@ -710,9 +1101,9 @@ class ImmutableSparseBits {
710
1101
  [Symbol.iterator]: () => sparseWhere(this.bits, set, from, to)
711
1102
  };
712
1103
  }
713
- ranges() {
1104
+ ranges(set = true) {
714
1105
  return {
715
- [Symbol.iterator]: () => sparseRanges(this.bits)
1106
+ [Symbol.iterator]: () => sparseRanges(this.bits, set)
716
1107
  };
717
1108
  }
718
1109
  *[Symbol.iterator]() {
@@ -729,11 +1120,9 @@ class ImmutableSparseBits {
729
1120
  return new DenseBits(bits);
730
1121
  }
731
1122
  slice(from, to) {
732
- return this.create(sparseSlice(this.bits, from, to));
1123
+ return this.create(sparseSlice(this.bits, from, to)); // ?? this.bits.length * 32));
733
1124
  }
734
- }
735
- exports.ImmutableSparseBits = ImmutableSparseBits;
736
- class SparseBits extends ImmutableSparseBits {
1125
+ //mutating methods
737
1126
  set(a) {
738
1127
  sparseSetMask(this.bits, a >> 5, 1 << (a & 0x1f));
739
1128
  }
@@ -750,6 +1139,7 @@ class SparseBits extends ImmutableSparseBits {
750
1139
  }
751
1140
  selfIntersect(other) {
752
1141
  sparseSelfIntersect(this.bits, other.bits);
1142
+ sparseDeleteUndefined(this.bits, other.bits);
753
1143
  return this;
754
1144
  }
755
1145
  selfUnion(other) {
@@ -760,24 +1150,47 @@ class SparseBits extends ImmutableSparseBits {
760
1150
  sparseCopyUndefined(sparseSelfXor(this.bits, other.bits), other.bits);
761
1151
  return this;
762
1152
  }
1153
+ selfDifference(other) {
1154
+ sparseSelfDifference(this.bits, other.bits);
1155
+ return this;
1156
+ }
763
1157
  }
764
1158
  exports.SparseBits = SparseBits;
765
1159
  ;
766
1160
  //-----------------------------------------------------------------------------
767
- // SparseBits2 as above, with an 'undef' member indicating whether undefined entries are treated as 0 or 0xffffffff
1161
+ // SparseBits2 as above, with 'undef' indicating whether undefined entries are treated as 0 or 0xffffffff
768
1162
  //-----------------------------------------------------------------------------
769
- class ImmutableSparseBits2 extends ImmutableSparseBits {
1163
+ class SparseBits2 extends SparseBits {
770
1164
  undef;
771
1165
  constructor(bits = [], initial = false) {
772
1166
  super(bits);
773
1167
  this.undef = initial ? -1 : 0;
774
1168
  }
775
- create(bits = [], init) {
776
- return new this.constructor(bits, init);
1169
+ create(bits = [], initial = false) {
1170
+ return new this.constructor(bits, initial);
1171
+ }
1172
+ copy() {
1173
+ return this.create({ ...this.bits }, !!this.undef);
1174
+ }
1175
+ empty() {
1176
+ return !this.undef && super.empty();
777
1177
  }
778
1178
  test(a) {
779
1179
  return sparseTest(this.bits, a, this.undef);
780
1180
  }
1181
+ equals(other) {
1182
+ return this.undef === other.undef && sparseEquals(this.bits, other.bits);
1183
+ }
1184
+ contains(other) {
1185
+ if (other.undef && !this.undef)
1186
+ return false;
1187
+ return sparseContains(this.bits, other.bits, this.undef);
1188
+ }
1189
+ intersects(other) {
1190
+ if (this.undef)
1191
+ return !!other.undef || sparseIntersects(other.bits, this.bits, this.undef);
1192
+ return sparseIntersects(this.bits, other.bits, other.undef);
1193
+ }
781
1194
  nthSet(a) {
782
1195
  return sparseNthSet(this.bits, a, this.undef);
783
1196
  }
@@ -785,22 +1198,33 @@ class ImmutableSparseBits2 extends ImmutableSparseBits {
785
1198
  return this.create(sparseComplement(this.bits), this.undef === 0);
786
1199
  }
787
1200
  intersect(other) {
1201
+ const bits = sparseIntersect(this.bits, other.bits);
1202
+ if (other.undef)
1203
+ sparseCopyUndefined(bits, this.bits);
788
1204
  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);
1205
+ return this.create(sparseCopyUndefined(bits, other.bits), !!other.undef);
1206
+ return this.create(bits, false);
791
1207
  }
792
1208
  union(other) {
1209
+ const bits = sparseUnion(this.bits, other.bits);
1210
+ if (!other.undef)
1211
+ sparseCopyUndefined(bits, this.bits);
793
1212
  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);
1213
+ return this.create(bits, true);
1214
+ return this.create(sparseCopyUndefined(bits, other.bits), !!other.undef);
796
1215
  }
797
1216
  xor(other) {
798
- return this.create(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits, this.undef), !!(this.undef ^ other.undef));
1217
+ return this.create(sparseCopyUndefined(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits, this.undef), this.bits, other.undef), !!(this.undef ^ other.undef));
799
1218
  }
800
- contains(other) {
801
- if (other.undef && !this.undef)
802
- return false;
803
- return sparseContains(this.bits, other.bits, this.undef);
1219
+ difference(other) {
1220
+ const bits = sparseDifference(this.bits, other.bits);
1221
+ if (!other.undef) {
1222
+ sparseCopyUndefined(bits, this.bits);
1223
+ return this.create(bits, !!this.undef);
1224
+ }
1225
+ if (this.undef)
1226
+ sparseCopyUndefined(bits, other.bits, -1);
1227
+ return this.create(bits, false);
804
1228
  }
805
1229
  next(from, set = true) {
806
1230
  return sparseNext(this.bits, from, set, this.undef);
@@ -810,9 +1234,9 @@ class ImmutableSparseBits2 extends ImmutableSparseBits {
810
1234
  [Symbol.iterator]: () => sparseWhere(this.bits, set, from, to, this.undef)
811
1235
  };
812
1236
  }
813
- ranges() {
1237
+ ranges(set = true) {
814
1238
  return {
815
- [Symbol.iterator]: () => sparseRanges(this.bits, this.undef)
1239
+ [Symbol.iterator]: () => sparseRanges(this.bits, set, this.undef)
816
1240
  };
817
1241
  }
818
1242
  *[Symbol.iterator]() {
@@ -836,11 +1260,12 @@ class ImmutableSparseBits2 extends ImmutableSparseBits {
836
1260
  return new DenseBits(bits);
837
1261
  }
838
1262
  slice(from, to) {
839
- return this.create(sparseSlice(this.bits, from, to), !!this.undef);
1263
+ //to ??= this.bits.length * 32;
1264
+ return this.undef
1265
+ ? this.create(sparseSelfComplement(sparseSlice(sparseComplement(this.bits), from, to)), true)
1266
+ : this.create(sparseSlice(this.bits, from, to), false);
840
1267
  }
841
- }
842
- exports.ImmutableSparseBits2 = ImmutableSparseBits2;
843
- class SparseBits2 extends ImmutableSparseBits2 {
1268
+ //mutating methods
844
1269
  set(a) {
845
1270
  sparseSetMask(this.bits, a >> 5, 1 << (a & 0x1f), this.undef);
846
1271
  }
@@ -856,8 +1281,8 @@ class SparseBits2 extends ImmutableSparseBits2 {
856
1281
  return this;
857
1282
  }
858
1283
  selfComplement() {
859
- this.undef = ~this.undef;
860
1284
  sparseSelfComplement(this.bits);
1285
+ this.undef = ~this.undef;
861
1286
  return this;
862
1287
  }
863
1288
  selfIntersect(other) {
@@ -866,6 +1291,9 @@ class SparseBits2 extends ImmutableSparseBits2 {
866
1291
  sparseCopyUndefined(this.bits, other.bits);
867
1292
  this.undef = other.undef;
868
1293
  }
1294
+ else if (!other.undef) {
1295
+ sparseDeleteUndefined(this.bits, other.bits);
1296
+ }
869
1297
  return this;
870
1298
  }
871
1299
  selfUnion(other) {
@@ -874,6 +1302,9 @@ class SparseBits2 extends ImmutableSparseBits2 {
874
1302
  sparseCopyUndefined(this.bits, other.bits);
875
1303
  this.undef = other.undef;
876
1304
  }
1305
+ else if (other.undef) {
1306
+ sparseDeleteUndefined(this.bits, other.bits);
1307
+ }
877
1308
  return this;
878
1309
  }
879
1310
  selfXor(other) {
@@ -882,6 +1313,15 @@ class SparseBits2 extends ImmutableSparseBits2 {
882
1313
  this.undef ^= other.undef;
883
1314
  return this;
884
1315
  }
1316
+ selfDifference(other) {
1317
+ sparseSelfDifference(this.bits, other.bits);
1318
+ if (other.undef) {
1319
+ if (this.undef)
1320
+ sparseCopyUndefined(this.bits, other.bits, -1);
1321
+ this.undef = 0;
1322
+ }
1323
+ return this;
1324
+ }
885
1325
  }
886
1326
  exports.SparseBits2 = SparseBits2;
887
1327
  ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isopodlabs/utilities",
3
- "version": "1.6.0",
3
+ "version": "1.7.1",
4
4
  "description": "Various typescript helpers.",
5
5
  "repository": {
6
6
  "type": "git",