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

vigna / sux-rs / 18730386058

22 Oct 2025 11:24AM UTC coverage: 65.858% (-0.04%) from 65.893%
18730386058

push

github

vigna
Alternate design based on refcell

3719 of 5647 relevant lines covered (65.86%)

115724944.87 hits per line

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

77.03
/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 is provided by the extension traits
14
//! [`BitVecOps`], [`BitVecOpsMut`], and [`AtomicBitVecOps`],
15
//! 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 depends 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+IntoAtomic%3E::AtomicType%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::{AtomicBitIterator, AtomicBitVecOps, BitIterator, BitVecOps, BitVecOpsMut};
79
use common_traits::{IntoAtomic, SelectInWord};
80
#[allow(unused_imports)] // this is in the std prelude but not in no_std!
81
use core::borrow::BorrowMut;
82
use core::fmt;
83
use mem_dbg::*;
84
use std::{
85
    ops::Index,
86
    sync::atomic::{AtomicUsize, Ordering},
87
};
88

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

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

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

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

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

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

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

231
impl BitVec<Vec<usize>> {
232
    /// Creates a new bit vector of length `len` initialized to `false`.
233
    pub fn new(len: usize) -> Self {
104,591✔
234
        Self::with_value(len, false)
209,182✔
235
    }
236

237
    /// Creates a new bit vector of length `len` initialized to `value`.
238
    pub fn with_value(len: usize, value: bool) -> Self {
105,261✔
239
        let n_of_words = len.div_ceil(BITS);
315,783✔
240
        let extra_bits = (n_of_words * BITS) - len;
210,522✔
241
        let word_value = if value { !0 } else { 0 };
315,783✔
242
        let mut bits = vec![word_value; n_of_words];
421,044✔
243
        if extra_bits > 0 {
106,700✔
244
            let last_word_value = word_value >> extra_bits;
4,317✔
245
            bits[n_of_words - 1] = last_word_value;
1,439✔
246
        }
247
        Self { bits, len }
248
    }
249

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

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

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

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

293
    /// Resizes the bit vector in place, extending it with `value` if it is
294
    /// necessary.
295
    pub fn resize(&mut self, new_len: usize, value: bool) {
10✔
296
        // TODO: rewrite by word
297
        if new_len > self.len {
10✔
298
            if new_len > self.bits.len() * BITS {
15✔
299
                self.bits.resize(new_len.div_ceil(BITS), 0);
15✔
300
            }
301
            for i in self.len..new_len {
510✔
302
                unsafe {
303
                    self.set_unchecked(i, value);
×
304
                }
305
            }
306
        }
307
        self.len = new_len;
10✔
308
    }
309
}
310

311
impl<B: AsRef<[usize]>> BitVec<B> {
312
    /// Returns an owned copy of the bit vector.
313
    pub fn to_owned(&self) -> BitVec {
×
314
        BitVec {
315
            bits: self.bits.as_ref().to_owned(),
×
316
            len: self.len,
×
317
        }
318
    }
319
}
320

321
impl<B> BitLength for BitVec<B> {
322
    #[inline(always)]
323
    fn len(&self) -> usize {
367,123,294✔
324
        self.len
367,123,294✔
325
    }
326
}
327

328
impl<B: AsRef<[usize]>> BitCount for BitVec<B> {
329
    fn count_ones(&self) -> usize {
102,268✔
330
        let full_words = self.len() / BITS;
204,536✔
331
        let residual = self.len() % BITS;
204,536✔
332
        let bits = self.as_ref();
306,804✔
333
        let mut num_ones = bits[..full_words]
204,536✔
334
            .iter()
335
            .map(|x| x.count_ones() as usize)
706,963,004✔
336
            .sum();
337
        if residual != 0 {
102,268✔
338
            num_ones += (self.as_ref()[full_words] << (BITS - residual)).count_ones() as usize
183,212✔
339
        }
340
        num_ones
102,268✔
341
    }
342
}
343

