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

vigna / sux-rs / 22807509805

07 Mar 2026 09:22PM UTC coverage: 77.85% (-1.0%) from 78.892%
22807509805

push

github

vigna
Fixed num-primitive version at 0.2.1

5170 of 6641 relevant lines covered (77.85%)

113353952.31 hits per line

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

86.92
/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, and presently we provide:
20
//!
21
//! - `BitVec<Vec<usize>>`: a mutable, growable and resizable bit vector;
22
//! - `BitVec<AsRef<[usize]>>`: an immutable bit vector, useful for
23
//!   [ε-serde](https://crates.io/crates/epserde) support;
24
//! - `BitVec<AsRef<[usize]> + AsMut<[usize]>>`: a mutable (but not resizable)
25
//!   bit vector;
26
//! - `AtomicBitVec<AsRef<[AtomicUsize]>>`: a thread-safe, mutable (but not
27
//!   resizable) bit vector.
28
//!
29
//! Note that nothing is assumed about the content of the backend outside the
30
//! bits of the bit vector. Moreover, the content of the backend outside of
31
//! the bit vector is never modified by the methods of this structure.
32
//!
33
//! It is possible to juggle between all flavors using [`From`]/[`Into`], and
34
//! with [`TryFrom`]/[`TryInto`] when going [from a non-atomic to an atomic bit
35
//! vector](BitVec#impl-TryFrom%3CBitVec%3C%26%5BW%5D%3E%3E-for-AtomicBitVec%3C%26%5B%3CW+as+AtomicPrimitive%3E::Atomic%5D%3E).
36
//!
37
//! # Examples
38
//!
39
//! ```rust
40
//! use sux::prelude::*;
41
//! use sux::traits::bit_vec_ops::*;
42
//! use std::sync::atomic::Ordering;
43
//!
44
//! // Convenience macro
45
//! let b = bit_vec![0, 1, 0, 1, 1, 0, 1, 0];
46
//! assert_eq!(b.len(), 8);
47
//! // Not constant time
48
//! assert_eq!(b.count_ones(), 4);
49
//! assert_eq!(b[0], false);
50
//! assert_eq!(b[1], true);
51
//! assert_eq!(b[2], false);
52
//!
53
//! let b: AddNumBits<_> = b.into();
54
//! // Constant time, but now b is immutable
55
//! assert_eq!(b.num_ones(), 4);
56
//!
57
//! let mut b = BitVec::new(0);
58
//! b.push(true);
59
//! b.push(false);
60
//! b.push(true);
61
//! assert_eq!(b.len(), 3);
62
//!
63
//! // Let's make it atomic
64
//! let mut a: AtomicBitVec = b.into();
65
//! a.set(1, true, Ordering::Relaxed);
66
//! assert!(a.get(0, Ordering::Relaxed));
67
//!
68
//! // Back to normal, but immutable size
69
//! let b: BitVec<Vec<usize>> = a.into();
70
//! let mut b: BitVec<Box<[usize]>> = b.into();
71
//! b.set(2, false);
72
//!
73
//! // If we create an artificially dirty bit vector, everything still works.
74
//! let ones = [usize::MAX; 2];
75
//! assert_eq!(unsafe { BitVec::from_raw_parts(ones, 1) }.count_ones(), 1);
76
//! ```
77

78
use crate::traits::{AtomicBitIter, AtomicBitVecOps, BitIter, BitVecOps};
79
use crate::utils::SelectInWord;
80
use atomic_primitive::AtomicPrimitive;
81
#[allow(unused_imports)] // this is in the std prelude but not in no_std!
82
use core::borrow::BorrowMut;
83
use core::fmt;
84
use mem_dbg::*;
85
use std::{
86
    ops::Index,
87
    sync::atomic::{AtomicUsize, Ordering},
88
};
89

90
use crate::{
91
    traits::{BITS, rank_sel::*},
92
    utils::{
93
        CannotCastToAtomicError, transmute_boxed_slice_from_atomic,
94
        transmute_boxed_slice_into_atomic, transmute_vec_from_atomic, transmute_vec_into_atomic,
95
    },
96
};
97

