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

vigna / sux-rs / 23354375031

20 Mar 2026 05:19PM UTC coverage: 76.49% (-1.4%) from 77.85%
23354375031

push

github

vigna
Downgraded Criterion to 0.7.0

5453 of 7129 relevant lines covered (76.49%)

109991459.88 hits per line

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

91.34
/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`](crate::traits::BitVecOpsMut), and
15
//! [`AtomicBitVecOps`], which must be pulled in scope as needed. There are also
16
//! operations that are specific to certain implementations, such as
17
//! [`push`](BitVec::push).
18
//!
19
//! These flavors depend on a backend with a word type `W`, and presently we
20
//! provide:
21
//!
22
//! - `BitVec<Vec<W>>`: a mutable, growable and resizable bit vector;
23
//! - `BitVec<AsRef<[W]>>`: an immutable bit vector, useful for
24
//!   [ε-serde](https://crates.io/crates/epserde) support;
25
//! - `BitVec<AsRef<[W]> + AsMut<[W]>>`: a mutable (but
26
//!   not resizable) bit vector;
27
//! - `AtomicBitVec<AsRef<[Atomic<W>]>>`: a thread-safe, mutable (but
28
//!   not resizable) bit vector.
29
//!
30
//! Note that nothing is assumed about the content of the backend outside the
31
//! bits of the bit vector. Moreover, the content of the backend outside of
32
//! the bit vector is never modified by the methods of this structure.
33
//!
34
//! It is possible to juggle between all flavors using [`From`]/[`Into`], and
35
//! with [`TryFrom`]/[`TryInto`] when going [from a non-atomic to an atomic bit
36
//! vector](BitVec#impl-TryFrom%3CBitVec%3C%26%5BW%5D%3E%3E-for-AtomicBitVec%3C%26%5B%3CW+as+AtomicPrimitive%3E::Atomic%5D%3E).
37
//!
38
//! # Type annotations
39
//!
40
//! Both [`BitVec`] and [`AtomicBitVec`] have default type parameters for
41
//! their backends. However, Rust does not apply struct default type
42
//! parameters in expression position, so constructor calls like
43
//! `BitVec::new(n)` or `AtomicBitVec::new(n)` leave the backend type
44
//! unconstrained.
45
//!
46
//! The fix is to annotate the binding with the bare type alias, which
47
//! *does* apply defaults:
48
//!
49
//! ```rust
50
//! # use sux::prelude::*;
51
//! let mut b: BitVec = BitVec::new(10);     // OK: B = Vec<usize>
52
//! let a: AtomicBitVec = AtomicBitVec::new(10); // OK: B = Box<[Atomic<usize>]>
53
//! ```
54
//!
55
//! The [`bit_vec!`](macro@crate::bits::bit_vec) macro and
56
//! [`FromIterator`] / [`Extend`] do not need
57
//! annotations because the word type is determined by the output context.
58
//!
59
//! # Examples
60
//!
61
//! ```rust
62
//! use sux::prelude::*;
63
//! use sux::traits::bit_vec_ops::*;
64

65
//! use std::sync::atomic::Ordering;
66
//!
67
//! // Convenience macro
68
//! let b = bit_vec![0, 1, 0, 1, 1, 0, 1, 0];
69
//! assert_eq!(b.len(), 8);
70
//! // Not constant time
71
//! assert_eq!(b.count_ones(), 4);
72
//! assert_eq!(b[0], false);
73
//! assert_eq!(b[1], true);
74
//! assert_eq!(b[2], false);
75
//!
76
//! let b: AddNumBits<_> = b.into();
77
//! // Constant time, but now b is immutable
78
//! assert_eq!(b.num_ones(), 4);
79
//!
80
//! let mut b: BitVec = BitVec::new(0);
81
//! b.push(true);
82
//! b.push(false);
83
//! b.push(true);
84
//! assert_eq!(b.len(), 3);
85
//!
86
//! // Let's make it atomic
87
//! let mut a: AtomicBitVec = b.into();
88
//! a.set(1, true, Ordering::Relaxed);
89
//! assert!(a.get(0, Ordering::Relaxed));
90
//!
91
//! // Back to normal, but immutable size
92
//! let b: BitVec<Vec<usize>> = a.into();
93
//! let mut b: BitVec<Box<[usize]>> = b.into();
94
//! b.set(2, false);
95
//!
96
//! // If we create an artificially dirty bit vector, everything still works.
97
//! let ones = [usize::MAX; 2];
98
//! assert_eq!(unsafe { BitVec::from_raw_parts(ones.as_slice(), 1) }.count_ones(), 1);
99
//! ```
100