344
impl<B: AsRef<[usize]>, C: AsRef<[usize]>> PartialEq<BitVec<C>> for BitVec<B> {
345
    fn eq(&self, other: &BitVec<C>) -> bool {
70✔
346
        let len = self.len();
210✔
347
        if len != other.len() {
140✔
348
            return false;
1✔
349
        }
350

351
        let full_words = len / BITS;
×
352
        if self.as_ref()[..full_words] != other.as_ref()[..full_words] {
×
353
            return false;
×
354
        }
355

356
        let residual = len % BITS;
×
357

358
        residual == 0
×
359
            || (self.as_ref()[full_words] ^ other.as_ref()[full_words]) << (BITS - residual) == 0
67✔
360
    }
361
}
362

363
impl<B: AsRef<[usize]>> Eq for BitVec<B> {}
364

365
impl<B: AsRef<[usize]>> Index<usize> for BitVec<B> {
366
    type Output = bool;
367

368
    fn index(&self, index: usize) -> &Self::Output {
325,878,760✔
369
        match self.get(index) {
651,757,520✔
370
            false => &false,
172,741,020✔
371
            true => &true,
153,137,740✔
372
        }
373
    }
374
}
375

376
impl Extend<bool> for BitVec<Vec<usize>> {
377
    fn extend<T>(&mut self, i: T)
20,582✔
378
    where
379
        T: IntoIterator<Item = bool>,
380
    {
381
        for b in i {
1,035,509,862✔
382
            self.push(b);
×
383
        }
384
    }
385
}
386

387
impl FromIterator<bool> for BitVec<Vec<usize>> {
388
    fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
20,582✔
389
        let mut res = Self::new(0);
41,164✔
390
        res.extend(iter);
61,746✔
391
        res
20,582✔
392
    }
393
}
394

395
impl<'a, B: AsRef<[usize]>> IntoIterator for &'a BitVec<B> {
396
    type IntoIter = BitIterator<'a, B>;
397
    type Item = bool;
398

399
    fn into_iter(self) -> Self::IntoIter {
6,794✔
400
        BitIterator::new(&self.bits, self.len())
27,176✔
401
    }
402
}
403

404
impl<B: AsRef<[usize]>> fmt::Display for BitVec<B> {
405
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
×
406
        write!(f, "[")?;
×
407
        for b in self {
×
408
            write!(f, "{:b}", b as usize)?;
×
409
        }
410
        write!(f, "]")?;
×
411
        Ok(())
×
412
    }
413
}
414

415
#[derive(Debug, Clone, MemDbg, MemSize)]
416
/// A thread-safe bit vector.
417
///
418
/// See the [module documentation](mod@crate::bits::bit_vec) for details.
419
pub struct AtomicBitVec<B = Box<[AtomicUsize]>> {
420
    bits: B,
421
    len: usize,
422
}
423

424
impl<B> AtomicBitVec<B> {
425
    /// Returns the number of bits in the bit vector.
426
    ///
427
    /// This method is equivalent to [`BitLength::len`], but it is provided to
428
    /// reduce ambiguity in method resolution.
429
    #[inline(always)]
430
    pub fn len(&self) -> usize {
6✔
431
        BitLength::len(self)
12✔
432
    }
433

434
    /// # Safety
435
    /// `len` must be between 0 (included) the number of
436
    /// bits in `bits` (included).
437
    #[inline(always)]
438
    pub unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
3✔
439
        Self { bits, len }
440
    }
441
    #[inline(always)]
442
    pub fn into_raw_parts(self) -> (B, usize) {
1✔
443
        (self.bits, self.len)
1✔
444
    }
445
}
446

447
impl AtomicBitVec<Box<[AtomicUsize]>> {
448
    /// Creates a new atomic bit vector of length `len` initialized to `false`.
449
    pub fn new(len: usize) -> Self {
115✔
450
        Self::with_value(len, false)
230✔
451
    }
452

453
    /// Creates a new atomic bit vector of length `len` initialized to `value`.
454
    pub fn with_value(len: usize, value: bool) -> Self {
120✔
455
        let n_of_words = len.div_ceil(BITS);
360✔
456
        let extra_bits = (n_of_words * BITS) - len;
240✔
457
        let word_value = if value { !0 } else { 0 };
360✔
458
        let mut bits = (0..n_of_words)
240✔
459
            .map(|_| AtomicUsize::new(word_value))
1,260✔
460
            .collect::<Vec<_>>()
461
            .into_boxed_slice();
462
        if extra_bits > 0 {
210✔
463
            let last_word_value = word_value >> extra_bits;
270✔
464
            bits[n_of_words - 1] = AtomicUsize::new(last_word_value);
180✔
465
        }
466
        Self { bits, len }
467
    }
468
}
469