98
/// A bit vector.
99
///
100
/// Instances can be created using [`new`](BitVec::new),
101
/// [`with_value`](BitVec::with_value), with the convenience macro
102
/// [`bit_vec!`](macro@crate::bits::bit_vec), or with a [`FromIterator`
103
/// implementation](#impl-FromIterator<bool>-for-BitVec).
104
///
105
/// See the [module documentation](mod@crate::bits::bit_vec) for more details.
106
#[derive(Debug, Clone, Copy, MemDbg, MemSize)]
107
#[cfg_attr(feature = "epserde", derive(epserde::Epserde))]
108
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
109
pub struct BitVec<B = Vec<usize>> {
110
    bits: B,
111
    len: usize,
112
}
113

114
/// Convenient, [`vec!`](vec!)-like macro to initialize bit vectors.
115
///
116
/// - `bit_vec![]` creates an empty bit vector.
117
///
118
/// - `bit_vec![false; n]` or `bit_vec![0; n]` creates a bit vector of length
119
///   `n` with all bits set to `false`.
120
///
121
/// - `bit_vec![true; n]` or `bit_vec![1; n]` creates a bit vector of length `n`
122
///   with all bits set to `true`.
123
///
124
/// - `bit_vec![b₀, b₁, b₂, …]` creates a bit vector with the specified bits,
125
///   where each `bᵢ` can be any expression that evaluates to a boolean or integer
126
///   (0 for `false`, non-zero for `true`).
127
///
128
/// # Examples
129
///
130
/// ```rust
131
/// use sux::prelude::*;
132
/// use sux::traits::BitVecOps;
133
///
134
/// // Empty bit vector
135
/// let b = bit_vec![];
136
/// assert_eq!(b.len(), 0);
137
///
138
/// // 10 bits set to true
139
/// let b = bit_vec![true; 10];
140
/// assert_eq!(b.len(), 10);
141
/// assert_eq!(b.iter().all(|x| x), true);
142
/// let b = bit_vec![1; 10];
143
/// assert_eq!(b.len(), 10);
144
/// assert_eq!(b.iter().all(|x| x), true);
145
///
146
/// // 10 bits set to false
147
/// let b = bit_vec![false; 10];
148
/// assert_eq!(b.len(), 10);
149
/// assert_eq!(b.iter().any(|x| x), false);
150
/// let b = bit_vec![0; 10];
151
/// assert_eq!(b.len(), 10);
152
/// assert_eq!(b.iter().any(|x| x), false);
153
///
154
/// // Bit list
155
/// let b = bit_vec![0, 1, 0, 1, 0, 0];
156
/// assert_eq!(b.len(), 6);
157
/// assert_eq!(b[0], false);
158
/// assert_eq!(b[1], true);
159
/// assert_eq!(b[2], false);
160
/// assert_eq!(b[3], true);
161
/// assert_eq!(b[4], false);
162
/// assert_eq!(b[5], false);
163
/// ```
164
#[macro_export]
165
macro_rules! bit_vec {
166
    () => {
167
        $crate::bits::BitVec::new(0)
168
    };
169
    (false; $n:expr) => {
170
        $crate::bits::BitVec::new($n)
171
    };
172
    (0; $n:expr) => {
173
        $crate::bits::BitVec::new($n)
174
    };
175
    (true; $n:expr) => {
176
        {
177
            $crate::bits::BitVec::with_value($n, true)
178
        }
179
    };
180
    (1; $n:expr) => {
181
        {
182
            $crate::bits::BitVec::with_value($n, true)
183
        }
184
    };
185
    ($($x:expr),+ $(,)?) => {
186
        {
187
            let mut b = $crate::bits::BitVec::with_capacity([$($x),+].len());
188
            $( b.push($x != 0); )*
189
            b
190
        }
191
    };
192
}
193

194
impl<B> BitVec<B> {
195
    /// Returns the number of bits in the bit vector.
196
    ///
197
    /// This method is equivalent to [`BitLength::len`], but it is provided to
198
    /// reduce ambiguity in method resolution.
199
    #[inline(always)]
200
    pub const fn len(&self) -> usize {
258,892✔
201
        self.len
258,892✔
202
    }
203

204
    /// # Safety
205
    /// `len` must be between 0 (included) and the number of
206
    /// bits in `bits` (included).
207
    #[inline(always)]
208
    pub const unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
24✔
209
        Self { bits, len }
210
    }
211

212
    #[inline(always)]
213
    pub fn into_raw_parts(self) -> (B, usize) {
2✔
214
        (self.bits, self.len)
2✔
215
    }
216

217
    #[inline(always)]
