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

vigna / sux-rs / 17861369619

19 Sep 2025 02:34PM UTC coverage: 66.129% (+1.4%) from 64.717%
17861369619

push

github

vigna
Minor fixes

3774 of 5707 relevant lines covered (66.13%)

117089019.02 hits per line

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

75.51
/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
//! These flavors depends on a backend, and presently we provide:
14
//!
15
//! - `BitVec<Vec<usize>>`: a mutable, growable and resizable bit vector;
16
//! - `BitVec<AsRef<[usize]>>`: an immutable bit vector, useful for
17
//!   [ε-serde](epserde) support;
18
//! - `BitVec<AsRef<[usize]> + AsMut<[usize]>>`: a mutable (but not resizable)
19
//!   bit vector;
20
//! - `AtomicBitVec<AsRef<[AtomicUsize]>>`: a thread-safe, mutable (but not
21
//!   resizable) bit vector.
22
//!
23
//! Note that nothing is assumed about the content of the backend outside the
24
//! bits of the bit vector. Moreover, the content of the backend outside of
25
//! the bit vector is never modified by the methods of this structure.
26
//!
27
//! It is possible to juggle between the three flavors using [`From`]/[`Into`].
28
//!
29
//! # Examples
30
//!
31
//! ```rust
32
//! use sux::bit_vec;
33
//! use sux::traits::{BitCount, BitLength, NumBits, AddNumBits};
34
//! use sux::bits::{BitVec, AtomicBitVec};
35
//! use core::sync::atomic::Ordering;
36
//!
37
//! // Convenience macro
38
//! let b = bit_vec![0, 1, 0, 1, 1, 0, 1, 0];
39
//! assert_eq!(b.len(), 8);
40
//! // Not constant time
41
//! assert_eq!(b.count_ones(), 4);
42
//! assert_eq!(b[0], false);
43
//! assert_eq!(b[1], true);
44
//! assert_eq!(b[2], false);
45
//!
46
//! let b: AddNumBits<_> = b.into();
47
//! // Constant time, but now b is immutable
48
//! assert_eq!(b.num_ones(), 4);
49
//!
50
//! let mut b = BitVec::new(0);
51
//! b.push(true);
52
//! b.push(false);
53
//! b.push(true);
54
//! assert_eq!(b.len(), 3);
55
//!
56
//! // Let's make it atomic
57
//! let mut a: AtomicBitVec = b.into();
58
//! a.set(1, true, Ordering::Relaxed);
59
//! assert!(a.get(0, Ordering::Relaxed));
60
//!
61
//! // Back to normal, but immutable size
62
//! let b: BitVec<Vec<usize>> = a.into();
63
//! let mut b: BitVec<Box<[usize]>> = b.into();
64
//! b.set(2, false);
65
//!
66
//! // If we create an artificially dirty bit vector, everything still works.
67
//! let ones = [usize::MAX; 2];
68
//! assert_eq!(unsafe { BitVec::from_raw_parts(ones, 1) }.count_ones(), 1);
69
//! ```
70

71
use common_traits::{IntoAtomic, SelectInWord};
72
#[allow(unused_imports)] // this is in the std prelude but not in no_std!
73
use core::borrow::BorrowMut;
74
use core::fmt;
75
use mem_dbg::*;
76
#[cfg(feature = "rayon")]
77
use rayon::prelude::*;
78
use std::{
79
    ops::Index,
80
    sync::atomic::{AtomicUsize, Ordering},
81
};
82

83
use crate::{
84
    traits::rank_sel::*,
85
    utils::{
86
        CannotCastToAtomicError, transmute_boxed_slice_from_atomic,
87
        transmute_boxed_slice_into_atomic, transmute_vec_from_atomic, transmute_vec_into_atomic,
88
    },
89
};
90

91
#[cfg(feature = "rayon")]
92
use crate::RAYON_MIN_LEN;
93

94
const BITS: usize = usize::BITS as usize;
95

96
/// Convenient, [`vec!`](vec!)-like macro to initialize bit vectors.
97
///
98
/// # Examples
99
///
100
/// ```rust
101
/// use sux::bit_vec;
102
/// use sux::traits::BitLength;
103
///
104
/// // Empty bit vector
105
/// let b = bit_vec![];
106
/// assert_eq!(b.len(), 0);
107
///
108
/// // 10 bits set to true
109
/// let b = bit_vec![true; 10];
110
/// assert_eq!(b.len(), 10);
111
/// assert_eq!(b.iter().all(|x| x), true);
112
/// let b = bit_vec![1; 10];
113
/// assert_eq!(b.len(), 10);
114
/// assert_eq!(b.iter().all(|x| x), true);
115
///
116
/// // 10 bits set to false
117
/// let b = bit_vec![false; 10];
118
/// assert_eq!(b.len(), 10);
119
/// assert_eq!(b.iter().any(|x| x), false);
120
/// let b = bit_vec![0; 10];
121
/// assert_eq!(b.len(), 10);
122
/// assert_eq!(b.iter().any(|x| x), false);
123
///
124
/// // Bit list
125
/// let b = bit_vec![0, 1, 0, 1, 0, 0];
126
/// assert_eq!(b.len(), 6);
127
/// assert_eq!(b[0], false);
128
/// assert_eq!(b[1], true);
129
/// assert_eq!(b[2], false);
130
/// assert_eq!(b[3], true);
131
/// assert_eq!(b[4], false);
132
/// assert_eq!(b[5], false);
133
/// ```
134
#[macro_export]
135
macro_rules! bit_vec {
136
    () => {
137
        $crate::bits::BitVec::new(0)
138
    };
139
    (false; $n:expr) => {
140
        $crate::bits::BitVec::new($n)
141
    };
142
    (0; $n:expr) => {
143
        $crate::bits::BitVec::new($n)
144
    };
145
    (true; $n:expr) => {
146
        {
147
            $crate::bits::BitVec::with_value($n, true)
148
        }
149
    };
150
    (1; $n:expr) => {
151
        {
152
            $crate::bits::BitVec::with_value($n, true)
153
        }
154
    };
155
    ($($x:expr),+ $(,)?) => {
156
        {
157
            let mut b = $crate::bits::BitVec::with_capacity([$($x),+].len());
158
            $( b.push($x != 0); )*
159
            b
160
        }
161
    };
162
}
163