101
use crate::traits::ambassador_impl_Backend;
102
use crate::traits::{AtomicBitIter, AtomicBitVecOps, Backend, BitIter, BitVecOps, Word};
103
use crate::utils::SelectInWord;
104
use crate::{
105
    traits::rank_sel::*,
106
    utils::{
107
        CannotCastToAtomicError, transmute_boxed_slice_from_atomic,
108
        transmute_boxed_slice_into_atomic, transmute_vec_from_atomic, transmute_vec_into_atomic,
109
    },
110
};
111
use ambassador::Delegate;
112
use atomic_primitive::{Atomic, AtomicPrimitive, PrimitiveAtomic, PrimitiveAtomicUnsigned};
113
#[allow(unused_imports)] // this is in the std prelude but not in no_std!
114
use core::borrow::BorrowMut;
115
use core::fmt;
116
use mem_dbg::*;
117
use num_primitive::PrimitiveInteger;
118
use std::{ops::Index, sync::atomic::Ordering};
119

120
/// A bit vector.
121
///
122
/// Instances can be created using [`new`](BitVec::new),
123
/// [`with_value`](BitVec::with_value), with the convenience macro
124
/// [`bit_vec!`](macro@crate::bits::bit_vec), or with a [`FromIterator`
125
/// implementation](#impl-FromIterator<bool>-for-BitVec).
126
///
127
/// See the [module documentation](mod@crate::bits::bit_vec) for more details.
128
#[derive(Debug, Clone, Copy, MemDbg, MemSize, Delegate)]
129
#[cfg_attr(feature = "epserde", derive(epserde::Epserde))]
130
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
131
#[delegate(crate::traits::Backend, target = "bits")]
132
pub struct BitVec<B = Vec<usize>> {
133
    bits: B,
134
    len: usize,
135
}
136

137
/// Convenient, [`vec!`](vec!)-like macro to initialize bit vectors.
138
///
139
/// - `bit_vec![]` creates an empty bit vector.
140
///
141
/// - `bit_vec![false; n]` or `bit_vec![0; n]` creates a bit vector of length
142
///   `n` with all bits set to `false`.
143
///
144
/// - `bit_vec![true; n]` or `bit_vec![1; n]` creates a bit vector of length `n`
145
///   with all bits set to `true`.
146
///
147
/// - `bit_vec![b₀, b₁, b₂, …]` creates a bit vector with the specified bits,
148
///   where each `bᵢ` can be any expression that evaluates to a boolean or integer
149
///   (0 for `false`, non-zero for `true`).
150
///
151
/// # Examples
152
///
153
/// ```rust
154
/// # #[cfg(target_pointer_width = "64")]
155
/// # {
156
/// # use sux::prelude::*;
157
/// # use sux::traits::BitVecOps;
158
/// // Empty bit vector
159
/// let b = bit_vec![];
160
/// assert_eq!(b.len(), 0);
161
///
162
/// // 10 bits set to true
163
/// let b = bit_vec![true; 10];
164
/// assert_eq!(b.len(), 10);
165
/// assert_eq!(b.iter().all(|x| x), true);
166
/// let b = bit_vec![1; 10];
167
/// assert_eq!(b.len(), 10);
168
/// assert_eq!(b.iter().all(|x| x), true);
169
///
170
/// // 10 bits set to false
171
/// let b = bit_vec![false; 10];
172
/// assert_eq!(b.len(), 10);
173
/// assert_eq!(b.iter().any(|x| x), false);
174
/// let b = bit_vec![0; 10];
175
/// assert_eq!(b.len(), 10);
176
/// assert_eq!(b.iter().any(|x| x), false);
177
///
178
/// // Bit list
179
/// let b = bit_vec![0, 1, 0, 1, 0, 0];
180
/// assert_eq!(b.len(), 6);
181
/// assert_eq!(b[0], false);
182
/// assert_eq!(b[1], true);
183
/// assert_eq!(b[2], false);
184
/// assert_eq!(b[3], true);
185
/// assert_eq!(b[4], false);
186
/// assert_eq!(b[5], false);
187
///
188
/// // With explicit word type (useful for cross-platform code)
189
/// let b = bit_vec![0, 1, 0, 1];
190
/// assert_eq!(b.len(), 4);
191
/// let b = bit_vec![false; 10];
192
/// assert_eq!(b.len(), 10);
193
/// # }
194
/// ```
195
#[macro_export]
196
macro_rules! bit_vec {
197
    // Arms with explicit word type (colon separator)
198
    ($W:ty) => {
199
        $crate::bits::BitVec::<Vec<$W>>::new(0)
200
    };
201
    ($W:ty: false; $n:expr) => {
202
        $crate::bits::BitVec::<Vec<$W>>::new($n)
203
    };
204
    ($W:ty: 0; $n:expr) => {
205
        $crate::bits::BitVec::<Vec<$W>>::new($n)
206
    };
207
    ($W:ty: true; $n:expr) => {
208
        {
209
            $crate::bits::BitVec::<Vec<$W>>::with_value($n, true)
210
        }
211
    };
212
    ($W:ty: 1; $n:expr) => {
213
        {
214
            $crate::bits::BitVec::<Vec<$W>>::with_value($n, true)
215
        }
216
    };
217
    ($W:ty: $($x:expr),+ $(,)?) => {
218
        {
219
            let mut b = $crate::bits::BitVec::<Vec<$W>>::with_capacity([$($x),+].len());
220
            $( b.push($x != 0); )*
221
            b
222
        }
223
    };
224
    // Default arms (usize backing)
225
    () => {
226
        $crate::bits::BitVec::<Vec<usize>>::new(0)
227
    };
228
    (false; $n:expr) => {
229
        $crate::bits::BitVec::<Vec<usize>>::new($n)
230
    };
231
    (0; $n:expr) => {
232
        $crate::bits::BitVec::<Vec<usize>>::new($n)
233
    };
234
    (true; $n:expr) => {
235
        {
236
            $crate::bits::BitVec::<Vec<usize>>::with_value($n, true)
237
        }
238
    };
239
    (1; $n:expr) => {
240
        {
241
            $crate::bits::BitVec::<Vec<usize>>::with_value($n, true)
242
        }
243
    };
244
    ($($x:expr),+ $(,)?) => {
245
        {
246
            let mut b = $crate::bits::BitVec::<Vec<usize>>::with_capacity([$($x),+].len());
247
            $( b.push($x != 0); )*
248
            b
249
        }
250
    };
251
}
252

