• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vigna / sux-rs / 29426297655

15 Jul 2026 03:02PM UTC coverage: 74.502%. First build
29426297655

Pull #111

github

web-flow
Merge 94de354d0 into 4d383f6b9
Pull Request #111: Harden succinct structures and construction contracts

850 of 1056 new or added lines in 40 files covered. (80.49%)

9046 of 12142 relevant lines covered (74.5%)

18306116.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.12
/src/bits/bit_vec.rs
1
/*
2
 * SPDX-FileCopyrightText: 2023 Inria
3
 * SPDX-FileCopyrightText: 2023 Sebastiano Vigna
4
 *
5
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
6
 */
7

8
//! Bit vector implementations.
9
//!
10
//! There are two flavors: [`BitVec`], a mutable bit vector, and
11
//! [`AtomicBitVec`], a mutable, thread-safe bit vector.
12
//!
13
//! Operations on these structures are provided by the extension traits
14
//! [`BitVecOps`], [`BitVecOpsMut`], [`BitVecValueOps`], and
15
//! [`AtomicBitVecOps`], which must be pulled in scope as needed. There are also
16
//! operations that are specific to certain implementations, such as [`push`].
17
//!
18
//! These flavors depend on a backend with a word type `W`, and presently we
19
//! provide:
20
//!
21
//! - `BitVec<Vec<W>>`: a mutable, growable and resizable bit vector;
22
//! - `BitVec<AsRef<[W]>>`: an immutable bit vector, useful for
23
//!   [ε-serde] support;
24
//! - `BitVec<AsRef<[W]> + AsMut<[W]>>`: a mutable (but
25
//!   not resizable) bit vector;
26
//! - `AtomicBitVec<AsRef<[Atomic<W>]>>`: a thread-safe, mutable (but
27
//!   not resizable) bit vector.
28
//!
29
//! Note that nothing is assumed about the content of the backend outside the
30
//! bits of the bit vector. Query and count methods never depend on it, and
31
//! growth operations that write into the last touched word (for example
32
//! [`resize`] filling with `true`) may set backend bits beyond the logical
33
//! length within that word; only bits past the allocation are never touched.
34
//!
35
//! [`resize`]: BitVec::resize
36
//!
37
//! It is possible to juggle between all flavors using [`From`]/[`Into`], and
38
//! with [`TryFrom`]/[`TryInto`] when going [from a non-atomic to an atomic bit vector].
39
//!
40
//! # Type annotations
41
//!
42
//! Both [`BitVec`] and [`AtomicBitVec`] have default type parameters for
43
//! their backends. However, Rust does not apply struct default type
44
//! parameters in expression position, so constructor calls like
45
//! `BitVec::new(n)` or `AtomicBitVec::new(n)` leave the backend type
46
//! unconstrained.
47
//!
48
//! There are two possible fixes: either to annotate the binding with the alias,
49
//! which does apply defaults, or to write the type between angular brackets
50
//! in the constructor call, which also applies defaults:
51
//!
52
//! ```rust
53
//! # use sux::prelude::*;
54
//! let mut b: BitVec = BitVec::new(10);     // OK: B = Vec<usize>
55
//! let mut b = <BitVec>::new(10);           // Identical
56
//!
57
//! let a: AtomicBitVec = AtomicBitVec::new(10); // OK: B = Box<[Atomic<usize>]>
58
//! let a = <AtomicBitVec>::new(10);             // Identical
59
//! ```
60
//!
61
//! The [`bit_vec!`] macro and [`FromIterator`] / [`Extend`] do not need
62
//! annotations because the word type is determined by the output context.
63
//!
64
//! # Conversions
65
//!
66
//! A wide range of conversion is available between the different flavors of bit
67
//! vectors, using [`From`]/[`Into`] and [`TryFrom`]/[`TryInto`] as needed. For
68
//! example, you can convert from a non-atomic to an atomic bit vector if the
69
//! alignment requirements are satisfied, and you can convert from a growable
70
//! bit vector to a fixed-size one by converting the backend to a boxed slice.
71
//!
72
//! # Slice-by-value support
73
//!
74
//! [`BitVec`] implement the [`BitFieldSlice`]/[`BitFieldSliceMut`] traits as a
75
//! bit-field slice of width one. [`BitVecValueOps`] provides bit-range
76
//! accessors (`get_bits`/`get_bits_unchecked`) whose names are distinct from
77
//! the index-based [`get_value`]/[`get_value_unchecked`] of [`SliceByValue`],
78
//! so the two traits can be pulled in together without disambiguation. Moreover, as part of [`SliceByValueMut`]
79
//! you can also obtain [mutable chunks] from a bit vector, provided they are
80
//! aligned enough.
81
//!
82
//! # Examples
83
//!
84
//! ```rust
85
//! use sux::prelude::*;
86
//! use sux::traits::bit_vec_ops::*;
87

88
//! use std::sync::atomic::Ordering;
89
//!
90
//! // Convenience macro
91
//! let b = bit_vec![0, 1, 0, 1, 1, 0, 1, 0];
92
//! assert_eq!(b.len(), 8);
93
//! // Not constant time
94
//! assert_eq!(b.count_ones(), 4);
95
//! assert_eq!(b[0], false);
96
//! assert_eq!(b[1], true);
97
//! assert_eq!(b[2], false);
98
//!
99
//! let b: AddNumBits<_> = b.into();
100
//! // Constant time, but now b is immutable
101
//! assert_eq!(b.num_ones(), 4);
102
//!
103
//! let mut b: BitVec = BitVec::new(0);
104
//! b.push(true);
105
//! b.push(false);
106
//! b.push(true);
107
//! assert_eq!(b.len(), 3);
108
//!
109
//! // Let's make it atomic
110
//! let mut a: AtomicBitVec = b.into();
111
//! a.set(1, true, Ordering::Relaxed);
112
//! assert!(a.get(0, Ordering::Relaxed));
113
//!
114
//! // Back to normal, but immutable size
115
//! let b: BitVec<Vec<usize>> = a.into();
116
//! let mut b: BitVec<Box<[usize]>> = b.into();
117
//! b.set(2, false);
118
//!
119
//! // If we create an artificially dirty bit vector, everything still works.
120
//! let ones = [usize::MAX; 2];
121
//! assert_eq!(unsafe { BitVec::from_raw_parts(ones.as_slice(), 1) }.count_ones(), 1);
122
//! ```
123
//!
124
//! [from a non-atomic to an atomic bit vector]: BitVec#impl-TryFrom%3CBitVec%3C%26%5BW%5D%3E%3E-for-AtomicBitVec%3C%26%5B%3CW+as+AtomicPrimitive%3E%3A%3AAtomic%5D%3E
125
//! [ε-serde]: https://crates.io/crates/epserde
126
//! [`push`]: BitVec::push
127
//! [`bit_vec!`]: macro@crate::bits::bit_vec
128
//! [mutable chunks]: SliceByValueMut::try_chunks_mut
129
//! [`get_value`]: SliceByValue::get_value
130
//! [`get_value_unchecked`]: SliceByValue::get_value_unchecked
131

132
use crate::ambassador_impl_Index;
133
use crate::traits::ambassador_impl_Backend;
134
use crate::traits::ambassador_impl_BitLength;
135
use crate::traits::{
136
    AtomicBitIter, AtomicBitVecOps, Backend, BitFieldSlice, BitFieldSliceMut, BitIter, BitVecOps,
137
    BitVecOpsMut, BitVecValueOps, BitWidth, Word,
138
};
139
use crate::utils::SelectInWord;
140
use crate::{
141
    traits::{bit_vec_ops::BitLength, rank_sel::*},
142
    utils::{
143
        CannotCastToAtomicError, transmute_boxed_slice_from_atomic,
144
        transmute_boxed_slice_into_atomic, transmute_vec_from_atomic, transmute_vec_into_atomic,
145
    },
146
};
147
use ambassador::Delegate;
148
use atomic_primitive::{Atomic, AtomicPrimitive, PrimitiveAtomic, PrimitiveAtomicUnsigned};
149
#[allow(unused_imports)] // this is in the std prelude but not in no_std!
150
use core::borrow::BorrowMut;
151
use core::fmt;
152
use mem_dbg::*;
153
use num_primitive::PrimitiveInteger;
154
use std::iter::FusedIterator;
155
use std::{ops::Index, sync::atomic::Ordering};
156
use value_traits::slices::{SliceByValue, SliceByValueMut};
157

158
/// Number of unused high bits in the last word of a bit vector of length `len`
159
/// whose words hold `bits_per_word` bits each (`0` when `len` fills the last
160
/// word exactly).
161
///
162
/// Equivalent to `len.div_ceil(bits_per_word) * bits_per_word - len`, but
163
/// without that multiplication: `n_of_words * bits_per_word` overflows usize for
164
/// `len` near usize::MAX, reachable as a ~512 MiB bit vector on 32-bit targets.
165
fn padding_bits(len: usize, bits_per_word: usize) -> usize {
435,719✔
166
    (bits_per_word - len % bits_per_word) % bits_per_word
871,438✔
167
}
168