164
macro_rules! panic_if_out_of_bounds {
165
    ($index: expr, $len: expr) => {
166
        if $index >= $len {
167
            panic!("Bit index out of bounds: {} >= {}", $index, $len)
168
        }
169
    };
170
}
171

172
#[derive(Debug, Clone, Copy, MemDbg, MemSize)]
173
#[cfg_attr(feature = "epserde", derive(epserde::Epserde))]
174
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
175
/// A bit vector.
176
pub struct BitVec<B = Vec<usize>> {
177
    bits: B,
178
    len: usize,
179
}
180

181
impl<B> BitVec<B> {
182
    /// Returns the number of bits in the bit vector.
183
    ///
184
    /// This method is equivalent to [`BitLength::len`], but it is provided to
185
    /// reduce ambiguity in method resolution.
186
    #[inline(always)]
187
    pub fn len(&self) -> usize {
222,035✔
188
        BitLength::len(self)
444,070✔
189
    }
190

191
    /// # Safety
192
    /// `len` must be between 0 (included) the number of
193
    /// bits in `bits` (included).
194
    #[inline(always)]
195
    pub unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
24✔
196
        Self { bits, len }
197
    }
198
    #[inline(always)]
199
    pub fn into_raw_parts(self) -> (B, usize) {
2✔
200
        (self.bits, self.len)
2✔
201
    }
202
    #[inline(always)]
203
    /// Modify the bit vector in place.
204
    /// # Safety
205
    /// This is unsafe because it's the caller's responsibility to ensure that
206
    /// that the length is compatible with the modified bits.
207
    pub unsafe fn map<B2>(self, f: impl FnOnce(B) -> B2) -> BitVec<B2> {
×
208
        BitVec {
209
            bits: f(self.bits),
×
210
            len: self.len,
×
211
        }
212
    }
213
}
214

215
impl<B: AsRef<[usize]>> BitVec<B> {
216
    /// Returns an owned copy of the bit vector.
217
    pub fn to_owned(&self) -> BitVec {
×
218
        BitVec {
219
            bits: self.bits.as_ref().to_owned(),
×
220
            len: self.len,
×
221
        }
222
    }
223

224
    /// Returns true if the bit of given index is set.
225
    #[inline]
226
    pub fn get(&self, index: usize) -> bool {
481,609,627✔
227
        panic_if_out_of_bounds!(index, self.len);
1,444,828,881✔
228
        unsafe { self.get_unchecked(index) }
481,609,627✔
229
    }
230

231
    /// Returns true if the bit of given index is set, without
232
    /// bound checks.
233
    ///
234
    /// # Safety
235
    ///
236
    /// `index` must be between 0 (included) and [`BitVec::len`] (excluded).
237
    #[inline(always)]
238
    pub unsafe fn get_unchecked(&self, index: usize) -> bool {
481,609,627✔
239
        let word_index = index / BITS;
963,219,254✔
240
        let word = unsafe { self.bits.as_ref().get_unchecked(word_index) };
1,926,438,508✔
241
        (word >> (index % BITS)) & 1 != 0
481,609,627✔
242
    }
243
}
244

245
impl<B: AsRef<[usize]> + AsMut<[usize]>> BitVec<B> {
246
    #[inline]
247
    pub fn set(&mut self, index: usize, value: bool) {
2,147,483,647✔
248
        panic_if_out_of_bounds!(index, self.len);
2,147,483,647✔
249
        unsafe { self.set_unchecked(index, value) }
2,147,483,647✔
250
    }
251

252
    /// # Safety
253
    ///
254
    /// `index` must be between 0 (included) and [`BitVec::len`] (excluded).
255
    #[inline(always)]
256
    pub unsafe fn set_unchecked(&mut self, index: usize, value: bool) {
2,147,483,647✔
257
        let word_index = index / BITS;
2,147,483,647✔
258
        let bit_index = index % BITS;
2,147,483,647✔
259
        let bits = self.bits.as_mut();
2,147,483,647✔
260
        // TODO: no test?
261
        // For constant values, this should be inlined with no test.
262
        unsafe {
263
            if value {
2,147,483,647✔
264
                *bits.get_unchecked_mut(word_index) |= 1 << bit_index;
2,147,483,647✔
265
            } else {
266
                *bits.get_unchecked_mut(word_index) &= !(1 << bit_index);
168,149✔
267
            }
268
        }
269
    }
270

271
    /// Sets all bits to the given value.
272
    pub fn fill(&mut self, value: bool) {
24✔
273
        let full_words = self.len() / BITS;
48✔
274
        let residual = self.len % BITS;
48✔
275
        let bits = self.bits.as_mut();
72✔
276
        let word_value = if value { !0 } else { 0 };
72✔
277
        bits[..full_words].iter_mut().for_each(|x| *x = word_value);
135✔
278
        if residual != 0 {
39✔
279
            let mask = (1 << residual) - 1;
45✔
280
            bits[full_words] = (bits[full_words] & !mask) | (word_value & mask);
45✔
281
        }
282
    }
283

284
    /// Sets all bits to the given value using a parallel implementation.
285
    #[cfg(feature = "rayon")]
286
    pub fn par_fill(&mut self, value: bool) {
16✔
287
        let full_words = self.len() / BITS;
32✔
288
        let residual = self.len % BITS;
32✔
289
        let bits = self.bits.as_mut();
48✔
290
        let word_value = if value { !0 } else { 0 };
48✔
291
        bits[..full_words]
16✔
292
            .par_iter_mut()
293
            .with_min_len(RAYON_MIN_LEN)
16✔
294
            .for_each(|x| *x = word_value);
58✔
295
        if residual != 0 {
26✔
296
            let mask = (1 << residual) - 1;
30✔
297
            bits[full_words] = (bits[full_words] & !mask) | (word_value & mask);
30✔
298
        }
299
    }
300

301
    /// Sets all bits to zero.
302
    pub fn reset(&mut self) {
×
303
        self.fill(false);
×
304
    }
305

306
    /// Sets all bits to zero using a parallel implementation.
307
    #[cfg(feature = "rayon")]
308
    pub fn par_reset(&mut self) {
×
309
        self.par_fill(false);
×
310
    }
311

312
    /// Flip all bits.
313
    pub fn flip(&mut self) {
22✔
314
        let full_words = self.len() / BITS;
44✔
315
        let residual = self.len % BITS;
44✔
316
        let bits = self.bits.as_mut();
66✔
317
        bits[..full_words].iter_mut().for_each(|x| *x = !*x);
156,281,364✔
318
        if residual != 0 {
34✔
319
            let mask = (1 << residual) - 1;
36✔
320
            bits[full_words] = (bits[full_words] & !mask) | (!bits[full_words] & mask);
36✔
321
        }
322
    }
323

324
    /// Flip all bits using a parallel implementation.
325
    #[cfg(feature = "rayon")]
326
    pub fn par_flip(&mut self) {
16✔
327
        let full_words = self.len() / BITS;
32✔
328
        let residual = self.len % BITS;
32✔
329
        let bits = self.bits.as_mut();
48✔
330
        bits[..full_words]
16✔
331
            .par_iter_mut()
332
            .with_min_len(RAYON_MIN_LEN)
16✔
333
            .for_each(|x| *x = !*x);
58✔
334
        if residual != 0 {
26✔
335
            let mask = (1 << residual) - 1;
30✔
336
            bits[full_words] = (bits[full_words] & !mask) | (!bits[full_words] & mask);
30✔
337
        }
338
    }
339

340
    /// A parallel version of [`BitVec::count_ones`].
341
    #[cfg(feature = "rayon")]
342
    pub fn par_count_ones(&self) -> usize {
×
343
        let full_words = self.len() / BITS;
×
344
        let residual = self.len() % BITS;
×
345
        let bits = self.bits.as_ref();
×
346
        let mut num_ones;
×
347
        num_ones = bits[..full_words]
×
348
            .par_iter()
×
349
            .with_min_len(RAYON_MIN_LEN)
×
350
            .map(|x| x.count_ones() as usize)
×
351
            .sum();
×
352
        if residual != 0 {
×
353
            num_ones += (self.as_ref()[full_words] << (BITS - residual)).count_ones() as usize
×
354
        }
355

356
        num_ones
×
357
    }
358
}
359