253
impl<B> BitVec<B> {
254
    /// Returns the number of bits in the bit vector.
255
    ///
256
    /// This method is equivalent to [`BitLength::len`], but it is provided to
257
    /// reduce ambiguity in method resolution.
258
    #[inline(always)]
259
    pub const fn len(&self) -> usize {
77,515✔
260
        self.len
77,515✔
261
    }
262

263
    /// # Safety
264
    /// `len` must be between 0 (included) and the number of
265
    /// bits in `bits` (included).
266
    #[inline(always)]
267
    pub const unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
32✔
268
        Self { bits, len }
269
    }
270

271
    /// Returns the backend and the length in bits, consuming this bit vector.
272
    #[inline(always)]
273
    pub fn into_raw_parts(self) -> (B, usize) {
2✔
274
        (self.bits, self.len)
2✔
275
    }
276

277
    /// Replaces the backend by applying a function, consuming this bit vector.
278
    ///
279
    /// # Safety
280
    /// The caller must ensure that the length is compatible with the new
281
    /// backend.
282
    #[inline(always)]
283
    pub unsafe fn map<B2>(self, f: impl FnOnce(B) -> B2) -> BitVec<B2> {
×
284
        BitVec {
285
            bits: f(self.bits),
×
286
            len: self.len,
×
287
        }
288
    }
289
}
290

