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

vigna / sux-rs / 18495149581

14 Oct 2025 11:34AM UTC coverage: 65.126% (-2.0%) from 67.167%
18495149581

push

github

vigna
Reviewed change log

6 of 8 new or added lines in 4 files covered. (75.0%)

266 existing lines in 9 files now uncovered.

3735 of 5735 relevant lines covered (65.13%)

117158861.86 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::bit_vec;
41
//! use sux::bits::bit_vec::{BitVec, AtomicBitVec, BitVecOps, BitVecOpsMut, AtomicBitVecOps};
42
//! use sux::traits::{BitCount, BitLength, NumBits, AddNumBits};
43
//! use core::sync::atomic::Ordering;
44
//!
45
//! // Convenience macro
46
//! let b = bit_vec![0, 1, 0, 1, 1, 0, 1, 0];
47
//! assert_eq!(b.len(), 8);
48
//! // Not constant time
49
//! assert_eq!(b.count_ones(), 4);
50
//! assert_eq!(b[0], false);
51
//! assert_eq!(b[1], true);
52
//! assert_eq!(b[2], false);
53
//!
54
//! let b: AddNumBits<_> = b.into();
55
//! // Constant time, but now b is immutable
56
//! assert_eq!(b.num_ones(), 4);
57
//!
58
//! let mut b = BitVec::new(0);
59
//! b.push(true);
60
//! b.push(false);
61
//! b.push(true);
62
//! assert_eq!(b.len(), 3);
63
//!
64
//! // Let's make it atomic
65
//! let mut a: AtomicBitVec = b.into();
66
//! a.set(1, true, Ordering::Relaxed);
67
//! assert!(a.get(0, Ordering::Relaxed));
68
//!
69
//! // Back to normal, but immutable size
70
//! let b: BitVec<Vec<usize>> = a.into();
71
//! let mut b: BitVec<Box<[usize]>> = b.into();
72
//! b.set(2, false);
73
//!
74
//! // If we create an artificially dirty bit vector, everything still works.
75
//! let ones = [usize::MAX; 2];
76
//! assert_eq!(unsafe { BitVec::from_raw_parts(ones, 1) }.count_ones(), 1);
77
//! ```
78

79
use crate::traits::{AtomicBitIterator, AtomicBitVecOps, BitIterator, BitVecOps, BitVecOpsMut};
80
use common_traits::{IntoAtomic, SelectInWord};
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
impl<B: AsRef<[usize]>, C: AsRef<[usize]>> PartialEq<BitVec<C>> for BitVec<B> {
115
    fn eq(&self, other: &BitVec<C>) -> bool {
70✔
116
        let len = self.len();
210✔
117
        if len != other.len() {
140✔
118
            return false;
1✔
119
        }
120

UNCOV
121
        let full_words = len / BITS;
×
UNCOV
122
        if self.as_ref()[..full_words] != other.as_ref()[..full_words] {
×
UNCOV
123
            return false;
×
124
        }
125

UNCOV
126
        let residual = len % BITS;
×
127

UNCOV
128
        residual == 0
×
129
            || (self.as_ref()[full_words] ^ other.as_ref()[full_words]) << (BITS - residual) == 0
67✔
130
    }
131
}
132

133
impl<B: AsRef<[usize]>> Eq for BitVec<B> {}
134

135
/// Convenient, [`vec!`](vec!)-like macro to initialize bit vectors.
136
///
137
/// - `bit_vec![]` creates an empty bit vector.
138
///
139
/// - `bit_vec![false; n]` or `bit_vec![0; n]` creates a bit vector of length
140
///   `n` with all bits set to `false`.
141
///
142
/// - `bit_vec![true; n]` or `bit_vec![1; n]` creates a bit vector of length `n`
143
///   with all bits set to `true`.
144
///
145
/// - `bit_vec![b₀, b₁, b₂, …]` creates a bit vector with the specified bits,
146
///   where each `bᵢ` can be any expression that evaluates to a boolean or integer
147
///   (0 for `false`, non-zero for `true`).
148
///
149
/// # Examples
150
///
151
/// ```rust
152
/// use sux::bit_vec;
153
/// use sux::bits::bit_vec::{BitVecOps, BitVecOpsMut};
154
/// use sux::traits::BitLength;
155
///
156
/// // Empty bit vector
157
/// let b = bit_vec![];
158
/// assert_eq!(b.len(), 0);
159
///
160
/// // 10 bits set to true
161
/// let b = bit_vec![true; 10];
162
/// assert_eq!(b.len(), 10);
163
/// assert_eq!(b.iter().all(|x| x), true);
164
/// let b = bit_vec![1; 10];
165
/// assert_eq!(b.len(), 10);
166
/// assert_eq!(b.iter().all(|x| x), true);
167
///
168
/// // 10 bits set to false
169
/// let b = bit_vec![false; 10];
170
/// assert_eq!(b.len(), 10);
171
/// assert_eq!(b.iter().any(|x| x), false);
172
/// let b = bit_vec![0; 10];
173
/// assert_eq!(b.len(), 10);
174
/// assert_eq!(b.iter().any(|x| x), false);
175
///
176
/// // Bit list
177
/// let b = bit_vec![0, 1, 0, 1, 0, 0];
178
/// assert_eq!(b.len(), 6);
179
/// assert_eq!(b[0], false);
180
/// assert_eq!(b[1], true);
181
/// assert_eq!(b[2], false);
182
/// assert_eq!(b[3], true);
183
/// assert_eq!(b[4], false);
184
/// assert_eq!(b[5], false);
185
/// ```
186
#[macro_export]
187
macro_rules! bit_vec {
188
    () => {
189
        $crate::bits::BitVec::new(0)
190
    };
191
    (false; $n:expr) => {
192
        $crate::bits::BitVec::new($n)
193
    };
194
    (0; $n:expr) => {
195
        $crate::bits::BitVec::new($n)
196
    };
197
    (true; $n:expr) => {
198
        {
199
            $crate::bits::BitVec::with_value($n, true)
200
        }
201
    };
202
    (1; $n:expr) => {
203
        {
204
            $crate::bits::BitVec::with_value($n, true)
205
        }
206
    };
207
    ($($x:expr),+ $(,)?) => {
208
        {
209
            let mut b = $crate::bits::BitVec::with_capacity([$($x),+].len());
210
            $( b.push($x != 0); )*
211
            b
212
        }
213
    };
214
}
215

216
impl<B> BitVec<B> {
217
    /// Returns the number of bits in the bit vector.
218
    ///
219
    /// This method is equivalent to [`BitLength::len`], but it is provided to
220
    /// reduce ambiguity in method resolution.
221
    #[inline(always)]
222
    pub fn len(&self) -> usize {
222,418✔
223
        BitLength::len(self)
444,836✔
224
    }
225

226
    /// # Safety
227
    /// `len` must be between 0 (included) the number of
228
    /// bits in `bits` (included).
229
    #[inline(always)]
230
    pub unsafe fn from_raw_parts(bits: B, len: usize) -> Self {
24✔
231
        Self { bits, len }
232
    }
233

234
    #[inline(always)]
235
    pub fn into_raw_parts(self) -> (B, usize) {
2✔
236
        (self.bits, self.len)
2✔
237
    }
238

239
    #[inline(always)]
240
    /// Modify the bit vector in place.
241
    ///
242
    ///
243
    /// # Safety
244
    /// This is unsafe because it's the caller's responsibility to ensure that
245
    /// that the length is compatible with the modified bits.
UNCOV
246
    pub unsafe fn map<B2>(self, f: impl FnOnce(B) -> B2) -> BitVec<B2> {
×
247
        BitVec {
UNCOV
248
            bits: f(self.bits),
×
UNCOV
249
            len: self.len,
×
250
        }
251
    }
252
}
253

254
impl BitVec<Vec<usize>> {
255
    /// Creates a new bit vector of length `len` initialized to `false`.
256
    pub fn new(len: usize) -> Self {
104,591✔
257
        Self::with_value(len, false)
209,182✔
258
    }
259

260
    /// Creates a new bit vector of length `len` initialized to `value`.
261
    pub fn with_value(len: usize, value: bool) -> Self {
105,261✔
262
        let n_of_words = len.div_ceil(BITS);
315,783✔
263
        let extra_bits = (n_of_words * BITS) - len;
210,522✔
264
        let word_value = if value { !0 } else { 0 };
315,783✔
265
        let mut bits = vec![word_value; n_of_words];
421,044✔
266
        if extra_bits > 0 {
106,700✔
267
            let last_word_value = word_value >> extra_bits;
4,317✔
268
            bits[n_of_words - 1] = last_word_value;
1,439✔
269
        }
270
        Self { bits, len }
271
    }
272

273
    /// Creates a new zero-length bit vector of given capacity.
274
    ///
275
    /// Note that the capacity will be rounded up to a multiple of the word
276
    /// size.
277
    pub fn with_capacity(capacity: usize) -> Self {
50✔
278
        let n_of_words = capacity.div_ceil(BITS);
150✔
279
        Self {
280
            bits: Vec::with_capacity(n_of_words),
50✔
281
            len: 0,
282
        }
283
    }
284

285
    /// Returns the currency capacity of this bit vector.
286
    pub fn capacity(&self) -> usize {
80✔
287
        self.bits.capacity() * BITS
80✔
288
    }
289

290
    /// Appends a bit to the end of this bit vector.
291
    pub fn push(&mut self, b: bool) {
2,147,483,647✔
292
        if self.bits.len() * BITS == self.len {
2,147,483,647✔
293
            self.bits.push(0);
40,495,570✔
294
        }
295
        let word_index = self.len / BITS;
2,147,483,647✔
296
        let bit_index = self.len % BITS;
2,147,483,647✔
297
        // Clear bit
298
        self.bits[word_index] &= !(1 << bit_index);
2,147,483,647✔
299
        // Set bit
300
        self.bits[word_index] |= (b as usize) << bit_index;
2,147,483,647✔
301
        self.len += 1;
2,147,483,647✔
302
    }
303

304
    /// Removes the last bit from the bit vector and returns it, or `None` if it
305
    /// is empty.
306
    pub fn pop(&mut self) -> Option<bool> {
1,005✔
307
        if self.len == 0 {
1,005✔
308
            return None;
5✔
309
        }
UNCOV
310
        let last_pos = self.len - 1;
×
UNCOV
311
        let result = unsafe { self.get_unchecked(last_pos) };
×
UNCOV
312
        self.len = last_pos;
×
UNCOV
313
        Some(result)
×
314
    }
315

316
    /// Resizes the bit vector in place, extending it with `value` if it is
317
    /// necessary.
318
    pub fn resize(&mut self, new_len: usize, value: bool) {
10✔
319
        // TODO: rewrite by word
320
        if new_len > self.len {
10✔
321
            if new_len > self.bits.len() * BITS {
15✔
322
                self.bits.resize(new_len.div_ceil(BITS), 0);
15✔
323
            }
324
            for i in self.len..new_len {
510✔
325
                unsafe {
UNCOV
326
                    self.set_unchecked(i, value);
×
327
                }
328
            }
329
        }
330
        self.len = new_len;
10✔
331
    }
332
}
333

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

341
impl<B: AsRef<[usize]>> BitCount for BitVec<B> {
342
    fn count_ones(&self) -> usize {
102,268✔
343
        let full_words = self.len() / BITS;
204,536✔
344
        let residual = self.len() % BITS;
204,536✔
345
        let bits = self.as_ref();
306,804✔
346
        let mut num_ones = bits[..full_words]
204,536✔
347
            .iter()
348
            .map(|x| x.count_ones() as usize)
706,963,004✔
349
            .sum();
350
        if residual != 0 {
102,268✔
351
            num_ones += (self.as_ref()[full_words] << (BITS - residual)).count_ones() as usize
183,212✔
352
        }
353
        num_ones
102,268✔
354
    }
355
}
356

357
impl<B: AsRef<[usize]>> BitVec<B> {
358
    /// Returns an owned copy of the bit vector.
UNCOV
359
    pub fn to_owned(&self) -> BitVec {
×
360
        BitVec {
UNCOV
361
            bits: self.bits.as_ref().to_owned(),
×
UNCOV
362
            len: self.len,
×
363
        }
364
    }
365
}
366

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

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

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

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

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

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

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

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

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

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

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

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

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

479
impl<B: AsRef<[AtomicUsize]>> Index<usize> for AtomicBitVec<B> {
480
    type Output = bool;
481

482
    /// Shorthand for `get` using [`Ordering::Relaxed`].
483
    fn index(&self, index: usize) -> &Self::Output {
10,000✔
484
        match self.get(index, Ordering::Relaxed) {
30,000✔
485
            false => &false,
9,500✔
486
            true => &true,
500✔
487
        }
488
    }
489
}
490

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

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

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

521
// Conversions
522

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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