360
impl BitVec<Vec<usize>> {
361
    /// Creates a new bit vector of length `len` initialized to `false`.
362
    pub fn new(len: usize) -> Self {
104,522✔
363
        Self::with_value(len, false)
209,044✔
364
    }
365

366
    /// Creates a new bit vector of length `len` initialized to `value`.
367
    pub fn with_value(len: usize, value: bool) -> Self {
105,192✔
368
        let n_of_words = len.div_ceil(BITS);
315,576✔
369
        let extra_bits = (n_of_words * BITS) - len;
210,384✔
370
        let word_value = if value { !0 } else { 0 };
315,576✔
371
        let mut bits = vec![word_value; n_of_words];
420,768✔
372
        if extra_bits > 0 {
106,567✔
373
            let last_word_value = word_value >> extra_bits;
4,125✔
374
            bits[n_of_words - 1] = last_word_value;
1,375✔
375
        }
376
        Self { bits, len }
377
    }
378

379
    /// Creates a new zero-length bit vector of given capacity.
380
    ///
381
    /// Note that the capacity will be rounded up to a multiple of the word
382
    /// size.
383
    pub fn with_capacity(capacity: usize) -> Self {
50✔
384
        let n_of_words = capacity.div_ceil(BITS);
150✔
385
        Self {
386
            bits: Vec::with_capacity(n_of_words),
50✔
387
            len: 0,
388
        }
389
    }
390

391
    pub fn capacity(&self) -> usize {
80✔
392
        self.bits.capacity() * BITS
80✔
393
    }
394

395
    pub fn push(&mut self, b: bool) {
2,147,483,647✔
396
        if self.bits.len() * BITS == self.len {
2,147,483,647✔
397
            self.bits.push(0);
40,495,570✔
398
        }
399
        let word_index = self.len / BITS;
2,147,483,647✔
400
        let bit_index = self.len % BITS;
2,147,483,647✔
401
        // Clear bit
402
        self.bits[word_index] &= !(1 << bit_index);
2,147,483,647✔
403
        // Set bit
404
        self.bits[word_index] |= (b as usize) << bit_index;
2,147,483,647✔
405
        self.len += 1;
2,147,483,647✔
406
    }
407

408
    pub fn pop(&mut self) -> Option<bool> {
1,005✔
409
        if self.len == 0 {
1,005✔
410
            return None;
5✔
411
        }
412
        self.len -= 1;
×
413
        let word_index = self.len / BITS;
×
414
        let bit_index = self.len % BITS;
×
415
        Some((self.bits[word_index] >> bit_index) & 1 != 0)
×
416
    }
417

418
    pub fn resize(&mut self, new_len: usize, value: bool) {
10✔
419
        // TODO: rewrite by word
420
        if new_len > self.len {
10✔
421
            if new_len > self.bits.len() * BITS {
15✔
422
                self.bits.resize(new_len.div_ceil(BITS), 0);
15✔
423
            }
424
            for i in self.len..new_len {
510✔
425
                unsafe {
426
                    self.set_unchecked(i, value);
×
427
                }
428
            }
429
        }
430
        self.len = new_len;
10✔
431
    }
432
}
433

434
impl<B> BitLength for BitVec<B> {
435
    #[inline(always)]
436
    fn len(&self) -> usize {
2,147,483,647✔
437
        self.len
2,147,483,647✔
438
    }
439
}
440

441
impl<B: AsRef<[usize]>> BitCount for BitVec<B> {
442
    fn count_ones(&self) -> usize {
102,230✔
443
        let full_words = self.len() / BITS;
204,460✔
444
        let residual = self.len() % BITS;
204,460✔
445
        let bits = self.bits.as_ref();
306,690✔
446
        let mut num_ones = bits[..full_words]
204,460✔
447
            .iter()
448
            .map(|x| x.count_ones() as usize)
706,962,970✔
449
            .sum();
450
        if residual != 0 {
102,230✔
451
            num_ones += (self.as_ref()[full_words] << (BITS - residual)).count_ones() as usize
183,136✔
452
        }
453
        num_ones
102,230✔
454
    }
455
}
456