291
impl<W: Word> BitVec<Vec<W>> {
292
    /// Creates a new bit vector of length `len` initialized to `false`.
293
    pub fn new(len: usize) -> Self {
40,017✔
294
        Self::with_value(len, false)
80,034✔
295
    }
296

297
    /// Creates a new bit vector of length `len` initialized to `value`.
298
    pub fn with_value(len: usize, value: bool) -> Self {
40,908✔
299
        let bits_per_word = W::BITS as usize;
81,816✔
300
        let n_of_words = len.div_ceil(bits_per_word);
163,632✔
301
        let extra_bits = (n_of_words * bits_per_word) - len;
81,816✔
302
        let word_value = if value { !W::ZERO } else { W::ZERO };
122,724✔
303
        let mut bits = vec![word_value; n_of_words];
163,632✔
304
        if extra_bits > 0 {
43,524✔
305
            let last_word_value = word_value >> extra_bits;
7,848✔
306
            bits[n_of_words - 1] = last_word_value;
2,616✔
307
        }
308
        Self { bits, len }
309
    }
310

311
    /// Creates a new zero-length bit vector of given capacity.
312
    ///
313
    /// Note that the capacity will be rounded up to a multiple of the word
314
    /// size.
315
    pub fn with_capacity(capacity: usize) -> Self {
45✔
316
        let bits_per_word = W::BITS as usize;
90✔
317
        let n_of_words = capacity.div_ceil(bits_per_word);
180✔
318
        Self {
319
            bits: Vec::with_capacity(n_of_words),
45✔
320
            len: 0,
321
        }
322
    }
323

324
    /// Returns the current capacity of this bit vector.
325
    pub fn capacity(&self) -> usize {
16✔
326
        self.bits.capacity() * W::BITS as usize
32✔
327
    }
328

329
    /// Appends a bit to the end of this bit vector.
330
    pub fn push(&mut self, b: bool) {
619,677,019✔
331
        let bits_per_word = W::BITS as usize;
1,239,354,038✔
332
        if self.bits.len() * bits_per_word == self.len {
1,250,456,054✔
333
            self.bits.push(W::ZERO);
11,102,016✔
334
        }
335
        let word_index = self.len / bits_per_word;
1,239,354,038✔
336
        let bit_index = self.len % bits_per_word;
1,239,354,038✔
337
        // Clear bit
338
        self.bits[word_index] &= !(W::ONE << bit_index);
619,677,019✔
339
        // Set bit
340
        if b {
899,769,375✔
341
            self.bits[word_index] |= W::ONE << bit_index;
280,092,356✔
342
        }
343
        self.len += 1;
619,677,019✔
344
    }
345

346
    /// Removes the last bit from the bit vector and returns it, or `None` if it
347
    /// is empty.
348
    pub fn pop(&mut self) -> Option<bool> {
1,206✔
349
        if self.len == 0 {
1,206✔
350
            return None;
6✔
351
        }
352
        let last_pos = self.len - 1;
2,400✔
353
        let result = unsafe { BitVecOps::<W>::get_unchecked(self, last_pos) };
4,800✔
354
        self.len = last_pos;
1,200✔
355
        Some(result)
1,200✔
356
    }
357

358
    /// Resizes the bit vector in place, extending it with `value` if it is
359
    /// necessary.
360
    pub fn resize(&mut self, new_len: usize, value: bool) {
12✔
361
        let bits_per_word = W::BITS as usize;
24✔
362
        if new_len > self.len {
12✔
363
            let old_len = self.len;
12✔
364
            let old_word = old_len / bits_per_word;
12✔
365
            let old_bit = old_len % bits_per_word;
12✔
366
            let word_value = if value { !W::ZERO } else { W::ZERO };
18✔
367

368
            self.bits
6✔
369
                .resize(new_len.div_ceil(bits_per_word), word_value);
30✔
370

371
            // Handle the partial word at old_len, then fill all
372
            // remaining words (which may contain stale data from
373
            // previous truncations).
374
            if old_bit != 0 {
6✔
375
                let mask = !W::ZERO << old_bit;
×
376
                self.bits[old_word] = (self.bits[old_word] & !mask) | (word_value & mask);
×
377
                self.bits[old_word + 1..].fill(word_value);
×
378
            } else {
379
                self.bits[old_word..].fill(word_value);
12✔
380
            }
381
        }
382
        self.len = new_len;
12✔
383
    }
384
}
385

386
impl<W: Word> Extend<bool> for BitVec<Vec<W>> {
387
    fn extend<T: IntoIterator<Item = bool>>(&mut self, i: T) {
30,481✔
388
        for b in i {
1,239,381,367✔
389
            self.push(b);
1,239,350,886✔
390
        }
391
    }
392
}
393

394
impl<W: Word> FromIterator<bool> for BitVec<Vec<W>> {
395
    fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
30,481✔
396
        let mut res = Self::new(0);
60,962✔
397
        res.extend(iter);
91,443✔
398
        res
30,481✔
399
    }
400
}
401

402
impl<B: ToOwned> BitVec<B> {
403
    /// Returns a copy of this bit vector with an owned backend.
404
    pub fn to_owned(&self) -> BitVec<<B as ToOwned>::Owned> {
×
405
        BitVec {
406
            bits: self.bits.to_owned(),
×
407
            len: self.len,
×
408
        }
409
    }
410
}
411

412
impl<B> BitLength for BitVec<B> {
413
    #[inline(always)]
414
    fn len(&self) -> usize {
2,147,483,647✔
415
        self.len
2,147,483,647✔
416
    }
417
}
418