169
/// A bit vector.
170
///
171
/// Instances can be created using [`new`], [`with_value`], with the
172
/// convenience macro [`bit_vec!`], or with a [`FromIterator` implementation].
173
///
174
/// See the [module documentation] for more details.
175
///
176
/// [`FromIterator` implementation]: #impl-FromIterator<bool>-for-BitVec
177
/// [`new`]: BitVec::new
178
/// [`with_value`]: BitVec::with_value
179
/// [`bit_vec!`]: macro@crate::bits::bit_vec
180
/// [module documentation]: mod@crate::bits::bit_vec
181
#[derive(Debug, Clone, MemSize, MemDbg, Delegate)]
182
#[cfg_attr(feature = "epserde", derive(epserde::Epserde))]
183
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
184
#[delegate(crate::traits::Backend, target = "bits")]
185
pub struct BitVec<B = Vec<usize>> {
186
    bits: B,
187
    len: usize,
188
}
189
#[cfg(feature = "serde")]
190
#[derive(serde::Deserialize)]
191
#[serde(rename = "BitVec")]
192
struct BitVecSerde<B> {
193
    bits: B,
194
    len: usize,
195
}
196

197
#[cfg(feature = "serde")]
198
impl<'de, B> serde::Deserialize<'de> for BitVec<B>
199
where
200
    B: Backend<Word: Word> + AsRef<[B::Word]> + serde::Deserialize<'de>,
201
{
202
    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
203
        let repr = BitVecSerde::<B>::deserialize(deserializer)?;
204
        let word_bits = usize::try_from(B::Word::BITS).expect("word width always fits in usize");
205
        let capacity = repr
206
            .bits
207
            .as_ref()
208
            .len()
209
            .checked_mul(word_bits)
210
            .ok_or_else(|| serde::de::Error::custom("bit-vector capacity overflows usize"))?;
211
        if repr.len > capacity {
212
            return Err(serde::de::Error::custom(
213
                "bit-vector length exceeds its backing storage",
214
            ));
215
        }
216
        Ok(Self {
217
            bits: repr.bits,
218
            len: repr.len,
219
        })
220
    }
221
}
222

223
/// Converts a supported [`bit_vec!`] item to a bit.
224
///
225
/// This trait is public only so exported macro expansions can name it.
226
#[doc(hidden)]
227
pub trait BitVecValue {
228
    fn into_bit(self) -> bool;
229
}
230

231
impl BitVecValue for bool {
232
    #[inline(always)]
233
    fn into_bit(self) -> bool {
1✔
234
        self
1✔
235
    }
236
}
237

238
macro_rules! impl_bit_vec_value {
239
    ($($t:ty),+ $(,)?) => {
240
        $(
241
            impl BitVecValue for $t {
242
                #[inline(always)]
243
                fn into_bit(self) -> bool {
264✔
244
                    self != 0
264✔
245
                }
246
            }
247
        )+
248
    };
249
}
250

251
impl_bit_vec_value!(
252
    u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
253
);
254

255
/// Convenient, [`vec!`]-like macro to initialize bit vectors.
256
///
257
/// By default, the underlying storage is `Vec<usize>`. An explicit word type
258
/// `W` can be selected by prepending `W:` to any form, producing a
259
/// [`BitVec<Vec<W>>`]; this is useful, for example, to obtain a reproducible
260
/// layout across platforms with different pointer widths.
261
///
262
/// - `bit_vec![]` creates an empty bit vector.
263
///
264
/// - `bit_vec![false; n]` or `bit_vec![0; n]` creates a bit vector of length
265
///   `n` with all bits set to `false`.
266
///
267
/// - `bit_vec![true; n]` or `bit_vec![1; n]` creates a bit vector of length `n`
268
///   with all bits set to `true`.
269
///
270
/// - `bit_vec![b₀, b₁, b₂, …]` creates a bit vector with the specified bits,
271
///   where each `bᵢ` can be any expression that evaluates to a boolean or
272
///   integer (0 for `false`, non-zero for `true`).
273
///
274
/// - `bit_vec![W]`, `bit_vec![W: false; n]`, `bit_vec![W: 0; n]`,
275
///   `bit_vec![W: true; n]`, `bit_vec![W: 1; n]`, and
276
///   `bit_vec![W: b₀, b₁, b₂, …]` are the same as the forms above, but
277
///   backed by `Vec<W>` instead of `Vec<usize>`.
278
///
279
/// # Examples
280
///
281
/// ```rust
282
/// # #[cfg(target_pointer_width = "64")]
283
/// # {
284
/// # use sux::prelude::*;
285
/// # use sux::traits::BitVecOps;
286
/// // Empty bit vector
287
/// let b = bit_vec![];
288
/// assert_eq!(b.len(), 0);
289
///
290
/// // 10 bits set to true
291
/// let b = bit_vec![true; 10];
292
/// assert_eq!(b.len(), 10);
293
/// assert_eq!(b.iter().all(|x| x), true);
294
/// let b = bit_vec![1; 10];
295
/// assert_eq!(b.len(), 10);
296
/// assert_eq!(b.iter().all(|x| x), true);
297
///
298
/// // 10 bits set to false
299
/// let b = bit_vec![false; 10];
300
/// assert_eq!(b.len(), 10);
301
/// assert_eq!(b.iter().any(|x| x), false);
302
/// let b = bit_vec![0; 10];
303
/// assert_eq!(b.len(), 10);
304
/// assert_eq!(b.iter().any(|x| x), false);
305
///
306
/// // Bit list
307
/// let b = bit_vec![0, 1, 0, 1, 0, 0];
308
/// assert_eq!(b.len(), 6);
309
/// assert_eq!(b[0], false);
310
/// assert_eq!(b[1], true);
311
/// assert_eq!(b[2], false);
312
/// assert_eq!(b[3], true);
313
/// assert_eq!(b[4], false);
314
/// assert_eq!(b[5], false);
315
///
316
/// // With explicit word type (useful for cross-platform code)
317
/// let b = bit_vec![u32: 0, 1, 0, 1];
318
/// assert_eq!(b.len(), 4);
319
/// let b = bit_vec![u32: false; 10];
320
/// assert_eq!(b.len(), 10);
321
/// # }
322
/// ```
323
///
324
/// [`vec!`]: vec!
325
#[macro_export]
326
macro_rules! bit_vec {
327
    // Arms with explicit word type (colon separator)
328
    ($W:ty) => {
329
        $crate::bits::BitVec::<Vec<$W>>::new(0)
330
    };
331
    ($W:ty: false; $n:expr) => {
332
        $crate::bits::BitVec::<Vec<$W>>::new($n)
333
    };
334
    ($W:ty: 0; $n:expr) => {
335
        $crate::bits::BitVec::<Vec<$W>>::new($n)
336
    };
337
    ($W:ty: true; $n:expr) => {
338
        {
339
            $crate::bits::BitVec::<Vec<$W>>::with_value($n, true)
340
        }
341
    };
342
    ($W:ty: 1; $n:expr) => {
343
        {
344
            $crate::bits::BitVec::<Vec<$W>>::with_value($n, true)
345
        }
346
    };
347
    ($W:ty: $($x:expr),+ $(,)?) => {
348
        {
349
            let capacity = [$(stringify!($x)),+].len();
350
            let mut b = $crate::bits::BitVec::<Vec<$W>>::with_capacity(capacity);
351
            $(
352
                let value = $x;
353
                b.push($crate::bits::BitVecValue::into_bit(value));
354
            )*
355
            b
356
        }
357
    };
358
    // Default arms (usize backing)
359
    () => {
360
        $crate::bits::BitVec::<Vec<usize>>::new(0)
361
    };
362
    (false; $n:expr) => {
363
        $crate::bits::BitVec::<Vec<usize>>::new($n)
364
    };
365
    (0; $n:expr) => {
366
        $crate::bits::BitVec::<Vec<usize>>::new($n)
367
    };
368
    (true; $n:expr) => {
369
        {
370
            $crate::bits::BitVec::<Vec<usize>>::with_value($n, true)
371
        }
372
    };
373
    (1; $n:expr) => {
374
        {
375
            $crate::bits::BitVec::<Vec<usize>>::with_value($n, true)
376
        }
377
    };
378
    ($($x:expr),+ $(,)?) => {
379
        {
380
            let capacity = [$(stringify!($x)),+].len();
381
            let mut b = $crate::bits::BitVec::<Vec<usize>>::with_capacity(capacity);
382
            $(
383
                let value = $x;
384
                b.push($crate::bits::BitVecValue::into_bit(value));
385
            )*
386
            b
387
        }
388
    };
389
}
390

391
impl<B> BitVec<B> {
392
    /// Returns the number of bits in the bit vector.
393
    ///
394
    /// This method is equivalent to [`BitLength::len`], but it is provided to
395
    /// reduce ambiguity in method resolution.
396
    #[inline(always)]
397
    pub const fn len(&self) -> usize {
30,122✔
398
        self.len
30,122✔
399
    }
400

401
    /// # Safety
402
    /// `len` must be between 0 (included) and the number of
403
    /// bits in `bits` (included).
404
    #[inline(always)]
405
    #[must_use]
406
    pub const unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
167✔
407
        Self { bits, len }
408
    }