457
impl<B: AsRef<[usize]>> Index<usize> for BitVec<B> {
458
    type Output = bool;
459

460
    fn index(&self, index: usize) -> &Self::Output {
325,878,760✔
461
        match self.get(index) {
651,757,520✔
462
            false => &false,
172,741,020✔
463
            true => &true,
153,137,740✔
464
        }
465
    }
466
}
467

468
impl Extend<bool> for BitVec<Vec<usize>> {
469
    fn extend<T>(&mut self, i: T)
20,582✔
470
    where
471
        T: IntoIterator<Item = bool>,
472
    {
473
        for b in i {
1,035,509,862✔
474
            self.push(b);
×
475
        }
476
    }
477
}
478

479
impl FromIterator<bool> for BitVec<Vec<usize>> {
480
    fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
20,582✔
481
        let mut res = Self::new(0);
41,164✔
482
        res.extend(iter);
61,746✔
483
        res
20,582✔
484
    }
485
}
486

487
impl<B: AsRef<[usize]>> RankHinted<64> for BitVec<B> {
488
    #[inline(always)]
489
    unsafe fn rank_hinted(&self, pos: usize, hint_pos: usize, hint_rank: usize) -> usize {
9✔
490
        let bits = self.as_ref();
27✔
491
        let mut rank = hint_rank;
18✔
492
        let mut hint_pos = hint_pos;
18✔
493

494
        debug_assert!(
9✔
495
            hint_pos < bits.len(),
18✔
496
            "hint_pos: {}, len: {}",
×
497
            hint_pos,
×
498
            bits.len()
×
499
        );
500

501
        while (hint_pos + 1) * 64 <= pos {
9✔
502
            rank += unsafe { bits.get_unchecked(hint_pos).count_ones() } as usize;
×
503
            hint_pos += 1;
×
504
        }
505

506
        rank + (unsafe { bits.get_unchecked(hint_pos) } & ((1 << (pos % 64)) - 1)).count_ones()
36✔
507
            as usize
9✔
508
    }
509
}
510

511
impl<B: AsRef<[usize]>> SelectHinted for BitVec<B> {
512
    unsafe fn select_hinted(&self, rank: usize, hint_pos: usize, hint_rank: usize) -> usize {
2,147,483,647✔
513
        let mut word_index = hint_pos / BITS;
2,147,483,647✔
514
        let bit_index = hint_pos % BITS;
2,147,483,647✔
515
        let mut residual = rank - hint_rank;
2,147,483,647✔
516
        let mut word =
2,147,483,647✔
517
            (unsafe { self.as_ref().get_unchecked(word_index) } >> bit_index) << bit_index;
2,147,483,647✔
518
        loop {
×
519
            let bit_count = word.count_ones() as usize;
2,147,483,647✔
520
            if residual < bit_count {
2,147,483,647✔
521
                return word_index * BITS + word.select_in_word(residual);
2,147,483,647✔
522
            }
523
            word_index += 1;
×
524
            word = *unsafe { self.as_ref().get_unchecked(word_index) };
×
525
            residual -= bit_count;
×
526
        }
527
    }
528
}
529

530
impl<B: AsRef<[usize]>> SelectZeroHinted for BitVec<B> {
531
    unsafe fn select_zero_hinted(&self, rank: usize, hint_pos: usize, hint_rank: usize) -> usize {
2,147,483,647✔
532
        let mut word_index = hint_pos / BITS;
2,147,483,647✔
533
        let bit_index = hint_pos % BITS;
2,147,483,647✔
534
        let mut residual = rank - hint_rank;
2,147,483,647✔
535
        let mut word =
2,147,483,647✔
536
            (!*unsafe { self.as_ref().get_unchecked(word_index) } >> bit_index) << bit_index;
2,147,483,647✔
537
        loop {
×
538
            let bit_count = word.count_ones() as usize;
2,147,483,647✔
539
            if residual < bit_count {
2,147,483,647✔
540
                return word_index * BITS + word.select_in_word(residual);
2,147,483,647✔
541
            }
542
            word_index += 1;
×
543
            word = unsafe { !self.as_ref().get_unchecked(word_index) };
×
544
            residual -= bit_count;
×
545
        }
546
    }
547
}
548

549
impl<B: AsRef<[usize]>, C: AsRef<[usize]>> PartialEq<BitVec<C>> for BitVec<B> {
550
    fn eq(&self, other: &BitVec<C>) -> bool {
70✔
551
        let len = self.len();
210✔
552
        if len != other.len() {
140✔
553
            return false;
1✔
554
        }
555

556
        let full_words = len / BITS;
×
557
        if self.as_ref()[..full_words] != other.as_ref()[..full_words] {
×
558
            return false;
×
559
        }
560

561
        let residual = len % BITS;
×
562

563
        residual == 0
×
564
            || (self.as_ref()[full_words] ^ other.as_ref()[full_words]) << (BITS - residual) == 0
67✔
565
    }
566
}
567

568
impl Eq for BitVec<Vec<usize>> {}
569

570
impl<B: AsRef<[usize]>> fmt::Display for BitVec<B> {
571
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
×
572
        write!(f, "[")?;
×
573
        for b in self {
×
574
            write!(f, "{:b}", b as usize)?;
×
575
        }
576
        write!(f, "]")?;
×
577
        Ok(())
×
578
    }
579
}
580

581
// An iterator over the bits of the bit vector as booleans.
582
#[derive(Debug, Clone, MemDbg, MemSize)]
583
pub struct BitIterator<'a, B> {
584
    bits: &'a B,
585
    len: usize,
586
    next_bit_pos: usize,
587
}
588

589
impl<'a, B: AsRef<[usize]>> IntoIterator for &'a BitVec<B> {
590
    type IntoIter = BitIterator<'a, B>;
591
    type Item = bool;
592

593
    fn into_iter(self) -> Self::IntoIter {
6,799✔
594
        BitIterator {
595
            bits: &self.bits,
6,799✔
596
            len: self.len,
6,799✔
597
            next_bit_pos: 0,
598
        }
599
    }
600
}
601

602
impl<B: AsRef<[usize]>> Iterator for BitIterator<'_, B> {
603
    type Item = bool;