419
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> BitCount for BitVec<B> {
420
    fn count_ones(&self) -> usize {
38,019✔
421
        let bits_per_word = B::Word::BITS as usize;
76,038✔
422
        let full_words = self.len() / bits_per_word;
114,057✔
423
        let residual = self.len() % bits_per_word;
114,057✔
424
        let bits: &[B::Word] = self.as_ref();
114,057✔
425
        let mut num_ones: usize = bits[..full_words]
114,057✔
426
            .iter()
427
            .map(|x| x.count_ones() as usize)
669,727,289✔
428
            .sum();
429
        if residual != 0 {
38,019✔
430
            num_ones += (bits[full_words] << (bits_per_word - residual)).count_ones() as usize
59,176✔
431
        }
432
        num_ones
38,019✔
433
    }
434
}
435

436
impl<B: Backend<Word: Word> + AsRef<[B::Word]>, C: Backend<Word = B::Word> + AsRef<[B::Word]>>
437
    PartialEq<BitVec<C>> for BitVec<B>
438
{
439
    fn eq(&self, other: &BitVec<C>) -> bool {
85✔
440
        let len = self.len();
255✔
441
        if len != other.len() {
170✔
442
            return false;
1✔
443
        }
444

445
        let word_bits = B::Word::BITS as usize;
168✔
446
        let full_words = len / word_bits;
168✔
447
        if self.as_ref()[..full_words] != other.as_ref()[..full_words] {
168✔
448
            return false;
×
449
        }
450

451
        let residual = len % word_bits;
168✔
452
        residual == 0
84✔
453
            || (self.as_ref()[full_words] ^ other.as_ref()[full_words]) << (word_bits - residual)
410✔
454
                == B::Word::ZERO
82✔
455
    }
456
}
457

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

460
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> Index<usize> for BitVec<B> {
461
    type Output = bool;
462

463
    fn index(&self, index: usize) -> &Self::Output {
329,650,502✔
464
        match BitVecOps::<B::Word>::get(self, index) {
659,301,004✔
465
            false => &false,
174,628,692✔
466
            true => &true,
155,021,810✔
467
        }
468
    }
469
}
470

471
impl<'a, B: Backend<Word: Word> + AsRef<[B::Word]>> IntoIterator for &'a BitVec<B> {
472
    type IntoIter = BitIter<'a, B::Word, B>;
473
    type Item = bool;
474

475
    fn into_iter(self) -> Self::IntoIter {
1,314✔
476
        BitIter::new(&self.bits, self.len())
5,256✔
477
    }
478
}
479

480
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> fmt::Display for BitVec<B> {
481
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
5✔
482
        write!(f, "[")?;
10✔
483
        for b in self {
20✔
484
            write!(f, "{:b}", b as usize)?;
45✔
485
        }
486
        write!(f, "]")?;
10✔
487
        Ok(())
5✔
488
    }
489
}
490

491
#[derive(Debug, Clone, MemDbg, MemSize, Delegate)]
492
/// A thread-safe bit vector.
493
///
494
/// See the [module documentation](mod@crate::bits::bit_vec) for details.
495
#[delegate(crate::traits::Backend, target = "bits")]
496
pub struct AtomicBitVec<B = Box<[Atomic<usize>]>> {
497
    bits: B,
498
    len: usize,
499
}
500

501
impl<B> AtomicBitVec<B> {
502
    /// Returns the number of bits in the bit vector.
503
    ///
504
    /// This method is equivalent to [`BitLength::len`], but it is provided to
505
    /// reduce ambiguity in method resolution.
506
    #[inline(always)]
507
    pub const fn len(&self) -> usize {
6✔
508
        self.len
6✔
509
    }
510

511
    /// # Safety
512
    /// `len` must be between 0 (included) and the number of
513
    /// bits in `bits` (included).
514
    #[inline(always)]
515
    pub const unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
3✔
516
        Self { bits, len }
517
    }
518
    /// Returns the backend and the length in bits, consuming this bit vector.
519
    #[inline(always)]
520
    pub fn into_raw_parts(self) -> (B, usize) {
1✔
521
        (self.bits, self.len)
1✔
522
    }
523
}
524