218
    /// Modify the bit vector in place.
219
    ///
220
    ///
221
    /// # Safety
222
    /// This is unsafe because it's the caller's responsibility to ensure that
223
    /// that the length is compatible with the modified bits.
224
    pub unsafe fn map<B2>(self, f: impl FnOnce(B) -> B2) -> BitVec<B2> {
×
225
        BitVec {
226
            bits: f(self.bits),
×
227
            len: self.len,
×
228
        }
229
    }
230
}
231

232
impl BitVec<Vec<usize>> {
233
    /// Creates a new bit vector of length `len` initialized to `false`.
234
    pub fn new(len: usize) -> Self {
126,012✔
235
        Self::with_value(len, false)
252,024✔
236
    }
237

238
    /// Creates a new bit vector of length `len` initialized to `value`.
239
    pub fn with_value(len: usize, value: bool) -> Self {
126,893✔
240
        let n_of_words = len.div_ceil(BITS);
380,679✔
241
        let extra_bits = (n_of_words * BITS) - len;
253,786✔
242
        let word_value = if value { !0 } else { 0 };
380,679✔
243
        let mut bits = vec![word_value; n_of_words];
507,572✔
244
        if extra_bits > 0 {
129,040✔
245
            let last_word_value = word_value >> extra_bits;
6,441✔
246
            bits[n_of_words - 1] = last_word_value;
2,147✔
247
        }
248
        Self { bits, len }
249
    }
250

251
    /// Creates a new zero-length bit vector of given capacity.
252
    ///
253
    /// Note that the capacity will be rounded up to a multiple of the word
254
    /// size.
255
    pub fn with_capacity(capacity: usize) -> Self {
60✔
256
        let n_of_words = capacity.div_ceil(BITS);
180✔
257
        Self {
258
            bits: Vec::with_capacity(n_of_words),
60✔
259
            len: 0,
260
        }
261
    }
262

263
    /// Returns the current capacity of this bit vector.
264
    pub fn capacity(&self) -> usize {
96✔
265
        self.bits.capacity() * BITS
96✔
266
    }
267

268
    /// Appends a bit to the end of this bit vector.
269
    pub fn push(&mut self, b: bool) {
2,147,483,647✔
270
        if self.bits.len() * BITS == self.len {
2,147,483,647✔
271
            self.bits.push(0);
48,594,684✔
272
        }
273
        let word_index = self.len / BITS;
2,147,483,647✔
274
        let bit_index = self.len % BITS;
2,147,483,647✔
275
        // Clear bit
276
        self.bits[word_index] &= !(1 << bit_index);
2,147,483,647✔
277
        // Set bit
278
        self.bits[word_index] |= (b as usize) << bit_index;
2,147,483,647✔
279
        self.len += 1;
2,147,483,647✔
280
    }
281

282
    /// Removes the last bit from the bit vector and returns it, or `None` if it
283
    /// is empty.
284
    pub fn pop(&mut self) -> Option<bool> {
1,206✔
285
        if self.len == 0 {
1,206✔
286
            return None;
6✔
287
        }
288
        let last_pos = self.len - 1;
2,400✔
289
        let result = unsafe { self.get_unchecked(last_pos) };
4,800✔
290
        self.len = last_pos;
1,200✔
291
        Some(result)
1,200✔
292
    }
293

294
    /// Resizes the bit vector in place, extending it with `value` if it is
295
    /// necessary.
296
    pub fn resize(&mut self, new_len: usize, value: bool) {
12✔
297
        if new_len > self.len {
12✔
298
            let old_len = self.len;
12✔
299
            let old_word = old_len / BITS;
12✔
300
            let old_bit = old_len % BITS;
12✔
301
            let word_value = if value { !0usize } else { 0 };
18✔
302

303
            self.bits.resize(new_len.div_ceil(BITS), word_value);
30✔
304

305
            // Handle the partial word at old_len, then fill all
306
            // remaining words (which may contain stale data from
307
            // previous truncations).
308
            if old_bit != 0 {
6✔
309
                let mask = !0usize << old_bit;
×
310
                self.bits[old_word] = (self.bits[old_word] & !mask) | (word_value & mask);
×
311
                self.bits[old_word + 1..].fill(word_value);
×
312
            } else {
313
                self.bits[old_word..].fill(word_value);
12✔
314
            }
315
        }
316
        self.len = new_len;
12✔
317
    }
318
}
319

320
impl<B: AsRef<[usize]>> BitVec<B> {
321
    /// Returns an owned copy of the bit vector.
322
    pub fn to_owned(&self) -> BitVec {
×
323
        BitVec {
324
            bits: self.bits.as_ref().to_owned(),
×
325
            len: self.len,
×
326
        }
327
    }
328
}
329

330
impl<B> BitLength for BitVec<B> {
331
    #[inline(always)]
332
    fn len(&self) -> usize {
2,147,483,647✔
333
        self.len
2,147,483,647✔
334
    }
335
}
336

337
impl<B: AsRef<[usize]>> BitCount for BitVec<B> {
338
    fn count_ones(&self) -> usize {
123,302✔
339
        let full_words = self.len() / BITS;
246,604✔
340
        let residual = self.len() % BITS;
246,604✔
341
        let bits = self.as_ref();
369,906✔
342
        let mut num_ones = bits[..full_words]
246,604✔
343
            .iter()
344
            .map(|x| x.count_ones() as usize)
723,360,442✔
345
            .sum();
346
        if residual != 0 {
123,302✔
347
            num_ones += (self.as_ref()[full_words] << (BITS - residual)).count_ones() as usize
221,018✔
348
        }
349
        num_ones
123,302✔
350
    }
351
}
352

353
impl<B: AsRef<[usize]>, C: AsRef<[usize]>> PartialEq<BitVec<C>> for BitVec<B> {
354
    fn eq(&self, other: &BitVec<C>) -> bool {
70✔
355
        let len = self.len();
210✔
356
        if len != other.len() {
140✔
357
            return false;
1✔
358
        }
359

360
        let full_words = len / BITS;
138✔
361
        if self.as_ref()[..full_words] != other.as_ref()[..full_words] {
138✔
362
            return false;
×
363
        }
364

365
        let residual = len % BITS;
138✔
366

367
        residual == 0
69✔
368
            || (self.as_ref()[full_words] ^ other.as_ref()[full_words]) << (BITS - residual) == 0
268✔
369
    }
370
}
371

372
impl<B: AsRef<[usize]>> Eq for BitVec<B> {}
373

374
impl<B: AsRef<[usize]>> Index<usize> for BitVec<B> {
375
    type Output = bool;
376

377
    fn index(&self, index: usize) -> &Self::Output {
325,894,040✔
378
        match self.get(index) {
651,788,080✔
379
            false => &false,
172,749,348✔
380
            true => &true,
153,144,692✔
381
        }
382
    }
383
}
384

385
impl Extend<bool> for BitVec<Vec<usize>> {
386
    fn extend<T>(&mut self, i: T)
20,582✔
387
    where
388
        T: IntoIterator<Item = bool>,
389
    {
390
        for b in i {
1,035,509,862✔
391
            self.push(b);
1,035,489,280✔
392
        }
393
    }
394
}
395

396
impl FromIterator<bool> for BitVec<Vec<usize>> {
397
    fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
20,582✔
398
        let mut res = Self::new(0);
41,164✔
399
        res.extend(iter);
61,746✔
400
        res
20,582✔
401
    }
402
}
403

404
impl<'a, B: AsRef<[usize]>> IntoIterator for &'a BitVec<B> {
405
    type IntoIter = BitIter<'a, B>;
406
    type Item = bool;
407

408
    fn into_iter(self) -> Self::IntoIter {
6,794✔
409
        BitIter::new(&self.bits, self.len())
27,176✔
410
    }
411
}
412

413
impl<B: AsRef<[usize]>> fmt::Display for BitVec<B> {
414
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
×
415
        write!(f, "[")?;
×
416
        for b in self {
×
417
            write!(f, "{:b}", b as usize)?;
×
418
        }
419
        write!(f, "]")?;
×
420
        Ok(())
×
421
    }
422
}
423

424
#[derive(Debug, Clone, MemDbg, MemSize)]
425
/// A thread-safe bit vector.
426
///
427
/// See the [module documentation](mod@crate::bits::bit_vec) for details.
428
pub struct AtomicBitVec<B = Box<[AtomicUsize]>> {
429
    bits: B,
430
    len: usize,
431
}
432