604
    fn next(&mut self) -> Option<bool> {
110,751,792✔
605
        if self.next_bit_pos == self.len {
110,751,792✔
606
            return None;
6,799✔
607
        }
608
        let word_idx = self.next_bit_pos / BITS;
×
609
        let bit_idx = self.next_bit_pos % BITS;
×
610
        let word = unsafe { *self.bits.as_ref().get_unchecked(word_idx) };
×
611
        let bit = (word >> bit_idx) & 1;
×
612
        self.next_bit_pos += 1;
×
613
        Some(bit != 0)
×
614
    }
615
}
616

617
/// An iterator over the positions of the ones in a bit vector.
618
#[derive(Debug, Clone, MemDbg, MemSize)]
619
pub struct OnesIterator<'a, B> {
620
    bits: &'a B,
621
    len: usize,
622
    word_idx: usize,
623
    /// This is a usize because BitVec is currently implemented only for `Vec<usize>` and `&[usize]`.
624
    word: usize,
625
}
626

627
impl<'a, B: AsRef<[usize]>> OnesIterator<'a, B> {
628
    pub fn new(bits: &'a B, len: usize) -> Self {
5✔
629
        let word = if bits.as_ref().is_empty() {
15✔
630
            0
×
631
        } else {
632
            unsafe { *bits.as_ref().get_unchecked(0) }
5✔
633
        };
634
        Self {
635
            bits,
636
            len,
637
            word_idx: 0,
638
            word,
639
        }
640
    }
641
}
642

643
impl<B: AsRef<[usize]>> Iterator for OnesIterator<'_, B> {
644
    type Item = usize;
645

646
    fn next(&mut self) -> Option<Self::Item> {
106✔
647
        // find the next word with ones
648
        while self.word == 0 {
115✔
649
            self.word_idx += 1;
13✔
650
            if self.word_idx == self.bits.as_ref().len() {
26✔
651
                return None;
4✔
652
            }
653
            self.word = unsafe { *self.bits.as_ref().get_unchecked(self.word_idx) };
×
654
        }
655
        // find the lowest bit set index in the word
656
        let bit_idx = self.word.trailing_zeros() as usize;
102✔
657
        // compute the global bit index
658
        let res = (self.word_idx * BITS) + bit_idx;
×
659
        if res >= self.len {
×
660
            None
1✔
661
        } else {
662
            // clear the lowest bit set
663
            self.word &= self.word - 1;
101✔
664
            Some(res)
×
665
        }
666
    }
667
}
668

669
/// An iterator over the positions of the zeros in a bit vector.
670
#[derive(Debug, Clone, MemDbg, MemSize)]
671
pub struct ZerosIterator<'a, B> {
672
    bits: &'a B,
673
    len: usize,
674
    word_idx: usize,
675
    /// This is a usize because BitVec is currently implemented only for `Vec<usize>` and `&[usize]`.
676
    word: usize,
677
}
678

679
impl<'a, B: AsRef<[usize]>> ZerosIterator<'a, B> {
680
    pub fn new(bits: &'a B, len: usize) -> Self {
5✔
681
        let word = if bits.as_ref().is_empty() {
15✔
682
            0
×
683
        } else {
684
            unsafe { !*bits.as_ref().get_unchecked(0) }
5✔
685
        };
686
        Self {
687
            bits,
688
            len,
689
            word_idx: 0,
690
            word,
691
        }
692
    }
693
}
694

695
impl<B: AsRef<[usize]>> Iterator for ZerosIterator<'_, B> {
696
    type Item = usize;
697

698
    fn next(&mut self) -> Option<Self::Item> {
106✔
699
        // find the next flipped word with zeros
700
        while self.word == 0 {
115✔
701
            self.word_idx += 1;
10✔
702
            if self.word_idx == self.bits.as_ref().len() {
20✔
703
                return None;
1✔
704
            }
705
            self.word = unsafe { !*self.bits.as_ref().get_unchecked(self.word_idx) };
×
706
        }
707
        // find the lowest zero bit index in the word
708
        let bit_idx = self.word.trailing_zeros() as usize;
105✔
709
        // compute the global bit index
710
        let res = (self.word_idx * BITS) + bit_idx;
×
711
        if res >= self.len {
×
712
            None
4✔
713
        } else {
714
            // clear the lowest bit set
715
            self.word &= self.word - 1;
101✔
716
            Some(res)
×
717
        }
718
    }
719
}
720

721
impl<B: AsRef<[usize]>> BitVec<B> {
722
    // Returns an iterator over the bits of the bit vector.
723
    #[inline(always)]
724
    pub fn iter(&self) -> BitIterator<'_, B> {
5✔
725
        self.into_iter()
10✔
726
    }
727

728
    // Returns an iterator over the positions of the ones in this bit vector.
729
    pub fn iter_ones(&self) -> OnesIterator<'_, B> {
5✔
730
        OnesIterator::new(&self.bits, self.len)
15✔
731
    }
732

733
    // Returns an iterator over the positions of the zeros in this bit vector.
734
    pub fn iter_zeros(&self) -> ZerosIterator<'_, B> {
5✔
735
        ZerosIterator::new(&self.bits, self.len)
15✔
736
    }
737
}
738

739
#[derive(Debug, Clone, MemDbg, MemSize)]
740
/// A thread-safe bit vector.
741
pub struct AtomicBitVec<B = Vec<AtomicUsize>> {
742
    bits: B,
743
    len: usize,
744
}
745

746
impl<B> AtomicBitVec<B> {
747
    /// Returns the number of bits in the bit vector.
748
    ///
749
    /// This method is equivalent to [`BitLength::len`], but it is provided to
750
    /// reduce ambiguity in method resolution.
751
    #[inline(always)]
752
    pub fn len(&self) -> usize {
77✔
753
        BitLength::len(self)
154✔
754
    }
755

756
    /// # Safety
757
    /// `len` must be between 0 (included) the number of
758
    /// bits in `bits` (included).
759
    #[inline(always)]
760
    pub unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
3✔
761
        Self { bits, len }
762
    }
763
    #[inline(always)]
764
    pub fn into_raw_parts(self) -> (B, usize) {
1✔
765
        (self.bits, self.len)
1✔
766
    }
767
}
768