470
impl<B> BitLength for AtomicBitVec<B> {
471
    #[inline(always)]
472
    fn len(&self) -> usize {
86,071✔
473
        self.len
86,071✔
474
    }
475
}
476

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

498
impl<B: AsRef<[AtomicUsize]>> Index<usize> for AtomicBitVec<B> {
499
    type Output = bool;
500

501
    /// Shorthand for `get` using [`Ordering::Relaxed`].
502
    fn index(&self, index: usize) -> &Self::Output {
10,000✔
503
        match self.get(index, Ordering::Relaxed) {
30,000✔
504
            false => &false,
9,500✔
505
            true => &true,
500✔
506
        }
507
    }
508
}
509

510
impl<'a, B: AsRef<[AtomicUsize]>> IntoIterator for &'a AtomicBitVec<B> {
511
    type IntoIter = AtomicBitIterator<'a, B>;
512
    type Item = bool;
513

514
    fn into_iter(self) -> Self::IntoIter {
×
515
        AtomicBitIterator::new(&self.bits, self.len())
×
516
    }
517
}
518

519
// Conversions
520

521
/// This conversion may fail if the alignment of `W` is not the same as
522
/// that of `W::AtomicType`.
523
impl<'a, W: IntoAtomic> TryFrom<BitVec<&'a [W]>> for AtomicBitVec<&'a [W::AtomicType]> {
524
    type Error = CannotCastToAtomicError<W>;
525
    fn try_from(value: BitVec<&'a [W]>) -> Result<Self, Self::Error> {
1✔
526
        if core::mem::align_of::<W>() != core::mem::align_of::<W::AtomicType>() {
1✔
527
            return Err(CannotCastToAtomicError::default());
×
528
        }
529
        Ok(AtomicBitVec {
×
530
            bits: unsafe { core::mem::transmute::<&'a [W], &'a [W::AtomicType]>(value.bits) },
×
531
            len: value.len,
×
532
        })
533
    }
534
}
535

536
/// This conversion may fail if the alignment of `W` is not the same as
537
/// that of `W::AtomicType`.
538
impl<'a, W: IntoAtomic> TryFrom<BitVec<&'a mut [W]>> for AtomicBitVec<&'a mut [W::AtomicType]> {
539
    type Error = CannotCastToAtomicError<W>;
540
    fn try_from(value: BitVec<&'a mut [W]>) -> Result<Self, Self::Error> {
1✔
541
        if core::mem::align_of::<W>() != core::mem::align_of::<W::AtomicType>() {
1✔
542
            return Err(CannotCastToAtomicError::default());
×
543
        }
544
        Ok(AtomicBitVec {
×
545
            bits: unsafe {
×
546
                core::mem::transmute::<&'a mut [W], &'a mut [W::AtomicType]>(value.bits)
×
547
            },
548
            len: value.len,
×
549
        })
550
    }
551
}
552

553
impl<W: IntoAtomic> From<AtomicBitVec<Box<[W::AtomicType]>>> for BitVec<Vec<W>> {
554
    fn from(value: AtomicBitVec<Box<[W::AtomicType]>>) -> Self {
1✔
555
        BitVec {
556
            bits: transmute_vec_from_atomic::<W::AtomicType>(value.bits.into_vec()),
3✔
557
            len: value.len,
1✔
558
        }
559
    }
560
}
561

562
impl<W: IntoAtomic> From<BitVec<Vec<W>>> for AtomicBitVec<Box<[W::AtomicType]>> {
563
    fn from(value: BitVec<Vec<W>>) -> Self {
2✔
564
        AtomicBitVec {
565
            bits: transmute_vec_into_atomic(value.bits).into_boxed_slice(),
6✔
566
            len: value.len,
2✔
567
        }
568
    }
569
}
570

