@isopodlabs/utilities 1.6.0 → 1.7.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 +109 -48
  2. package/dist/bits.js +550 -112
  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,83 @@ 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 {
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 SparseNumberArray = number[] | Record<number, number>;
130
+ type ExtraParams<T> = T extends new (bits: SparseNumberArray, ...args: infer P) => any ? P : never;
131
+ export declare class SparseBits implements BitSet {
82
132
  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;
133
+ constructor(bits?: SparseNumberArray);
134
+ protected create(bits?: SparseNumberArray): this;
135
+ static fromEntries<C extends new (bits: SparseNumberArray, ...args: any[]) => any>(this: C, entries: Record<number, number> | [number, number][], ...extra: ExtraParams<C>): InstanceType<C>;
136
+ static fromIndices<C extends new (bits: SparseNumberArray, ...args: any[]) => any>(this: C, ...indices: number[]): InstanceType<C>;
137
+ static fromIndices<C extends new (bits: SparseNumberArray, ...args: any[]) => any>(this: C, indices: number[], ...extra: ExtraParams<C>): InstanceType<C>;
138
+ copy(): this;
139
+ empty(): boolean;
86
140
  keys(): number[];
87
141
  entries(): [number, number][];
88
142
  test(a: number): boolean;
143
+ equals(other: this): boolean;
144
+ contains(other: SparseBits): boolean;
145
+ intersects(other: SparseBits): boolean;
89
146
  countSet(): number;
90
147
  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;
148
+ complement(): SparseBits2;
149
+ intersect(other: SparseBits): this;
150
+ union(other: SparseBits): this;
151
+ xor(other: SparseBits): this;
152
+ difference(other: this): BitSet;
96
153
  next(from: number, set?: boolean): number;
97
154
  where(set: boolean, from?: number, to?: number): {
98
155
  [Symbol.iterator]: () => Generator<number, void, unknown>;
99
156
  };
100
- ranges(): {
101
- [Symbol.iterator]: () => Generator<number[], void, unknown>;
157
+ ranges(set?: boolean): {
158
+ [Symbol.iterator]: () => Generator<[number, number], any, any>;
102
159
  };
103
160
  [Symbol.iterator](): Generator<number>;
104
161
  clean(): this;
105
162
  toDense(): DenseBits;
106
- slice(from: number, to?: number): ImmutableBitSet;
107
- }
108
- export declare class SparseBits extends ImmutableSparseBits implements BitSet {
163
+ slice(from: number, to?: number): BitSet;
109
164
  set(a: number): void;
110
165
  clear(a: number): void;
111
166
  setRange(a: number, b: number): this;
@@ -113,31 +168,35 @@ export declare class SparseBits extends ImmutableSparseBits implements BitSet {
113
168
  selfIntersect(other: SparseBits): this;
114
169
  selfUnion(other: SparseBits): this;
115
170
  selfXor(other: SparseBits): this;
171
+ selfDifference(other: this): this;
116
172
  }
117
- export declare class ImmutableSparseBits2 extends ImmutableSparseBits {
173
+ export declare class SparseBits2 extends SparseBits {
118
174
  protected undef: number;
119
- constructor(bits?: number[], initial?: boolean);
120
- protected create(bits?: number[], init?: boolean): this;
175
+ constructor(bits?: SparseNumberArray, initial?: boolean);
176
+ protected create(bits?: SparseNumberArray, initial?: boolean): this;
177
+ copy(): this;
178
+ empty(): boolean;
121
179
  test(a: number): boolean;
180
+ equals(other: this): boolean;
181
+ contains(other: SparseBits2): boolean;
182
+ intersects(other: SparseBits2): boolean;
122
183
  nthSet(a: number): number;
123
184
  complement(): this;
124
- intersect(other: ImmutableSparseBits2): this;
125
- union(other: ImmutableSparseBits2): this;
126
- xor(other: ImmutableSparseBits2): this;
127
- contains(other: ImmutableSparseBits2): boolean;
185
+ intersect(other: SparseBits2): this;
186
+ union(other: SparseBits2): this;
187
+ xor(other: SparseBits2): this;
188
+ difference(other: SparseBits2): BitSet;
128
189
  next(from: number, set?: boolean): number;
129
190
  where(set: boolean, from?: number, to?: number): {
130
191
  [Symbol.iterator]: () => Generator<number, void, unknown>;
131
192
  };
132
- ranges(): {
133
- [Symbol.iterator]: () => Generator<number[], void, unknown>;
193
+ ranges(set?: boolean): {
194
+ [Symbol.iterator]: () => Generator<[number, number], any, any>;
134
195
  };
135
196
  [Symbol.iterator](): Generator<number>;
136
197
  clean(): this;
137
198
  toDense(): DenseBits;
138
- slice(from: number, to?: number): ImmutableBitSet;
139
- }
140
- export declare class SparseBits2 extends ImmutableSparseBits2 implements BitSet {
199
+ slice(from: number, to?: number): BitSet;
141
200
  set(a: number): void;
142
201
  clear(a: number): void;
143
202
  setRange(a: number, b: number): this;
@@ -146,4 +205,6 @@ export declare class SparseBits2 extends ImmutableSparseBits2 implements BitSet
146
205
  selfIntersect(other: SparseBits2): this;
147
206
  selfUnion(other: SparseBits2): this;
148
207
  selfXor(other: SparseBits2): this;
208
+ selfDifference(other: this): this;
149
209
  }
210
+ 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,275 @@ 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;
403
670
  }
404
- return dest;
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;
701
+ }
702
+ }
703
+ exports.DenseBits32 = DenseBits32;
704
+ ;
705
+ //-----------------------------------------------------------------------------
706
+ // SparseBits - a sparse bitset where each entry in the 'bits' array represents 32 bits
707
+ //-----------------------------------------------------------------------------
708
+ function sparseFromIndices(indices) {
709
+ const bits = [];
710
+ for (const i of indices)
711
+ bits[i >> 5] |= 1 << (i & 0x1f);
712
+ return bits;
405
713
  }
406
714
  function sparseCopyUndefined(bits, other, xor = 0) {
407
715
  for (const i in other) {
@@ -410,6 +718,13 @@ function sparseCopyUndefined(bits, other, xor = 0) {
410
718
  }
411
719
  return bits;
412
720
  }
721
+ function sparseDeleteUndefined(bits, other) {
722
+ for (const i in bits) {
723
+ if (other[i] === undefined)
724
+ delete bits[i];
725
+ }
726
+ return bits;
727
+ }
413
728
  function sparseClean(bits, undef = 0) {
414
729
  for (const i in bits) {
415
730
  if (bits[i] === undef)
@@ -503,14 +818,41 @@ function sparseNthSet(bits, a, undef = 0) {
503
818
  function sparseComplement(bits) {
504
819
  return bits.map(b => ~b);
505
820
  }
506
- function sparseIntersect(bits, other, undef = 0) {
507
- return bits.map((b, i) => b & (other[i] ?? undef));
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;
508
829
  }
509
- function sparseUnion(bits, other, undef = 0) {
510
- 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;
511
838
  }
512
- function sparseXor(bits, other, undef = 0) {
513
- 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;
847
+ }
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];
533
878
  return bits;
534
879
  }
880
+ function sparseSelfDifference(bits, other) {
881
+ for (const i in bits)
882
+ if (other[i] !== undefined)
883
+ bits[i] &= ~other[i];
884
+ return bits;
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,94 +940,93 @@ 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
+ if (i > to32)
1017
+ break;
1018
+ let b = bits[k];
1019
+ if (i === from32)
1020
+ b &= -fromM;
1021
+ if (i === to32)
1022
+ b &= toM - 1;
1023
+ if (b !== 0)
1024
+ result[k] = b;
1025
+ }
659
1026
  }
660
1027
  return result;
661
1028
  }
662
- class ImmutableSparseBits {
1029
+ class SparseBits {
663
1030
  bits;
664
1031
  constructor(bits = []) {
665
1032
  this.bits = bits;
@@ -667,10 +1034,23 @@ class ImmutableSparseBits {
667
1034
  create(bits = []) {
668
1035
  return new this.constructor(bits);
669
1036
  }
670
- static fromEntries(entries, ...args) {
671
- const r = new this(...args);
672
- r.bits = sparseFromEntries(entries);
673
- return r;
1037
+ static fromEntries(entries, ...extra) {
1038
+ return new this(Array.isArray(entries) ? Object.fromEntries(entries) : entries, ...extra);
1039
+ }
1040
+ static fromIndices(indicesOrFirst, ...rest) {
1041
+ return Array.isArray(indicesOrFirst)
1042
+ ? new this(sparseFromIndices(indicesOrFirst), ...rest)
1043
+ : new this(sparseFromIndices([indicesOrFirst, ...rest]));
1044
+ }
1045
+ copy() {
1046
+ return this.create({ ...this.bits });
1047
+ }
1048
+ empty() {
1049
+ for (const i in this.bits) {
1050
+ if (this.bits[i] !== 0)
1051
+ return false;
1052
+ }
1053
+ return true;
674
1054
  }
675
1055
  keys() {
676
1056
  return Object.keys(this.bits).map(k => +k);
@@ -681,6 +1061,15 @@ class ImmutableSparseBits {
681
1061
  test(a) {
682
1062
  return sparseTest(this.bits, a);
683
1063
  }
1064
+ equals(other) {
1065
+ return sparseEquals(this.bits, other.bits);
1066
+ }
1067
+ contains(other) {
1068
+ return sparseContains(this.bits, other.bits);
1069
+ }
1070
+ intersects(other) {
1071
+ return sparseIntersects(this.bits, other.bits);
1072
+ }
684
1073
  countSet() {
685
1074
  return sparseCountSet(this.bits);
686
1075
  }
@@ -688,19 +1077,19 @@ class ImmutableSparseBits {
688
1077
  return sparseNthSet(this.bits, a);
689
1078
  }
690
1079
  complement() {
691
- return new ImmutableSparseBits2(sparseComplement(this.bits), true);
1080
+ return new SparseBits2(sparseComplement(this.bits), true);
692
1081
  }
693
1082
  intersect(other) {
694
1083
  return this.create(sparseIntersect(this.bits, other.bits));
695
1084
  }
696
1085
  union(other) {
697
- return this.create(sparseCopyUndefined(sparseUnion(this.bits, other.bits), other.bits));
1086
+ return this.create(sparseCopyUndefined(sparseCopyUndefined(sparseUnion(this.bits, other.bits), other.bits), this.bits));
698
1087
  }
699
1088
  xor(other) {
700
- return this.create(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits));
1089
+ return this.create(sparseCopyUndefined(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits, -1), this.bits, -1));
701
1090
  }
702
- contains(other) {
703
- return sparseContains(this.bits, other.bits);
1091
+ difference(other) {
1092
+ return this.create(sparseCopyUndefined(sparseDifference(this.bits, other.bits), this.bits));
704
1093
  }
705
1094
  next(from, set = true) {
706
1095
  return sparseNext(this.bits, from, set);
@@ -710,9 +1099,9 @@ class ImmutableSparseBits {
710
1099
  [Symbol.iterator]: () => sparseWhere(this.bits, set, from, to)
711
1100
  };
712
1101
  }
713
- ranges() {
1102
+ ranges(set = true) {
714
1103
  return {
715
- [Symbol.iterator]: () => sparseRanges(this.bits)
1104
+ [Symbol.iterator]: () => sparseRanges(this.bits, set)
716
1105
  };
717
1106
  }
718
1107
  *[Symbol.iterator]() {
@@ -729,11 +1118,9 @@ class ImmutableSparseBits {
729
1118
  return new DenseBits(bits);
730
1119
  }
731
1120
  slice(from, to) {
732
- return this.create(sparseSlice(this.bits, from, to));
1121
+ return this.create(sparseSlice(this.bits, from, to)); // ?? this.bits.length * 32));
733
1122
  }
734
- }
735
- exports.ImmutableSparseBits = ImmutableSparseBits;
736
- class SparseBits extends ImmutableSparseBits {
1123
+ //mutating methods
737
1124
  set(a) {
738
1125
  sparseSetMask(this.bits, a >> 5, 1 << (a & 0x1f));
739
1126
  }
@@ -750,6 +1137,7 @@ class SparseBits extends ImmutableSparseBits {
750
1137
  }
751
1138
  selfIntersect(other) {
752
1139
  sparseSelfIntersect(this.bits, other.bits);
1140
+ sparseDeleteUndefined(this.bits, other.bits);
753
1141
  return this;
754
1142
  }
755
1143
  selfUnion(other) {
@@ -760,24 +1148,47 @@ class SparseBits extends ImmutableSparseBits {
760
1148
  sparseCopyUndefined(sparseSelfXor(this.bits, other.bits), other.bits);
761
1149
  return this;
762
1150
  }
1151
+ selfDifference(other) {
1152
+ sparseSelfDifference(this.bits, other.bits);
1153
+ return this;
1154
+ }
763
1155
  }
764
1156
  exports.SparseBits = SparseBits;
765
1157
  ;
766
1158
  //-----------------------------------------------------------------------------
767
- // SparseBits2 as above, with an 'undef' member indicating whether undefined entries are treated as 0 or 0xffffffff
1159
+ // SparseBits2 as above, with 'undef' indicating whether undefined entries are treated as 0 or 0xffffffff
768
1160
  //-----------------------------------------------------------------------------
769
- class ImmutableSparseBits2 extends ImmutableSparseBits {
1161
+ class SparseBits2 extends SparseBits {
770
1162
  undef;
771
1163
  constructor(bits = [], initial = false) {
772
1164
  super(bits);
773
1165
  this.undef = initial ? -1 : 0;
774
1166
  }
775
- create(bits = [], init) {
776
- return new this.constructor(bits, init);
1167
+ create(bits = [], initial = false) {
1168
+ return new this.constructor(bits, initial);
1169
+ }
1170
+ copy() {
1171
+ return this.create({ ...this.bits }, !!this.undef);
1172
+ }
1173
+ empty() {
1174
+ return !this.undef && super.empty();
777
1175
  }
778
1176
  test(a) {
779
1177
  return sparseTest(this.bits, a, this.undef);
780
1178
  }
1179
+ equals(other) {
1180
+ return this.undef === other.undef && sparseEquals(this.bits, other.bits);
1181
+ }
1182
+ contains(other) {
1183
+ if (other.undef && !this.undef)
1184
+ return false;
1185
+ return sparseContains(this.bits, other.bits, this.undef);
1186
+ }
1187
+ intersects(other) {
1188
+ if (this.undef)
1189
+ return !!other.undef || sparseIntersects(other.bits, this.bits, this.undef);
1190
+ return sparseIntersects(this.bits, other.bits, other.undef);
1191
+ }
781
1192
  nthSet(a) {
782
1193
  return sparseNthSet(this.bits, a, this.undef);
783
1194
  }
@@ -785,22 +1196,33 @@ class ImmutableSparseBits2 extends ImmutableSparseBits {
785
1196
  return this.create(sparseComplement(this.bits), this.undef === 0);
786
1197
  }
787
1198
  intersect(other) {
1199
+ const bits = sparseIntersect(this.bits, other.bits);
1200
+ if (other.undef)
1201
+ sparseCopyUndefined(bits, this.bits);
788
1202
  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);
1203
+ return this.create(sparseCopyUndefined(bits, other.bits), !!other.undef);
1204
+ return this.create(bits, false);
791
1205
  }
792
1206
  union(other) {
1207
+ const bits = sparseUnion(this.bits, other.bits);
1208
+ if (!other.undef)
1209
+ sparseCopyUndefined(bits, this.bits);
793
1210
  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);
1211
+ return this.create(bits, true);
1212
+ return this.create(sparseCopyUndefined(bits, other.bits), !!other.undef);
796
1213
  }
797
1214
  xor(other) {
798
- return this.create(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits, this.undef), !!(this.undef ^ other.undef));
1215
+ return this.create(sparseCopyUndefined(sparseCopyUndefined(sparseXor(this.bits, other.bits), other.bits, this.undef), this.bits, other.undef), !!(this.undef ^ other.undef));
799
1216
  }
800
- contains(other) {
801
- if (other.undef && !this.undef)
802
- return false;
803
- return sparseContains(this.bits, other.bits, this.undef);
1217
+ difference(other) {
1218
+ const bits = sparseDifference(this.bits, other.bits);
1219
+ if (!other.undef) {
1220
+ sparseCopyUndefined(bits, this.bits);
1221
+ return this.create(bits, !!this.undef);
1222
+ }
1223
+ if (this.undef)
1224
+ sparseCopyUndefined(bits, other.bits, -1);
1225
+ return this.create(bits, false);
804
1226
  }
805
1227
  next(from, set = true) {
806
1228
  return sparseNext(this.bits, from, set, this.undef);
@@ -810,9 +1232,9 @@ class ImmutableSparseBits2 extends ImmutableSparseBits {
810
1232
  [Symbol.iterator]: () => sparseWhere(this.bits, set, from, to, this.undef)
811
1233
  };
812
1234
  }
813
- ranges() {
1235
+ ranges(set = true) {
814
1236
  return {
815
- [Symbol.iterator]: () => sparseRanges(this.bits, this.undef)
1237
+ [Symbol.iterator]: () => sparseRanges(this.bits, set, this.undef)
816
1238
  };
817
1239
  }
818
1240
  *[Symbol.iterator]() {
@@ -836,11 +1258,12 @@ class ImmutableSparseBits2 extends ImmutableSparseBits {
836
1258
  return new DenseBits(bits);
837
1259
  }
838
1260
  slice(from, to) {
839
- return this.create(sparseSlice(this.bits, from, to), !!this.undef);
1261
+ //to ??= this.bits.length * 32;
1262
+ return this.undef
1263
+ ? this.create(sparseSelfComplement(sparseSlice(sparseComplement(this.bits), from, to)), true)
1264
+ : this.create(sparseSlice(this.bits, from, to), false);
840
1265
  }
841
- }
842
- exports.ImmutableSparseBits2 = ImmutableSparseBits2;
843
- class SparseBits2 extends ImmutableSparseBits2 {
1266
+ //mutating methods
844
1267
  set(a) {
845
1268
  sparseSetMask(this.bits, a >> 5, 1 << (a & 0x1f), this.undef);
846
1269
  }
@@ -856,8 +1279,8 @@ class SparseBits2 extends ImmutableSparseBits2 {
856
1279
  return this;
857
1280
  }
858
1281
  selfComplement() {
859
- this.undef = ~this.undef;
860
1282
  sparseSelfComplement(this.bits);
1283
+ this.undef = ~this.undef;
861
1284
  return this;
862
1285
  }
863
1286
  selfIntersect(other) {
@@ -866,6 +1289,9 @@ class SparseBits2 extends ImmutableSparseBits2 {
866
1289
  sparseCopyUndefined(this.bits, other.bits);
867
1290
  this.undef = other.undef;
868
1291
  }
1292
+ else if (!other.undef) {
1293
+ sparseDeleteUndefined(this.bits, other.bits);
1294
+ }
869
1295
  return this;
870
1296
  }
871
1297
  selfUnion(other) {
@@ -874,6 +1300,9 @@ class SparseBits2 extends ImmutableSparseBits2 {
874
1300
  sparseCopyUndefined(this.bits, other.bits);
875
1301
  this.undef = other.undef;
876
1302
  }
1303
+ else if (other.undef) {
1304
+ sparseDeleteUndefined(this.bits, other.bits);
1305
+ }
877
1306
  return this;
878
1307
  }
879
1308
  selfXor(other) {
@@ -882,6 +1311,15 @@ class SparseBits2 extends ImmutableSparseBits2 {
882
1311
  this.undef ^= other.undef;
883
1312
  return this;
884
1313
  }
1314
+ selfDifference(other) {
1315
+ sparseSelfDifference(this.bits, other.bits);
1316
+ if (other.undef) {
1317
+ if (this.undef)
1318
+ sparseCopyUndefined(this.bits, other.bits, -1);
1319
+ this.undef = 0;
1320
+ }
1321
+ return this;
1322
+ }
885
1323
  }
886
1324
  exports.SparseBits2 = SparseBits2;
887
1325
  ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@isopodlabs/utilities",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Various typescript helpers.",
5
5
  "repository": {
6
6
  "type": "git",