769
impl<B: AsRef<[AtomicUsize]>> AtomicBitVec<B> {
770
    pub fn get(&self, index: usize, ordering: Ordering) -> bool {
64,368✔
771
        panic_if_out_of_bounds!(index, self.len);
193,104✔
772
        unsafe { self.get_unchecked(index, ordering) }
64,368✔
773
    }
774

775
    pub fn set(&self, index: usize, value: bool, ordering: Ordering) {
21,550✔
776
        panic_if_out_of_bounds!(index, self.len);
64,650✔
777
        unsafe { self.set_unchecked(index, value, ordering) }
21,550✔
778
    }
779

780
    pub fn swap(&self, index: usize, value: bool, ordering: Ordering) -> bool {
3✔
781
        panic_if_out_of_bounds!(index, self.len);
9✔
782
        unsafe { self.swap_unchecked(index, value, ordering) }
3✔
783
    }
784

785
    unsafe fn get_unchecked(&self, index: usize, ordering: Ordering) -> bool {
64,368✔
786
        let word_index = index / BITS;
128,736✔
787
        let bits = self.bits.as_ref();
193,104✔
788
        let word = unsafe { bits.get_unchecked(word_index).load(ordering) };
321,840✔
789
        (word >> (index % BITS)) & 1 != 0
64,368✔
790
    }
791
    #[inline(always)]
792
    unsafe fn set_unchecked(&self, index: usize, value: bool, ordering: Ordering) {
21,550✔
793
        let word_index = index / BITS;
43,100✔
794
        let bit_index = index % BITS;
43,100✔
795
        let bits = self.bits.as_ref();
64,650✔
796

797
        // For constant values, this should be inlined with no test.
798
        unsafe {
799
            if value {
37,850✔
800
                bits.get_unchecked(word_index)
48,900✔
801
                    .fetch_or(1 << bit_index, ordering);
32,600✔
802
            } else {
803
                bits.get_unchecked(word_index)
5,250✔
804
                    .fetch_and(!(1 << bit_index), ordering);
5,250✔
805
            }
806
        }
807
    }
808

809
    #[inline(always)]
810
    unsafe fn swap_unchecked(&self, index: usize, value: bool, ordering: Ordering) -> bool {
3✔
811
        let word_index = index / BITS;
6✔
812
        let bit_index = index % BITS;
6✔
813
        let bits = self.bits.as_ref();
9✔
814

815
        let old_word = unsafe {
816
            if value {
3✔
817
                bits.get_unchecked(word_index)
4✔
818
                    .fetch_or(1 << bit_index, ordering)
6✔
819
            } else {
820
                bits.get_unchecked(word_index)
1✔
821
                    .fetch_and(!(1 << bit_index), ordering)
×
822
            }
823
        };
824

825
        (old_word >> (bit_index)) & 1 != 0
3✔
826
    }
827

828
    /// Sets all bits to the given value.
829
    pub fn fill(&mut self, value: bool, ordering: Ordering) {
24✔
830
        let full_words = self.len() / BITS;
48✔
831
        let residual = self.len % BITS;
48✔
832
        let bits = self.bits.as_ref();
72✔
833
        let word_value = if value { !0 } else { 0 };
72✔
834
        // Just to be sure, add a fence to ensure that we will see all the final
835
        // values
836
        core::sync::atomic::fence(Ordering::SeqCst);
48✔
837
        bits[..full_words]
24✔
838
            .iter()
839
            .for_each(|x| x.store(word_value, ordering));
276✔
840
        if residual != 0 {
39✔
841
            let mask = (1 << residual) - 1;
45✔
842
            bits[full_words].store(
45✔
843
                (bits[full_words].load(ordering) & !mask) | (word_value & mask),
60✔
844
                ordering,
15✔
845
            );
846
        }
847
    }
848

849
    /// Sets all bits to the given value using a parallel implementation.
850
    #[cfg(feature = "rayon")]
851
    pub fn par_fill(&mut self, value: bool, ordering: Ordering) {
16✔
852
        let full_words = self.len() / BITS;
32✔
853
        let residual = self.len % BITS;
32✔
854
        let bits = self.bits.as_ref();
48✔
855
        let word_value = if value { !0 } else { 0 };
48✔
856

857
        // Just to be sure, add a fence to ensure that we will see all the final
858
        // values
859
        core::sync::atomic::fence(Ordering::SeqCst);
32✔
860
        bits[..full_words]
16✔
861
            .par_iter()
862
            .with_min_len(RAYON_MIN_LEN)
16✔
863
            .for_each(|x| x.store(word_value, ordering));
184✔
864
        if residual != 0 {
26✔
865
            let mask = (1 << residual) - 1;
30✔
866
            bits[full_words].store(
30✔
867
                (bits[full_words].load(ordering) & !mask) | (word_value & mask),
40✔
868
                ordering,
10✔
869
            );
870
        }
871
    }
872

873
    /// Sets all bits to zero.
874
    pub fn reset(&mut self, ordering: Ordering) {
×
875
        self.fill(false, ordering);
×
876
    }
877

878
    /// Sets all bits to zero using a parallel implementation.
879
    #[cfg(feature = "rayon")]
880
    pub fn par_reset(&mut self, ordering: Ordering) {
×
881
        self.par_fill(false, ordering);
×
882
    }
883

884
    /// Flip all bits.
885
    pub fn flip(&mut self, ordering: Ordering) {
16✔
886
        let full_words = self.len() / BITS;
32✔
887
        let residual = self.len % BITS;
32✔
888
        let bits = self.bits.as_ref();
48✔
889
        // Just to be sure, add a fence to ensure that we will see all the final
890
        // values
891
        core::sync::atomic::fence(Ordering::SeqCst);
32✔
892
        bits[..full_words]
16✔
893
            .iter()
894
            .for_each(|x| _ = x.fetch_xor(!0, ordering));
142✔
895
        if residual != 0 {
26✔
896
            let mask = (1 << residual) - 1;
30✔
897
            let last_word = bits[full_words].load(ordering);
50✔
898
            bits[full_words].store((last_word & !mask) | (!last_word & mask), ordering);
40✔
899
        }
900
    }
901

902
    /// Flip all bits using a parallel implementation.
903
    #[cfg(feature = "rayon")]
904
    pub fn par_flip(&mut self, ordering: Ordering) {
16✔
905
        let full_words = self.len() / BITS;
32✔
906
        let residual = self.len % BITS;
32✔
907
        let bits = self.bits.as_ref();
48✔
908
        // Just to be sure, add a fence to ensure that we will see all the final
909
        // values
910
        core::sync::atomic::fence(Ordering::SeqCst);
32✔
911
        bits[..full_words]
16✔
912
            .par_iter()
913
            .with_min_len(RAYON_MIN_LEN)
16✔
914
            .for_each(|x| _ = x.fetch_xor(!0, ordering));
142✔
915
        if residual != 0 {
26✔
916
            let mask = (1 << residual) - 1;
30✔
917
            let last_word = bits[full_words].load(ordering);
50✔
918
            bits[full_words].store((last_word & !mask) | (!last_word & mask), ordering);
40✔
919
        }
920
    }
921

922
    /// A parallel version of [`BitVec::count_ones`].
923
    #[cfg(feature = "rayon")]
924
    pub fn par_count_ones(&self) -> usize {
×
925
        let full_words = self.len() / BITS;
×
926
        let residual = self.len() % BITS;
×
927
        let bits = self.bits.as_ref();
×
928
        let mut num_ones;
×
929
        // Just to be sure, add a fence to ensure that we will see all the final
930
        // values
931
        core::sync::atomic::fence(Ordering::SeqCst);
×
932
        num_ones = bits[..full_words]
×
933
            .par_iter()
×
934
            .with_min_len(RAYON_MIN_LEN)
×
935
            .map(|x| x.load(Ordering::Relaxed).count_ones() as usize)
×
936
            .sum();
×
937
        if residual != 0 {
×
938
            num_ones += (bits[full_words].load(Ordering::Relaxed) << (BITS - residual)).count_ones()
×
939
                as usize
×
940
        }
941
        num_ones
×
942
    }
943
}
944

945
impl AtomicBitVec<Vec<AtomicUsize>> {
946
    /// Creates a new atomic bit vector of length `len` initialized to `false`.
947
    pub fn new(len: usize) -> Self {
115✔
948
        Self::with_value(len, false)
230✔
949
    }
950

951
    /// Creates a new atomic bit vector of length `len` initialized to `value`.
952
    pub fn with_value(len: usize, value: bool) -> Self {
120✔
953
        let n_of_words = len.div_ceil(BITS);
360✔
954
        let extra_bits = (n_of_words * BITS) - len;
240✔
955
        let word_value = if value { !0 } else { 0 };
360✔
956
        let mut bits = (0..n_of_words)
240✔
957
            .map(|_| AtomicUsize::new(word_value))
1,260✔
958
            .collect::<Vec<_>>();
959
        if extra_bits > 0 {
210✔
960
            let last_word_value = word_value >> extra_bits;
270✔
961
            bits[n_of_words - 1] = AtomicUsize::new(last_word_value);
180✔
962
        }
963
        Self { bits, len }
964
    }
965
}
966

967
impl<B> BitLength for AtomicBitVec<B> {
968
    #[inline(always)]
969
    fn len(&self) -> usize {
77✔
970
        self.len
77✔
971
    }
972
}
973

974
impl<B: AsRef<[AtomicUsize]>> Index<usize> for AtomicBitVec<B> {
975
    type Output = bool;
976

977
    /// Shorthand for [`Self::get`] using [`Ordering::Relaxed`].
978
    fn index(&self, index: usize) -> &Self::Output {
10,000✔
979
        match self.get(index, Ordering::Relaxed) {
30,000✔
980
            false => &false,
9,500✔
981
            true => &true,
500✔
982
        }
983
    }
984
}
985

986
impl<B: AsRef<[AtomicUsize]>> BitCount for AtomicBitVec<B> {
987
    fn count_ones(&self) -> usize {
3✔
988
        let full_words = self.len() / BITS;
6✔
989
        let residual = self.len() % BITS;
6✔
990
        let bits = self.bits.as_ref();
9✔
991
        let mut num_ones;
×
992
        // Just to be sure, add a fence to ensure that we will see all the final
993
        // values
994
        core::sync::atomic::fence(Ordering::SeqCst);
6✔
995
        num_ones = bits[..full_words]
3✔
996
            .iter()
3✔
997
            .map(|x| x.load(Ordering::Relaxed).count_ones() as usize)
63✔
998
            .sum();
3✔
999
        if residual != 0 {
3✔
1000
            num_ones += (bits[full_words].load(Ordering::Relaxed) << (BITS - residual)).count_ones()
6✔
1001
                as usize
2✔
1002
        }
1003
        num_ones
3✔
1004
    }
1005
}
1006

1007
// Conversions
1008

1009
impl<W: IntoAtomic> From<BitVec<Vec<W>>> for AtomicBitVec<Vec<W::AtomicType>> {
1010
    fn from(value: BitVec<Vec<W>>) -> Self {
2✔
1011
        AtomicBitVec {
1012
            bits: transmute_vec_into_atomic(value.bits),
4✔
1013
            len: value.len,
2✔
1014
        }
1015
    }
1016
}
1017

1018
impl<'a, W: IntoAtomic> TryFrom<BitVec<&'a [W]>> for AtomicBitVec<&'a [W::AtomicType]> {
1019
    type Error = CannotCastToAtomicError<W>;
1020
    fn try_from(value: BitVec<&'a [W]>) -> Result<Self, Self::Error> {
1✔
1021
        if core::mem::align_of::<W>() != core::mem::align_of::<W::AtomicType>() {
1✔
1022
            return Err(CannotCastToAtomicError::default());
×
1023
        }
1024
        Ok(AtomicBitVec {
×
1025
            bits: unsafe { core::mem::transmute::<&'a [W], &'a [W::AtomicType]>(value.bits) },
×
1026
            len: value.len,
×
1027
        })
1028
    }
1029
}
1030

1031
impl<'a, W: IntoAtomic> TryFrom<BitVec<&'a mut [W]>> for AtomicBitVec<&'a mut [W::AtomicType]> {
1032
    type Error = CannotCastToAtomicError<W>;
1033
    fn try_from(value: BitVec<&'a mut [W]>) -> Result<Self, Self::Error> {
1✔
1034
        if core::mem::align_of::<W>() != core::mem::align_of::<W::AtomicType>() {
1✔
1035
            return Err(CannotCastToAtomicError::default());
×
1036
        }
1037
        Ok(AtomicBitVec {
×
1038
            bits: unsafe {
×
1039
                core::mem::transmute::<&'a mut [W], &'a mut [W::AtomicType]>(value.bits)
×
1040
            },
1041
            len: value.len,
×
1042
        })
1043
    }
1044
}
1045

1046
impl<W: IntoAtomic> From<AtomicBitVec<Vec<W::AtomicType>>> for BitVec<Vec<W>> {
1047
    fn from(value: AtomicBitVec<Vec<W::AtomicType>>) -> Self {
30✔
1048
        BitVec {
1049
            bits: transmute_vec_from_atomic::<W::AtomicType>(value.bits),
60✔
1050
            len: value.len,
30✔
1051
        }
1052
    }
1053
}
1054

1055
impl<W: IntoAtomic> From<AtomicBitVec<Box<[W::AtomicType]>>> for BitVec<Box<[W]>> {
1056
    fn from(value: AtomicBitVec<Box<[W::AtomicType]>>) -> Self {
1✔
1057
        BitVec {
1058
            bits: transmute_boxed_slice_from_atomic::<W::AtomicType>(value.bits),
2✔
1059
            len: value.len,
1✔
1060
        }
1061
    }
1062
}
1063

1064
impl<W: IntoAtomic + Copy> From<BitVec<Box<[W]>>> for AtomicBitVec<Box<[W::AtomicType]>> {
1065
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
1066
        AtomicBitVec {
1067
            bits: transmute_boxed_slice_into_atomic::<W>(value.bits),
2✔
1068
            len: value.len,
1✔
1069
        }
1070
    }
1071
}
1072

1073
impl<'a, W: IntoAtomic> From<AtomicBitVec<&'a [W::AtomicType]>> for BitVec<&'a [W]> {
1074
    fn from(value: AtomicBitVec<&'a [W::AtomicType]>) -> Self {
1✔
1075
        BitVec {
1076
            bits: unsafe { core::mem::transmute::<&'a [W::AtomicType], &'a [W]>(value.bits) },
1✔
1077
            len: value.len,
1✔
1078
        }
1079
    }
1080
}
1081

1082
impl<'a, W: IntoAtomic> From<AtomicBitVec<&'a mut [W::AtomicType]>> for BitVec<&'a mut [W]> {
1083
    fn from(value: AtomicBitVec<&'a mut [W::AtomicType]>) -> Self {
1✔
1084
        BitVec {
1085
            bits: unsafe {
1✔
1086
                core::mem::transmute::<&'a mut [W::AtomicType], &'a mut [W]>(value.bits)
1087
            },
1088
            len: value.len,
1✔
1089
        }
1090
    }
1091
}
1092

1093
impl<W> From<BitVec<Vec<W>>> for BitVec<Box<[W]>> {
1094
    fn from(value: BitVec<Vec<W>>) -> Self {
96✔
1095
        BitVec {
1096
            bits: value.bits.into_boxed_slice(),
192✔
1097
            len: value.len,
96✔
1098
        }
1099
    }
1100
}
1101

1102
impl<W> From<BitVec<Box<[W]>>> for BitVec<Vec<W>> {
1103
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
1104
        BitVec {
1105
            bits: value.bits.into_vec(),
2✔
1106
            len: value.len,
1✔
1107
        }
1108
    }
1109
}
1110

1111
impl<W, B: AsRef<[W]>> AsRef<[W]> for BitVec<B> {
1112
    #[inline(always)]
1113
    fn as_ref(&self) -> &[W] {
2,147,483,647✔
1114
        self.bits.as_ref()
2,147,483,647✔
1115
    }
1116
}
1117

1118
impl<W, B: AsMut<[W]>> AsMut<[W]> for BitVec<B> {
1119
    #[inline(always)]
1120
    fn as_mut(&mut self) -> &mut [W] {
×
1121
        self.bits.as_mut()
×
1122
    }
1123
}
1124

1125
impl<W, B: AsRef<[W]>> AsRef<[W]> for AtomicBitVec<B> {
1126
    #[inline(always)]
1127
    fn as_ref(&self) -> &[W] {
10✔
1128
        self.bits.as_ref()
10✔
1129
    }
1130
}
1131
// An iterator over the bits of this atomic bit vector as booleans.
1132
#[derive(Debug, MemDbg, MemSize)]
1133
pub struct AtomicBitIterator<'a, B> {
1134
    bits: &'a mut B,
1135
    len: usize,
1136
    next_bit_pos: usize,
1137
}
1138

1139
// We implement [`IntoIterator`] for a mutable reference so no
1140
// outstanding references are allowed while iterating.
1141
impl<'a, B: AsRef<[AtomicUsize]>> IntoIterator for &'a mut AtomicBitVec<B> {
1142
    type IntoIter = AtomicBitIterator<'a, B>;
1143
    type Item = bool;
1144

1145
    fn into_iter(self) -> Self::IntoIter {
1✔
1146
        AtomicBitIterator {
1147
            bits: &mut self.bits,
1✔
1148
            len: self.len,
1✔
1149
            next_bit_pos: 0,
1150
        }
1151
    }
1152
}
1153

1154
impl<B: AsRef<[AtomicUsize]>> Iterator for AtomicBitIterator<'_, B> {
1155
    type Item = bool;
1156
    fn next(&mut self) -> Option<bool> {
101✔
1157
        if self.next_bit_pos == self.len {
101✔
1158
            return None;
1✔
1159
        }
1160
        let word_idx = self.next_bit_pos / BITS;
×
1161
        let bit_idx = self.next_bit_pos % BITS;
×
1162
        let word = unsafe {
1163
            self.bits
×
1164
                .as_ref()
1165
                .get_unchecked(word_idx)
×
1166
                .load(Ordering::Relaxed)
×
1167
        };
1168
        let bit = (word >> bit_idx) & 1;
×
1169
        self.next_bit_pos += 1;
×
1170
        Some(bit != 0)
×
1171
    }
1172
}
1173

1174
impl<B: AsRef<[AtomicUsize]>> AtomicBitVec<B> {
1175
    // Returns an iterator over the bits of the bit vector.
1176
    //
1177
    // Note that this method takes a mutable reference to the bit vector,
1178
    // so no outstanding references are allowed while iterating.
1179
    #[inline(always)]
1180
    pub fn iter(&mut self) -> AtomicBitIterator<'_, B> {
1✔
1181
        self.into_iter()
2✔
1182
    }
1183
}
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