525
impl<B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + From<Vec<B::Word>>> AtomicBitVec<B> {
526
    /// Creates a new atomic bit vector of length `len` initialized to `false`.
527
    pub fn new(len: usize) -> Self {
138✔
528
        Self::with_value(len, false)
276✔
529
    }
530

531
    /// Creates a new atomic bit vector of length `len` initialized to `value`.
532
    pub fn with_value(len: usize, value: bool) -> Self {
144✔
533
        let bits_per_word = <B::Word as PrimitiveAtomic>::Value::BITS as usize;
288✔
534
        let n_of_words = len.div_ceil(bits_per_word);
576✔
535
        let extra_bits = (n_of_words * bits_per_word) - len;
288✔
536
        let word_value = if value {
288✔
537
            !<B::Word as PrimitiveAtomic>::Value::ZERO
6✔
538
        } else {
539
            <B::Word as PrimitiveAtomic>::Value::ZERO
138✔
540
        };
541
        let mut bits: Vec<B::Word> = (0..n_of_words).map(|_| B::Word::new(word_value)).collect();
2,088✔
542
        if extra_bits > 0 {
252✔
543
            let last_word_value = word_value >> extra_bits;
324✔
544
            bits[n_of_words - 1] = B::Word::new(last_word_value);
216✔
545
        }
546
        Self {
547
            bits: B::from(bits),
288✔
548
            len,
549
        }
550
    }
551
}
552

553
impl<B> BitLength for AtomicBitVec<B> {
554
    #[inline(always)]
555
    fn len(&self) -> usize {
90,375✔
556
        self.len
90,375✔
557
    }
558
}
559

560
impl<B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + AsRef<[B::Word]>> BitCount
561
    for AtomicBitVec<B>
562
{
563
    fn count_ones(&self) -> usize {
3✔
564
        let bits_per_word = <B::Word as PrimitiveAtomic>::Value::BITS as usize;
6✔
565
        let full_words = self.len() / bits_per_word;
9✔
566
        let residual = self.len() % bits_per_word;
9✔
567
        let bits: &[B::Word] = self.as_ref();
9✔
568
        let mut num_ones;
×
569
        // Just to be sure, add a fence to ensure that we will see all the final
570
        // values
571
        core::sync::atomic::fence(Ordering::SeqCst);
6✔
572
        num_ones = bits[..full_words]
3✔
573
            .iter()
3✔
574
            .map(|x| x.load(Ordering::Relaxed).count_ones() as usize)
63✔
575
            .sum();
3✔
576
        if residual != 0 {
3✔
577
            num_ones += (bits[full_words].load(Ordering::Relaxed) << (bits_per_word - residual))
8✔
578
                .count_ones() as usize
2✔
579
        }
580
        num_ones
3✔
581
    }
582
}
583

584
impl<B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + AsRef<[B::Word]>> Index<usize>
585
    for AtomicBitVec<B>
586
{
587
    type Output = bool;
588

589
    /// Shorthand for `get` using [`Ordering::Relaxed`].
590
    fn index(&self, index: usize) -> &Self::Output {
10,000✔
591
        match AtomicBitVecOps::<B::Word>::get(self, index, Ordering::Relaxed) {
30,000✔
592
            false => &false,
9,500✔
593
            true => &true,
500✔
594
        }
595
    }
596
}
597

598
impl<'a, B: Backend<Word: PrimitiveAtomicUnsigned<Value: Word>> + AsRef<[B::Word]>> IntoIterator
599
    for &'a AtomicBitVec<B>
600
{
601
    type IntoIter = AtomicBitIter<'a, B::Word, B>;
602
    type Item = bool;
603

604
    fn into_iter(self) -> Self::IntoIter {
×
605
        AtomicBitIter::new(&self.bits, self.len())
×
606
    }
607
}
608

609
// Conversions
610

611
/// This conversion may fail if the alignment of `W` is not the same as
612
/// that of `W::Atomic`.
613
impl<'a, W: AtomicPrimitive> TryFrom<BitVec<&'a [W]>> for AtomicBitVec<&'a [W::Atomic]> {
614
    type Error = CannotCastToAtomicError<W>;
615
    fn try_from(value: BitVec<&'a [W]>) -> Result<Self, Self::Error> {
1✔
616
        if core::mem::align_of::<W>() != core::mem::align_of::<W::Atomic>() {
1✔
617
            return Err(CannotCastToAtomicError::default());
×
618
        }
619
        Ok(AtomicBitVec {
1✔
620
            bits: unsafe { core::mem::transmute::<&'a [W], &'a [W::Atomic]>(value.bits) },
1✔
621
            len: value.len,
1✔
622
        })
623
    }
624
}
625

626
/// This conversion may fail if the alignment of `W` is not the same as
627
/// that of `W::Atomic`.
628
impl<'a, W: AtomicPrimitive> TryFrom<BitVec<&'a mut [W]>> for AtomicBitVec<&'a mut [W::Atomic]> {
629
    type Error = CannotCastToAtomicError<W>;