433
impl<B> AtomicBitVec<B> {
434
    /// Returns the number of bits in the bit vector.
435
    ///
436
    /// This method is equivalent to [`BitLength::len`], but it is provided to
437
    /// reduce ambiguity in method resolution.
438
    #[inline(always)]
439
    pub const fn len(&self) -> usize {
6✔
440
        self.len
6✔
441
    }
442

443
    /// # Safety
444
    /// `len` must be between 0 (included) and the number of
445
    /// bits in `bits` (included).
446
    #[inline(always)]
447
    pub const unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
3✔
448
        Self { bits, len }
449
    }
450
    #[inline(always)]
451
    pub fn into_raw_parts(self) -> (B, usize) {
1✔
452
        (self.bits, self.len)
1✔
453
    }
454
}
455

456
impl AtomicBitVec<Box<[AtomicUsize]>> {
457
    /// Creates a new atomic bit vector of length `len` initialized to `false`.
458
    pub fn new(len: usize) -> Self {
138✔
459
        Self::with_value(len, false)
276✔
460
    }
461

462
    /// Creates a new atomic bit vector of length `len` initialized to `value`.
463
    pub fn with_value(len: usize, value: bool) -> Self {
144✔
464
        let n_of_words = len.div_ceil(BITS);
432✔
465
        let extra_bits = (n_of_words * BITS) - len;
288✔
466
        let word_value = if value { !0 } else { 0 };
432✔
467
        let mut bits = (0..n_of_words)
288✔
468
            .map(|_| AtomicUsize::new(word_value))
1,512✔
469
            .collect::<Vec<_>>()
470
            .into_boxed_slice();
471
        if extra_bits > 0 {
252✔
472
            let last_word_value = word_value >> extra_bits;
324✔
473
            bits[n_of_words - 1] = AtomicUsize::new(last_word_value);
216✔
474
        }
475
        Self { bits, len }
476
    }
477
}
478

479
impl<B> BitLength for AtomicBitVec<B> {
480
    #[inline(always)]
481
    fn len(&self) -> usize {
90,375✔
482
        self.len
90,375✔
483
    }
484
}
485

486
impl<B: AsRef<[AtomicUsize]>> BitCount for AtomicBitVec<B> {
487
    fn count_ones(&self) -> usize {
3✔
488
        let full_words = self.len() / BITS;
6✔
489
        let residual = self.len() % BITS;
6✔
490
        let bits = self.as_ref();
9✔
491
        let mut num_ones;
×
492
        // Just to be sure, add a fence to ensure that we will see all the final
493
        // values
494
        core::sync::atomic::fence(Ordering::SeqCst);
6✔
495
        num_ones = bits[..full_words]
3✔
496
            .iter()
3✔
497
            .map(|x| x.load(Ordering::Relaxed).count_ones() as usize)
63✔
498
            .sum();
3✔
499
        if residual != 0 {
3✔
500
            num_ones += (bits[full_words].load(Ordering::Relaxed) << (BITS - residual)).count_ones()
6✔
501
                as usize
2✔
502
        }
503
        num_ones
3✔
504
    }
505
}
506

507
impl<B: AsRef<[AtomicUsize]>> Index<usize> for AtomicBitVec<B> {
508
    type Output = bool;
509

510
    /// Shorthand for `get` using [`Ordering::Relaxed`].
511
    fn index(&self, index: usize) -> &Self::Output {
10,000✔
512
        match self.get(index, Ordering::Relaxed) {
30,000✔
513
            false => &false,
9,500✔
514
            true => &true,
500✔
515
        }
516
    }
517
}
518

519
impl<'a, B: AsRef<[AtomicUsize]>> IntoIterator for &'a AtomicBitVec<B> {
520
    type IntoIter = AtomicBitIter<'a, B>;
521
    type Item = bool;
522

523
    fn into_iter(self) -> Self::IntoIter {
×
524
        AtomicBitIter::new(&self.bits, self.len())
×
525
    }
526
}
527

528
// Conversions
529

530
/// This conversion may fail if the alignment of `W` is not the same as
531
/// that of `W::Atomic`.
532
impl<'a, W: AtomicPrimitive> TryFrom<BitVec<&'a [W]>> for AtomicBitVec<&'a [W::Atomic]> {
533
    type Error = CannotCastToAtomicError<W>;