409

410
    /// Returns the backend and the length in bits, consuming this bit vector.
411
    #[inline(always)]
412
    pub fn into_raw_parts(self) -> (B, usize) {
2✔
413
        (self.bits, self.len)
2✔
414
    }
415

416
    /// Replaces the backend by applying a function, consuming this bit vector.
417
    ///
418
    /// # Safety
419
    /// The caller must ensure that the length is compatible with the new
420
    /// backend.
421
    #[inline(always)]
422
    pub unsafe fn map<B2>(self, f: impl FnOnce(B) -> B2) -> BitVec<B2> {
×
423
        BitVec {
424
            bits: f(self.bits),
×
425
            len: self.len,
×
426
        }
427
    }
428
}
429

430
impl<W: Word> BitVec<Vec<W>> {
431
    /// Creates a new bit vector of length `len` initialized to `false`.
432
    #[must_use]
433
    pub fn new(len: usize) -> Self {
290,540✔
434
        Self::with_value(len, false)
581,080✔
435
    }
436

437
    /// Creates a new bit vector of length `len` initialized to `value`.
438
    #[must_use]
439
    pub fn with_value(len: usize, value: bool) -> Self {
292,120✔
440
        let bits_per_word = W::BITS as usize;
584,240✔
441
        let n_of_words = len.div_ceil(bits_per_word);
1,168,480✔
442
        let extra_bits = padding_bits(len, bits_per_word);
1,168,480✔
443
        let word_value = if value { !W::ZERO } else { W::ZERO };
876,360✔
444
        let mut bits = vec![word_value; n_of_words];
1,168,480✔
445
        if extra_bits > 0 {
299,009✔
446
            let last_word_value = word_value >> extra_bits;
20,667✔
447
            bits[n_of_words - 1] = last_word_value;
6,889✔
448
        }
449
        Self { bits, len }
450
    }
451

452
    /// Creates a new zero-length bit vector of given capacity.
453
    ///
454
    /// Note that the capacity will be rounded up to a multiple of the word
455
    /// size.
456
    #[must_use]
457
    pub fn with_capacity(capacity: usize) -> Self {
53✔
458
        let bits_per_word = W::BITS as usize;
106✔
459
        let n_of_words = capacity.div_ceil(bits_per_word);
212✔
460
        Self {
461
            bits: Vec::with_capacity(n_of_words),
53✔
462
            len: 0,
463
        }
464
    }
465

466
    /// Returns the current capacity of this bit vector.
467
    pub fn capacity(&self) -> usize {
20✔
468
        // saturating: on 32-bit targets bits.capacity() * W::BITS can overflow;
469
        // capacity() must never wrap below len(), so cap the report at usize::MAX.
470
        self.bits.capacity().saturating_mul(W::BITS as usize)
80✔
471
    }
472

473
    /// Appends a bit to the end of this bit vector.
474
    pub fn push(&mut self, b: bool) {
678,076,027✔
475
        let bits_per_word = W::BITS as usize;
1,356,152,054✔
476
        let new_len = self.len.checked_add(1).expect("bit length overflows usize");
2,147,483,647✔
477
        // `len / bits_per_word == bits.len()` means every allocated bit is in
478
        // use; this avoids `bits.len() * bits_per_word`, which overflows usize
479
        // for a near-usize::MAX-length vector on 32-bit targets.
480
        if self.len / bits_per_word == self.bits.len() {
1,368,961,452✔
481
            self.bits.push(W::ZERO);
12,809,398✔
482
        }
483
        let word_index = self.len / bits_per_word;
1,356,152,054✔
484
        let bit_index = self.len % bits_per_word;
1,356,152,054✔
485
        // Clear bit
486
        self.bits[word_index] &= !(W::ONE << bit_index);
678,076,027✔
487
        // Set bit
488
        if b {
985,644,752✔
489
            self.bits[word_index] |= W::ONE << bit_index;
307,568,725✔
490
        }
491
        self.len = new_len;
678,076,027✔
492
    }
493

494
    /// Appends the lower `width` bits of `value` to the end of this bit
495
    /// vector.
496
    ///
497
    /// # Panics
498
    ///
499
    /// Panics if `width` > `W::BITS`, or if the resulting bit length
500
    /// overflows `usize`.
501
    pub fn append_value(&mut self, value: W, width: usize) {
31,410✔
502
        assert!(
31,410✔
503
            width <= W::BITS as usize,
31,410✔
504
            "width {} must be at most W::BITS ({})",
×
505
            width,
×
506
            W::BITS
×
507
        );
508
        if width == 0 {
31,410✔
509
            return;
669✔
510
        }
511
        let bits_per_word = W::BITS as usize;
61,482✔
512
        let l = bits_per_word - width;
61,482✔
513
        let value = (value << l) >> l;
61,482✔
514
        let new_len = self
61,482✔
515
            .len
30,741✔
516
            .checked_add(width)
61,482✔
517
            .expect("bit length overflows usize");
518
        let needed_words = new_len.div_ceil(bits_per_word);
122,964✔
519
        // Grow the backing storage if necessary.
520
        self.bits.resize(needed_words, W::ZERO);
92,223✔
521

522
        let word_idx = self.len / bits_per_word;
61,482✔
523
        let bit_idx = self.len % bits_per_word;
61,482✔
524

525
        // Clear bits
526
        self.bits[word_idx] &= !(W::MAX << bit_idx);
30,741✔
527
        self.bits[word_idx] |= value << bit_idx;
61,482✔
528
        if bit_idx + width > bits_per_word {
42,530✔
529
            self.bits[word_idx + 1] = value.wrapping_shr(bit_idx.wrapping_neg() as u32);
47,156✔
530
        }
531
        self.len = new_len;
30,741✔
532
    }
533

534
    /// Removes the last bit from the bit vector and returns it, or `None` if it
535
    /// is empty.
536
    pub fn pop(&mut self) -> Option<bool> {
2,958✔
537
        if self.len == 0 {
2,958✔
538
            return None;
6✔
539
        }
540
        let last_pos = self.len - 1;
5,904✔
541
        let result = self.get(last_pos);
11,808✔
542
        self.len = last_pos;
2,952✔
543
        Some(result)
2,952✔
544
    }
545

546
    /// Reserves capacity for at least `additional` more bits to be appended.
547
    ///
548
    /// After calling `reserve`, capacity will be greater than or equal to
549
    /// `self.len() + additional`. The allocator may reserve more space to
550
    /// speculatively avoid frequent reallocations. Does nothing if the
551
    /// capacity is already sufficient.
552
    ///
553
    /// # Panics
554
    ///
555
    /// Panics if the resulting bit length overflows `usize`.
556
    pub fn reserve(&mut self, additional: usize) {
108✔
557
        let needed_words = self
216✔
558
            .len
108✔
559
            .checked_add(additional)
216✔
560
            .expect("bit length overflows usize")
561
            .div_ceil(W::BITS as usize);
216✔
562
        self.bits
108✔
563
            .reserve(needed_words.saturating_sub(self.bits.len()));
540✔
564
    }
565

566
    /// Reserves the minimum capacity for at least `additional` more bits to
567
    /// be appended.
568
    ///
569
    /// After calling `reserve_exact`, capacity will be greater than or equal
570
    /// to `self.len() + additional`. Does nothing if the capacity is already
571
    /// sufficient.
572
    ///
573
    /// Note that the allocator may give the collection more space than it
574
    /// requests. Therefore, capacity cannot be relied upon to be precisely
575
    /// minimal.
576
    ///
577
    /// # Panics
578
    ///
579
    /// Panics if the resulting bit length overflows `usize`.
580
    pub fn reserve_exact(&mut self, additional: usize) {
3✔
581
        let needed_words = self
6✔
582
            .len
3✔
583
            .checked_add(additional)
6✔
584
            .expect("bit length overflows usize")
585
            .div_ceil(W::BITS as usize);
6✔
586
        self.bits
3✔
587
            .reserve_exact(needed_words.saturating_sub(self.bits.len()));
15✔
588
    }
589

590
    /// Appends the bits of `other` to the end of this bit vector.
591
    ///
592
    /// Unlike [`Vec::append`], `other` is not drained: its contents are
593
    /// copied into `self`.
594
    pub fn append<B2: AsRef<[W]>>(&mut self, other: &BitVec<B2>) {
730✔
595
        let other_len = other.len;
1,460✔
596
        if other_len == 0 {
730✔
597
            return;
66✔
598
        }
599

600
        // checked: on 32-bit targets two large bit vectors can sum past usize.
601
        // Done before mutating self so an overflow leaves self unchanged.
602
        let new_total = self
1,328✔
603
            .len
664✔
604
            .checked_add(other_len)
1,328✔
605
            .expect("appended bit-vector length overflows usize");
606

607
        let bpw = W::BITS as usize;
1,328✔
608
        let offset = self.len % bpw;
1,328✔
609
        let src: &[W] = other.bits.as_ref();
1,992✔
610
        let src_words = other_len.div_ceil(bpw);
2,656✔
611
        let self_words = self.len.div_ceil(bpw);
2,656✔
612
        self.bits.truncate(self_words);
1,992✔
613
        let new_word_count = new_total.div_ceil(bpw);
2,656✔
614

615
        if offset == 0 {
845✔
616
            self.bits.extend_from_slice(&src[..src_words]);
543✔
617
        } else {
618
            self.bits
483✔
619
                .reserve(new_word_count.saturating_sub(self.bits.len()));
2,415✔
620

621
            let last_idx = self.bits.len() - 1;
966✔
622
            // Clear bits
623
            self.bits[last_idx] &= !(W::MAX << offset);
483✔
624
            self.bits[last_idx] |= src[0] << offset;
966✔
625

626
            let shift_right = bpw - offset;
966✔
627
            for i in 1..src_words {
1,253✔
628
                self.bits
770✔
629
                    .push((src[i - 1] >> shift_right) | (src[i] << offset));
1,155✔
630
            }
631

632
            if new_word_count > self.bits.len() {
1,163✔
633
                self.bits.push(src[src_words - 1] >> shift_right);
591✔
634
            }
635
        }
636

637
        self.len = new_total;
664✔
638
    }
639

640
    /// Resizes the bit vector in place, extending it with `value` if it is
641
    /// necessary.
642
    pub fn resize(&mut self, new_len: usize, value: bool) {
16✔
643
        let bits_per_word = W::BITS as usize;
32✔
644
        if new_len > self.len {
16✔
645
            let old_len = self.len;
12✔
646
            let old_word = old_len / bits_per_word;
12✔
647
            let old_bit = old_len % bits_per_word;
12✔
648
            let word_value = if value { !W::ZERO } else { W::ZERO };
18✔
649

650
            self.bits
6✔
651
                .resize(new_len.div_ceil(bits_per_word), word_value);
30✔
652

653
            // Handle the partial word at old_len, then fill all
654
            // remaining words (which may contain stale data from
655
            // previous truncations).
656
            if old_bit != 0 {
6✔
657
                let mask = !W::ZERO << old_bit;
×
658
                self.bits[old_word] = (self.bits[old_word] & !mask) | (word_value & mask);
×
659
                self.bits[old_word + 1..].fill(word_value);
×
660
            } else {
661
                self.bits[old_word..].fill(word_value);
12✔
662
            }
663
        }
664
        self.len = new_len;
16✔
665
    }
666

667
    /// Ensures a padding word is present at the end and converts the
668
    /// backend to `Box<[W]>`.
669
    ///
670
    /// The extra word ensures that unaligned reads of `size_of::<W>()`
671
    /// bytes starting at any byte offset within the data never exceed the
672
    /// allocation. If the allocation already has more words than needed
673
    /// for the data, no word is added.
674
    pub fn into_padded(mut self) -> BitVec<Box<[W]>> {
105✔
675
        let needed = self.len.div_ceil(W::BITS as usize);
420✔
676
        if self.bits.len() <= needed {
315✔
677
            self.bits.push(W::ZERO);
105✔
678
        }
679
        unsafe { BitVec::from_raw_parts(self.bits.into_boxed_slice(), self.len) }
420✔
680
    }
681

682
    #[deprecated(note = "Use `BitVec<Box<[W]>>::new_padded` instead")]
683
    pub fn new_padded(len: usize) -> BitVec<Box<[W]>> {
×
684
        let n_of_words = len.div_ceil(W::BITS as usize);
×
685
        unsafe { BitVec::from_raw_parts(vec![W::ZERO; n_of_words + 1].into_boxed_slice(), len) }
×
686
    }
687
}
688

689
impl<W: Word> BitVec<Box<[W]>> {
690
    /// Creates a new bit vector of length `len` initialized to `false`,
691
    /// with a padding word at the end for safe unaligned reads.
692
    ///
693
    /// This constructor is useful for structures implementing
694
    /// [`TryIntoUnaligned`] that want to avoid reallocations.
695
    ///
696
    /// [`TryIntoUnaligned`]: crate::traits::TryIntoUnaligned
697
    pub fn new_padded(len: usize) -> BitVec<Box<[W]>> {
25✔
698
        let n_of_words = len.div_ceil(W::BITS as usize);
100✔
699
        unsafe { BitVec::from_raw_parts(vec![W::ZERO; n_of_words + 1].into_boxed_slice(), len) }
125✔
700
    }
701
}
702

703
impl<W: Word> Extend<bool> for BitVec<Vec<W>> {
704
    fn extend<T: IntoIterator<Item = bool>>(&mut self, i: T) {
35,938✔
705
        let i = i.into_iter();
107,814✔
706
        // Reserve for the lower bound (one bit per element) to avoid repeated
707
        // word reallocation. Best-effort: skip the hint if the total bit
708
        // length would overflow (push would then panic anyway).
709
        let (lo, _) = i.size_hint();
71,876✔
710
        if let Some(needed_words) = self
71,876✔
711
            .len
35,938✔
712
            .checked_add(lo)
71,876✔
713
            .map(|bits| bits.div_ceil(W::BITS as usize))
143,752✔
714
        {
715
            self.bits
71,876✔
716
                .reserve(needed_words.saturating_sub(self.bits.len()));
143,752✔
717
        }
718
        for b in i {
1,355,345,472✔
719
            self.push(b);
1,355,309,534✔
720
        }
721
    }
722
}
723

724
impl<W: Word> FromIterator<bool> for BitVec<Vec<W>> {
725
    fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
35,938✔
726
        let mut res = Self::new(0);
71,876✔
727
        res.extend(iter);
107,814✔
728
        res
35,938✔
729
    }
730
}
731

732
impl<B: ToOwned> BitVec<B> {
733
    /// Returns a copy of this bit vector with an owned backend.
734
    pub fn to_owned(&self) -> BitVec<<B as ToOwned>::Owned> {
×
735
        BitVec {
736
            bits: self.bits.to_owned(),
×
737
            len: self.len,
×
738
        }
739
    }
740
}
741

742
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> BitVecValueOps<B::Word> for BitVec<B> {
743
    fn get_bits(&self, pos: usize, width: usize) -> B::Word {
19,541✔
744
        assert!(
19,541✔
745
            width <= B::Word::BITS as usize,
19,541✔
746
            "width {} must be at most W::BITS ({})",
×
747
            width,
×
748
            B::Word::BITS
×
749
        );
750
        let end = pos
39,082✔
751
            .checked_add(width)
39,082✔
752
            .expect("bit range end (pos + width) overflows usize");
753
        assert!(
19,541✔
754
            end <= self.len,
19,541✔
755
            "bit range {}..{} out of bounds for length {}",
×
756
            pos,
×
757
            end,
×
758
            self.len
×
759
        );
760
        // SAFETY: the assertions above guarantee pos + width <= self.len and
761
        // width <= W::BITS, satisfying the contract of get_bits_unchecked.
762
        unsafe { self.get_bits_unchecked(pos, width) }
78,160✔
763
    }
764

765
    #[inline]
766
    unsafe fn get_bits_unchecked(&self, pos: usize, width: usize) -> B::Word {
46,992✔
767
        let bits = B::Word::BITS as usize;
93,984✔
768
        let word_index = pos / bits;
93,984✔
769
        let bit_index = pos % bits;
93,984✔
770
        let l = bits - width;
93,984✔
771
        let data = self.bits.as_ref();
140,976✔
772

773
        if width == 0 {
46,992✔
774
            return B::Word::ZERO;
813✔
775
        }
776

777
        unsafe {
778
            if bit_index <= l {
46,179✔
779
                (*data.get_unchecked(word_index) << (l - bit_index)) >> l
79,587✔
780
            } else {
781
                (*data.get_unchecked(word_index) >> bit_index)
58,950✔
782
                    | ((*data.get_unchecked(word_index + 1))
58,950✔
783
                        .wrapping_shl(l.wrapping_sub(bit_index) as u32)
58,950✔
784
                        >> l)
19,650✔
785
            }
786
        }
787
    }
788
}
789

790
impl<B> BitLength for BitVec<B> {
791
    #[inline(always)]
792
    fn len(&self) -> usize {
226,818,146✔
793
        self.len
226,818,146✔
794
    }
795
}
796

797
impl<B: Backend<Word: Word> + AsRef<[B::Word]>, C: Backend<Word = B::Word> + AsRef<[B::Word]>>
798
    PartialEq<BitVec<C>> for BitVec<B>
799
{
800
    fn eq(&self, other: &BitVec<C>) -> bool {
813✔
801
        let len = self.len();
2,439✔
802
        if len != other.len() {
1,626✔
803
            return false;
1✔
804
        }
805

806
        let word_bits = B::Word::BITS as usize;
1,624✔
807
        let full_words = len / word_bits;
1,624✔
808
        if self.as_ref()[..full_words] != other.as_ref()[..full_words] {
1,624✔
809
            return false;
×
810
        }
811

812
        let residual = len % word_bits;
1,624✔
813
        residual == 0
812✔
814
            || (self.as_ref()[full_words] ^ other.as_ref()[full_words]) << (word_bits - residual)
3,360✔
815
                == B::Word::ZERO
672✔
816
    }
817
}
818

819
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> Eq for BitVec<B> {}
820

821
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> std::hash::Hash for BitVec<B> {
822
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
×
823
        let len = self.len();
×
824
        len.hash(state);
×
825
        let word_bits = B::Word::BITS as usize;
×
826
        let full_words = len / word_bits;
×
827
        self.as_ref()[..full_words].hash(state);
×
828
        let residual = len % word_bits;
×
829
        if residual != 0 {
×
830
            // Mask off the padding bits before hashing the last partial word.
831
            (self.as_ref()[full_words] << (word_bits - residual)).hash(state);
×
832
        }
833
    }
834
}
835

836
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> Index<usize> for BitVec<B> {
837
    type Output = bool;
838

839
    fn index(&self, index: usize) -> &Self::Output {
332,502,752✔
840
        match BitVecOps::<B::Word>::get(self, index) {
665,005,504✔
841
            false => &false,
176,039,027✔
842
            true => &true,
156,463,725✔
843
        }
844
    }
845
}
846

847
impl<'a, B: Backend<Word: Word> + AsRef<[B::Word]>> IntoIterator for &'a BitVec<B> {
848
    type IntoIter = BitIter<'a, B::Word>;
849
    type Item = bool;
850

851
    fn into_iter(self) -> Self::IntoIter {
1,314✔
852
        BitIter::new(&self.bits, self.len())
5,256✔
853
    }
854
}
855

856
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> fmt::Display for BitVec<B> {
857
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5✔
858
        write!(f, "[")?;
10✔
859
        for b in self {
20✔
860
            write!(f, "{:b}", b as usize)?;
45✔
861
        }
862
        write!(f, "]")?;
10✔
863
        Ok(())
5✔
864
    }
865
}
866

867
/// An iterator over contiguous mutable chunks of a [`BitVec`], yielding
868
/// [`BitVec<&mut [W]>`] views.
869
///
870
/// This struct is created by [`BitVec`]'s [`try_chunks_mut`]
871
/// implementation. When the vector length is not evenly divided by the
872
/// chunk size, the last chunk will be shorter.
873
///
874
/// [`try_chunks_mut`]: SliceByValueMut::try_chunks_mut
875
pub struct BitVecChunksMut<'a, W: Word> {
876
    remaining: usize,
877
    chunk_size: usize,
878
    iter: std::slice::ChunksMut<'a, W>,
879
}
880

881
impl<'a, W: Word> Iterator for BitVecChunksMut<'a, W> {
882
    type Item = BitVec<&'a mut [W]>;
883

884
    #[inline]
885
    fn next(&mut self) -> Option<Self::Item> {
29✔
886
        self.iter.next().map(|chunk| {
115✔
887
            let size = Ord::min(self.chunk_size, self.remaining);
112✔
888
            // SAFETY: size is bounded by the original length; the
889
            // backing slice contains size.div_ceil(W::BITS) words,
890
            // which is exactly what std::slice::ChunksMut hands us.
891
            let next = unsafe { BitVec::from_raw_parts(chunk, size) };
112✔
892
            self.remaining -= size;
28✔
893
            next
28✔
894
        })
895
    }
896

897
    #[inline]
898
    fn size_hint(&self) -> (usize, Option<usize>) {
2✔
899
        // Exact: one chunk per inner slice chunk.
900
        self.iter.size_hint()
4✔
901
    }
902
}
903

904
impl<'a, W: Word> ExactSizeIterator for BitVecChunksMut<'a, W> where
905
    std::slice::ChunksMut<'a, W>: ExactSizeIterator
906
{
907
}
908

909
impl<'a, W: Word> FusedIterator for BitVecChunksMut<'a, W> where
910
    std::slice::ChunksMut<'a, W>: FusedIterator
911
{
912
}
913

914
/// Error returned when [`BitVec::try_chunks_mut`] receives a zero or
915
/// insufficiently aligned chunk size.
916
///
917
/// [`BitVec::try_chunks_mut`]: SliceByValueMut::try_chunks_mut
918
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
919
pub struct BitVecChunksMutError<W: Word> {
920
    chunk_size: usize,
921
    _marker: core::marker::PhantomData<W>,
922
}
923

924
impl<W: Word> fmt::Display for BitVecChunksMutError<W> {
925
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
NEW
926
        if self.chunk_size == 0 {
×
NEW
927
            return write!(f, "try_chunks_mut needs a nonzero chunk size");
×
928
        }
929
        write!(
×
930
            f,
×
931
            "try_chunks_mut needs the chunk size ({}) to be a multiple of W::BITS ({}) to return more than one chunk",
932
            self.chunk_size,
×
933
            W::BITS as usize
×
934
        )
935
    }
936
}
937

938
impl<W: Word> std::error::Error for BitVecChunksMutError<W> {}
939

940
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> SliceByValue for BitVec<B> {
941
    type Value = B::Word;
942

943
    #[inline(always)]
944
    fn len(&self) -> usize {
×
945
        self.len
×
946
    }
947

948
    #[inline(always)]
949
    unsafe fn get_value_unchecked(&self, index: usize) -> B::Word {
×
950
        // Delegate to the canonical BitVecOps::get_unchecked; LLVM
951
        // collapses the if to the same (word >> bit) & 1 it would
952
        // emit for a direct implementation.
953
        if unsafe { self.get_unchecked(index) } {
×
954
            B::Word::ONE
×
955
        } else {
956
            B::Word::ZERO
×
957
        }
958
    }
959
}
960

961
impl<B: Backend<Word: Word>> BitWidth for BitVec<B> {
962
    #[inline(always)]
963
    fn bit_width(&self) -> usize {
×
964
        1
×
965
    }
966
}
967

968
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> BitFieldSlice for BitVec<B> {
969
    #[inline(always)]
970
    fn as_slice(&self) -> &[Self::Value] {
×
971
        self.bits.as_ref()
×
972
    }
973
}
974

975
impl<B: Backend<Word: Word> + AsRef<[B::Word]> + AsMut<[B::Word]>> SliceByValueMut for BitVec<B> {
976
    #[inline(always)]
977
    unsafe fn set_value_unchecked(&mut self, index: usize, value: B::Word) {
×
978
        // Delegate to BitVecOpsMut::set_unchecked: its if value
979
        // form dead-code-eliminates to a single RMW when the caller
980
        // passes a compile-time constant, and ties my hand-rolled
981
        // branchless form on random-runtime values.
982
        unsafe { self.set_unchecked(index, value != B::Word::ZERO) }
×
983
    }
984

985
    type ChunksMut<'a>
986
        = BitVecChunksMut<'a, B::Word>
987
    where
988
        Self: 'a;
989

990
    type ChunksMutError = BitVecChunksMutError<B::Word>;
991

992
    /// # Errors
993
    ///
994
    /// Returns an error if `chunk_size` is zero, or if it is not a multiple of
995
    /// `W::BITS` and more than one chunk must be returned.
996
    fn try_chunks_mut(
27✔
997
        &mut self,
998
        chunk_size: usize,
999
    ) -> Result<Self::ChunksMut<'_>, BitVecChunksMutError<B::Word>> {
1000
        let len = self.len;
54✔
1001
        let bits = B::Word::BITS as usize;
54✔
1002
        if chunk_size != 0 && (len <= chunk_size || chunk_size % bits == 0) {
53✔
1003
            let words_per_chunk = chunk_size.div_ceil(bits);
100✔
1004
            Ok(BitVecChunksMut {
25✔
1005
                remaining: len,
50✔
1006
                chunk_size,
50✔
1007
                iter: self.bits.as_mut()[..len.div_ceil(bits)].chunks_mut(words_per_chunk),
100✔
1008
            })
1009
        } else {
1010
            Err(BitVecChunksMutError {
2✔
1011
                chunk_size,
2✔
1012
                _marker: core::marker::PhantomData,
2✔
1013
            })
1014
        }
1015
    }
1016
}
1017

1018
impl<B: Backend<Word: Word> + AsRef<[B::Word]> + AsMut<[B::Word]>> BitFieldSliceMut for BitVec<B> {
1019
    fn reset(&mut self) {
×
1020
        <Self as BitVecOpsMut<B::Word>>::fill(self, false);
×
1021
    }
1022

1023
    #[cfg(feature = "rayon")]
1024
    fn par_reset(&mut self) {
×
1025
        use rayon::prelude::*;
1026

1027
        use crate::ParallelWithLen;
1028
        let bits_per_word = B::Word::BITS as usize;
×
1029
        let full_words = self.len / bits_per_word;
×
1030
        let residual = self.len % bits_per_word;
×
1031
        let data = self.bits.as_mut();
×
1032
        data[..full_words]
×
1033
            .par_iter_mut()
1034
            .with_len(crate::RAYON_MIN_LEN)
×
1035
            .for_each(|x| *x = B::Word::ZERO);
×
1036
        if residual != 0 {
×
1037
            data[full_words] &= B::Word::MAX << residual;
×
1038
        }
1039
    }
1040

1041
    #[inline(always)]
1042
    fn as_mut_slice(&mut self) -> &mut [Self::Value] {
×
1043
        self.bits.as_mut()
×
1044
    }
1045
}
1046

1047
#[derive(Debug, Clone, MemSize, MemDbg, Delegate)]
1048
/// A thread-safe bit vector.
1049
///
1050
/// See the [module documentation] for details.
1051
///
1052
/// [module documentation]: mod@crate::bits::bit_vec
1053
#[delegate(crate::traits::Backend, target = "bits")]
1054
pub struct AtomicBitVec<B = Box<[Atomic<usize>]>> {
1055
    bits: B,
1056
    len: usize,
1057
}
1058

1059
impl<B> AtomicBitVec<B> {
1060
    /// Returns the number of bits in the bit vector.
1061
    ///
1062
    /// This method is equivalent to [`BitLength::len`], but it is provided to
1063
    /// reduce ambiguity in method resolution.
1064
    #[inline(always)]
1065
    pub const fn len(&self) -> usize {
77✔
1066
        self.len
77✔
1067
    }
1068

1069
    /// # Safety
1070
    /// `len` must be between 0 (included) and the number of
1071
    /// bits in `bits` (included).
1072
    #[inline(always)]
1073
    #[must_use]
1074
    pub const unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
2✔
1075
        Self { bits, len }
1076
    }
1077
    /// Returns the backend and the length in bits, consuming this bit vector.
1078
    #[inline(always)]
1079
    pub fn into_raw_parts(self) -> (B, usize) {
×
1080
        (self.bits, self.len)
×
1081
    }
1082
}
1083

1084
impl<B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + From<Vec<B::Word>>> AtomicBitVec<B> {
1085
    /// Creates a new atomic bit vector of length `len` initialized to `false`.
1086
    #[must_use]
1087
    pub fn new(len: usize) -> Self {
31✔
1088
        Self::with_value(len, false)
62✔
1089
    }
1090

1091
    /// Creates a new atomic bit vector of length `len` initialized to `value`.
1092
    #[must_use]
1093
    pub fn with_value(len: usize, value: bool) -> Self {
32✔
1094
        let bits_per_word = <B::Word as PrimitiveAtomic>::Value::BITS as usize;
64✔
1095
        let n_of_words = len.div_ceil(bits_per_word);
128✔
1096
        let extra_bits = padding_bits(len, bits_per_word);
128✔
1097
        let word_value = if value {
64✔
1098
            !<B::Word as PrimitiveAtomic>::Value::ZERO
1✔
1099
        } else {
1100
            <B::Word as PrimitiveAtomic>::Value::ZERO
31✔
1101
        };
1102
        let mut bits: Vec<B::Word> = (0..n_of_words).map(|_| B::Word::new(word_value)).collect();
408✔
1103
        if extra_bits > 0 {
57✔
1104
            let last_word_value = word_value >> extra_bits;
75✔
1105
            bits[n_of_words - 1] = B::Word::new(last_word_value);
50✔
1106
        }
1107
        Self {
1108
            bits: B::from(bits),
64✔
1109
            len,
1110
        }
1111
    }
1112
}
1113

1114
impl<B> BitLength for AtomicBitVec<B> {
1115
    #[inline(always)]
1116
    fn len(&self) -> usize {
2,237✔
1117
        self.len
2,237✔
1118
    }
1119
}
1120

1121
impl<B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + AsRef<[B::Word]>> AtomicBitVec<B> {
1122
    /// Returns the number of ones in the bit vector, reading every backing
1123
    /// word with a relaxed atomic load and masking bits past the logical length.
1124
    ///
1125
    /// Concurrent writes may be observed independently, so the result is not a
1126
    /// linearizable snapshot of the entire vector.
1127
    pub fn count_ones(&self) -> usize {
3✔
1128
        let bits_per_word = <B::Word as PrimitiveAtomic>::Value::BITS as usize;
6✔
1129
        let full_words = self.len() / bits_per_word;
9✔
1130
        let residual = self.len() % bits_per_word;
9✔
1131
        let bits: &[B::Word] = self.as_ref();
9✔
1132
        let mut num_ones;
×
1133
        num_ones = bits[..full_words]
3✔
1134
            .iter()
3✔
1135
            .map(|x| x.load(Ordering::Relaxed).count_ones() as usize)
63✔
1136
            .sum();
3✔
1137
        if residual != 0 {
3✔
1138
            num_ones += (bits[full_words].load(Ordering::Relaxed) << (bits_per_word - residual))
8✔
1139
                .count_ones() as usize
2✔
1140
        }
1141
        num_ones
3✔
1142
    }
1143
}
1144

1145
impl<B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + AsRef<[B::Word]>> Index<usize>
1146
    for AtomicBitVec<B>
1147
{
1148
    type Output = bool;
1149

1150
    /// Shorthand for `get` using [`Ordering::Relaxed`].
1151
    fn index(&self, index: usize) -> &Self::Output {
10,000✔
1152
        match AtomicBitVecOps::<B::Word>::get(self, index, Ordering::Relaxed) {
30,000✔
1153
            false => &false,
9,500✔
1154
            true => &true,
500✔
1155
        }
1156
    }
1157
}
1158

1159
impl<'a, B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + AsRef<[B::Word]>> IntoIterator
1160
    for &'a AtomicBitVec<B>
1161
{
1162
    type IntoIter = AtomicBitIter<'a, B::Word>;
1163
    type Item = bool;
1164

1165
    fn into_iter(self) -> Self::IntoIter {
×
1166
        AtomicBitIter::new(&self.bits, self.len())
×
1167
    }
1168
}
1169

1170
// Conversions
1171

1172
impl<'a, B: Backend + AsRef<[B::Word]>> From<&'a BitVec<B>> for BitVec<&'a [B::Word]> {
1173
    fn from(value: &'a BitVec<B>) -> Self {
1✔
1174
        BitVec {
1175
            bits: value.bits.as_ref(),
1✔
1176
            len: value.len,
1✔
1177
        }
1178
    }
1179
}
1180

1181
impl<'a, B: Backend + AsRef<[B::Word]>> From<&'a AtomicBitVec<B>> for AtomicBitVec<&'a [B::Word]> {
1182
    fn from(value: &'a AtomicBitVec<B>) -> Self {
1✔
1183
        AtomicBitVec {
1184
            bits: value.bits.as_ref(),
1✔
1185
            len: value.len,
1✔
1186
        }
1187
    }
1188
}
1189

1190
impl<'a, B: Backend + AsMut<[B::Word]>> From<&'a mut BitVec<B>> for BitVec<&'a mut [B::Word]> {
1191
    fn from(value: &'a mut BitVec<B>) -> Self {
2✔
1192
        BitVec {
1193
            bits: value.bits.as_mut(),
2✔
1194
            len: value.len,
2✔
1195
        }
1196
    }
1197
}
1198

1199
impl<'a, B: Backend + AsMut<[B::Word]>> From<&'a mut AtomicBitVec<B>>
1200
    for AtomicBitVec<&'a mut [B::Word]>
1201
{
1202
    fn from(value: &'a mut AtomicBitVec<B>) -> Self {
1✔
1203
        AtomicBitVec {
1204
            bits: value.bits.as_mut(),
1✔
1205
            len: value.len,
1✔
1206
        }
1207
    }
1208
}
1209

1210
/// This conversion may fail if the alignment of `W` is not the same as
1211
/// that of `W::Atomic`.
1212
impl<'a, W: AtomicPrimitive> TryFrom<BitVec<&'a mut [W]>> for AtomicBitVec<&'a mut [W::Atomic]> {
1213
    type Error = CannotCastToAtomicError<W>;
1214
    fn try_from(value: BitVec<&'a mut [W]>) -> Result<Self, Self::Error> {
1✔
1215
        if core::mem::align_of::<W>() != core::mem::align_of::<W::Atomic>() {
1✔
1216
            return Err(CannotCastToAtomicError::default());
×
1217
        }
1218
        Ok(AtomicBitVec {
1✔
1219
            bits: unsafe { core::mem::transmute::<&'a mut [W], &'a mut [W::Atomic]>(value.bits) },
1✔
1220
            len: value.len,
1✔
1221
        })
1222
    }
1223
}
1224

1225
impl<W: AtomicPrimitive> From<AtomicBitVec<Box<[W::Atomic]>>> for BitVec<Vec<W>> {
1226
    fn from(value: AtomicBitVec<Box<[W::Atomic]>>) -> Self {
1✔
1227
        BitVec {
1228
            bits: transmute_vec_from_atomic::<W::Atomic>(value.bits.into_vec()),
3✔
1229
            len: value.len,
1✔
1230
        }
1231
    }
1232
}
1233

1234
impl<W: AtomicPrimitive> From<BitVec<Vec<W>>> for AtomicBitVec<Box<[W::Atomic]>> {
1235
    fn from(value: BitVec<Vec<W>>) -> Self {
2✔
1236
        AtomicBitVec {
1237
            bits: transmute_vec_into_atomic(value.bits).into_boxed_slice(),
6✔
1238
            len: value.len,
2✔
1239
        }
1240
    }
1241
}
1242

1243
impl<W: AtomicPrimitive> From<AtomicBitVec<Box<[W::Atomic]>>> for BitVec<Box<[W]>> {
1244
    fn from(value: AtomicBitVec<Box<[W::Atomic]>>) -> Self {
10✔
1245
        BitVec {
1246
            bits: transmute_boxed_slice_from_atomic::<W::Atomic>(value.bits),
20✔
1247
            len: value.len,
10✔
1248
        }
1249
    }
1250
}
1251

1252
impl<W: AtomicPrimitive + Copy> From<BitVec<Box<[W]>>> for AtomicBitVec<Box<[W::Atomic]>> {
1253
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
1254
        AtomicBitVec {
1255
            bits: transmute_boxed_slice_into_atomic::<W>(value.bits),
2✔
1256
            len: value.len,
1✔
1257
        }
1258
    }
1259
}
1260

1261
impl<'a, W: AtomicPrimitive> From<AtomicBitVec<&'a mut [W::Atomic]>> for BitVec<&'a mut [W]> {
1262
    fn from(value: AtomicBitVec<&'a mut [W::Atomic]>) -> Self {
1✔
1263
        BitVec {
1264
            bits: unsafe { core::mem::transmute::<&'a mut [W::Atomic], &'a mut [W]>(value.bits) },
1✔
1265
            len: value.len,
1✔
1266
        }
1267
    }
1268
}
1269

1270
impl<W> From<BitVec<Vec<W>>> for BitVec<Box<[W]>> {
1271
    fn from(value: BitVec<Vec<W>>) -> Self {
333✔
1272
        BitVec {
1273
            bits: value.bits.into_boxed_slice(),
666✔
1274
            len: value.len,
333✔
1275
        }
1276
    }
1277
}
1278

1279
impl<W> From<BitVec<Box<[W]>>> for BitVec<Vec<W>> {
1280
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
1281
        BitVec {
1282
            bits: value.bits.into_vec(),
2✔
1283
            len: value.len,
1✔
1284
        }
1285
    }
1286
}
1287

1288
impl<W: Word, B: AsRef<[W]>> AsRef<[W]> for BitVec<B> {
1289
    #[inline(always)]
1290
    fn as_ref(&self) -> &[W] {
775,370,308✔
1291
        self.bits.as_ref()
775,370,308✔
1292
    }
1293
}
1294

1295
impl<W: Word, B: AsMut<[W]>> AsMut<[W]> for BitVec<B> {
1296
    #[inline(always)]
1297
    fn as_mut(&mut self) -> &mut [W] {
9,924,966✔
1298
        self.bits.as_mut()
9,924,966✔
1299
    }
1300
}
1301

1302
impl<B: Backend + AsRef<[B::Word]>> AsRef<[B::Word]> for AtomicBitVec<B> {
1303
    #[inline(always)]
1304
    fn as_ref(&self) -> &[B::Word] {
2,249✔
1305
        self.bits.as_ref()
2,249✔
1306
    }
1307
}
1308

1309
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> RankHinted for BitVec<B> {
1310
    #[inline(always)]
1311
    unsafe fn rank_hinted<const WORDS_PER_SUBBLOCK: usize>(
49,522,509✔
1312
        &self,
1313
        pos: usize,
1314
        hint_pos: usize,
1315
        hint_rank: usize,
1316
    ) -> usize {
1317
        let bits_per_word = usize::try_from(B::Word::BITS).expect("word width fits in usize");
198,090,036✔
1318
        let bits: &[B::Word] = self.as_ref();
148,567,527✔
1319
        let target_word = pos / bits_per_word;
99,045,018✔
1320
        let mut rank = hint_rank;
99,045,018✔
1321
        let mut current_word = hint_pos;
99,045,018✔
1322

1323
        debug_assert!(hint_pos <= target_word);
99,045,018✔
1324
        debug_assert!(target_word < bits.len());
148,567,527✔
1325
        debug_assert!(
49,522,509✔
1326
            WORDS_PER_SUBBLOCK == usize::MAX || WORDS_PER_SUBBLOCK > target_word - hint_pos
99,045,018✔
1327
        );
1328

1329
        // Prefetch only for finite subblocks spanning more than a cache line.
1330
        if WORDS_PER_SUBBLOCK != usize::MAX
49,522,509✔
1331
            && WORDS_PER_SUBBLOCK > 64 / core::mem::size_of::<B::Word>()
49,522,509✔
1332
        {
1333
            crate::utils::prefetch_index(bits, target_word);
19,809,000✔
1334
        }
1335

1336
        if WORDS_PER_SUBBLOCK == usize::MAX {
49,522,509✔
NEW
1337
            while current_word < target_word {
×
1338
                // SAFETY: the caller guarantees that every word from the hint
1339
                // through the target is backed by the underlying bit vector.
NEW
1340
                let word = unsafe { bits.get_unchecked(current_word) };
×
NEW
1341
                rank += usize::try_from(word.count_ones()).expect("a word popcount fits in usize");
×
NEW
1342
                current_word += 1;
×
1343
            }
1344
        } else {
1345
            for _ in 0..WORDS_PER_SUBBLOCK.saturating_sub(1) {
49,522,509✔
1346
                if current_word == target_word {
167,094,365✔
1347
                    break;
35,402,945✔
1348
                }
1349
                // SAFETY: the caller guarantees that the finite subblock
1350
                // covers the target and all preceding scanned words.
1351
                let word = unsafe { bits.get_unchecked(current_word) };
526,765,680✔
1352
                rank += usize::try_from(word.count_ones()).expect("a word popcount fits in usize");
526,765,680✔
1353
                current_word += 1;
131,691,420✔
1354
            }
1355
        }
1356
        debug_assert_eq!(current_word, target_word);
49,522,509✔
1357

1358
        // SAFETY: pos is in bounds and current_word is the word containing it.
1359
        let word = unsafe { *bits.get_unchecked(current_word) };
148,567,527✔
1360
        let bit_offset = u32::try_from(pos % bits_per_word).expect("bit offset fits in u32");
247,612,545✔
1361
        rank + usize::try_from(
148,567,527✔
1362
            (word & (B::Word::ONE << bit_offset).wrapping_sub(B::Word::ONE)).count_ones(),
198,090,036✔
1363
        )
1364
        .expect("a word popcount fits in usize")
49,522,509✔
1365
    }
1366
}
1367

1368
// SelectHinted and SelectZeroHinted for BitVec.
1369

1370
impl<B: Backend<Word: Word + SelectInWord> + AsRef<[B::Word]>> SelectHinted for BitVec<B> {
1371
    #[inline(always)]
1372
    unsafe fn select_hinted<const WORDS_PER_SUBBLOCK: usize>(
103,629,291✔
1373
        &self,
1374
        rank: usize,
1375
        hint_pos: usize,
1376
        hint_rank: usize,
1377
    ) -> usize {
1378
        let bits_per_word = usize::try_from(B::Word::BITS).expect("word width fits in usize");
414,517,164✔
1379
        let bits: &[B::Word] = self.as_ref();
310,887,873✔
1380
        let mut word_index = hint_pos / bits_per_word;
207,258,582✔
1381
        let bit_index = hint_pos % bits_per_word;
207,258,582✔
1382
        let mut residual = rank - hint_rank;
207,258,582✔
1383
        debug_assert!(WORDS_PER_SUBBLOCK == usize::MAX || WORDS_PER_SUBBLOCK > 0);
291,949,599✔
1384

1385
        // SAFETY: the caller guarantees that hint_pos is within the bit vector.
1386
        let mut word = (unsafe { *bits.get_unchecked(word_index) } >> bit_index) << bit_index;
310,887,873✔
1387
        let mut remaining = WORDS_PER_SUBBLOCK;
207,258,582✔
1388
        loop {
1389
            let bit_count =
550,147,985✔
1390
                usize::try_from(word.count_ones()).expect("a word popcount fits in usize");
2,147,483,647✔
1391
            if residual < bit_count {
550,147,985✔
1392
                return word_index * bits_per_word + word.select_in_word(residual);
310,887,873✔
1393
            }
1394
            residual -= bit_count;
446,518,694✔
1395

1396
            if remaining != usize::MAX {
446,518,694✔
1397
                remaining -= 1;
387,543,067✔
1398
                if remaining == 0 {
387,543,067✔
NEW
1399
                    break;
×
1400
                }
1401
            }
1402
            word_index += 1;
446,518,694✔
1403
            // SAFETY: the caller guarantees that the bounded scan reaches the
1404
            // target, so every word loaded before the target exists.
1405
            word = unsafe { *bits.get_unchecked(word_index) };
893,037,388✔
1406
        }
1407
        unreachable!("WORDS_PER_SUBBLOCK did not cover the selected one")
1408
    }
1409
}
1410

1411
impl<B: Backend<Word: Word + SelectInWord> + AsRef<[B::Word]>> SelectZeroHinted for BitVec<B> {
1412
    #[inline(always)]
1413
    unsafe fn select_zero_hinted<const WORDS_PER_SUBBLOCK: usize>(
59,887,933✔
1414
        &self,
1415
        rank: usize,
1416
        hint_pos: usize,
1417
        hint_rank: usize,
1418
    ) -> usize {
1419
        let bits_per_word = usize::try_from(B::Word::BITS).expect("word width fits in usize");
239,551,732✔
1420
        let bits: &[B::Word] = self.as_ref();
179,663,799✔
1421
        let mut word_index = hint_pos / bits_per_word;
119,775,866✔
1422
        let bit_index = hint_pos % bits_per_word;
119,775,866✔
1423
        let mut residual = rank - hint_rank;
119,775,866✔
1424
        debug_assert!(WORDS_PER_SUBBLOCK == usize::MAX || WORDS_PER_SUBBLOCK > 0);
160,530,797✔
1425

1426
        // SAFETY: the caller guarantees that hint_pos is within the bit vector.
1427
        let mut word = (!unsafe { *bits.get_unchecked(word_index) } >> bit_index) << bit_index;
179,663,799✔
1428
        let mut remaining = WORDS_PER_SUBBLOCK;
119,775,866✔
1429
        loop {
1430
            let bit_count =
503,789,684✔
1431
                usize::try_from(word.count_ones()).expect("a word popcount fits in usize");
2,147,483,647✔
1432
            if residual < bit_count {
503,789,684✔
1433
                return word_index * bits_per_word + word.select_in_word(residual);
179,663,799✔
1434
            }
1435
            residual -= bit_count;
443,901,751✔
1436

1437
            if remaining != usize::MAX {
443,901,751✔
1438
                remaining -= 1;
137,095,172✔
1439
                if remaining == 0 {
137,095,172✔
NEW
1440
                    break;
×
1441
                }
1442
            }
1443
            word_index += 1;
443,901,751✔
1444
            // SAFETY: the caller guarantees that the bounded scan reaches the
1445
            // target, so every word loaded before the target exists.
1446
            word = unsafe { !*bits.get_unchecked(word_index) };
887,803,502✔
1447
        }
1448
        unreachable!("WORDS_PER_SUBBLOCK did not cover the selected zero")
1449
    }
1450
}
1451

1452
/// A wrapper around [`BitVec`] that implements [`BitVecValueOps`] using
1453
/// unaligned reads.
1454
///
1455
/// Obtain an instance via [`TryIntoUnaligned`] on a `BitVec<Box<[W]>>`,
1456
/// which adds a padding word if one is not already present. You can recover
1457
/// the original [`BitVec`] using a [`From` implementation]
1458
///
1459
/// Reads use the one-word unaligned path when the requested range fits in one
1460
/// such read and fall back to the regular two-word path otherwise.
1461
///
1462
/// We delegate [`Backend`], [`BitLength`], and
1463
/// [`AsRef<[Backend::Word]>`](core::convert::AsRef) to make [`BitVecOps`]
1464
/// methods available, and [`Index`] to make slice-like read-only access
1465
/// available.
1466
///
1467
/// [`From` implementation]: #impl-From<BitVecU<Box<%5BW%5D>>-for-BitVec<Box<%5BW%5D>>
1468
/// [`TryIntoUnaligned`]: crate::traits::TryIntoUnaligned
1469
#[derive(Debug, Clone, MemSize, MemDbg, Delegate)]
1470
#[cfg_attr(feature = "epserde", derive(epserde::Epserde))]
1471
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1472
#[delegate(Index<usize>, target = "0")]
1473
#[delegate(crate::traits::Backend, target = "0")]
1474
#[delegate(crate::traits::bit_vec_ops::BitLength, target = "0")]
1475
pub struct BitVecU<B>(BitVec<B>);
1476
#[cfg(feature = "serde")]
1477
#[derive(serde::Deserialize)]
1478
#[serde(
1479
    rename = "BitVecU",
1480
    bound(deserialize = "BitVec<B>: serde::Deserialize<'de>")
1481
)]
1482
struct BitVecUSerde<B: Backend>(BitVec<B>);
1483

1484
#[cfg(feature = "serde")]
1485
impl<'de, B> serde::Deserialize<'de> for BitVecU<B>
1486
where
1487
    B: Backend<Word: Word> + AsRef<[B::Word]> + serde::Deserialize<'de>,
1488
{
1489
    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1490
        let BitVecUSerde(bits) = BitVecUSerde::<B>::deserialize(deserializer)?;
1491
        let word_bits = usize::try_from(B::Word::BITS).expect("word width always fits in usize");
1492
        let logical_words = bits.len.div_ceil(word_bits);
1493
        if bits.bits.as_ref().len() <= logical_words {
1494
            return Err(serde::de::Error::custom(
1495
                "unaligned bit vector requires one padding word",
1496
            ));
1497
        }
1498
        Ok(Self(bits))
1499
    }
1500
}
1501

1502
impl<W: Word> From<BitVecU<Box<[W]>>> for BitVec<Box<[W]>> {
1503
    /// Converts a [`BitVecU`] back into a [`BitVec`].
1504
    ///
1505
    /// The padding word is kept in the backing storage so that a subsequent
1506
    /// [`try_into_unaligned`] does not need to reallocate.
1507
    ///
1508
    /// [`try_into_unaligned`]: crate::traits::TryIntoUnaligned::try_into_unaligned
1509
    fn from(unaligned: BitVecU<Box<[W]>>) -> Self {
1✔
1510
        unaligned.0
1✔
1511
    }
1512
}
1513

1514
impl<W: Word> crate::traits::TryIntoUnaligned for BitVec<Box<[W]>> {
1515
    type Unaligned = BitVecU<Box<[W]>>;
1516

1517
    fn try_into_unaligned(
6✔
1518
        self,
1519
    ) -> Result<Self::Unaligned, crate::traits::UnalignedConversionError> {
1520
        let needed = self.len().div_ceil(W::BITS as usize);
30✔
1521
        if self.as_ref().len() > needed {
12✔
1522
            Ok(BitVecU(self))
5✔
1523
        } else {
1524
            let (raw, len) = self.into_raw_parts();
3✔
1525
            let mut v = raw.into_vec();
3✔
1526
            v.reserve_exact(1);
2✔
1527
            v.push(W::ZERO);
2✔
1528
            Ok(BitVecU(unsafe {
1✔
1529
                BitVec::from_raw_parts(v.into_boxed_slice(), len)
3✔
1530
            }))
1531
        }
1532
    }
1533
}
1534

1535
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> BitVecValueOps<B::Word> for BitVecU<B> {
1536
    #[inline(always)]
1537
    fn get_bits(&self, pos: usize, width: usize) -> B::Word {
×
NEW
1538
        if crate::bits::test_unaligned_pos!(B::Word, pos, width) {
×
NEW
1539
            self.0.get_value_unaligned(pos, width)
×
1540
        } else {
NEW
1541
            self.0.get_bits(pos, width)
×
1542
        }
1543
    }
1544

1545
    #[inline(always)]
1546
    unsafe fn get_bits_unchecked(&self, pos: usize, width: usize) -> B::Word {
1,204✔
1547
        if crate::bits::test_unaligned_pos!(B::Word, pos, width) {
3,612✔
1548
            // SAFETY: the caller guarantees the range is within the logical
1549
            // vector; the branch additionally proves it fits one unaligned read.
1550
            unsafe { self.0.get_value_unaligned_unchecked(pos, width) }
4,240✔
1551
        } else {
1552
            // SAFETY: the caller guarantees `pos + width <= self.len()` and
1553
            // `width <= Word::BITS`, exactly the delegated method's contract.
1554
            unsafe { self.0.get_bits_unchecked(pos, width) }
576✔
1555
        }
1556
    }
1557
}
1558

1559
impl<B: Backend + AsRef<[B::Word]>> AsRef<[B::Word]> for BitVecU<B> {
1560
    #[inline(always)]
1561
    fn as_ref(&self) -> &[B::Word] {
9,000✔
1562
        self.0.bits.as_ref()
9,000✔
1563
    }
1564
}
1565

1566
#[cfg(test)]
1567
mod padding_tests {
1568
    use super::padding_bits;
1569

1570
    #[test]
1571
    fn padding_bits_is_overflow_safe() {
1572
        // Ordinary cases: pad up to the next word boundary.
1573
        assert_eq!(padding_bits(0, 64), 0);
1574
        assert_eq!(padding_bits(64, 64), 0);
1575
        assert_eq!(padding_bits(1, 64), 63);
1576
        assert_eq!(padding_bits(65, 64), 63);
1577
        assert_eq!(padding_bits(63, 64), 1);
1578
        // usize::MAX is not a multiple of 64 (2^64 is), so one padding bit is
1579
        // needed; the old `n_of_words * bits_per_word - len` form overflows here.
1580
        assert_eq!(padding_bits(usize::MAX, 64), 1);
1581
        assert_eq!(padding_bits(usize::MAX, 32), 1);
1582
    }
1583
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc