vers_vecs/bit_vec/mod.rs
1//! This module contains a simple [bit vector][BitVec] implementation with no overhead and a fast succinct
2//! bit vector implementation with [rank and select queries][fast_rs_vec::RsVec].
3
4use crate::bit_vec::mask::MaskedBitVec;
5use crate::util::impl_vector_iterator;
6use std::cmp::min;
7use std::hash::{Hash, Hasher};
8use std::mem::size_of;
9
10pub mod fast_rs_vec;
11
12pub mod sparse;
13
14pub mod mask;
15
16/// Size of a word in bitvectors. All vectors operate on 64-bit words.
17const WORD_SIZE: usize = 64;
18
19/// Type alias for masked bitvectors that implement a simple bitwise binary operation.
20/// The first lifetime is for the bit vector that is being masked, the second lifetime is for the
21/// mask.
22pub type BitMask<'s, 'b> = MaskedBitVec<'s, 'b, fn(u64, u64) -> u64>;
23
24/// A simple bit vector that does not support rank and select queries.
25/// Bits are stored in little-endian order, i.e. the least significant bit is stored first.
26/// The bit vector is stored as a sequence of 64 bit limbs.
27/// The last limb may be partially filled.
28///
29/// The bit vector has a wide range of constructors that allow for easy creation from various
30/// sources.
31/// Among them are constructors for creating an empty vector ([`BitVec::new`]),
32/// creating one from single bits of various integer types ([`BitVec::from_bits`] and variations),
33/// creating limbs from u64 values directly ([`BitVec::from_limbs`] and variations),
34/// or packing a sequence of numerical values into a dense bit sequence
35/// ([`BitVec::pack_sequence_u64`] and variations).
36///
37/// The bit vector can be modified after creation
38/// (e.g. by appending [bits](BitVec::append_bits)
39/// or [words](BitVec::append_word),
40/// [flipping](BitVec::flip_bit),
41/// or [setting](BitVec::set) bits).
42/// Bits can be [accessed](BitVec::get) by position,
43/// and [multiple bits](BitVec::get_bits) can be accessed at once.
44/// Bits can be [dropped](BitVec::drop_last) from the end.
45///
46/// # Example
47/// ```rust
48/// use vers_vecs::{BitVec, RsVec};
49///
50/// let mut bit_vec = BitVec::new();
51/// bit_vec.append_bit(0u64);
52/// bit_vec.append_bit_u32(1u32);
53/// bit_vec.append_word(0b1010_1010_1010_1010u64); // appends exactly 64 bits
54///
55/// assert_eq!(bit_vec.len(), 66);
56/// assert_eq!(bit_vec.get(0), Some(0u64));
57/// assert_eq!(bit_vec.get(1), Some(1u64));
58/// ```
59#[derive(Clone, Debug, Default)]
60#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
61#[cfg_attr(feature = "mem_dbg", derive(mem_dbg::MemSize, mem_dbg::MemDbg))]
62pub struct BitVec {
63 data: Vec<u64>,
64 len: usize,
65}
66
67impl BitVec {
68 /// Create a new empty bit vector.
69 #[must_use]
70 pub fn new() -> Self {
71 Self::default()
72 }
73
74 /// Create a new empty bit vector with the given capacity.
75 /// The capacity is measured in bits.
76 /// The bit vector will be able to hold at least `capacity` bits without reallocating.
77 /// More memory may be allocated according to the underlying allocation strategy.
78 #[must_use]
79 pub fn with_capacity(capacity: usize) -> Self {
80 Self {
81 data: Vec::with_capacity(capacity / WORD_SIZE + 1),
82 len: 0,
83 }
84 }
85
86 /// Create a new bit vector with all zeros and the given length.
87 /// The length is measured in bits.
88 #[must_use]
89 pub fn from_zeros(len: usize) -> Self {
90 let mut data = vec![0; len / WORD_SIZE];
91 if !len.is_multiple_of(WORD_SIZE) {
92 data.push(0);
93 }
94 Self { data, len }
95 }
96
97 /// Create a new bit vector with all ones and the given length.
98 /// The length is measured in bits.
99 #[must_use]
100 pub fn from_ones(len: usize) -> Self {
101 let mut data = vec![u64::MAX; len / WORD_SIZE];
102 if !len.is_multiple_of(WORD_SIZE) {
103 data.push((1 << (len % WORD_SIZE)) - 1);
104 }
105 Self { data, len }
106 }
107
108 /// Construct a bit vector from a set of bits given as distinct u8 values.
109 /// The constructor will take the least significant bit from each value and append it to a
110 /// bit vector.
111 /// All other bits are ignored.
112 ///
113 /// See also: [`from_bits_u16`], [`from_bits_u32`], [`from_bits_u64`], [`from_bits_iter`]
114 ///
115 /// # Example
116 /// ```rust
117 /// use vers_vecs::BitVec;
118 ///
119 /// let bits: &[u8] = &[1, 0, 1, 1, 1, 1];
120 /// let bv = BitVec::from_bits(&bits);
121 ///
122 /// assert_eq!(bv.len(), 6);
123 /// assert_eq!(bv.get_bits(0, 6), Some(0b111101u64));
124 /// ```
125 ///
126 /// [`from_bits_u16`]: BitVec::from_bits_u16
127 /// [`from_bits_u32`]: BitVec::from_bits_u32
128 /// [`from_bits_u64`]: BitVec::from_bits_u64
129 /// [`from_bits_iter`]: BitVec::from_bits_iter
130 #[must_use]
131 pub fn from_bits(bits: &[u8]) -> Self {
132 let mut bv = Self::with_capacity(bits.len());
133 bits.iter().for_each(|&b| bv.append_bit(b.into()));
134 bv
135 }
136
137 /// Construct a bit vector from a set of bits given as distinct u16 values.
138 /// The constructor will take the least significant bit from each value and append it to a
139 /// bit vector.
140 /// All other bits are ignored.
141 ///
142 /// See also: [`from_bits`], [`from_bits_u32`], [`from_bits_u64`], [`from_bits_iter`]
143 ///
144 /// [`from_bits`]: BitVec::from_bits
145 /// [`from_bits_u32`]: BitVec::from_bits_u32
146 /// [`from_bits_u64`]: BitVec::from_bits_u64
147 /// [`from_bits_iter`]: BitVec::from_bits_iter
148 #[must_use]
149 pub fn from_bits_u16(bits: &[u16]) -> Self {
150 let mut bv = Self::with_capacity(bits.len());
151 bits.iter().for_each(|&b| bv.append_bit_u16(b));
152 bv
153 }
154
155 /// Construct a bit vector from a set of bits given as distinct u32 values.
156 /// The constructor will take the least significant bit from each value and append it to a
157 /// bit vector.
158 /// All other bits are ignored.
159 ///
160 /// See also: [`from_bits`], [`from_bits_u16`], [`from_bits_u64`], [`from_bits_iter`]
161 ///
162 /// [`from_bits`]: BitVec::from_bits
163 /// [`from_bits_u16`]: BitVec::from_bits_u16
164 /// [`from_bits_u64`]: BitVec::from_bits_u64
165 /// [`from_bits_iter`]: BitVec::from_bits_iter
166 #[must_use]
167 pub fn from_bits_u32(bits: &[u32]) -> Self {
168 let mut bv = Self::with_capacity(bits.len());
169 bits.iter().for_each(|&b| bv.append_bit_u32(b));
170 bv
171 }
172
173 /// Construct a bit vector from a set of bits given as distinct u64 values.
174 /// The constructor will take the least significant bit from each value and append it to a
175 /// bit vector.
176 /// All other bits are ignored.
177 ///
178 /// See also: [`from_bits`], [`from_bits_u16`], [`from_bits_u32`], [`from_bits_iter`]
179 ///
180 /// [`from_bits`]: BitVec::from_bits
181 /// [`from_bits_u16`]: BitVec::from_bits_u16
182 /// [`from_bits_u32`]: BitVec::from_bits_u32
183 /// [`from_bits_iter`]: BitVec::from_bits_iter
184 #[must_use]
185 pub fn from_bits_u64(bits: &[u64]) -> Self {
186 let mut bv = Self::with_capacity(bits.len());
187 bits.iter().for_each(|&b| bv.append_bit(b));
188 bv
189 }
190
191 /// Construct a bit vector from an iterator of bits.
192 /// The constructor will take the least significant bit from each value and append it to a
193 /// bit vector.
194 /// All other bits are ignored.
195 /// The iterator must yield values that can be converted into u64 values.
196 ///
197 /// See also: [`from_bits`], [`from_bits_u16`], [`from_bits_u32`], [`from_bits_u64`]
198 ///
199 /// # Example
200 /// ```rust
201 /// use vers_vecs::BitVec;
202 ///
203 /// let bits = [true, false, true, true, true, true];
204 /// let bv = BitVec::from_bits_iter(bits.iter().copied());
205 ///
206 /// let bits = [0b1u8, 0b0, 0b1, 0b1, 0b1, 0b1];
207 /// let bv2 = BitVec::from_bits_iter(bits.iter().copied());
208 ///
209 /// assert_eq!(bv.len(), 6);
210 /// assert_eq!(bv.get_bits(0, 6), Some(0b111101u64));
211 /// assert_eq!(bv, bv2);
212 /// ```
213 ///
214 /// [`from_bits`]: BitVec::from_bits
215 /// [`from_bits_u16`]: BitVec::from_bits_u16
216 /// [`from_bits_u32`]: BitVec::from_bits_u32
217 /// [`from_bits_u64`]: BitVec::from_bits_u64
218 #[must_use]
219 pub fn from_bits_iter<I, E>(iter: I) -> Self
220 where
221 E: Into<u64>,
222 I: IntoIterator<Item = E>,
223 {
224 let iter = iter.into_iter();
225 let mut bv = Self::with_capacity(iter.size_hint().0);
226 for bit in iter {
227 bv.append_bit(bit.into());
228 }
229 bv
230 }
231
232 /// Construct a bit vector from a slice of u64 quad words.
233 /// The quad words are interpreted as limbs of the bit vector (i.e. each quad word contributes
234 /// 64 bits to the bit vector).
235 /// Since the data is only cloned without any masking or transformation,
236 /// this is one of the fastest ways to create a bit vector.
237 ///
238 /// See also: [`from_vec`], [`from_limbs_iter`]
239 ///
240 /// # Example
241 /// ```rust
242 /// use vers_vecs::BitVec;
243 ///
244 /// let words = [0, 256, u64::MAX];
245 /// let bv = BitVec::from_limbs(&words);
246 ///
247 /// assert_eq!(bv.len(), 192);
248 /// assert_eq!(bv.get_bits(0, 64), Some(0u64));
249 /// assert_eq!(bv.get(72), Some(1));
250 /// assert_eq!(bv.get_bits(128, 64), Some(u64::MAX));
251 /// ```
252 ///
253 /// [`from_vec`]: BitVec::from_vec
254 /// [`from_limbs_iter`]: BitVec::from_limbs_iter
255 #[must_use]
256 pub fn from_limbs(words: &[u64]) -> Self {
257 let len = words.len() * WORD_SIZE;
258 Self {
259 data: words.to_vec(),
260 len,
261 }
262 }
263
264 /// Construct a bit vector from an iterator of u64 quad words.
265 /// The quad words are interpreted as limbs of the bit vector (i.e. each quad word contributes
266 /// 64 bits to the bit vector).
267 /// Since the data is only cloned without any masking or transformation,
268 /// this is one of the fastest ways to create a bit vector.
269 ///
270 /// See also: [`from_limbs`], [`from_vec`]
271 ///
272 /// # Example
273 /// ```rust
274 /// use std::iter::repeat;
275 /// use vers_vecs::BitVec;
276 ///
277 /// let zeros = repeat(0xaaaaaaaaaaaaaaaau64).take(10);
278 /// let bv = BitVec::from_limbs_iter(zeros);
279 ///
280 /// assert_eq!(bv.len(), 640);
281 /// for i in 0..640 {
282 /// assert_eq!(bv.get(i), Some((i % 2 == 1) as u64));
283 /// }
284 /// ```
285 ///
286 /// [`from_limbs`]: BitVec::from_limbs
287 /// [`from_vec`]: BitVec::from_vec
288 pub fn from_limbs_iter<I, E>(iter: I) -> Self
289 where
290 E: Into<u64>,
291 I: IntoIterator<Item = E>,
292 {
293 let vec = iter.into_iter().map(Into::into).collect();
294 Self::from_vec(vec)
295 }
296
297 /// Construct a bit vector from a vector of u64 quad words.
298 /// The quad words are interpreted as limbs of the bit vector
299 /// (i.e. each quad word contributes 64 bits to the bit vector).
300 /// Since the data is moved without any masking or transformation, this is one of the fastest ways
301 /// to create a bit vector.
302 ///
303 /// See also: [`from_limbs`], [`from_limbs_iter`]
304 ///
305 /// # Example
306 /// ```rust
307 /// use vers_vecs::BitVec;
308 ///
309 /// let words = vec![0, 256, u64::MAX];
310 /// let bv = BitVec::from_vec(words);
311 ///
312 /// assert_eq!(bv.len(), 192);
313 /// assert_eq!(bv.get_bits(0, 64), Some(0u64));
314 /// assert_eq!(bv.get(72), Some(1));
315 /// assert_eq!(bv.get_bits(128, 64), Some(u64::MAX));
316 /// ```
317 ///
318 /// [`from_limbs`]: BitVec::from_limbs
319 /// [`from_limbs_iter`]: BitVec::from_limbs_iter
320 #[must_use]
321 pub fn from_vec(data: Vec<u64>) -> Self {
322 let len = data.len() * WORD_SIZE;
323 Self { data, len }
324 }
325
326 /// Helper function for packing constructors to pack a slice of elements into a bit-vector,
327 /// taking the least significant `bits_per_element` per element.
328 fn pack_bits<T, const MAX_BITS: usize>(sequence: &[T], bits_per_element: usize) -> Self
329 where
330 T: Into<u64> + Copy,
331 {
332 let mut bv = Self::with_capacity(sequence.len() * bits_per_element);
333 for &word in sequence {
334 Self::pack_word_into_vector::<MAX_BITS>(&mut bv, word.into(), bits_per_element);
335 }
336 bv
337 }
338
339 /// Helper function for packing constructors to pack elements from an iterator into a bit-vector,
340 /// taking the least significant `bits_per_element` per element.
341 fn pack_bits_iter<T, I: IntoIterator<Item = T>, const MAX_BITS: usize>(
342 iter: I,
343 bits_per_element: usize,
344 ) -> Self
345 where
346 T: Into<u64> + Copy,
347 {
348 let mut bv = Self::new();
349
350 for word in iter {
351 Self::pack_word_into_vector::<MAX_BITS>(&mut bv, word.into(), bits_per_element);
352 }
353
354 bv
355 }
356
357 /// Helper function for packing constructors to pack `num_bits` of a given word into the given
358 /// vector.
359 #[inline(always)]
360 fn pack_word_into_vector<const MAX_BITS: usize>(bv: &mut BitVec, word: u64, num_bits: usize) {
361 if num_bits <= MAX_BITS {
362 bv.append_bits(word, num_bits);
363 } else {
364 bv.append_bits(word, MAX_BITS);
365 let mut rest = num_bits - MAX_BITS;
366 while rest > 0 {
367 bv.append_bits(0, min(rest, MAX_BITS));
368 rest = rest.saturating_sub(MAX_BITS);
369 }
370 }
371 }
372
373 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
374 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
375 /// The number of bits per element is given by `bits_per_element`.
376 /// The sequence is given as a slice of u64 values.
377 /// If the number of bits per element is smaller than 64, the function takes the
378 /// least significant bits of each element, and discards the rest.
379 /// If the number of bits per element is larger than 64, the function will pad the elements
380 /// with zeros.
381 /// The function will append the bits of each element to the bit vector in the order they are
382 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
383 ///
384 /// See also: [`pack_sequence_u32`], [`pack_sequence_u16`], [`pack_sequence_u8`]
385 ///
386 /// # Example
387 /// ```rust
388 /// use vers_vecs::BitVec;
389 ///
390 /// let sequence = [0b1010u64, 0b1100u64, 0b1111u64];
391 /// let bv = BitVec::pack_sequence_u64(&sequence, 4);
392 ///
393 /// assert_eq!(bv.len(), 12);
394 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
395 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
396 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
397 /// ```
398 ///
399 /// [`pack_sequence_u32`]: BitVec::pack_sequence_u32
400 /// [`pack_sequence_u16`]: BitVec::pack_sequence_u16
401 /// [`pack_sequence_u8`]: BitVec::pack_sequence_u8
402 #[must_use]
403 pub fn pack_sequence_u64(sequence: &[u64], bits_per_element: usize) -> Self {
404 Self::pack_bits::<_, 64>(sequence, bits_per_element)
405 }
406
407 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
408 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
409 /// The number of bits per element is given by `bits_per_element`.
410 /// The sequence is given as a slice of u32 values.
411 /// If the number of bits per element is smaller than 32, the function takes the
412 /// least significant bits of each element, and discards the rest.
413 /// If the number of bits per element is larger than 32, the function will pad the elements
414 /// with zeros.
415 /// The function will append the bits of each element to the bit vector in the order they are
416 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
417 ///
418 /// See also: [`pack_sequence_u64`], [`pack_sequence_u16`], [`pack_sequence_u8`]
419 ///
420 /// # Example
421 /// ```rust
422 /// use vers_vecs::BitVec;
423 ///
424 /// let sequence = [0b1010u32, 0b1100u32, 0b1111u32];
425 /// let bv = BitVec::pack_sequence_u32(&sequence, 4);
426 ///
427 /// assert_eq!(bv.len(), 12);
428 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
429 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
430 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
431 /// ```
432 ///
433 /// [`pack_sequence_u64`]: BitVec::pack_sequence_u64
434 /// [`pack_sequence_u16`]: BitVec::pack_sequence_u16
435 /// [`pack_sequence_u8`]: BitVec::pack_sequence_u8
436 #[must_use]
437 pub fn pack_sequence_u32(sequence: &[u32], bits_per_element: usize) -> Self {
438 Self::pack_bits::<_, 32>(sequence, bits_per_element)
439 }
440
441 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
442 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
443 /// The number of bits per element is given by `bits_per_element`.
444 /// The sequence is given as a slice of u16 values.
445 /// If the number of bits per element is smaller than 16, the function takes the
446 /// least significant bits of each element, and discards the rest.
447 /// If the number of bits per element is larger than 16, the function will pad the elements
448 /// with zeros.
449 /// The function will append the bits of each element to the bit vector in the order they are
450 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
451 ///
452 /// See also: [`pack_sequence_u64`], [`pack_sequence_u32`], [`pack_sequence_u8`]
453 ///
454 /// # Example
455 /// ```rust
456 /// use vers_vecs::BitVec;
457 ///
458 /// let sequence = [0b1010u16, 0b1100u16, 0b1111u16];
459 /// let bv = BitVec::pack_sequence_u16(&sequence, 4);
460 ///
461 /// assert_eq!(bv.len(), 12);
462 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
463 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
464 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
465 /// ```
466 ///
467 /// [`pack_sequence_u64`]: BitVec::pack_sequence_u64
468 /// [`pack_sequence_u32`]: BitVec::pack_sequence_u32
469 /// [`pack_sequence_u8`]: BitVec::pack_sequence_u8
470 #[must_use]
471 pub fn pack_sequence_u16(sequence: &[u16], bits_per_element: usize) -> Self {
472 Self::pack_bits::<_, 16>(sequence, bits_per_element)
473 }
474
475 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
476 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
477 /// The number of bits per element is given by `bits_per_element`.
478 /// The sequence is given as a slice of u8 values.
479 /// If the number of bits per element is smaller than 8, the function takes the
480 /// least significant bits of each element, and discards the rest.
481 /// If the number of bits per element is larger than 8, the function will pad the elements
482 /// with zeros.
483 /// The function will append the bits of each element to the bit vector in the order they are
484 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
485 ///
486 /// See also: [`pack_sequence_u64`], [`pack_sequence_u32`], [`pack_sequence_u16`]
487 ///
488 /// # Example
489 /// ```rust
490 /// use vers_vecs::BitVec;
491 ///
492 /// let sequence = [0b1010u8, 0b1100u8, 0b1111u8];
493 /// let bv = BitVec::pack_sequence_u8(&sequence, 4);
494 ///
495 /// assert_eq!(bv.len(), 12);
496 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
497 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
498 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
499 /// ```
500 ///
501 /// [`pack_sequence_u64`]: BitVec::pack_sequence_u64
502 /// [`pack_sequence_u32`]: BitVec::pack_sequence_u32
503 /// [`pack_sequence_u16`]: BitVec::pack_sequence_u16
504 #[must_use]
505 pub fn pack_sequence_u8(sequence: &[u8], bits_per_element: usize) -> Self {
506 Self::pack_bits::<_, 8>(sequence, bits_per_element)
507 }
508
509 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
510 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
511 /// The number of bits per element is given by `bits_per_element`.
512 /// The sequence is given as an iterator of u64 values.
513 /// If the number of bits per element is smaller than 64, the function takes the
514 /// least significant bits of each element, and discards the rest.
515 /// If the number of bits per element is larger than 64, the function will pad the elements
516 /// with zeros.
517 /// The function will append the bits of each element to the bit vector in the order they are
518 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
519 ///
520 /// See also: [`pack_from_iter_u32`], [`pack_from_iter_u16`], [`pack_from_iter_u8`], or the
521 /// functions to pack from a slice: [`pack_sequence_u64`]
522 ///
523 /// # Example
524 /// ```rust
525 /// use vers_vecs::BitVec;
526 ///
527 /// let sequence = [0b1010u64, 0b1100u64, 0b1111u64];
528 /// let bv = BitVec::pack_from_iter_u64(sequence.into_iter(), 4);
529 ///
530 /// assert_eq!(bv.len(), 12);
531 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
532 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
533 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
534 /// ```
535 ///
536 /// [`pack_from_iter_u32`]: BitVec::pack_from_iter_u32
537 /// [`pack_from_iter_u16`]: BitVec::pack_from_iter_u16
538 /// [`pack_from_iter_u8`]: BitVec::pack_from_iter_u8
539 /// [`pack_sequence_u64`]: BitVec::pack_sequence_u64
540 pub fn pack_from_iter_u64<I: IntoIterator<Item = u64>>(
541 iter: I,
542 bits_per_element: usize,
543 ) -> Self {
544 Self::pack_bits_iter::<_, _, 64>(iter, bits_per_element)
545 }
546
547 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
548 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
549 /// The number of bits per element is given by `bits_per_element`.
550 /// The sequence is given as an iterator of u32 values.
551 /// If the number of bits per element is smaller than 32, the function takes the
552 /// least significant bits of each element, and discards the rest.
553 /// If the number of bits per element is larger than 32, the function will pad the elements
554 /// with zeros.
555 /// The function will append the bits of each element to the bit vector in the order they are
556 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
557 ///
558 /// See also: [`pack_from_iter_u64`], [`pack_from_iter_u16`], [`pack_from_iter_u8`], or the
559 /// functions to pack from a slice: [`pack_sequence_u32`]
560 ///
561 /// # Example
562 /// ```rust
563 /// use vers_vecs::BitVec;
564 ///
565 /// let sequence = [0b1010u32, 0b1100u32, 0b1111u32];
566 /// let bv = BitVec::pack_from_iter_u32(sequence.into_iter(), 4);
567 ///
568 /// assert_eq!(bv.len(), 12);
569 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
570 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
571 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
572 /// ```
573 ///
574 /// [`pack_from_iter_u64`]: BitVec::pack_from_iter_u64
575 /// [`pack_from_iter_u16`]: BitVec::pack_from_iter_u16
576 /// [`pack_from_iter_u8`]: BitVec::pack_from_iter_u8
577 /// [`pack_sequence_u32`]: BitVec::pack_sequence_u32
578 pub fn pack_from_iter_u32<I: IntoIterator<Item = u32>>(
579 iter: I,
580 bits_per_element: usize,
581 ) -> Self {
582 Self::pack_bits_iter::<_, _, 32>(iter, bits_per_element)
583 }
584
585 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
586 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
587 /// The number of bits per element is given by `bits_per_element`.
588 /// The sequence is given as an iterator of u16 values.
589 /// If the number of bits per element is smaller than 16, the function takes the
590 /// least significant bits of each element, and discards the rest.
591 /// If the number of bits per element is larger than 16, the function will pad the elements
592 /// with zeros.
593 /// The function will append the bits of each element to the bit vector in the order they are
594 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
595 ///
596 /// See also: [`pack_from_iter_u64`], [`pack_from_iter_u32`], [`pack_from_iter_u8`], or the
597 /// functions to pack from a slice: [`pack_sequence_u16`]
598 ///
599 /// # Example
600 /// ```rust
601 /// use vers_vecs::BitVec;
602 ///
603 /// let sequence = [0b1010u16, 0b1100u16, 0b1111u16];
604 /// let bv = BitVec::pack_from_iter_u16(sequence.into_iter(), 4);
605 ///
606 /// assert_eq!(bv.len(), 12);
607 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
608 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
609 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
610 /// ```
611 ///
612 /// [`pack_from_iter_u64`]: BitVec::pack_from_iter_u64
613 /// [`pack_from_iter_u32`]: BitVec::pack_from_iter_u32
614 /// [`pack_from_iter_u8`]: BitVec::pack_from_iter_u8
615 /// [`pack_sequence_u16`]: BitVec::pack_sequence_u16
616 pub fn pack_from_iter_u16<I: IntoIterator<Item = u16>>(
617 iter: I,
618 bits_per_element: usize,
619 ) -> Self {
620 Self::pack_bits_iter::<_, _, 16>(iter, bits_per_element)
621 }
622
623 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
624 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
625 /// The number of bits per element is given by `bits_per_element`.
626 /// The sequence is given as an iterator of u8 values.
627 /// If the number of bits per element is smaller than 8, the function takes the
628 /// least significant bits of each element, and discards the rest.
629 /// If the number of bits per element is larger than 8, the function will pad the elements
630 /// with zeros.
631 /// The function will append the bits of each element to the bit vector in the order they are
632 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
633 ///
634 /// See also: [`pack_from_iter_u64`], [`pack_from_iter_u32`], [`pack_from_iter_u16`], or the
635 /// functions to pack from a slice: [`pack_sequence_u8`]
636 ///
637 /// # Example
638 /// ```rust
639 /// use vers_vecs::BitVec;
640 ///
641 /// let sequence = [0b1010u8, 0b1100u8, 0b1111u8];
642 /// let bv = BitVec::pack_from_iter_u8(sequence.into_iter(), 4);
643 ///
644 /// assert_eq!(bv.len(), 12);
645 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
646 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
647 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
648 /// ```
649 ///
650 /// [`pack_from_iter_u64`]: BitVec::pack_from_iter_u64
651 /// [`pack_from_iter_u32`]: BitVec::pack_from_iter_u32
652 /// [`pack_from_iter_u16`]: BitVec::pack_from_iter_u16
653 /// [`pack_sequence_u8`]: BitVec::pack_sequence_u8
654 pub fn pack_from_iter_u8<I: IntoIterator<Item = u8>>(iter: I, bits_per_element: usize) -> Self {
655 Self::pack_bits_iter::<_, _, 8>(iter, bits_per_element)
656 }
657
658 /// Construct a bit vector from bits given as boolean values in a slice.
659 /// The function will append the bits to the bit vector in the order they are
660 /// given in the sequence (i.e. the first bool is the first bit of the vector).
661 ///
662 /// # Example
663 /// ```rust
664 /// use vers_vecs::BitVec;
665 ///
666 /// let sequence = [true, false, true, true];
667 /// let bv = BitVec::from_bools(&sequence);
668 ///
669 /// assert_eq!(bv.len(), 4);
670 /// assert_eq!(bv.is_bit_set(0), Some(true));
671 /// assert_eq!(bv.is_bit_set(1), Some(false));
672 /// assert_eq!(bv.is_bit_set(2), Some(true));
673 /// assert_eq!(bv.is_bit_set(3), Some(true));
674 /// ```
675 pub fn from_bools(bools: &[bool]) -> Self {
676 let mut bv = BitVec::with_capacity(bools.len());
677 bools.iter().for_each(|&b| bv.append(b));
678 bv
679 }
680
681 /// Construct a bit vector from bits given as boolean values from an iterator.
682 /// The function will append the bits to the bit vector in the order they are
683 /// given in the sequence (i.e. the first bool is the first bit of the vector).
684 ///
685 /// # Example
686 /// ```rust
687 /// use vers_vecs::BitVec;
688 ///
689 /// let sequence = [true, false, true, true];
690 /// let bv = BitVec::from_bool_iter(sequence.into_iter());
691 ///
692 /// assert_eq!(bv.len(), 4);
693 /// assert_eq!(bv.is_bit_set(0), Some(true));
694 /// assert_eq!(bv.is_bit_set(1), Some(false));
695 /// assert_eq!(bv.is_bit_set(2), Some(true));
696 /// assert_eq!(bv.is_bit_set(3), Some(true));
697 /// ```
698 pub fn from_bool_iter<I: IntoIterator<Item = bool>>(iter: I) -> Self {
699 let mut bv = BitVec::new();
700 iter.into_iter().for_each(|b| bv.append(b));
701 bv
702 }
703
704 /// Append a bit encoded as a `bool` to the bit vector, where `true` means 1 and `false` means 0.
705 ///
706 /// See also: [`append_bit`], [`append_bit_u32`], [`append_bit_u16`], [`append_bit_u8`], [`append_word`]
707 ///
708 /// # Example
709 ///
710 /// ```rust
711 /// use vers_vecs::BitVec;
712 ///
713 /// let mut bv = BitVec::new();
714 /// bv.append(true);
715 ///
716 /// assert_eq!(bv.len(), 1);
717 /// assert_eq!(bv.get(0), Some(1));
718 /// ```
719 ///
720 /// [`append_bit`]: BitVec::append_bit
721 /// [`append_bit_u32`]: BitVec::append_bit_u32
722 /// [`append_bit_u16`]: BitVec::append_bit_u16
723 /// [`append_bit_u8`]: BitVec::append_bit_u8
724 /// [`append_word`]: BitVec::append_word
725 pub fn append(&mut self, bit: bool) {
726 if self.len.is_multiple_of(WORD_SIZE) {
727 self.data.push(0);
728 }
729 if bit {
730 self.data[self.len / WORD_SIZE] |= 1 << (self.len % WORD_SIZE);
731 } else {
732 self.data[self.len / WORD_SIZE] &= !(1 << (self.len % WORD_SIZE));
733 }
734 self.len += 1;
735 }
736
737 /// Drop the last n bits from the bit vector. If more bits are dropped than the bit vector
738 /// contains, the bit vector is cleared.
739 ///
740 /// # Example
741 ///
742 /// ```rust
743 /// use vers_vecs::BitVec;
744 ///
745 /// let mut bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
746 /// bv.drop_last(3);
747 ///
748 /// assert_eq!(bv.len(), 3);
749 /// assert_eq!(bv.get_bits(0, 3), Some(0b101u64));
750 ///
751 /// bv.drop_last(4);
752 ///
753 /// assert!(bv.is_empty());
754 /// ```
755 pub fn drop_last(&mut self, n: usize) {
756 if n > self.len {
757 self.data.clear();
758 self.len = 0;
759 return;
760 }
761
762 let new_limb_count = (self.len - n).div_ceil(WORD_SIZE);
763
764 // cut off limbs that we no longer need
765 if new_limb_count < self.data.len() {
766 self.data.truncate(new_limb_count);
767 }
768
769 // update bit vector length
770 self.len -= n;
771 }
772
773 /// Append a bit encoded in a u64.
774 /// The least significant bit is appended to the bit vector.
775 /// All other bits are ignored.
776 ///
777 /// See also: [`append`], [`append_bit_u32`], [`append_bit_u16`], [`append_bit_u8`], [`append_word`]
778 ///
779 /// # Example
780 ///
781 /// ```rust
782 /// use vers_vecs::BitVec;
783 ///
784 /// let mut bv = BitVec::new();
785 ///
786 /// bv.append_bit(1);
787 /// bv.append_bit(0);
788 ///
789 /// assert_eq!(bv.len(), 2);
790 /// assert_eq!(bv.get(0), Some(1));
791 /// assert_eq!(bv.get(1), Some(0));
792 /// ```
793 ///
794 /// [`append`]: BitVec::append
795 /// [`append_bit_u32`]: BitVec::append_bit_u32
796 /// [`append_bit_u16`]: BitVec::append_bit_u16
797 /// [`append_bit_u8`]: BitVec::append_bit_u8
798 /// [`append_word`]: BitVec::append_word
799 pub fn append_bit(&mut self, bit: u64) {
800 if self.len.is_multiple_of(WORD_SIZE) {
801 self.data.push(0);
802 }
803 if bit % 2 == 1 {
804 self.data[self.len / WORD_SIZE] |= 1 << (self.len % WORD_SIZE);
805 } else {
806 self.data[self.len / WORD_SIZE] &= !(1 << (self.len % WORD_SIZE));
807 }
808
809 self.len += 1;
810 }
811
812 /// Append a bit from a u32. The least significant bit is appended to the bit vector.
813 /// All other bits are ignored.
814 ///
815 /// See also: [`append`], [`append_bit`], [`append_bit_u16`], [`append_bit_u8`], [`append_word`]
816 ///
817 /// [`append`]: BitVec::append
818 /// [`append_bit`]: BitVec::append_bit
819 /// [`append_bit_u16`]: BitVec::append_bit_u16
820 /// [`append_bit_u8`]: BitVec::append_bit_u8
821 /// [`append_word`]: BitVec::append_word
822 pub fn append_bit_u32(&mut self, bit: u32) {
823 self.append_bit(u64::from(bit));
824 }
825
826 /// Append a bit from a u16. The least significant bit is appended to the bit vector.
827 /// All other bits are ignored.
828 ///
829 /// See also: [`append`], [`append_bit`], [`append_bit_u32`], [`append_bit_u8`], [`append_word`]
830 ///
831 /// [`append`]: BitVec::append
832 /// [`append_bit`]: BitVec::append_bit
833 /// [`append_bit_u32`]: BitVec::append_bit_u32
834 /// [`append_bit_u8`]: BitVec::append_bit_u8
835 /// [`append_word`]: BitVec::append_word
836 pub fn append_bit_u16(&mut self, bit: u16) {
837 self.append_bit(u64::from(bit));
838 }
839
840 /// Append a bit from a u8. The least significant bit is appended to the bit vector.
841 /// All other bits are ignored.
842 ///
843 /// See also: [`append`], [`append_bit`], [`append_bit_u32`], [`append_bit_u16`], [`append_word`]
844 ///
845 /// [`append`]: BitVec::append
846 /// [`append_bit`]: BitVec::append_bit
847 /// [`append_bit_u32`]: BitVec::append_bit_u32
848 /// [`append_bit_u16`]: BitVec::append_bit_u16
849 /// [`append_word`]: BitVec::append_word
850 pub fn append_bit_u8(&mut self, bit: u8) {
851 self.append_bit(u64::from(bit));
852 }
853
854 /// Append a word to the bit vector. The bits are appended in little endian order (i.e. the first
855 /// bit of the word is appended first).
856 ///
857 /// See also: [`append`], [`append_bit`], [`append_bit_u32`], [`append_bit_u16`], [`append_bit_u8`]
858 ///
859 /// # Example
860 ///
861 /// ```rust
862 /// use vers_vecs::BitVec;
863 ///
864 /// let mut bv = BitVec::new();
865 /// bv.append_word(0b1010_1010_1010_1010u64);
866 ///
867 /// assert_eq!(bv.len(), 64);
868 /// for i in 0..64 {
869 /// assert_eq!(bv.get(i), Some((0b1010_1010_1010_1010u64 >> i) & 1));
870 /// }
871 /// ```
872 ///
873 /// [`append`]: BitVec::append
874 /// [`append_bit`]: BitVec::append_bit
875 /// [`append_bit_u32`]: BitVec::append_bit_u32
876 /// [`append_bit_u16`]: BitVec::append_bit_u16
877 /// [`append_bit_u8`]: BitVec::append_bit_u8
878 pub fn append_word(&mut self, word: u64) {
879 if self.len.is_multiple_of(WORD_SIZE) {
880 self.data.push(word);
881 } else {
882 // zero out the unused bits before or-ing the new one, to ensure no garbage data remains
883 self.data[self.len / WORD_SIZE] &= !(u64::MAX << (self.len % WORD_SIZE));
884 self.data[self.len / WORD_SIZE] |= word << (self.len % WORD_SIZE);
885
886 self.data.push(word >> (WORD_SIZE - self.len % WORD_SIZE));
887 }
888 self.len += WORD_SIZE;
889 }
890
891 /// Append multiple bits to the bit vector.
892 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
893 /// The number of bits to append is given by `len`. The bits are taken from the least
894 /// significant bits of `bits`.
895 /// All other bits are ignored.
896 ///
897 /// # Example
898 ///
899 /// ```rust
900 /// use vers_vecs::BitVec;
901 ///
902 /// let mut bv = BitVec::new();
903 /// bv.append_bits(0b1010_1010_1010_1010u64, 16);
904 ///
905 /// assert_eq!(bv.len(), 16);
906 /// assert_eq!(bv.get_bits(0, 16), Some(0b1010_1010_1010_1010u64));
907 /// ```
908 ///
909 /// # Panics
910 /// Panics if `len` is larger than 64.
911 pub fn append_bits(&mut self, bits: u64, len: usize) {
912 assert!(len <= 64, "Cannot append more than 64 bits");
913
914 if self.len.is_multiple_of(WORD_SIZE) {
915 if len > 0 {
916 self.data.push(bits);
917 }
918 } else {
919 // zero out the unused bits before or-ing the new one, to ensure no garbage data remains
920 self.data[self.len / WORD_SIZE] &= !(u64::MAX << (self.len % WORD_SIZE));
921 self.data[self.len / WORD_SIZE] |= bits << (self.len % WORD_SIZE);
922
923 if self.len % WORD_SIZE + len > WORD_SIZE {
924 self.data.push(bits >> (WORD_SIZE - self.len % WORD_SIZE));
925 }
926 }
927 self.len += len;
928 }
929
930 /// Append multiple bits to the bit vector.
931 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
932 /// The number of bits to append is given by `len`. The bits are taken from the least
933 /// significant bits of `bits`.
934 ///
935 /// This function does not check if `len` is larger than 64.
936 ///
937 /// Furthermore, if the bit-vector has trailing bits that are not zero
938 /// (i.e. the length is not a multiple of 64, and those bits are partially set),
939 /// the function will OR the new data with the trailing bits, destroying the appended data.
940 /// This can happen, if a call `append_bits[_unchecked](word, len)` appends a word which has
941 /// set bits beyond the `len - 1`-th bit,
942 /// or if bits have been dropped from the bit vector using [`drop_last`].
943 ///
944 /// This means the function must only be called during initial construction of vectors which are known
945 /// to not have contained data previously, and if the input data is known to not contain superfluous set bits.
946 ///
947 /// See [`append_bits`] for a checked version of this function.
948 ///
949 /// # Panics
950 /// If `len` is larger than 64, the behavior is platform-dependent, and a processor
951 /// exception might be triggered.
952 ///
953 /// [`append_bits`]: BitVec::append_bits
954 /// [`drop_last`]: BitVec::drop_last
955 pub fn append_bits_unchecked(&mut self, bits: u64, len: usize) {
956 if self.len.is_multiple_of(WORD_SIZE) {
957 if len > 0 {
958 self.data.push(bits);
959 }
960 } else {
961 self.data[self.len / WORD_SIZE] |= bits << (self.len % WORD_SIZE);
962
963 if self.len % WORD_SIZE + len > WORD_SIZE {
964 self.data.push(bits >> (WORD_SIZE - self.len % WORD_SIZE));
965 }
966 }
967 self.len += len;
968 }
969
970 /// Append the bits of another bit vector to the end of this vector.
971 /// If this vector does not contain a multiple of 64 bits, the appended limbs need to be
972 /// shifted to the left.
973 /// This function is guaranteed to reallocate the underlying vector at most once.
974 pub fn extend_bitvec(&mut self, other: &Self) {
975 // reserve space for the new bits, ensuring at most one re-allocation
976 self.data
977 .reserve((self.len + other.len).div_ceil(WORD_SIZE) - self.data.len());
978
979 let full_limbs = other.len() / WORD_SIZE;
980 for i in 0..full_limbs {
981 self.append_bits(other.data[i], WORD_SIZE);
982 }
983
984 let partial_bits = other.len % WORD_SIZE;
985 if partial_bits > 0 {
986 self.append_bits(other.data[full_limbs], partial_bits);
987 }
988 }
989
990 /// Return the length of the bit vector. The length is measured in bits.
991 #[must_use]
992 pub fn len(&self) -> usize {
993 self.len
994 }
995
996 /// Return whether the bit vector is empty (contains no bits).
997 #[must_use]
998 pub fn is_empty(&self) -> bool {
999 self.len == 0
1000 }
1001
1002 /// Flip the bit at the given position.
1003 ///
1004 /// # Example
1005 ///
1006 /// ```rust
1007 /// use vers_vecs::BitVec;
1008 ///
1009 /// let mut bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
1010 /// bv.flip_bit(1);
1011 ///
1012 /// assert_eq!(bv.len(), 6);
1013 /// assert_eq!(bv.get_bits(0, 6), Some(0b111111u64));
1014 /// ```
1015 ///
1016 /// # Panics
1017 /// If the position is larger than the length of the vector, the function panics.
1018 pub fn flip_bit(&mut self, pos: usize) {
1019 assert!(pos < self.len, "Index out of bounds");
1020 self.flip_bit_unchecked(pos);
1021 }
1022
1023 /// Flip the bit at the given position.
1024 ///
1025 /// See also: [`flip_bit`]
1026 ///
1027 /// # Panics
1028 /// If the position is larger than the length of the
1029 /// vector, the function will either modify unused memory or panic.
1030 /// This will not corrupt memory.
1031 ///
1032 /// [`flip_bit`]: BitVec::flip_bit
1033 pub fn flip_bit_unchecked(&mut self, pos: usize) {
1034 self.data[pos / WORD_SIZE] ^= 1 << (pos % WORD_SIZE);
1035 }
1036
1037 /// Return the bit at the given position.
1038 /// The bit is encoded in the least significant bit of a u64 value.
1039 /// If the position is larger than the length of the vector, None is returned.
1040 ///
1041 /// See also: [`get_unchecked`]
1042 ///
1043 /// # Example
1044 ///
1045 /// ```rust
1046 /// use vers_vecs::BitVec;
1047 ///
1048 /// let bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
1049 ///
1050 /// assert_eq!(bv.get(1), Some(0));
1051 /// assert_eq!(bv.get(2), Some(1));
1052 /// ```
1053 ///
1054 /// [`get_unchecked`]: Self::get_unchecked
1055 #[must_use]
1056 pub fn get(&self, pos: usize) -> Option<u64> {
1057 if pos >= self.len {
1058 None
1059 } else {
1060 Some(self.get_unchecked(pos))
1061 }
1062 }
1063
1064 /// Return the bit at the given position.
1065 /// The bit is encoded in the least significant bit of a u64 value.
1066 ///
1067 /// # Panics
1068 /// If the position is larger than the length of the vector,
1069 /// the function will either return unpredictable data, or panic.
1070 /// Use [`get`] to properly handle this case with an `Option`.
1071 ///
1072 /// [`get`]: BitVec::get
1073 #[must_use]
1074 pub fn get_unchecked(&self, pos: usize) -> u64 {
1075 (self.data[pos / WORD_SIZE] >> (pos % WORD_SIZE)) & 1
1076 }
1077
1078 /// Set the bit at the given position.
1079 /// The bit is encoded in the least significant bit of a u64 value.
1080 ///
1081 /// See also: [`set_unchecked`]
1082 ///
1083 /// # Example
1084 ///
1085 /// ```rust
1086 /// use vers_vecs::BitVec;
1087 ///
1088 /// let mut bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
1089 /// bv.set(1, 1).unwrap();
1090 ///
1091 /// assert_eq!(bv.len(), 6);
1092 /// assert_eq!(bv.get_bits(0, 6), Some(0b111111u64));
1093 /// ```
1094 ///
1095 /// # Errors
1096 /// If the position is out of range, the function will return `Err` with an error message,
1097 /// otherwise it will return an empty `Ok`.
1098 ///
1099 /// [`set_unchecked`]: BitVec::set_unchecked
1100 pub fn set(&mut self, pos: usize, value: u64) -> Result<(), &str> {
1101 if pos >= self.len {
1102 Err("out of range")
1103 } else {
1104 self.set_unchecked(pos, value);
1105 Ok(())
1106 }
1107 }
1108
1109 /// Set the bit at the given position.
1110 /// The bit is encoded in the least significant bit of a u64 value.
1111 ///
1112 /// # Panics
1113 /// If the position is larger than the length of the vector,
1114 /// the function will either do nothing, or panic.
1115 /// Use [`set`] to properly handle this case with a `Result`.
1116 ///
1117 /// [`set`]: BitVec::set
1118 pub fn set_unchecked(&mut self, pos: usize, value: u64) {
1119 self.data[pos / WORD_SIZE] = (self.data[pos / WORD_SIZE] & !(0x1 << (pos % WORD_SIZE)))
1120 | ((value & 0x1) << (pos % WORD_SIZE));
1121 }
1122
1123 /// Return whether the bit at the given position is set.
1124 /// If the position is larger than the length of the vector, None is returned.
1125 ///
1126 /// See also: [`is_bit_set_unchecked`]
1127 ///
1128 /// # Example
1129 ///
1130 /// ```rust
1131 /// use vers_vecs::BitVec;
1132 ///
1133 /// let bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
1134 ///
1135 /// assert!(!bv.is_bit_set(1).unwrap());
1136 /// assert!(bv.is_bit_set(2).unwrap());
1137 /// ```
1138 ///
1139 /// [`is_bit_set_unchecked`]: BitVec::is_bit_set_unchecked
1140 #[must_use]
1141 pub fn is_bit_set(&self, pos: usize) -> Option<bool> {
1142 if pos >= self.len {
1143 None
1144 } else {
1145 Some(self.is_bit_set_unchecked(pos))
1146 }
1147 }
1148
1149 /// Return whether the bit at the given position is set.
1150 ///
1151 /// # Panics
1152 /// If the position is larger than the length of the vector,
1153 /// the function will either return unpredictable data, or panic.
1154 /// Use [`is_bit_set`] to properly handle this case with an `Option`.
1155 ///
1156 /// [`is_bit_set`]: BitVec::is_bit_set
1157 #[must_use]
1158 pub fn is_bit_set_unchecked(&self, pos: usize) -> bool {
1159 self.get_unchecked(pos) != 0
1160 }
1161
1162 /// Return multiple bits at the given position.
1163 /// The number of bits to return is given by `len`.
1164 /// At most 64 bits can be returned.
1165 /// If the position at the end of the query is larger than the length of the vector,
1166 /// None is returned (even if the query partially overlaps with the vector).
1167 /// If the length of the query is larger than 64, None is returned.
1168 ///
1169 /// The first bit at `pos` is the most significant bit of the return value
1170 /// limited to `len` bits.
1171 #[must_use]
1172 pub fn get_bits(&self, pos: usize, len: usize) -> Option<u64> {
1173 if len > WORD_SIZE || len == 0 {
1174 return None;
1175 }
1176 if pos + len > self.len {
1177 None
1178 } else {
1179 Some(self.get_bits_unchecked(pos, len))
1180 }
1181 }
1182
1183 /// Return multiple bits at the given position. The number of bits to return is given by `len`.
1184 /// At most 64 bits can be returned.
1185 ///
1186 /// Reading 0 bits is always legal, even if the index is out of bounds.
1187 /// This behavior was chosen such that operations like the following behave expectedly:
1188 /// ```
1189 /// # use vers_vecs::BitVec;
1190 /// let mut bv = BitVec::new();
1191 /// bv.append_bits_unchecked(1, 0);
1192 /// bv.append_bits_unchecked(63, 0);
1193 /// bv.append_bits_unchecked(1, 0);
1194 ///
1195 /// assert_eq!(bv.get_bits_unchecked(0, 0), 0);
1196 /// assert_eq!(bv.get_bits_unchecked(1, 0), 0);
1197 /// assert_eq!(bv.get_bits_unchecked(2, 0), 0);
1198 /// ```
1199 ///
1200 /// # Errors
1201 /// If the length of the query is larger than 64, unpredictable data will be returned.
1202 /// Use [`get_bits`] to avoid this.
1203 ///
1204 /// # Panics
1205 /// If the position or interval is larger than the length of the vector,
1206 /// the function will either return any valid results padded with unpredictable
1207 /// data or panic.
1208 ///
1209 /// [`get_bits`]: BitVec::get_bits
1210 // This function is always inlined, because it gains a lot from loop optimization and
1211 // can utilize the processor pre-fetcher better if it is.
1212 #[must_use]
1213 #[allow(clippy::inline_always)]
1214 #[allow(clippy::comparison_chain)] // readability
1215 #[inline(always)] // inline to gain loop optimization and pipeline advantages for elias fano
1216 #[allow(clippy::cast_possible_truncation)] // parameter must be out of scope for this to happen
1217 pub fn get_bits_unchecked(&self, pos: usize, len: usize) -> u64 {
1218 debug_assert!(len <= WORD_SIZE);
1219 if len == 0 {
1220 return 0;
1221 }
1222
1223 let partial_word = self.data[pos / WORD_SIZE] >> (pos % WORD_SIZE);
1224 if pos % WORD_SIZE + len <= WORD_SIZE {
1225 partial_word & 1u64.checked_shl(len as u32).unwrap_or(0).wrapping_sub(1)
1226 } else {
1227 (partial_word | (self.data[pos / WORD_SIZE + 1] << (WORD_SIZE - pos % WORD_SIZE)))
1228 & 1u64.checked_shl(len as u32).unwrap_or(0).wrapping_sub(1)
1229 }
1230 }
1231
1232 /// Extract a packed element from a bit vector. The element is encoded in the bits at the given
1233 /// `index`. The number of bits per encoded element is given by `n`.
1234 ///
1235 /// This is a convenience method to access elements previously packed using the [`pack_sequence_*`] methods,
1236 /// and is equivalent to calling [`get_bits(index * n, n)`].
1237 /// It is thus safe to use this method with any index and any size n <= 64.
1238 ///
1239 /// If the element is out of bounds, None is returned.
1240 /// The element is returned as a u64 value.
1241 ///
1242 /// # Example
1243 /// ```rust
1244 /// use vers_vecs::BitVec;
1245 ///
1246 /// let sequence = [10, 100, 124, 45, 223];
1247 /// let bv = BitVec::pack_sequence_u64(&sequence, 8);
1248 ///
1249 /// assert_eq!(bv.unpack_element(0, 8), Some(10));
1250 /// assert_eq!(bv.unpack_element(2, 8), Some(124));
1251 /// ```
1252 ///
1253 /// [`pack_sequence_*`]: BitVec::pack_sequence_u64
1254 /// [`get_bits(index * n, n)`]: BitVec::get_bits
1255 #[must_use]
1256 #[allow(clippy::inline_always)]
1257 #[inline(always)] // to gain optimization if n is constant
1258 pub fn unpack_element(&self, index: usize, n: usize) -> Option<u64> {
1259 self.get_bits(index * n, n)
1260 }
1261
1262 /// Extract a packed element from a bit vector. The element is encoded in the bits at the given
1263 /// `index`. The number of bits per encoded element is given by `n`.
1264 ///
1265 /// This is a convenience method to access elements previously packed using the [`pack_sequence_*`] methods,
1266 /// and is equivalent to calling [`get_bits_unchecked(index * n, n)`].
1267 /// It is thus safe to use this method with any index where `index * n + n` is in-bounds,
1268 /// and any size n <= 64.
1269 ///
1270 /// # Panics
1271 /// If the element is out of bounds, the function will either return unpredictable data or panic.
1272 /// Use [`unpack_element`] for a checked version of this function.
1273 ///
1274 /// [`pack_sequence_*`]: BitVec::pack_sequence_u64
1275 /// [`get_bits_unchecked(index * n, n)`]: BitVec::get_bits_unchecked
1276 /// [`unpack_element`]: BitVec::unpack_element
1277 #[must_use]
1278 #[allow(clippy::inline_always)]
1279 #[inline(always)] // to gain optimization if n is constant
1280 pub fn unpack_element_unchecked(&self, index: usize, n: usize) -> u64 {
1281 self.get_bits_unchecked(index * n, n)
1282 }
1283
1284 /// Return the number of ones in the bit vector. Since the bit vector doesn't store additional
1285 /// metadata, this value is calculated. Use [`RsVec`] for constant-time rank operations.
1286 ///
1287 /// [`RsVec`]: crate::RsVec
1288 #[must_use]
1289 #[allow(clippy::missing_panics_doc)] // can't panic because of manual bounds check
1290 pub fn count_ones(&self) -> u64 {
1291 let mut ones: u64 = self.data[0..self.len / WORD_SIZE]
1292 .iter()
1293 .map(|limb| u64::from(limb.count_ones()))
1294 .sum();
1295 if !self.len.is_multiple_of(WORD_SIZE) {
1296 ones += u64::from(
1297 (self.data.last().unwrap() & ((1 << (self.len % WORD_SIZE)) - 1)).count_ones(),
1298 );
1299 }
1300 ones
1301 }
1302
1303 /// Return the number of zeros in the bit vector. Since the bit vector doesn't store additional
1304 /// metadata, this value is calculated. Use [`RsVec`] for constant-time rank operations.
1305 /// This method calls [`count_ones`].
1306 ///
1307 /// [`RsVec`]: crate::RsVec
1308 /// [`count_ones`]: BitVec::count_ones
1309 #[must_use]
1310 pub fn count_zeros(&self) -> u64 {
1311 self.len as u64 - self.count_ones()
1312 }
1313
1314 /// Mask this bit vector with another bitvector using bitwise or. The mask is applied lazily
1315 /// whenever an operation on the resulting vector is performed.
1316 ///
1317 /// # Errors
1318 /// Returns an error if the length of the vector doesn't match the mask length.
1319 #[inline]
1320 pub fn mask_or<'s, 'b>(&'s self, mask: &'b BitVec) -> Result<BitMask<'s, 'b>, String> {
1321 MaskedBitVec::new(self, mask, |a, b| a | b)
1322 }
1323
1324 /// Mask this bit vector with another bitvector using bitwise or.
1325 /// The mask is applied immediately, unlike in [`mask_or`].
1326 ///
1327 /// # Errors
1328 /// Returns an error if the length of the vector doesn't match the mask length.
1329 ///
1330 /// [`mask_or`]: BitVec::mask_or
1331 pub fn apply_mask_or(&mut self, mask: &BitVec) -> Result<(), String> {
1332 if self.len != mask.len {
1333 return Err(String::from(
1334 "mask cannot have different length than vector",
1335 ));
1336 }
1337
1338 for i in 0..self.data.len() {
1339 self.data[i] |= mask.data[i];
1340 }
1341
1342 Ok(())
1343 }
1344
1345 /// Mask this bit vector with another bitvector using bitwise and. The mask is applied lazily
1346 /// whenever an operation on the resulting vector is performed.
1347 ///
1348 /// # Errors
1349 /// Returns an error if the length of the vector doesn't match the mask length.
1350 #[inline]
1351 pub fn mask_and<'s, 'b>(&'s self, mask: &'b BitVec) -> Result<BitMask<'s, 'b>, String> {
1352 MaskedBitVec::new(self, mask, |a, b| a & b)
1353 }
1354
1355 /// Mask this bit vector with another bitvector using bitwise and.
1356 /// The mask is applied immediately, unlike in [`mask_and`].
1357 ///
1358 /// # Errors
1359 /// Returns an error if the length of the vector doesn't match the mask length.
1360 ///
1361 /// [`mask_and`]: BitVec::mask_and
1362 pub fn apply_mask_and(&mut self, mask: &BitVec) -> Result<(), String> {
1363 if self.len != mask.len {
1364 return Err(String::from(
1365 "mask cannot have different length than vector",
1366 ));
1367 }
1368
1369 for i in 0..self.data.len() {
1370 self.data[i] &= mask.data[i];
1371 }
1372
1373 Ok(())
1374 }
1375
1376 /// Mask this bit vector with another bitvector using bitwise xor. The mask is applied lazily
1377 /// whenever an operation on the resulting vector is performed.
1378 ///
1379 /// # Errors
1380 /// Returns an error if the length of the vector doesn't match the mask length.
1381 #[inline]
1382 pub fn mask_xor<'s, 'b>(&'s self, mask: &'b BitVec) -> Result<BitMask<'s, 'b>, String> {
1383 MaskedBitVec::new(self, mask, |a, b| a ^ b)
1384 }
1385
1386 /// Mask this bit vector with another bitvector using bitwise xor.
1387 /// The mask is applied immediately, unlike in [`mask_xor`].
1388 ///
1389 /// # Errors
1390 /// Returns an error if the length of the vector doesn't match the mask length.
1391 ///
1392 /// [`mask_xor`]: BitVec::mask_xor
1393 pub fn apply_mask_xor(&mut self, mask: &BitVec) -> Result<(), String> {
1394 if self.len != mask.len {
1395 return Err(String::from(
1396 "mask cannot have different length than vector",
1397 ));
1398 }
1399
1400 for i in 0..self.data.len() {
1401 self.data[i] ^= mask.data[i];
1402 }
1403
1404 Ok(())
1405 }
1406
1407 /// Mask this bit vector with another bitvector using a custom masking operation. The mask is
1408 /// applied lazily whenever an operation on the resulting vector is performed.
1409 ///
1410 /// The masking operation takes two 64 bit values which contain blocks of 64 bits each.
1411 /// The last block of a bit vector might contain fewer bits, and will be padded with
1412 /// unpredictable data. Implementations may choose to modify those padding bits without
1413 /// repercussions. Implementations shouldn't use operations like bit shift, because the bit order
1414 /// within the vector is unspecified.
1415 ///
1416 /// # Errors
1417 /// Returns an error if the length of the vector doesn't match the mask length.
1418 #[inline]
1419 pub fn mask_custom<'s, 'b, F>(
1420 &'s self,
1421 mask: &'b BitVec,
1422 mask_op: F,
1423 ) -> Result<MaskedBitVec<'s, 'b, F>, String>
1424 where
1425 F: Fn(u64, u64) -> u64,
1426 {
1427 MaskedBitVec::new(self, mask, mask_op)
1428 }
1429
1430 /// Mask this bit vector with another bitvector using a custom masking operation.
1431 /// The mask is applied immediately, unlike in [`mask_custom`].
1432 ///
1433 /// The masking operation takes two 64 bit values which contain blocks of 64 bits each.
1434 /// The last block of a bit vector might contain fewer bits, and will be padded with
1435 /// unpredictable data. Implementations may choose to modify those padding bits without
1436 /// repercussions. Implementations shouldn't use operations like bit shift, because the bit order
1437 /// within the vector is unspecified.
1438 ///
1439 /// # Errors
1440 /// Returns an error if the length of the vector doesn't match the mask length.
1441 ///
1442 /// [`mask_custom`]: BitVec::mask_custom
1443 #[inline]
1444 pub fn apply_mask_custom(
1445 &mut self,
1446 mask: &BitVec,
1447 mask_op: fn(u64, u64) -> u64,
1448 ) -> Result<(), String> {
1449 if self.len != mask.len {
1450 return Err(String::from(
1451 "mask cannot have different length than vector",
1452 ));
1453 }
1454
1455 for i in 0..self.data.len() {
1456 self.data[i] = mask_op(self.data[i], mask.data[i]);
1457 }
1458
1459 Ok(())
1460 }
1461
1462 /// Returns the number of bytes on the heap for this vector.
1463 /// Does not include allocated memory that isn't used.
1464 #[must_use]
1465 pub fn heap_size(&self) -> usize {
1466 self.data.len() * size_of::<u64>()
1467 }
1468
1469 /// Split the vector in two at the specified index. The left half contains bits `0..at` and the
1470 /// right half the remaining bits `at..`. If the split index is larger than the length of the
1471 /// vector, the vector is returned unmodified in an `Err` variant.
1472 ///
1473 /// # Errors
1474 /// If the index is out of bounds, the function will return an error
1475 /// containing the original vector.
1476 ///
1477 /// See also: [`split_at_unchecked`]
1478 ///
1479 /// [`split_at_unchecked`]: Self::split_at_unchecked
1480 pub fn split_at(self, at: usize) -> Result<(Self, Self), Self> {
1481 if at > self.len {
1482 Err(self)
1483 } else {
1484 Ok(self.split_at_unchecked(at))
1485 }
1486 }
1487
1488 /// Split the vector in two at the specified index. The left half contains bits `0..at` and the
1489 /// right half the remaining bits `at..`.
1490 ///
1491 /// # Panics
1492 /// If the index is larger than the length of the vector the function will panic or run
1493 /// out of memory.
1494 /// Use [`split_at`] to properly handle this case.
1495 ///
1496 /// [`split_at`]: Self::split_at
1497 #[must_use]
1498 pub fn split_at_unchecked(mut self, at: usize) -> (Self, Self) {
1499 let other_len = self.len - at;
1500 let mut other = Self::with_capacity(other_len);
1501
1502 if other_len == 0 {
1503 return (self, other);
1504 }
1505
1506 let first_limb = at / WORD_SIZE;
1507 let last_limb = self.len / WORD_SIZE;
1508
1509 // First, we figure out the number of bits from the first limb to retain in this vector:
1510 let leading_partial = at % WORD_SIZE;
1511
1512 // If the split point is in the last limb, and the vector ends before the last bit, first_limb
1513 // and last_limb will be equal, and the other half is simply other_len bits off the limb
1514 // right shifted by the number of bits to retain in this vector.
1515 if first_limb == last_limb {
1516 other.append_bits_unchecked(self.data[first_limb] >> leading_partial, other_len);
1517 } else {
1518 // Otherwise, some range n..last_limb should be copied in their entirety to the other half,
1519 // with n=first_limb+1 if the split point is inside the first limb (leading_partial > 0), or
1520 // n=first_limb if the entire first limb belongs in the other half.
1521 let full_limbs = if leading_partial > 0 {
1522 // If the split point is inside the first limb, we also have to remember to copy over
1523 // the trailing bits to the new vector.
1524 other.append_bits_unchecked(
1525 self.data[first_limb] >> leading_partial,
1526 WORD_SIZE - leading_partial,
1527 );
1528 first_limb + 1..last_limb
1529 } else {
1530 first_limb..last_limb
1531 };
1532
1533 // Copy over any full limbs.
1534 for i in full_limbs {
1535 other.append_bits_unchecked(self.data[i], WORD_SIZE);
1536 }
1537
1538 // Finally, if the vector has a partially filled last limb, we need to put those bits
1539 // in the other half.
1540 let trailing_partial = self.len % WORD_SIZE;
1541 if trailing_partial > 0 {
1542 other.append_bits_unchecked(self.data[last_limb], trailing_partial);
1543 }
1544 }
1545
1546 // remove the copied bits from the original vector
1547 self.drop_last(other_len);
1548
1549 (self, other)
1550 }
1551
1552 /// Iterate through the u64 limbs of the bitvector.
1553 /// The limbs are encoded starting at the least significant bit (i.e., the first bit in the bit
1554 /// vector is the least significant bit in the first limb).
1555 /// Note that the last limb may be incomplete, if the number of bits in the vector is not
1556 /// divisible by 64.
1557 /// In this case, the least significant `self.len() % 64` bits are the correct bits.
1558 /// The remaining bits of the last limb are in an unspecified state and code should not rely
1559 /// on them being set or unset.
1560 #[inline]
1561 pub fn iter_limbs(&self) -> impl Iterator<Item = u64> + use<'_> {
1562 self.data.iter().copied()
1563 }
1564}
1565
1566impl_vector_iterator! { BitVec, BitVecIter, BitVecRefIter }
1567
1568/// Create a new bit vector from a slice of u64 values.
1569/// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
1570/// The function will append the bits of each element to the bit vector in the order they are
1571/// given in the slice (i.e. the first element takes bits `0..64` of the vector).
1572impl From<&[u64]> for BitVec {
1573 fn from(data: &[u64]) -> Self {
1574 BitVec::from_limbs(data)
1575 }
1576}
1577
1578/// Create a new bit vector from a slice of u64 values.
1579/// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
1580/// The function will append the bits of each element to the bit vector in the order they are
1581/// given in the slice (i.e. the first element takes bits `0..64` of the vector).
1582impl From<Vec<u64>> for BitVec {
1583 fn from(data: Vec<u64>) -> Self {
1584 BitVec::from_limbs(&data)
1585 }
1586}
1587
1588impl Extend<BitVec> for BitVec {
1589 fn extend<T: IntoIterator<Item = BitVec>>(&mut self, iter: T) {
1590 for v in iter {
1591 self.extend_bitvec(&v);
1592 }
1593 }
1594}
1595
1596impl<'t> Extend<&'t BitVec> for BitVec {
1597 fn extend<T: IntoIterator<Item = &'t BitVec>>(&mut self, iter: T) {
1598 for v in iter {
1599 self.extend_bitvec(v);
1600 }
1601 }
1602}
1603
1604/// Create a new bit vector from u64 values.
1605/// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
1606/// The function will append the bits of each element to the bit vector in the order they are
1607/// given in the iterator (i.e. the first element takes bits `0..64` of the vector).
1608impl FromIterator<u64> for BitVec {
1609 fn from_iter<T: IntoIterator<Item = u64>>(iter: T) -> Self {
1610 BitVec::from_limbs_iter(iter)
1611 }
1612}
1613
1614impl PartialEq for BitVec {
1615 // unlike the auto-derived implementation, this custom implementation ignores junk data at
1616 // the end of the bit vector
1617 fn eq(&self, other: &Self) -> bool {
1618 if self.len != other.len {
1619 return false;
1620 }
1621
1622 if self.len == 0 {
1623 return true;
1624 }
1625
1626 for i in 0..self.data.len() - 1 {
1627 if self.data[i] != other.data[i] {
1628 return false;
1629 }
1630 }
1631
1632 // in last limb, ignore junk data
1633 let mask = (1 << (self.len % WORD_SIZE)) - 1;
1634 if self.data[self.data.len() - 1] & mask != other.data[self.data.len() - 1] & mask {
1635 return false;
1636 }
1637
1638 true
1639 }
1640}
1641
1642impl Eq for BitVec {}
1643
1644impl Hash for BitVec {
1645 fn hash<H: Hasher>(&self, state: &mut H) {
1646 state.write_usize(self.len);
1647 if self.len > 0 {
1648 self.data[0..self.data.len() - 1]
1649 .iter()
1650 .for_each(|x| state.write_u64(*x));
1651 let masked_last_limb = self.data.last().unwrap() & ((1 << (self.len % WORD_SIZE)) - 1);
1652 state.write_u64(masked_last_limb);
1653 }
1654 }
1655}
1656
1657#[cfg(test)]
1658mod tests;