Skip to main content

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;