571
impl<W: IntoAtomic> From<AtomicBitVec<Box<[W::AtomicType]>>> for BitVec<Box<[W]>> {
572
    fn from(value: AtomicBitVec<Box<[W::AtomicType]>>) -> Self {
30✔
573
        BitVec {
574
            bits: transmute_boxed_slice_from_atomic::<W::AtomicType>(value.bits),
60✔
575
            len: value.len,
30✔
576
        }
577
    }
578
}
579

580
impl<W: IntoAtomic + Copy> From<BitVec<Box<[W]>>> for AtomicBitVec<Box<[W::AtomicType]>> {
581
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
582
        AtomicBitVec {
583
            bits: transmute_boxed_slice_into_atomic::<W>(value.bits),
2✔
584
            len: value.len,
1✔
585
        }
586
    }
587
}
588

589
impl<'a, W: IntoAtomic> From<AtomicBitVec<&'a [W::AtomicType]>> for BitVec<&'a [W]> {
590
    fn from(value: AtomicBitVec<&'a [W::AtomicType]>) -> Self {
1✔
591
        BitVec {
592
            bits: unsafe { core::mem::transmute::<&'a [W::AtomicType], &'a [W]>(value.bits) },
1✔
593
            len: value.len,
1✔
594
        }
595
    }
596
}
597

598
impl<'a, W: IntoAtomic> From<AtomicBitVec<&'a mut [W::AtomicType]>> for BitVec<&'a mut [W]> {
599
    fn from(value: AtomicBitVec<&'a mut [W::AtomicType]>) -> Self {
1✔
600
        BitVec {
601
            bits: unsafe {
1✔
602
                core::mem::transmute::<&'a mut [W::AtomicType], &'a mut [W]>(value.bits)
603
            },
604
            len: value.len,
1✔
605
        }
606
    }
607
}
608

609
impl<W> From<BitVec<Vec<W>>> for BitVec<Box<[W]>> {
610
    fn from(value: BitVec<Vec<W>>) -> Self {
130✔
611
        BitVec {
612
            bits: value.bits.into_boxed_slice(),
260✔
613
            len: value.len,
130✔
614
        }
615
    }
616
}
617

618
impl<W> From<BitVec<Box<[W]>>> for BitVec<Vec<W>> {
619
    fn from(value: BitVec<Box<[W]>>) -> Self {
1✔
620
        BitVec {
621
            bits: value.bits.into_vec(),
2✔
622
            len: value.len,
1✔
623
        }
624
    }
625
}
626

627
impl<W, B: AsRef<[W]>> AsRef<[W]> for BitVec<B> {
628
    #[inline(always)]
629
    fn as_ref(&self) -> &[W] {
2,147,483,647✔
630
        self.bits.as_ref()
2,147,483,647✔
631
    }
632
}
633

634
impl<W, B: AsMut<[W]>> AsMut<[W]> for BitVec<B> {
635
    #[inline(always)]
636
    fn as_mut(&mut self) -> &mut [W] {
2,147,483,647✔
637
        self.bits.as_mut()
2,147,483,647✔
638
    }
639
}
640

641
impl<W, B: AsRef<[W]>> AsRef<[W]> for AtomicBitVec<B> {
642
    #[inline(always)]
643
    fn as_ref(&self) -> &[W] {
85,996✔
644
        self.bits.as_ref()
85,996✔
645
    }
646
}
647

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

655
        debug_assert!(
9✔
656
            hint_pos < bits.len(),
18✔
657
            "hint_pos: {}, len: {}",
×
658
            hint_pos,
×
659
            bits.len()
×
660
        );
661

662
        while (hint_pos + 1) * 64 <= pos {
9✔
663
            rank += unsafe { bits.get_unchecked(hint_pos).count_ones() } as usize;
×
664
            hint_pos += 1;
×
665
        }
666

667
        rank + (unsafe { bits.get_unchecked(hint_pos) } & ((1 << (pos % 64)) - 1)).count_ones()
36✔
668
            as usize
9✔
669
    }
670
}
671

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

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