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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! Bit-set operations over a slice of words: the index-free layer
//! between single-word combinators and a real succinct structure.
//!
//! Every function is a linear scan over words with O(1) work per word;
//! positions are absolute bit indices (`word_index * BITS + bit`).
//! Build rank/select directories on top when the slice is large; use
//! these directly when it is not, or when the words change often.
use crateBits;
use crateWord;
/// Number of set bits in the whole slice.
/// Number of set bits at positions `< i`. `i` may equal the slice's
/// bit length; larger `i` counts everything.
/// Position of the `k`-th set bit (0-indexed), if `k < popcount`.
/// Lowest set position `>= i`, if any.
/// Lowest position where `k` consecutive set bits start, if any.
/// `k` in `1..=BITS`; a run may straddle one word boundary.
///
/// Per word: [`Bits::run_starts`] finds runs inside the word; a run
/// crossing into the next word is detected from this word's leading
/// ones and the next word's trailing ones, no wider window needed.
///
/// ```
/// use hakmem::slice::find_run;
///
/// // 60 free slots, then 4 allocated, then free: a 6-run must straddle.
/// let words = [u64::MAX >> 4, u64::MAX];
/// assert_eq!(find_run(&words, 6), Some(0));
/// let words = [0xFFu64 << 56, u64::MAX];
/// assert_eq!(find_run(&words, 16), Some(56));
/// assert_eq!(find_run(&[0u64, 0], 1), None);
/// ```
/// Positions of every set bit, ascending, across the words: the
/// selection vector of a bitmap.
///
/// ```
/// use hakmem::slice::positions;
///
/// let v: Vec<usize> = positions(&[0b101u64, 1]).collect();
/// assert_eq!(v, [0, 2, 64]);
/// ```
+ '_