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

vigna / sux-rs / 17841719366

18 Sep 2025 09:21PM UTC coverage: 64.717% (-2.2%) from 66.912%
17841719366

push

github

vigna
Completed delegations for custom iterators; fixed infinite recursion when delegating traits to MemCase

0 of 7 new or added lines in 3 files covered. (0.0%)

909 existing lines in 21 files now uncovered.

3674 of 5677 relevant lines covered (64.72%)

117564551.11 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 epserde::*;
76
use mem_dbg::*;
77
#[cfg(feature = "rayon")]
78
use rayon::prelude::*;
79
use std::{
80
    ops::Index,
81
    sync::atomic::{AtomicUsize, Ordering},
82
};
83

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

UNCOV
355
        num_ones
×
356
    }
357
}
358

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

UNCOV
560
        let residual = len % BITS;
×
561

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1006
// Conversions
1007

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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