534
    fn try_from(value: BitVec<&'a [W]>) -> Result<Self, Self::Error> {
1✔
535
        if core::mem::align_of::<W>() != core::mem::align_of::<W::Atomic>() {
1✔
536
            return Err(CannotCastToAtomicError::default());
×
537
        }
538
        Ok(AtomicBitVec {
1✔
539
            bits: unsafe { core::mem::transmute::<&'a [W], &'a [W::Atomic]>(value.bits) },
1✔
540
            len: value.len,
1✔
541
        })
542
    }
543
}
544

545
/// This conversion may fail if the alignment of `W` is not the same as
546
/// that of `W::Atomic`.
547
impl<'a, W: AtomicPrimitive> TryFrom<BitVec<&'a mut [W]>> for AtomicBitVec<&'a mut [W::Atomic]> {
548
    type Error = CannotCastToAtomicError<W>;
549
    fn try_from(value: BitVec<&'a mut [W]>) -> Result<Self, Self::Error> {
1✔
550
        if core::mem::align_of::<W>() != core::mem::align_of::<W::Atomic>() {
1✔
551
            return Err(CannotCastToAtomicError::default());
×
552
        }
553
        Ok(AtomicBitVec {
1✔
554
            bits: unsafe { core::mem::transmute::<&'a mut [W], &'a mut [W::Atomic]>(value.bits) },
1✔
555
            len: value.len,
1✔
556
        })
557
    }
558
}
559

560
impl<W: AtomicPrimitive> From<AtomicBitVec<Box<[W::Atomic]>>> for BitVec<Vec<W>> {
561
    fn from(value: AtomicBitVec<Box<[W::Atomic]>>) -> Self {
1✔
562
        BitVec {
563
            bits: transmute_vec_from_atomic::<W::Atomic>(value.bits.into_vec()),
3✔
564
            len: value.len,
1✔
565
        }
566
    }
567
}
568

569
impl<W: AtomicPrimitive> From<BitVec<Vec<W>>> for AtomicBitVec<Box<[W::Atomic]>> {
570
    fn from(value: BitVec<Vec<W>>) -> Self {
2✔
571
        AtomicBitVec {
572
            bits: transmute_vec_into_atomic(value.bits).into_boxed_slice(),
6✔
573
            len: value.len,
2✔
574
        }
575
    }
576
}
577

578
impl<W: AtomicPrimitive> From<AtomicBitVec<Box<[W::Atomic]>>> for BitVec<Box<[W]>> {
579
    fn from(value: AtomicBitVec<Box<[W::Atomic]>>) -> Self {
36✔
580
        BitVec {
581
            bits: transmute_boxed_slice_from_atomic::<W::Atomic>(value.bits),
72✔
582
            len: value.len,
36✔
583
        }
584
    }
585
}
586

587
impl<W: AtomicPrimitive + Copy> From<BitVec<Box<[W]>>> for AtomicBitVec<Box<[W::Atomic]>> {
588
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
589
        AtomicBitVec {
590
            bits: transmute_boxed_slice_into_atomic::<W>(value.bits),
2✔
591
            len: value.len,
1✔
592
        }
593
    }
594
}
595

596
impl<'a, W: AtomicPrimitive> From<AtomicBitVec<&'a [W::Atomic]>> for BitVec<&'a [W]> {
597
    fn from(value: AtomicBitVec<&'a [W::Atomic]>) -> Self {
1✔
598
        BitVec {
599
            bits: unsafe { core::mem::transmute::<&'a [W::Atomic], &'a [W]>(value.bits) },
1✔
600
            len: value.len,
1✔
601
        }
602
    }
603
}
604

605
impl<'a, W: AtomicPrimitive> From<AtomicBitVec<&'a mut [W::Atomic]>> for BitVec<&'a mut [W]> {
606
    fn from(value: AtomicBitVec<&'a mut [W::Atomic]>) -> Self {
1✔
607
        BitVec {
608
            bits: unsafe { core::mem::transmute::<&'a mut [W::Atomic], &'a mut [W]>(value.bits) },
1✔
609
            len: value.len,
1✔
610
        }
611
    }
612
}
613

614
impl<W> From<BitVec<Vec<W>>> for BitVec<Box<[W]>> {
615
    fn from(value: BitVec<Vec<W>>) -> Self {
504✔
616
        BitVec {
617
            bits: value.bits.into_boxed_slice(),
1,008✔
618
            len: value.len,
504✔
619
        }
620
    }
621
}
622

623
impl<W> From<BitVec<Box<[W]>>> for BitVec<Vec<W>> {
624
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
625
        BitVec {
626
            bits: value.bits.into_vec(),
2✔
627
            len: value.len,
1✔
628
        }
629
    }
630
}
631

632
impl<W, B: AsRef<[W]>> AsRef<[W]> for BitVec<B> {
633
    #[inline(always)]
634
    fn as_ref(&self) -> &[W] {
2,147,483,647✔
635
        self.bits.as_ref()
2,147,483,647✔
636
    }
637
}
638

639
impl<W, B: AsMut<[W]>> AsMut<[W]> for BitVec<B> {
640
    #[inline(always)]
641
    fn as_mut(&mut self) -> &mut [W] {
2,147,483,647✔
642
        self.bits.as_mut()
2,147,483,647✔
643
    }
644
}
645

646
impl<W, B: AsRef<[W]>> AsRef<[W]> for AtomicBitVec<B> {
647
    #[inline(always)]
648
    fn as_ref(&self) -> &[W] {
90,306✔
649
        self.bits.as_ref()
90,306✔
650
    }
651
}
652

653
impl<B: AsRef<[usize]>> RankHinted<64> for BitVec<B> {
654
    #[inline(always)]
655
    unsafe fn rank_hinted(&self, pos: usize, hint_pos: usize, hint_rank: usize) -> usize {
9✔
656
        let bits = self.as_ref();
27✔
657
        let mut rank = hint_rank;
18✔
658
        let mut hint_pos = hint_pos;
18✔
659

660
        debug_assert!(
9✔
661
            hint_pos < bits.len(),
18✔
662
            "hint_pos: {}, len: {}",
×
663
            hint_pos,
×
664
            bits.len()
×
665
        );
666

667
        while (hint_pos + 1) * 64 <= pos {
9✔
668
            rank += unsafe { bits.get_unchecked(hint_pos).count_ones() } as usize;
×
669
            hint_pos += 1;
×
670
        }
671

672
        rank + (unsafe { bits.get_unchecked(hint_pos) } & ((1 << (pos % 64)) - 1)).count_ones()
36✔
673
            as usize
9✔
674
    }
675
}
676

677
impl<B: AsRef<[usize]>> SelectHinted for BitVec<B> {
678
    unsafe fn select_hinted(&self, rank: usize, hint_pos: usize, hint_rank: usize) -> usize {
2,147,483,647✔
679
        let mut word_index = hint_pos / BITS;
2,147,483,647✔
680
        let bit_index = hint_pos % BITS;
2,147,483,647✔
681
        let mut residual = rank - hint_rank;
2,147,483,647✔
682
        let mut word =
2,147,483,647✔
683
            (unsafe { self.as_ref().get_unchecked(word_index) } >> bit_index) << bit_index;
2,147,483,647✔
684
        loop {
×
685
            let bit_count = word.count_ones() as usize;
2,147,483,647✔
686
            if residual < bit_count {
2,147,483,647✔
687
                return word_index * BITS + word.select_in_word(residual);
2,147,483,647✔
688
            }
689
            word_index += 1;
2,147,483,647✔
690
            word = *unsafe { self.as_ref().get_unchecked(word_index) };
2,147,483,647✔
691
            residual -= bit_count;
2,147,483,647✔
692
        }
693
    }
694
}
695

696
impl<B: AsRef<[usize]>> SelectZeroHinted for BitVec<B> {
697
    unsafe fn select_zero_hinted(&self, rank: usize, hint_pos: usize, hint_rank: usize) -> usize {
2,147,483,647✔
698
        let mut word_index = hint_pos / BITS;
2,147,483,647✔
699
        let bit_index = hint_pos % BITS;
2,147,483,647✔
700
        let mut residual = rank - hint_rank;
2,147,483,647✔
701
        let mut word =
2,147,483,647✔
702
            (!*unsafe { self.as_ref().get_unchecked(word_index) } >> bit_index) << bit_index;
2,147,483,647✔
703
        loop {
×
704
            let bit_count = word.count_ones() as usize;
2,147,483,647✔
705
            if residual < bit_count {
2,147,483,647✔
706
                return word_index * BITS + word.select_in_word(residual);
2,147,483,647✔
707
            }
708
            word_index += 1;
2,147,483,647✔
709
            word = unsafe { !self.as_ref().get_unchecked(word_index) };
2,147,483,647✔
710
            residual -= bit_count;
2,147,483,647✔
711
        }
712
    }
713
}
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