630
    fn try_from(value: BitVec<&'a mut [W]>) -> Result<Self, Self::Error> {
1✔
631
        if core::mem::align_of::<W>() != core::mem::align_of::<W::Atomic>() {
1✔
632
            return Err(CannotCastToAtomicError::default());
×
633
        }
634
        Ok(AtomicBitVec {
1✔
635
            bits: unsafe { core::mem::transmute::<&'a mut [W], &'a mut [W::Atomic]>(value.bits) },
1✔
636
            len: value.len,
1✔
637
        })
638
    }
639
}
640

641
impl<W: AtomicPrimitive> From<AtomicBitVec<Box<[W::Atomic]>>> for BitVec<Vec<W>> {
642
    fn from(value: AtomicBitVec<Box<[W::Atomic]>>) -> Self {
1✔
643
        BitVec {
644
            bits: transmute_vec_from_atomic::<W::Atomic>(value.bits.into_vec()),
3✔
645
            len: value.len,
1✔
646
        }
647
    }
648
}
649

650
impl<W: AtomicPrimitive> From<BitVec<Vec<W>>> for AtomicBitVec<Box<[W::Atomic]>> {
651
    fn from(value: BitVec<Vec<W>>) -> Self {
2✔
652
        AtomicBitVec {
653
            bits: transmute_vec_into_atomic(value.bits).into_boxed_slice(),
6✔
654
            len: value.len,
2✔
655
        }
656
    }
657
}
658

659
impl<W: AtomicPrimitive> From<AtomicBitVec<Box<[W::Atomic]>>> for BitVec<Box<[W]>> {
660
    fn from(value: AtomicBitVec<Box<[W::Atomic]>>) -> Self {
36✔
661
        BitVec {
662
            bits: transmute_boxed_slice_from_atomic::<W::Atomic>(value.bits),
72✔
663
            len: value.len,
36✔
664
        }
665
    }
666
}
667

668
impl<W: AtomicPrimitive + Copy> From<BitVec<Box<[W]>>> for AtomicBitVec<Box<[W::Atomic]>> {
669
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
670
        AtomicBitVec {
671
            bits: transmute_boxed_slice_into_atomic::<W>(value.bits),
2✔
672
            len: value.len,
1✔
673
        }
674
    }
675
}
676

677
impl<'a, W: AtomicPrimitive> From<AtomicBitVec<&'a [W::Atomic]>> for BitVec<&'a [W]> {
678
    fn from(value: AtomicBitVec<&'a [W::Atomic]>) -> Self {
1✔
679
        BitVec {
680
            bits: unsafe { core::mem::transmute::<&'a [W::Atomic], &'a [W]>(value.bits) },
1✔
681
            len: value.len,
1✔
682
        }
683
    }
684
}
685

686
impl<'a, W: AtomicPrimitive> From<AtomicBitVec<&'a mut [W::Atomic]>> for BitVec<&'a mut [W]> {
687
    fn from(value: AtomicBitVec<&'a mut [W::Atomic]>) -> Self {
1✔
688
        BitVec {
689
            bits: unsafe { core::mem::transmute::<&'a mut [W::Atomic], &'a mut [W]>(value.bits) },
1✔
690
            len: value.len,
1✔
691
        }
692
    }
693
}
694

695
impl<W> From<BitVec<Vec<W>>> for BitVec<Box<[W]>> {
696
    fn from(value: BitVec<Vec<W>>) -> Self {
875✔
697
        BitVec {
698
            bits: value.bits.into_boxed_slice(),
1,750✔
699
            len: value.len,
875✔
700
        }
701
    }
702
}
703

704
impl<W> From<BitVec<Box<[W]>>> for BitVec<Vec<W>> {
705
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
706
        BitVec {
707
            bits: value.bits.into_vec(),
2✔
708
            len: value.len,
1✔
709
        }
710
    }
711
}
712

713
impl<W: Word, B: AsRef<[W]>> AsRef<[W]> for BitVec<B> {
714
    #[inline(always)]
715
    fn as_ref(&self) -> &[W] {
2,147,483,647✔
716
        self.bits.as_ref()
2,147,483,647✔
717
    }
718
}
719

720
impl<W: Word, B: AsMut<[W]>> AsMut<[W]> for BitVec<B> {
721
    #[inline(always)]
722
    fn as_mut(&mut self) -> &mut [W] {
2,147,483,647✔
723
        self.bits.as_mut()
2,147,483,647✔
724
    }
725
}
726

727
impl<B: Backend + AsRef<[B::Word]>> AsRef<[B::Word]> for AtomicBitVec<B> {
728
    #[inline(always)]
729
    fn as_ref(&self) -> &[B::Word] {
90,306✔
730
        self.bits.as_ref()
90,306✔
731
    }
732
}
733

734
impl<B: Backend<Word: Word> + AsRef<[B::Word]>> RankHinted for BitVec<B> {
735
    #[inline(always)]
736
    unsafe fn rank_hinted(&self, pos: usize, hint_pos: usize, hint_rank: usize) -> usize {
9,904,509✔
737
        let bits_per_word = B::Word::BITS as usize;
19,809,018✔
738
        let bits: &[B::Word] = self.as_ref();
29,713,527✔
739
        let mut rank = hint_rank;
19,809,018✔
740
        let mut hint_pos = hint_pos;
19,809,018✔
741

742
        debug_assert!(
9,904,509✔
743
            hint_pos < bits.len(),
19,809,018✔
744
            "hint_pos: {}, len: {}",
×
745
            hint_pos,
×
746
            bits.len()
×
747
        );
748

749
        while (hint_pos + 1) * bits_per_word <= pos {
19,791,333✔
750
            rank += unsafe { bits.get_unchecked(hint_pos) }.count_ones() as usize;
9,886,824✔
751
            hint_pos += 1;
4,943,412✔
752
        }
753

754
        rank + (unsafe { *bits.get_unchecked(hint_pos) }
39,618,036✔
755
            & (B::Word::ONE << (pos % bits_per_word)).wrapping_sub(B::Word::ONE))
9,904,509✔
756
        .count_ones() as usize
9,904,509✔
757
    }
758
}
759

760
// SelectHinted and SelectZeroHinted for BitVec.
761

762
impl<B: Backend<Word: Word + SelectInWord> + AsRef<[B::Word]>> SelectHinted for BitVec<B> {
763
    unsafe fn select_hinted(&self, rank: usize, hint_pos: usize, hint_rank: usize) -> usize {
2,147,483,647✔
764
        let bits_per_word = B::Word::BITS as usize;
2,147,483,647✔
765
        let mut word_index = hint_pos / bits_per_word;
2,147,483,647✔
766
        let bit_index = hint_pos % bits_per_word;
2,147,483,647✔
767
        let mut residual = rank - hint_rank;
2,147,483,647✔
768
        let mut word =
2,147,483,647✔
769
            (unsafe { *self.as_ref().get_unchecked(word_index) } >> bit_index) << bit_index;
2,147,483,647✔
770
        loop {
×
771
            let bit_count = word.count_ones() as usize;
2,147,483,647✔
772
            if residual < bit_count {
2,147,483,647✔
773
                return word_index * bits_per_word + word.select_in_word(residual);
2,147,483,647✔
774
            }
775
            word_index += 1;
2,147,483,647✔
776
            word = *unsafe { self.as_ref().get_unchecked(word_index) };
2,147,483,647✔
777
            residual -= bit_count;
2,147,483,647✔
778
        }
779
    }
780
}
781

782
impl<B: Backend<Word: Word + SelectInWord> + AsRef<[B::Word]>> SelectZeroHinted for BitVec<B> {
783
    unsafe fn select_zero_hinted(&self, rank: usize, hint_pos: usize, hint_rank: usize) -> usize {
2,147,483,647✔
784
        let bits_per_word = B::Word::BITS as usize;
2,147,483,647✔
785
        let mut word_index = hint_pos / bits_per_word;
2,147,483,647✔
786
        let bit_index = hint_pos % bits_per_word;
2,147,483,647✔
787
        let mut residual = rank - hint_rank;
2,147,483,647✔
788
        let mut word =
2,147,483,647✔
789
            (!*unsafe { self.as_ref().get_unchecked(word_index) } >> bit_index) << bit_index;
2,147,483,647✔
790
        loop {
×
791
            let bit_count = word.count_ones() as usize;
2,147,483,647✔
792
            if residual < bit_count {
2,147,483,647✔
793
                return word_index * bits_per_word + word.select_in_word(residual);
2,147,483,647✔
794
            }
795
            word_index += 1;
2,147,483,647✔
796
            word = unsafe { !*self.as_ref().get_unchecked(word_index) };
2,147,483,647✔
797
            residual -= bit_count;
2,147,483,647✔
798
        }
799
    }
800
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc