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::mem::size_of;
8
9pub mod fast_rs_vec;
10
11pub mod sparse;
12
13pub mod mask;
14
15/// Size of a word in bitvectors. All vectors operate on 64-bit words.
16const WORD_SIZE: usize = 64;
17
18/// Type alias for masked bitvectors that implement a simple bitwise binary operation.
19/// The first lifetime is for the bit vector that is being masked, the second lifetime is for the
20/// mask.
21pub type BitMask<'s, 'b> = MaskedBitVec<'s, 'b, fn(u64, u64) -> u64>;
22
23/// A simple bit vector that does not support rank and select queries.
24/// Bits are stored in little-endian order, i.e. the least significant bit is stored first.
25/// The bit vector is stored as a sequence of 64 bit limbs.
26/// The last limb may be partially filled.
27///
28/// The bit vector has a wide range of constructors that allow for easy creation from various
29/// sources.
30/// Among them are constructors for creating an empty vector ([`BitVec::new`]),
31/// creating one from single bits of various integer types ([`BitVec::from_bits`] and variations),
32/// creating limbs from u64 values directly ([`BitVec::from_limbs`] and variations),
33/// or packing a sequence of numerical values into a dense bit sequence
34/// ([`BitVec::pack_sequence_u64`] and variations).
35///
36/// The bit vector can be modified after creation
37/// (e.g. by appending [bits](BitVec::append_bits)
38/// or [words](BitVec::append_word),
39/// [flipping](BitVec::flip_bit),
40/// or [setting](BitVec::set) bits).
41/// Bits can be [accessed](BitVec::get) by position,
42/// and [multiple bits](BitVec::get_bits) can be accessed at once.
43/// Bits can be [dropped](BitVec::drop_last) from the end.
44///
45/// # Example
46/// ```rust
47/// use vers_vecs::{BitVec, RsVec};
48///
49/// let mut bit_vec = BitVec::new();
50/// bit_vec.append_bit(0u64);
51/// bit_vec.append_bit_u32(1u32);
52/// bit_vec.append_word(0b1010_1010_1010_1010u64); // appends exactly 64 bits
53///
54/// assert_eq!(bit_vec.len(), 66);
55/// assert_eq!(bit_vec.get(0), Some(0u64));
56/// assert_eq!(bit_vec.get(1), Some(1u64));
57/// ```
58#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
59#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60pub struct BitVec {
61 data: Vec<u64>,
62 len: usize,
63}
64
65impl BitVec {
66 /// Create a new empty bit vector.
67 #[must_use]
68 pub fn new() -> Self {
69 Self::default()
70 }
71
72 /// Create a new empty bit vector with the given capacity.
73 /// The capacity is measured in bits.
74 /// The bit vector will be able to hold at least `capacity` bits without reallocating.
75 /// More memory may be allocated according to the underlying allocation strategy.
76 #[must_use]
77 pub fn with_capacity(capacity: usize) -> Self {
78 Self {
79 data: Vec::with_capacity(capacity / WORD_SIZE + 1),
80 len: 0,
81 }
82 }
83
84 /// Create a new bit vector with all zeros and the given length.
85 /// The length is measured in bits.
86 #[must_use]
87 pub fn from_zeros(len: usize) -> Self {
88 let mut data = vec![0; len / WORD_SIZE];
89 if len % WORD_SIZE != 0 {
90 data.push(0);
91 }
92 Self { data, len }
93 }
94
95 /// Create a new bit vector with all ones and the given length.
96 /// The length is measured in bits.
97 #[must_use]
98 pub fn from_ones(len: usize) -> Self {
99 let mut data = vec![u64::MAX; len / WORD_SIZE];
100 if len % WORD_SIZE != 0 {
101 data.push((1 << (len % WORD_SIZE)) - 1);
102 }
103 Self { data, len }
104 }
105
106 /// Construct a bit vector from a set of bits given as distinct u8 values.
107 /// The constructor will take the least significant bit from each value and append it to a
108 /// bit vector.
109 /// All other bits are ignored.
110 ///
111 /// See also: [`from_bits_u16`], [`from_bits_u32`], [`from_bits_u64`], [`from_bits_iter`]
112 ///
113 /// # Example
114 /// ```rust
115 /// use vers_vecs::BitVec;
116 ///
117 /// let bits: &[u8] = &[1, 0, 1, 1, 1, 1];
118 /// let bv = BitVec::from_bits(&bits);
119 ///
120 /// assert_eq!(bv.len(), 6);
121 /// assert_eq!(bv.get_bits(0, 6), Some(0b111101u64));
122 /// ```
123 ///
124 /// [`from_bits_u16`]: BitVec::from_bits_u16
125 /// [`from_bits_u32`]: BitVec::from_bits_u32
126 /// [`from_bits_u64`]: BitVec::from_bits_u64
127 /// [`from_bits_iter`]: BitVec::from_bits_iter
128 #[must_use]
129 pub fn from_bits(bits: &[u8]) -> Self {
130 let mut bv = Self::with_capacity(bits.len());
131 bits.iter().for_each(|&b| bv.append_bit(b.into()));
132 bv
133 }
134
135 /// Construct a bit vector from a set of bits given as distinct u16 values.
136 /// The constructor will take the least significant bit from each value and append it to a
137 /// bit vector.
138 /// All other bits are ignored.
139 ///
140 /// See also: [`from_bits`], [`from_bits_u32`], [`from_bits_u64`], [`from_bits_iter`]
141 ///
142 /// [`from_bits`]: BitVec::from_bits
143 /// [`from_bits_u32`]: BitVec::from_bits_u32
144 /// [`from_bits_u64`]: BitVec::from_bits_u64
145 /// [`from_bits_iter`]: BitVec::from_bits_iter
146 #[must_use]
147 pub fn from_bits_u16(bits: &[u16]) -> Self {
148 let mut bv = Self::with_capacity(bits.len());
149 bits.iter().for_each(|&b| bv.append_bit_u16(b));
150 bv
151 }
152
153 /// Construct a bit vector from a set of bits given as distinct u32 values.
154 /// The constructor will take the least significant bit from each value and append it to a
155 /// bit vector.
156 /// All other bits are ignored.
157 ///
158 /// See also: [`from_bits`], [`from_bits_u16`], [`from_bits_u64`], [`from_bits_iter`]
159 ///
160 /// [`from_bits`]: BitVec::from_bits
161 /// [`from_bits_u16`]: BitVec::from_bits_u16
162 /// [`from_bits_u64`]: BitVec::from_bits_u64
163 /// [`from_bits_iter`]: BitVec::from_bits_iter
164 #[must_use]
165 pub fn from_bits_u32(bits: &[u32]) -> Self {
166 let mut bv = Self::with_capacity(bits.len());
167 bits.iter().for_each(|&b| bv.append_bit_u32(b));
168 bv
169 }
170
171 /// Construct a bit vector from a set of bits given as distinct u64 values.
172 /// The constructor will take the least significant bit from each value and append it to a
173 /// bit vector.
174 /// All other bits are ignored.
175 ///
176 /// See also: [`from_bits`], [`from_bits_u16`], [`from_bits_u32`], [`from_bits_iter`]
177 ///
178 /// [`from_bits`]: BitVec::from_bits
179 /// [`from_bits_u16`]: BitVec::from_bits_u16
180 /// [`from_bits_u32`]: BitVec::from_bits_u32
181 /// [`from_bits_iter`]: BitVec::from_bits_iter
182 #[must_use]
183 pub fn from_bits_u64(bits: &[u64]) -> Self {
184 let mut bv = Self::with_capacity(bits.len());
185 bits.iter().for_each(|&b| bv.append_bit(b));
186 bv
187 }
188
189 /// Construct a bit vector from an iterator of bits.
190 /// The constructor will take the least significant bit from each value and append it to a
191 /// bit vector.
192 /// All other bits are ignored.
193 /// The iterator must yield values that can be converted into u64 values.
194 ///
195 /// See also: [`from_bits`], [`from_bits_u16`], [`from_bits_u32`], [`from_bits_u64`]
196 ///
197 /// # Example
198 /// ```rust
199 /// use vers_vecs::BitVec;
200 ///
201 /// let bits = [true, false, true, true, true, true];
202 /// let bv = BitVec::from_bits_iter(bits.iter().copied());
203 ///
204 /// let bits = [0b1u8, 0b0, 0b1, 0b1, 0b1, 0b1];
205 /// let bv2 = BitVec::from_bits_iter(bits.iter().copied());
206 ///
207 /// assert_eq!(bv.len(), 6);
208 /// assert_eq!(bv.get_bits(0, 6), Some(0b111101u64));
209 /// assert_eq!(bv, bv2);
210 /// ```
211 ///
212 /// [`from_bits`]: BitVec::from_bits
213 /// [`from_bits_u16`]: BitVec::from_bits_u16
214 /// [`from_bits_u32`]: BitVec::from_bits_u32
215 /// [`from_bits_u64`]: BitVec::from_bits_u64
216 #[must_use]
217 pub fn from_bits_iter<I, E>(iter: I) -> Self
218 where
219 E: Into<u64>,
220 I: IntoIterator<Item = E>,
221 {
222 let iter = iter.into_iter();
223 let mut bv = Self::with_capacity(iter.size_hint().0);
224 for bit in iter {
225 bv.append_bit(bit.into());
226 }
227 bv
228 }
229
230 /// Construct a bit vector from a slice of u64 quad words.
231 /// The quad words are interpreted as limbs of the bit vector (i.e. each quad word contributes
232 /// 64 bits to the bit vector).
233 /// Since the data is only cloned without any masking or transformation,
234 /// this is one of the fastest ways to create a bit vector.
235 ///
236 /// See also: [`from_vec`], [`from_limbs_iter`]
237 ///
238 /// # Example
239 /// ```rust
240 /// use vers_vecs::BitVec;
241 ///
242 /// let words = [0, 256, u64::MAX];
243 /// let bv = BitVec::from_limbs(&words);
244 ///
245 /// assert_eq!(bv.len(), 192);
246 /// assert_eq!(bv.get_bits(0, 64), Some(0u64));
247 /// assert_eq!(bv.get(72), Some(1));
248 /// assert_eq!(bv.get_bits(128, 64), Some(u64::MAX));
249 /// ```
250 ///
251 /// [`from_vec`]: BitVec::from_vec
252 /// [`from_limbs_iter`]: BitVec::from_limbs_iter
253 #[must_use]
254 pub fn from_limbs(words: &[u64]) -> Self {
255 let len = words.len() * WORD_SIZE;
256 Self {
257 data: words.to_vec(),
258 len,
259 }
260 }
261
262 /// Construct a bit vector from an iterator of u64 quad words.
263 /// The quad words are interpreted as limbs of the bit vector (i.e. each quad word contributes
264 /// 64 bits to the bit vector).
265 /// Since the data is only cloned without any masking or transformation,
266 /// this is one of the fastest ways to create a bit vector.
267 ///
268 /// See also: [`from_limbs`], [`from_vec`]
269 ///
270 /// # Example
271 /// ```rust
272 /// use std::iter::repeat;
273 /// use vers_vecs::BitVec;
274 ///
275 /// let zeros = repeat(0xaaaaaaaaaaaaaaaau64).take(10);
276 /// let bv = BitVec::from_limbs_iter(zeros);
277 ///
278 /// assert_eq!(bv.len(), 640);
279 /// for i in 0..640 {
280 /// assert_eq!(bv.get(i), Some((i % 2 == 1) as u64));
281 /// }
282 /// ```
283 ///
284 /// [`from_limbs`]: BitVec::from_limbs
285 /// [`from_vec`]: BitVec::from_vec
286 pub fn from_limbs_iter<I, E>(iter: I) -> Self
287 where
288 E: Into<u64>,
289 I: IntoIterator<Item = E>,
290 {
291 let vec = iter.into_iter().map(Into::into).collect();
292 Self::from_vec(vec)
293 }
294
295 /// Construct a bit vector from a vector of u64 quad words.
296 /// The quad words are interpreted as limbs of the bit vector
297 /// (i.e. each quad word contributes 64 bits to the bit vector).
298 /// Since the data is moved without any masking or transformation, this is one of the fastest ways
299 /// to create a bit vector.
300 ///
301 /// See also: [`from_limbs`], [`from_limbs_iter`]
302 ///
303 /// # Example
304 /// ```rust
305 /// use vers_vecs::BitVec;
306 ///
307 /// let words = vec![0, 256, u64::MAX];
308 /// let bv = BitVec::from_vec(words);
309 ///
310 /// assert_eq!(bv.len(), 192);
311 /// assert_eq!(bv.get_bits(0, 64), Some(0u64));
312 /// assert_eq!(bv.get(72), Some(1));
313 /// assert_eq!(bv.get_bits(128, 64), Some(u64::MAX));
314 /// ```
315 ///
316 /// [`from_limbs`]: BitVec::from_limbs
317 /// [`from_limbs_iter`]: BitVec::from_limbs_iter
318 #[must_use]
319 pub fn from_vec(data: Vec<u64>) -> Self {
320 let len = data.len() * WORD_SIZE;
321 Self { data, len }
322 }
323
324 fn pack_bits<T, const MAX_BITS: usize>(sequence: &[T], bits_per_element: usize) -> Self
325 where
326 T: Into<u64> + Copy,
327 {
328 let mut bv = Self::with_capacity(sequence.len() * bits_per_element);
329 for &word in sequence {
330 if bits_per_element <= MAX_BITS {
331 bv.append_bits(word.into(), bits_per_element);
332 } else {
333 bv.append_bits(word.into(), MAX_BITS);
334 let mut rest = bits_per_element - MAX_BITS;
335 while rest > 0 {
336 bv.append_bits(0, min(rest, MAX_BITS));
337 rest = rest.saturating_sub(MAX_BITS);
338 }
339 }
340 }
341 bv
342 }
343
344 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
345 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
346 /// The number of bits per element is given by `bits_per_element`.
347 /// The sequence is given as a slice of u64 values.
348 /// If the number of bits per element is smaller than 64, the function takes the
349 /// least significant bits of each element, and discards the rest.
350 /// If the number of bits per element is larger than 64, the function will pad the elements
351 /// with zeros.
352 /// The function will append the bits of each element to the bit vector in the order they are
353 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
354 ///
355 /// See also: [`pack_sequence_u32`], [`pack_sequence_u16`], [`pack_sequence_u8`]
356 ///
357 /// # Example
358 /// ```rust
359 /// use vers_vecs::BitVec;
360 ///
361 /// let sequence = [0b1010u64, 0b1100u64, 0b1111u64];
362 /// let bv = BitVec::pack_sequence_u64(&sequence, 4);
363 ///
364 /// assert_eq!(bv.len(), 12);
365 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
366 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
367 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
368 /// ```
369 ///
370 /// [`pack_sequence_u32`]: BitVec::pack_sequence_u32
371 /// [`pack_sequence_u16`]: BitVec::pack_sequence_u16
372 /// [`pack_sequence_u8`]: BitVec::pack_sequence_u8
373 #[must_use]
374 pub fn pack_sequence_u64(sequence: &[u64], bits_per_element: usize) -> Self {
375 Self::pack_bits::<_, 64>(sequence, bits_per_element)
376 }
377
378 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
379 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
380 /// The number of bits per element is given by `bits_per_element`.
381 /// The sequence is given as a slice of u32 values.
382 /// If the number of bits per element is smaller than 32, the function takes the
383 /// least significant bits of each element, and discards the rest.
384 /// If the number of bits per element is larger than 32, the function will pad the elements
385 /// with zeros.
386 /// The function will append the bits of each element to the bit vector in the order they are
387 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
388 ///
389 /// See also: [`pack_sequence_u64`], [`pack_sequence_u16`], [`pack_sequence_u8`]
390 ///
391 /// # Example
392 /// ```rust
393 /// use vers_vecs::BitVec;
394 ///
395 /// let sequence = [0b1010u32, 0b1100u32, 0b1111u32];
396 /// let bv = BitVec::pack_sequence_u32(&sequence, 4);
397 ///
398 /// assert_eq!(bv.len(), 12);
399 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
400 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
401 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
402 /// ```
403 ///
404 /// [`pack_sequence_u64`]: BitVec::pack_sequence_u64
405 /// [`pack_sequence_u16`]: BitVec::pack_sequence_u16
406 /// [`pack_sequence_u8`]: BitVec::pack_sequence_u8
407 #[must_use]
408 pub fn pack_sequence_u32(sequence: &[u32], bits_per_element: usize) -> Self {
409 Self::pack_bits::<_, 32>(sequence, bits_per_element)
410 }
411
412 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
413 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
414 /// The number of bits per element is given by `bits_per_element`.
415 /// The sequence is given as a slice of u16 values.
416 /// If the number of bits per element is smaller than 16, the function takes the
417 /// least significant bits of each element, and discards the rest.
418 /// If the number of bits per element is larger than 16, the function will pad the elements
419 /// with zeros.
420 /// The function will append the bits of each element to the bit vector in the order they are
421 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
422 ///
423 /// See also: [`pack_sequence_u64`], [`pack_sequence_u32`], [`pack_sequence_u8`]
424 ///
425 /// # Example
426 /// ```rust
427 /// use vers_vecs::BitVec;
428 ///
429 /// let sequence = [0b1010u16, 0b1100u16, 0b1111u16];
430 /// let bv = BitVec::pack_sequence_u16(&sequence, 4);
431 ///
432 /// assert_eq!(bv.len(), 12);
433 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
434 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
435 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
436 /// ```
437 ///
438 /// [`pack_sequence_u64`]: BitVec::pack_sequence_u64
439 /// [`pack_sequence_u32`]: BitVec::pack_sequence_u32
440 /// [`pack_sequence_u8`]: BitVec::pack_sequence_u8
441 #[must_use]
442 pub fn pack_sequence_u16(sequence: &[u16], bits_per_element: usize) -> Self {
443 Self::pack_bits::<_, 16>(sequence, bits_per_element)
444 }
445
446 /// Construct a bit vector by packing a sequence of numerical values into a dense sequence.
447 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
448 /// The number of bits per element is given by `bits_per_element`.
449 /// The sequence is given as a slice of u8 values.
450 /// If the number of bits per element is smaller than 8, the function takes the
451 /// least significant bits of each element, and discards the rest.
452 /// If the number of bits per element is larger than 8, the function will pad the elements
453 /// with zeros.
454 /// The function will append the bits of each element to the bit vector in the order they are
455 /// given in the sequence (i.e. the first element takes bits `0..bits_per_element` of the vector).
456 ///
457 /// See also: [`pack_sequence_u64`], [`pack_sequence_u32`], [`pack_sequence_u16`]
458 ///
459 /// # Example
460 /// ```rust
461 /// use vers_vecs::BitVec;
462 ///
463 /// let sequence = [0b1010u8, 0b1100u8, 0b1111u8];
464 /// let bv = BitVec::pack_sequence_u8(&sequence, 4);
465 ///
466 /// assert_eq!(bv.len(), 12);
467 /// assert_eq!(bv.get_bits(0, 4), Some(0b1010u64));
468 /// assert_eq!(bv.get_bits(4, 4), Some(0b1100u64));
469 /// assert_eq!(bv.get_bits(8, 4), Some(0b1111u64));
470 /// ```
471 ///
472 /// [`pack_sequence_u64`]: BitVec::pack_sequence_u64
473 /// [`pack_sequence_u32`]: BitVec::pack_sequence_u32
474 /// [`pack_sequence_u16`]: BitVec::pack_sequence_u16
475 #[must_use]
476 pub fn pack_sequence_u8(sequence: &[u8], bits_per_element: usize) -> Self {
477 Self::pack_bits::<_, 8>(sequence, bits_per_element)
478 }
479
480 /// Append a bit encoded as a `bool` to the bit vector, where `true` means 1 and `false` means 0.
481 ///
482 /// See also: [`append_bit`], [`append_bit_u32`], [`append_bit_u16`], [`append_bit_u8`], [`append_word`]
483 ///
484 /// # Example
485 ///
486 /// ```rust
487 /// use vers_vecs::BitVec;
488 ///
489 /// let mut bv = BitVec::new();
490 /// bv.append(true);
491 ///
492 /// assert_eq!(bv.len(), 1);
493 /// assert_eq!(bv.get(0), Some(1));
494 /// ```
495 ///
496 /// [`append_bit`]: BitVec::append_bit
497 /// [`append_bit_u32`]: BitVec::append_bit_u32
498 /// [`append_bit_u16`]: BitVec::append_bit_u16
499 /// [`append_bit_u8`]: BitVec::append_bit_u8
500 /// [`append_word`]: BitVec::append_word
501 pub fn append(&mut self, bit: bool) {
502 if self.len % WORD_SIZE == 0 {
503 self.data.push(0);
504 }
505 if bit {
506 self.data[self.len / WORD_SIZE] |= 1 << (self.len % WORD_SIZE);
507 } else {
508 self.data[self.len / WORD_SIZE] &= !(1 << (self.len % WORD_SIZE));
509 }
510 self.len += 1;
511 }
512
513 /// Drop the last n bits from the bit vector. If more bits are dropped than the bit vector
514 /// contains, the bit vector is cleared.
515 ///
516 /// # Example
517 ///
518 /// ```rust
519 /// use vers_vecs::BitVec;
520 ///
521 /// let mut bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
522 /// bv.drop_last(3);
523 ///
524 /// assert_eq!(bv.len(), 3);
525 /// assert_eq!(bv.get_bits(0, 3), Some(0b101u64));
526 ///
527 /// bv.drop_last(4);
528 ///
529 /// assert!(bv.is_empty());
530 /// ```
531 pub fn drop_last(&mut self, n: usize) {
532 if n > self.len {
533 self.data.clear();
534 self.len = 0;
535 return;
536 }
537
538 let new_limb_count = (self.len - n).div_ceil(WORD_SIZE);
539
540 // cut off limbs that we no longer need
541 if new_limb_count < self.data.len() {
542 self.data.truncate(new_limb_count);
543 }
544
545 // update bit vector length
546 self.len -= n;
547 }
548
549 /// Append a bit encoded in a u64.
550 /// The least significant bit is appended to the bit vector.
551 /// All other bits are ignored.
552 ///
553 /// See also: [`append`], [`append_bit_u32`], [`append_bit_u16`], [`append_bit_u8`], [`append_word`]
554 ///
555 /// # Example
556 ///
557 /// ```rust
558 /// use vers_vecs::BitVec;
559 ///
560 /// let mut bv = BitVec::new();
561 ///
562 /// bv.append_bit(1);
563 /// bv.append_bit(0);
564 ///
565 /// assert_eq!(bv.len(), 2);
566 /// assert_eq!(bv.get(0), Some(1));
567 /// assert_eq!(bv.get(1), Some(0));
568 /// ```
569 ///
570 /// [`append`]: BitVec::append
571 /// [`append_bit_u32`]: BitVec::append_bit_u32
572 /// [`append_bit_u16`]: BitVec::append_bit_u16
573 /// [`append_bit_u8`]: BitVec::append_bit_u8
574 /// [`append_word`]: BitVec::append_word
575 pub fn append_bit(&mut self, bit: u64) {
576 if self.len % WORD_SIZE == 0 {
577 self.data.push(0);
578 }
579 if bit % 2 == 1 {
580 self.data[self.len / WORD_SIZE] |= 1 << (self.len % WORD_SIZE);
581 } else {
582 self.data[self.len / WORD_SIZE] &= !(1 << (self.len % WORD_SIZE));
583 }
584
585 self.len += 1;
586 }
587
588 /// Append a bit from a u32. The least significant bit is appended to the bit vector.
589 /// All other bits are ignored.
590 ///
591 /// See also: [`append`], [`append_bit`], [`append_bit_u16`], [`append_bit_u8`], [`append_word`]
592 ///
593 /// [`append`]: BitVec::append
594 /// [`append_bit`]: BitVec::append_bit
595 /// [`append_bit_u16`]: BitVec::append_bit_u16
596 /// [`append_bit_u8`]: BitVec::append_bit_u8
597 /// [`append_word`]: BitVec::append_word
598 pub fn append_bit_u32(&mut self, bit: u32) {
599 self.append_bit(u64::from(bit));
600 }
601
602 /// Append a bit from a u16. The least significant bit is appended to the bit vector.
603 /// All other bits are ignored.
604 ///
605 /// See also: [`append`], [`append_bit`], [`append_bit_u32`], [`append_bit_u8`], [`append_word`]
606 ///
607 /// [`append`]: BitVec::append
608 /// [`append_bit`]: BitVec::append_bit
609 /// [`append_bit_u32`]: BitVec::append_bit_u32
610 /// [`append_bit_u8`]: BitVec::append_bit_u8
611 /// [`append_word`]: BitVec::append_word
612 pub fn append_bit_u16(&mut self, bit: u16) {
613 self.append_bit(u64::from(bit));
614 }
615
616 /// Append a bit from a u8. The least significant bit is appended to the bit vector.
617 /// All other bits are ignored.
618 ///
619 /// See also: [`append`], [`append_bit`], [`append_bit_u32`], [`append_bit_u16`], [`append_word`]
620 ///
621 /// [`append`]: BitVec::append
622 /// [`append_bit`]: BitVec::append_bit
623 /// [`append_bit_u32`]: BitVec::append_bit_u32
624 /// [`append_bit_u16`]: BitVec::append_bit_u16
625 /// [`append_word`]: BitVec::append_word
626 pub fn append_bit_u8(&mut self, bit: u8) {
627 self.append_bit(u64::from(bit));
628 }
629
630 /// Append a word to the bit vector. The bits are appended in little endian order (i.e. the first
631 /// bit of the word is appended first).
632 ///
633 /// See also: [`append`], [`append_bit`], [`append_bit_u32`], [`append_bit_u16`], [`append_bit_u8`]
634 ///
635 /// # Example
636 ///
637 /// ```rust
638 /// use vers_vecs::BitVec;
639 ///
640 /// let mut bv = BitVec::new();
641 /// bv.append_word(0b1010_1010_1010_1010u64);
642 ///
643 /// assert_eq!(bv.len(), 64);
644 /// for i in 0..64 {
645 /// assert_eq!(bv.get(i), Some((0b1010_1010_1010_1010u64 >> i) & 1));
646 /// }
647 /// ```
648 ///
649 /// [`append`]: BitVec::append
650 /// [`append_bit`]: BitVec::append_bit
651 /// [`append_bit_u32`]: BitVec::append_bit_u32
652 /// [`append_bit_u16`]: BitVec::append_bit_u16
653 /// [`append_bit_u8`]: BitVec::append_bit_u8
654 pub fn append_word(&mut self, word: u64) {
655 if self.len % WORD_SIZE == 0 {
656 self.data.push(word);
657 } else {
658 // zero out the unused bits before or-ing the new one, to ensure no garbage data remains
659 self.data[self.len / WORD_SIZE] &= !(u64::MAX << (self.len % WORD_SIZE));
660 self.data[self.len / WORD_SIZE] |= word << (self.len % WORD_SIZE);
661
662 self.data.push(word >> (WORD_SIZE - self.len % WORD_SIZE));
663 }
664 self.len += WORD_SIZE;
665 }
666
667 /// Append multiple bits to the bit vector.
668 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
669 /// The number of bits to append is given by `len`. The bits are taken from the least
670 /// significant bits of `bits`.
671 /// All other bits are ignored.
672 ///
673 /// # Example
674 ///
675 /// ```rust
676 /// use vers_vecs::BitVec;
677 ///
678 /// let mut bv = BitVec::new();
679 /// bv.append_bits(0b1010_1010_1010_1010u64, 16);
680 ///
681 /// assert_eq!(bv.len(), 16);
682 /// assert_eq!(bv.get_bits(0, 16), Some(0b1010_1010_1010_1010u64));
683 /// ```
684 ///
685 /// # Panics
686 /// Panics if `len` is larger than 64.
687 pub fn append_bits(&mut self, bits: u64, len: usize) {
688 assert!(len <= 64, "Cannot append more than 64 bits");
689
690 if self.len % WORD_SIZE == 0 {
691 self.data.push(bits);
692 } else {
693 // zero out the unused bits before or-ing the new one, to ensure no garbage data remains
694 self.data[self.len / WORD_SIZE] &= !(u64::MAX << (self.len % WORD_SIZE));
695 self.data[self.len / WORD_SIZE] |= bits << (self.len % WORD_SIZE);
696
697 if self.len % WORD_SIZE + len > WORD_SIZE {
698 self.data.push(bits >> (WORD_SIZE - self.len % WORD_SIZE));
699 }
700 }
701 self.len += len;
702 }
703
704 /// Append multiple bits to the bit vector.
705 /// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
706 /// The number of bits to append is given by `len`. The bits are taken from the least
707 /// significant bits of `bits`.
708 ///
709 /// This function does not check if `len` is larger than 64.
710 ///
711 /// Furthermore, if the bit-vector has trailing bits that are not zero
712 /// (i.e. the length is not a multiple of 64, and those bits are partially set),
713 /// the function will OR the new data with the trailing bits, destroying the appended data.
714 /// This can happen, if a call `append_bits[_unchecked](word, len)` appends a word which has
715 /// set bits beyond the `len - 1`-th bit,
716 /// or if bits have been dropped from the bit vector using [`drop_last`].
717 ///
718 /// See [`append_bits`] for a checked version of this function.
719 ///
720 /// # Panics
721 /// If `len` is larger than 64, the behavior is platform-dependent, and a processor
722 /// exception might be triggered.
723 ///
724 /// [`append_bits`]: BitVec::append_bits
725 /// [`drop_last`]: BitVec::drop_last
726 pub fn append_bits_unchecked(&mut self, bits: u64, len: usize) {
727 if self.len % WORD_SIZE == 0 {
728 self.data.push(bits);
729 } else {
730 self.data[self.len / WORD_SIZE] |= bits << (self.len % WORD_SIZE);
731
732 if self.len % WORD_SIZE + len > WORD_SIZE {
733 self.data.push(bits >> (WORD_SIZE - self.len % WORD_SIZE));
734 }
735 }
736 self.len += len;
737 }
738
739 /// Return the length of the bit vector. The length is measured in bits.
740 #[must_use]
741 pub fn len(&self) -> usize {
742 self.len
743 }
744
745 /// Return whether the bit vector is empty (contains no bits).
746 #[must_use]
747 pub fn is_empty(&self) -> bool {
748 self.len == 0
749 }
750
751 /// Flip the bit at the given position.
752 ///
753 /// # Example
754 ///
755 /// ```rust
756 /// use vers_vecs::BitVec;
757 ///
758 /// let mut bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
759 /// bv.flip_bit(1);
760 ///
761 /// assert_eq!(bv.len(), 6);
762 /// assert_eq!(bv.get_bits(0, 6), Some(0b111111u64));
763 /// ```
764 ///
765 /// # Panics
766 /// If the position is larger than the length of the vector, the function panics.
767 pub fn flip_bit(&mut self, pos: usize) {
768 assert!(pos < self.len, "Index out of bounds");
769 self.flip_bit_unchecked(pos);
770 }
771
772 /// Flip the bit at the given position.
773 ///
774 /// See also: [`flip_bit`]
775 ///
776 /// # Panics
777 /// If the position is larger than the length of the
778 /// vector, the function will either modify unused memory or panic.
779 /// This will not corrupt memory.
780 ///
781 /// [`flip_bit`]: BitVec::flip_bit
782 pub fn flip_bit_unchecked(&mut self, pos: usize) {
783 self.data[pos / WORD_SIZE] ^= 1 << (pos % WORD_SIZE);
784 }
785
786 /// Return the bit at the given position.
787 /// The bit is encoded in the least significant bit of a u64 value.
788 /// If the position is larger than the length of the vector, None is returned.
789 ///
790 /// See also: [`get_unchecked`]
791 ///
792 /// # Example
793 ///
794 /// ```rust
795 /// use vers_vecs::BitVec;
796 ///
797 /// let bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
798 ///
799 /// assert_eq!(bv.get(1), Some(0));
800 /// assert_eq!(bv.get(2), Some(1));
801 /// ```
802 #[must_use]
803 pub fn get(&self, pos: usize) -> Option<u64> {
804 if pos >= self.len {
805 None
806 } else {
807 Some(self.get_unchecked(pos))
808 }
809 }
810
811 /// Return the bit at the given position.
812 /// The bit is encoded in the least significant bit of a u64 value.
813 ///
814 /// # Panics
815 /// If the position is larger than the length of the vector,
816 /// the function will either return unpredictable data, or panic.
817 /// Use [`get`] to properly handle this case with an `Option`.
818 ///
819 /// [`get`]: BitVec::get
820 #[must_use]
821 pub fn get_unchecked(&self, pos: usize) -> u64 {
822 (self.data[pos / WORD_SIZE] >> (pos % WORD_SIZE)) & 1
823 }
824
825 /// Set the bit at the given position.
826 /// The bit is encoded in the least significant bit of a u64 value.
827 ///
828 /// See also: [`set_unchecked`]
829 ///
830 /// # Example
831 ///
832 /// ```rust
833 /// use vers_vecs::BitVec;
834 ///
835 /// let mut bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
836 /// bv.set(1, 1).unwrap();
837 ///
838 /// assert_eq!(bv.len(), 6);
839 /// assert_eq!(bv.get_bits(0, 6), Some(0b111111u64));
840 /// ```
841 ///
842 /// # Errors
843 /// If the position is out of range, the function will return `Err` with an error message,
844 /// otherwise it will return an empty `Ok`.
845 ///
846 /// [`set_unchecked`]: BitVec::set_unchecked
847 pub fn set(&mut self, pos: usize, value: u64) -> Result<(), &str> {
848 if pos >= self.len {
849 Err("out of range")
850 } else {
851 self.set_unchecked(pos, value);
852 Ok(())
853 }
854 }
855
856 /// Set the bit at the given position.
857 /// The bit is encoded in the least significant bit of a u64 value.
858 ///
859 /// # Panics
860 /// If the position is larger than the length of the vector,
861 /// the function will either do nothing, or panic.
862 /// Use [`set`] to properly handle this case with a `Result`.
863 ///
864 /// [`set`]: BitVec::set
865 pub fn set_unchecked(&mut self, pos: usize, value: u64) {
866 self.data[pos / WORD_SIZE] = (self.data[pos / WORD_SIZE] & !(0x1 << (pos % WORD_SIZE)))
867 | ((value & 0x1) << (pos % WORD_SIZE));
868 }
869
870 /// Return whether the bit at the given position is set.
871 /// If the position is larger than the length of the vector, None is returned.
872 ///
873 /// See also: [`is_bit_set_unchecked`]
874 ///
875 /// # Example
876 ///
877 /// ```rust
878 /// use vers_vecs::BitVec;
879 ///
880 /// let bv = BitVec::from_bits(&[1, 0, 1, 1, 1, 1]);
881 ///
882 /// assert!(!bv.is_bit_set(1).unwrap());
883 /// assert!(bv.is_bit_set(2).unwrap());
884 /// ```
885 ///
886 /// [`is_bit_set_unchecked`]: BitVec::is_bit_set_unchecked
887 #[must_use]
888 pub fn is_bit_set(&self, pos: usize) -> Option<bool> {
889 if pos >= self.len {
890 None
891 } else {
892 Some(self.is_bit_set_unchecked(pos))
893 }
894 }
895
896 /// Return whether the bit at the given position is set.
897 ///
898 /// # Panics
899 /// If the position is larger than the length of the vector,
900 /// the function will either return unpredictable data, or panic.
901 /// Use [`is_bit_set`] to properly handle this case with an `Option`.
902 ///
903 /// [`is_bit_set`]: BitVec::is_bit_set
904 #[must_use]
905 pub fn is_bit_set_unchecked(&self, pos: usize) -> bool {
906 self.get_unchecked(pos) != 0
907 }
908
909 /// Return multiple bits at the given position.
910 /// The number of bits to return is given by `len`.
911 /// At most 64 bits can be returned.
912 /// If the position at the end of the query is larger than the length of the vector,
913 /// None is returned (even if the query partially overlaps with the vector).
914 /// If the length of the query is larger than 64, None is returned.
915 #[must_use]
916 pub fn get_bits(&self, pos: usize, len: usize) -> Option<u64> {
917 if len > WORD_SIZE || len == 0 {
918 return None;
919 }
920 if pos + len > self.len {
921 None
922 } else {
923 Some(self.get_bits_unchecked(pos, len))
924 }
925 }
926
927 /// Return multiple bits at the given position. The number of bits to return is given by `len`.
928 /// At most 64 bits can be returned.
929 ///
930 /// This function is always inlined, because it gains a lot from loop optimization and
931 /// can utilize the processor pre-fetcher better if it is.
932 ///
933 /// # Errors
934 /// If the length of the query is larger than 64, unpredictable data will be returned.
935 /// Use [`get_bits`] to avoid this.
936 ///
937 /// # Panics
938 /// If the position or interval is larger than the length of the vector,
939 /// the function will either return any valid results padded with unpredictable
940 /// data or panic.
941 ///
942 /// [`get_bits`]: BitVec::get_bits
943 #[must_use]
944 #[allow(clippy::inline_always)]
945 #[allow(clippy::comparison_chain)] // readability
946 #[inline(always)] // inline to gain loop optimization and pipeline advantages for elias fano
947 #[allow(clippy::cast_possible_truncation)] // parameter must be out of scope for this to happen
948 pub fn get_bits_unchecked(&self, pos: usize, len: usize) -> u64 {
949 debug_assert!(len <= WORD_SIZE);
950 let partial_word = self.data[pos / WORD_SIZE] >> (pos % WORD_SIZE);
951 if pos % WORD_SIZE + len == WORD_SIZE {
952 partial_word
953 } else if pos % WORD_SIZE + len < WORD_SIZE {
954 partial_word & ((1 << (len % WORD_SIZE)) - 1)
955 } else {
956 (partial_word | (self.data[pos / WORD_SIZE + 1] << (WORD_SIZE - pos % WORD_SIZE)))
957 & 1u64.checked_shl(len as u32).unwrap_or(0).wrapping_sub(1)
958 }
959 }
960
961 /// Extract a packed element from a bit vector. The element is encoded in the bits at the given
962 /// `index`. The number of bits per encoded element is given by `n`.
963 ///
964 /// This is a convenience method to access elements previously packed using the [`pack_sequence_*`] methods,
965 /// and is equivalent to calling [`get_bits(index * n, n)`].
966 /// It is thus safe to use this method with any index and any size n <= 64.
967 ///
968 /// If the element is out of bounds, None is returned.
969 /// The element is returned as a u64 value.
970 ///
971 /// # Example
972 /// ```rust
973 /// use vers_vecs::BitVec;
974 ///
975 /// let sequence = [10, 100, 124, 45, 223];
976 /// let bv = BitVec::pack_sequence_u64(&sequence, 8);
977 ///
978 /// assert_eq!(bv.unpack_element(0, 8), Some(10));
979 /// assert_eq!(bv.unpack_element(2, 8), Some(124));
980 /// ```
981 ///
982 /// [`pack_sequence_*`]: BitVec::pack_sequence_u64
983 /// [`get_bits(index * n, n)`]: BitVec::get_bits
984 #[must_use]
985 #[allow(clippy::inline_always)]
986 #[inline(always)] // to gain optimization if n is constant
987 pub fn unpack_element(&self, index: usize, n: usize) -> Option<u64> {
988 self.get_bits(index * n, n)
989 }
990
991 /// Extract a packed element from a bit vector. The element is encoded in the bits at the given
992 /// `index`. The number of bits per encoded element is given by `n`.
993 ///
994 /// This is a convenience method to access elements previously packed using the [`pack_sequence_*`] methods,
995 /// and is equivalent to calling [`get_bits_unchecked(index * n, n)`].
996 /// It is thus safe to use this method with any index where `index * n + n` is in-bounds,
997 /// and any size n <= 64.
998 ///
999 /// # Panics
1000 /// If the element is out of bounds, the function will either return unpredictable data or panic.
1001 /// Use [`unpack_element`] for a checked version of this function.
1002 ///
1003 /// [`pack_sequence_*`]: BitVec::pack_sequence_u64
1004 /// [`get_bits_unchecked(index * n, n)`]: BitVec::get_bits_unchecked
1005 /// [`unpack_element`]: BitVec::unpack_element
1006 #[must_use]
1007 #[allow(clippy::inline_always)]
1008 #[inline(always)] // to gain optimization if n is constant
1009 pub fn unpack_element_unchecked(&self, index: usize, n: usize) -> u64 {
1010 self.get_bits_unchecked(index * n, n)
1011 }
1012
1013 /// Return the number of ones in the bit vector. Since the bit vector doesn't store additional
1014 /// metadata, this value is calculated. Use [`RsVec`] for constant-time rank operations.
1015 ///
1016 /// [`RsVec`]: crate::RsVec
1017 #[must_use]
1018 #[allow(clippy::missing_panics_doc)] // can't panic because of manual bounds check
1019 pub fn count_ones(&self) -> u64 {
1020 let mut ones: u64 = self.data[0..self.len / WORD_SIZE]
1021 .iter()
1022 .map(|limb| u64::from(limb.count_ones()))
1023 .sum();
1024 if self.len % WORD_SIZE > 0 {
1025 ones += u64::from(
1026 (self.data.last().unwrap() & ((1 << (self.len % WORD_SIZE)) - 1)).count_ones(),
1027 );
1028 }
1029 ones
1030 }
1031
1032 /// Return the number of zeros in the bit vector. Since the bit vector doesn't store additional
1033 /// metadata, this value is calculated. Use [`RsVec`] for constant-time rank operations.
1034 /// This method calls [`count_ones`].
1035 ///
1036 /// [`RsVec`]: crate::RsVec
1037 /// [`count_ones`]: BitVec::count_ones
1038 #[must_use]
1039 pub fn count_zeros(&self) -> u64 {
1040 self.len as u64 - self.count_ones()
1041 }
1042
1043 /// Mask this bit vector with another bitvector using bitwise or. The mask is applied lazily
1044 /// whenever an operation on the resulting vector is performed.
1045 ///
1046 /// # Errors
1047 /// Returns an error if the length of the vector doesn't match the mask length.
1048 #[inline]
1049 pub fn mask_or<'s, 'b>(&'s self, mask: &'b BitVec) -> Result<BitMask<'s, 'b>, String> {
1050 MaskedBitVec::new(self, mask, |a, b| a | b)
1051 }
1052
1053 /// Mask this bit vector with another bitvector using bitwise or.
1054 /// The mask is applied immediately, unlike in [`mask_or`].
1055 ///
1056 /// # Errors
1057 /// Returns an error if the length of the vector doesn't match the mask length.
1058 ///
1059 /// [`mask_or`]: BitVec::mask_or
1060 pub fn apply_mask_or(&mut self, mask: &BitVec) -> Result<(), String> {
1061 if self.len != mask.len {
1062 return Err(String::from(
1063 "mask cannot have different length than vector",
1064 ));
1065 }
1066
1067 for i in 0..self.data.len() {
1068 self.data[i] |= mask.data[i];
1069 }
1070
1071 Ok(())
1072 }
1073
1074 /// Mask this bit vector with another bitvector using bitwise and. The mask is applied lazily
1075 /// whenever an operation on the resulting vector is performed.
1076 ///
1077 /// # Errors
1078 /// Returns an error if the length of the vector doesn't match the mask length.
1079 #[inline]
1080 pub fn mask_and<'s, 'b>(&'s self, mask: &'b BitVec) -> Result<BitMask<'s, 'b>, String> {
1081 MaskedBitVec::new(self, mask, |a, b| a & b)
1082 }
1083
1084 /// Mask this bit vector with another bitvector using bitwise and.
1085 /// The mask is applied immediately, unlike in [`mask_and`].
1086 ///
1087 /// # Errors
1088 /// Returns an error if the length of the vector doesn't match the mask length.
1089 ///
1090 /// [`mask_and`]: BitVec::mask_and
1091 pub fn apply_mask_and(&mut self, mask: &BitVec) -> Result<(), String> {
1092 if self.len != mask.len {
1093 return Err(String::from(
1094 "mask cannot have different length than vector",
1095 ));
1096 }
1097
1098 for i in 0..self.data.len() {
1099 self.data[i] &= mask.data[i];
1100 }
1101
1102 Ok(())
1103 }
1104
1105 /// Mask this bit vector with another bitvector using bitwise xor. The mask is applied lazily
1106 /// whenever an operation on the resulting vector is performed.
1107 ///
1108 /// # Errors
1109 /// Returns an error if the length of the vector doesn't match the mask length.
1110 #[inline]
1111 pub fn mask_xor<'s, 'b>(&'s self, mask: &'b BitVec) -> Result<BitMask<'s, 'b>, String> {
1112 MaskedBitVec::new(self, mask, |a, b| a ^ b)
1113 }
1114
1115 /// Mask this bit vector with another bitvector using bitwise xor.
1116 /// The mask is applied immediately, unlike in [`mask_xor`].
1117 ///
1118 /// # Errors
1119 /// Returns an error if the length of the vector doesn't match the mask length.
1120 ///
1121 /// [`mask_xor`]: BitVec::mask_xor
1122 pub fn apply_mask_xor(&mut self, mask: &BitVec) -> Result<(), String> {
1123 if self.len != mask.len {
1124 return Err(String::from(
1125 "mask cannot have different length than vector",
1126 ));
1127 }
1128
1129 for i in 0..self.data.len() {
1130 self.data[i] ^= mask.data[i];
1131 }
1132
1133 Ok(())
1134 }
1135
1136 /// Mask this bit vector with another bitvector using a custom masking operation. The mask is
1137 /// applied lazily whenever an operation on the resulting vector is performed.
1138 ///
1139 /// The masking operation takes two 64 bit values which contain blocks of 64 bits each.
1140 /// The last block of a bit vector might contain fewer bits, and will be padded with
1141 /// unpredictable data. Implementations may choose to modify those padding bits without
1142 /// repercussions. Implementations shouldn't use operations like bit shift, because the bit order
1143 /// within the vector is unspecified.
1144 ///
1145 /// # Errors
1146 /// Returns an error if the length of the vector doesn't match the mask length.
1147 #[inline]
1148 pub fn mask_custom<'s, 'b, F>(
1149 &'s self,
1150 mask: &'b BitVec,
1151 mask_op: F,
1152 ) -> Result<MaskedBitVec<'s, 'b, F>, String>
1153 where
1154 F: Fn(u64, u64) -> u64,
1155 {
1156 MaskedBitVec::new(self, mask, mask_op)
1157 }
1158
1159 /// Mask this bit vector with another bitvector using a custom masking operation.
1160 /// The mask is applied immediately, unlike in [`mask_custom`].
1161 ///
1162 /// The masking operation takes two 64 bit values which contain blocks of 64 bits each.
1163 /// The last block of a bit vector might contain fewer bits, and will be padded with
1164 /// unpredictable data. Implementations may choose to modify those padding bits without
1165 /// repercussions. Implementations shouldn't use operations like bit shift, because the bit order
1166 /// within the vector is unspecified.
1167 ///
1168 /// # Errors
1169 /// Returns an error if the length of the vector doesn't match the mask length.
1170 ///
1171 /// [`mask_custom`]: BitVec::mask_custom
1172 #[inline]
1173 pub fn apply_mask_custom(
1174 &mut self,
1175 mask: &BitVec,
1176 mask_op: fn(u64, u64) -> u64,
1177 ) -> Result<(), String> {
1178 if self.len != mask.len {
1179 return Err(String::from(
1180 "mask cannot have different length than vector",
1181 ));
1182 }
1183
1184 for i in 0..self.data.len() {
1185 self.data[i] = mask_op(self.data[i], mask.data[i]);
1186 }
1187
1188 Ok(())
1189 }
1190
1191 /// Returns the number of bytes on the heap for this vector.
1192 /// Does not include allocated memory that isn't used.
1193 #[must_use]
1194 pub fn heap_size(&self) -> usize {
1195 self.data.len() * size_of::<u64>()
1196 }
1197}
1198
1199impl_vector_iterator! { BitVec, BitVecIter, BitVecRefIter }
1200
1201/// Create a new bit vector from a slice of u64 values.
1202/// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
1203/// The function will append the bits of each element to the bit vector in the order they are
1204/// given in the slice (i.e. the first element takes bits `0..64` of the vector).
1205impl From<&[u64]> for BitVec {
1206 fn from(data: &[u64]) -> Self {
1207 BitVec::from_limbs(data)
1208 }
1209}
1210
1211/// Create a new bit vector from a slice of u64 values.
1212/// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
1213/// The function will append the bits of each element to the bit vector in the order they are
1214/// given in the slice (i.e. the first element takes bits `0..64` of the vector).
1215impl From<Vec<u64>> for BitVec {
1216 fn from(data: Vec<u64>) -> Self {
1217 BitVec::from_limbs(&data)
1218 }
1219}
1220
1221/// Create a new bit vector from u64 values.
1222/// The bits are appended in little-endian order (i.e. the least significant bit is appended first).
1223/// The function will append the bits of each element to the bit vector in the order they are
1224/// given in the iterator (i.e. the first element takes bits `0..64` of the vector).
1225impl FromIterator<u64> for BitVec {
1226 fn from_iter<T: IntoIterator<Item = u64>>(iter: T) -> Self {
1227 BitVec::from_limbs_iter(iter)
1228 }
1229}
1230
1231#[cfg(test)]
1232mod tests;