-
Notifications
You must be signed in to change notification settings - Fork 21
/
bit-array.ts
90 lines (81 loc) · 2.05 KB
/
bit-array.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import type { Bit } from "./utility-types.ts";
type BitPosition = {
bucket: number;
position: number;
};
/**
* Uses Uint32Array as an array or vector of bits. It's a simpler version of BitField
* that only sets and checks individual bits.
*
* @example
* const array = BitArray.create(10);
* array.getBit(0);
* //=> 0
* array.setBit(0).getBit(0);
* //=> 1
* array.size;
* //=> 10
* array.length;
* //=> 1
*/
export class BitArray extends Uint32Array {
lastPosition: BitPosition = { bucket: 0, position: 0 };
static get [Symbol.species](): Uint32ArrayConstructor {
return Uint32Array;
}
/**
* The amount of bits in the array.
*/
get size(): number {
return this.length << 5;
}
/**
* Creates a BitArray of the specified size.
*
* @param size the maximum amount of bits in the array
* @return a new BitArray
*/
static create<T extends typeof BitArray>(
this: T,
size: number,
): InstanceType<T> {
return new this(this.getLength(size)) as InstanceType<T>;
}
/**
* Returns the length of the underlying TypedArray required to hold the given amount of bits.
*
* @param size the amount of bits
* @return the required length
*/
static getLength(size: number): number {
return Math.ceil(size / 32);
}
/**
* Returns the bit at a given index.
*
* @param index the index
* @return the bit
*/
getBit(index: number): Bit {
const { bucket, position } = this.getBitPosition(index);
return ((this[bucket] >> position) & 1) as Bit;
}
getBitPosition(index: number): BitPosition {
const bucket = index >> 5;
this.lastPosition.bucket = bucket;
this.lastPosition.position = index - (bucket << 5);
return this.lastPosition;
}
/**
* Sets the bit at a given index.
*
* @param index the index
* @param value the value
* @return this
*/
setBit(index: number, value: Bit = 1): this {
const { bucket, position } = this.getBitPosition(index);
this[bucket] = (this[bucket] & ~(1 << position)) | (value << position);
return this;
}
}