blob: ead0b43623e1f28f21199743499acaa511544fc0 [file] [log] [blame]
#![doc = include_str!("../doc/vec.md")]
#![cfg(feature = "alloc")]
#[cfg(not(feature = "std"))]
use alloc::vec;
use alloc::vec::Vec;
use core::{
mem::{
self,
ManuallyDrop,
},
ptr,
slice,
};
use tap::Pipe;
use wyz::comu::{
Const,
Mut,
};
pub use self::iter::{
Drain,
Splice,
};
pub use crate::boxed::IntoIter;
use crate::{
boxed::BitBox,
index::BitIdx,
mem::bits_of,
order::{
BitOrder,
Lsb0,
},
ptr::{
AddressExt,
BitPtr,
BitSpan,
BitSpanError,
},
slice::BitSlice,
store::BitStore,
view::BitView,
};
mod api;
mod iter;
mod ops;
mod tests;
mod traits;
#[repr(C)]
#[doc = include_str!("../doc/vec/BitVec.md")]
pub struct BitVec<T = usize, O = Lsb0>
where
T: BitStore,
O: BitOrder,
{
/// Span description of the live bits in the allocation.
bitspan: BitSpan<Mut, T, O>,
/// Allocation capacity, measured in `T` elements.
capacity: usize,
}
/// Constructors.
impl<T, O> BitVec<T, O>
where
T: BitStore,
O: BitOrder,
{
/// An empty bit-vector with no backing allocation.
pub const EMPTY: Self = Self {
bitspan: BitSpan::EMPTY,
capacity: 0,
};
/// Creates a new bit-vector by repeating a bit for the desired length.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let zeros = BitVec::<u8, Msb0>::repeat(false, 50);
/// let ones = BitVec::<u16, Lsb0>::repeat(true, 50);
/// ```
#[inline]
pub fn repeat(bit: bool, len: usize) -> Self {
let mut out = Self::with_capacity(len);
unsafe {
out.set_len(len);
out.as_raw_mut_slice().fill_with(|| {
BitStore::new(if bit { !<T::Mem>::ZERO } else { <T::Mem>::ZERO })
});
}
out
}
/// Copies the contents of a bit-slice into a new heap allocation.
///
/// This copies the raw underlying elements into a new allocation, and sets
/// the produced bit-vector to use the same memory layout as the originating
/// bit-slice. This means that it may begin at any bit in the first element,
/// not just the zeroth bit. If you require this property, call
/// [`.force_align()`].
///
/// Dead bits in the copied memory elements are guaranteed to be zeroed.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bits = bits![0, 1, 0, 0, 1];
/// let bv = BitVec::from_bitslice(bits);
/// assert_eq!(bv, bits);
/// ```
///
/// [`.force_align()`]: Self::force_align
#[inline]
pub fn from_bitslice(slice: &BitSlice<T, O>) -> Self {
let bitspan = slice.as_bitspan();
let mut vec = bitspan
.elements()
.pipe(Vec::with_capacity)
.pipe(ManuallyDrop::new);
vec.extend(slice.domain());
let bitspan = unsafe {
BitSpan::new_unchecked(
vec.as_mut_ptr().cast::<T>().into_address(),
bitspan.head(),
bitspan.len(),
)
};
let capacity = vec.capacity();
Self { bitspan, capacity }
}
/// Constructs a new bit-vector from a single element.
///
/// This copies `elem` into a new heap allocation, and sets the bit-vector
/// to cover it entirely.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bv = BitVec::<_, Msb0>::from_element(1u8);
/// assert!(bv[7]);
/// ```
#[inline]
pub fn from_element(elem: T) -> Self {
Self::from_vec(vec![elem])
}
/// Constructs a new bit-vector from a slice of memory elements.
///
/// This copies `slice` into a new heap allocation, and sets the bit-vector
/// to cover it entirely.
///
/// ## Panics
///
/// This panics if `slice` exceeds bit-vector capacity.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let slice = &[0u8, 1, 2, 3];
/// let bv = BitVec::<_, Lsb0>::from_slice(slice);
/// assert_eq!(bv.len(), 32);
/// ```
#[inline]
pub fn from_slice(slice: &[T]) -> Self {
Self::try_from_slice(slice).unwrap()
}
/// Fallibly constructs a new bit-vector from a slice of memory elements.
///
/// This fails early if `slice` exceeds bit-vector capacity. If it is not,
/// then `slice` is copied into a new heap allocation and fully spanned by
/// the returned bit-vector.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let slice = &[0u8, 1, 2, 3];
/// let bv = BitVec::<_, Lsb0>::try_from_slice(slice).unwrap();
/// assert_eq!(bv.len(), 32);
/// ```
#[inline]
pub fn try_from_slice(slice: &[T]) -> Result<Self, BitSpanError<T>> {
BitSlice::<T, O>::try_from_slice(slice).map(Self::from_bitslice)
}
/// Converts a regular vector in-place into a bit-vector.
///
/// The produced bit-vector spans every bit in the original vector. No
/// reällocation occurs; this is purely a transform of the handle.
///
/// ## Panics
///
/// This panics if the source vector is too long to view as a bit-slice.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let v = vec![0u8, 1, 2, 3];
/// let bv = BitVec::<_, Msb0>::from_vec(v);
/// assert_eq!(bv.len(), 32);
/// ```
#[inline]
pub fn from_vec(vec: Vec<T>) -> Self {
Self::try_from_vec(vec)
.expect("vector was too long to be converted into a `BitVec`")
}
/// Attempts to convert a regular vector in-place into a bit-vector.
///
/// This fails if the source vector is too long to view as a bit-slice. On
/// success, the produced bit-vector spans every bit in the original vector.
/// No reällocation occurs; this is purely a transform of the handle.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let v = vec![0u8; 20];
/// assert_eq!(BitVec::<_, Msb0>::try_from_vec(v).unwrap().len(), 160);
/// ```
///
/// It is not practical to allocate a vector that will fail this conversion.
#[inline]
pub fn try_from_vec(vec: Vec<T>) -> Result<Self, Vec<T>> {
let mut vec = ManuallyDrop::new(vec);
let capacity = vec.capacity();
BitPtr::from_mut_slice(vec.as_mut_slice())
.span(vec.len() * bits_of::<T::Mem>())
.map(|bitspan| Self { bitspan, capacity })
.map_err(|_| ManuallyDrop::into_inner(vec))
}
/// Appends the contents of a bit-slice to a bit-vector.
///
/// This can extend from a bit-slice of any type parameters; it is not
/// restricted to using the same parameters as `self`. However, when the
/// type parameters *do* match, it is possible for this to use a batch-copy
/// optimization to go faster than the individual-bit crawl that is
/// necessary when they differ.
///
/// Until Rust provides extensive support for specialization in trait
/// implementations, you should use this method whenever you are extending
/// from a `BitSlice` proper, and only use the general [`.extend()`]
/// implementation if you are required to use a generic `bool` source.
///
/// ## Original
///
/// [`Vec::extend_from_slice`](alloc::vec::Vec::extend_from_slice)
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let mut bv = bitvec![0, 1];
/// bv.extend_from_bitslice(bits![0, 1, 0, 0, 1]);
/// assert_eq!(bv, bits![0, 1, 0, 1, 0, 0, 1]);
/// ```
///
/// [`.extend()`]: https://docs.rs/bitvec/latest/bitvec/vec/struct.Vec.html#impl-Extend
#[inline]
pub fn extend_from_bitslice<T2, O2>(&mut self, other: &BitSlice<T2, O2>)
where
T2: BitStore,
O2: BitOrder,
{
let len = self.len();
let olen = other.len();
self.resize(len + olen, false);
unsafe { self.get_unchecked_mut(len ..) }.clone_from_bitslice(other);
}
/// Appends a slice of `T` elements to a bit-vector.
///
/// The slice is viewed as a `BitSlice<T, O>`, then appended directly to the
/// bit-vector.
///
/// ## Original
///
/// [`Vec::extend_from_slice`](alloc::vec::Vec::extend_from_slice)
#[inline]
pub fn extend_from_raw_slice(&mut self, slice: &[T]) {
self.extend_from_bitslice(slice.view_bits::<O>());
}
}
/// Converters.
impl<T, O> BitVec<T, O>
where
T: BitStore,
O: BitOrder,
{
/// Explicitly views the bit-vector as a bit-slice.
#[inline]
pub fn as_bitslice(&self) -> &BitSlice<T, O> {
unsafe { self.bitspan.into_bitslice_ref() }
}
/// Explicitly views the bit-vector as a mutable bit-slice.
#[inline]
pub fn as_mut_bitslice(&mut self) -> &mut BitSlice<T, O> {
unsafe { self.bitspan.into_bitslice_mut() }
}
/// Views the bit-vector as a slice of its underlying memory elements.
#[inline]
pub fn as_raw_slice(&self) -> &[T] {
let (data, len) =
(self.bitspan.address().to_const(), self.bitspan.elements());
unsafe { slice::from_raw_parts(data, len) }
}
/// Views the bit-vector as a mutable slice of its underlying memory
/// elements.
#[inline]
pub fn as_raw_mut_slice(&mut self) -> &mut [T] {
let (data, len) =
(self.bitspan.address().to_mut(), self.bitspan.elements());
unsafe { slice::from_raw_parts_mut(data, len) }
}
/// Creates an unsafe shared bit-pointer to the start of the buffer.
///
/// ## Original
///
/// [`Vec::as_ptr`](alloc::vec::Vec::as_ptr)
///
/// ## Safety
///
/// You must initialize the contents of the underlying buffer before
/// accessing memory through this pointer. See the `BitPtr` documentation
/// for more details.
#[inline]
pub fn as_bitptr(&self) -> BitPtr<Const, T, O> {
self.bitspan.to_bitptr().to_const()
}
/// Creates an unsafe writable bit-pointer to the start of the buffer.
///
/// ## Original
///
/// [`Vec::as_mut_ptr`](alloc::vec::Vec::as_mut_ptr)
///
/// ## Safety
///
/// You must initialize the contents of the underlying buffer before
/// accessing memory through this pointer. See the `BitPtr` documentation
/// for more details.
#[inline]
pub fn as_mut_bitptr(&mut self) -> BitPtr<Mut, T, O> {
self.bitspan.to_bitptr()
}
/// Converts a bit-vector into a boxed bit-slice.
///
/// This may cause a reällocation to drop any excess capacity.
///
/// ## Original
///
/// [`Vec::into_boxed_slice`](alloc::vec::Vec::into_boxed_slice)
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bv = bitvec![0, 1, 0, 0, 1];
/// let bb = bv.into_boxed_bitslice();
/// ```
#[inline]
pub fn into_boxed_bitslice(self) -> BitBox<T, O> {
let mut bitspan = self.bitspan;
let mut boxed =
self.into_vec().into_boxed_slice().pipe(ManuallyDrop::new);
unsafe {
bitspan.set_address(boxed.as_mut_ptr().into_address());
BitBox::from_raw(bitspan.into_bitslice_ptr_mut())
}
}
/// Converts a bit-vector into a `Vec` of its underlying storage.
///
/// The produced vector contains all elements that contained live bits. Dead
/// bits have an unspecified value; you should call [`.set_uninitialized()`]
/// before converting into a vector.
///
/// This does not affect the allocated memory; it is purely a conversion of
/// the handle.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bv = bitvec![u8, Msb0; 0, 1, 0, 0, 1];
/// let v = bv.into_vec();
/// assert_eq!(v[0] & 0xF8, 0b01001_000);
/// ```
///
/// [`.set_uninitialized()`]: Self::set_uninitialized
#[inline]
pub fn into_vec(self) -> Vec<T> {
let (bitspan, capacity) = (self.bitspan, self.capacity);
mem::forget(self);
unsafe {
Vec::from_raw_parts(
bitspan.address().to_mut(),
bitspan.elements(),
capacity,
)
}
}
}
/// Utilities.
impl<T, O> BitVec<T, O>
where
T: BitStore,
O: BitOrder,
{
/// Overwrites each element (visible in [`.as_raw_mut_slice()`]) with a new
/// bit-pattern.
///
/// This unconditionally writes `element` into each element in the backing
/// slice, without altering the bit-vector’s length or capacity.
///
/// This guarantees that dead bits visible in [`.as_raw_slice()`] but not
/// [`.as_bitslice()`] are initialized according to the bit-pattern of
/// `element.` The elements not visible in the raw slice, but present in the
/// allocation, do *not* specify a value. You may not rely on them being
/// zeroed *or* being set to the `element` bit-pattern.
///
/// ## Parameters
///
/// - `&mut self`
/// - `element`: The bit-pattern with which each live element in the backing
/// store is initialized.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let mut bv = bitvec![u8, Msb0; 0; 20];
/// assert_eq!(bv.as_raw_slice(), [0; 3]);
/// bv.set_elements(0xA5);
/// assert_eq!(bv.as_raw_slice(), [0xA5; 3]);
/// ```
///
/// [`.as_bitslice()`]: Self::as_bitslice
/// [`.as_raw_mut_slice()`]: Self::as_raw_mut_slice
/// [`.as_raw_slice()`]: Self::as_raw_slice
#[inline]
pub fn set_elements(&mut self, element: T::Mem) {
self.as_raw_mut_slice()
.iter_mut()
.for_each(|elt| elt.store_value(element));
}
/// Sets the uninitialized bits of a bit-vector to a known value.
///
/// This method modifies all bits that are observable in [`.as_raw_slice()`]
/// but *not* observable in [`.as_bitslice()`] to a known value.
/// Memory beyond the raw-slice view, but still within the allocation, is
/// considered fully dead and will never be seen.
///
/// This can be used to zero the unused memory so that when viewed as a raw
/// slice, unused bits have a consistent and predictable value.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let mut bv = 0b1101_1100u8.view_bits::<Lsb0>().to_bitvec();
/// assert_eq!(bv.as_raw_slice()[0], 0b1101_1100u8);
///
/// bv.truncate(4);
/// assert_eq!(bv.count_ones(), 2);
/// assert_eq!(bv.as_raw_slice()[0], 0b1101_1100u8);
///
/// bv.set_uninitialized(false);
/// assert_eq!(bv.as_raw_slice()[0], 0b0000_1100u8);
///
/// bv.set_uninitialized(true);
/// assert_eq!(bv.as_raw_slice()[0], 0b1111_1100u8);
/// ```
///
/// [`.as_bitslice()`]: Self::as_bitslice
/// [`.as_raw_slice()`]: Self::as_raw_slice
#[inline]
pub fn set_uninitialized(&mut self, value: bool) {
let head = self.bitspan.head().into_inner() as usize;
let last = head + self.len();
let all = self.as_raw_mut_slice().view_bits_mut::<O>();
unsafe {
all.get_unchecked_mut(.. head).fill(value);
all.get_unchecked_mut(last ..).fill(value);
}
}
/// Ensures that the live region of the bit-vector’s contents begin at the
/// front edge of the buffer.
///
/// `BitVec` has performance optimizations where it moves its view of its
/// buffer contents in order to avoid needless moves of its data within the
/// buffer. This can lead to unexpected contents of the raw memory values,
/// so this method ensures that the semantic contents of the bit-vector
/// match its in-memory storage.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let data = 0b00_1111_00u8;
/// let bits = data.view_bits::<Msb0>();
///
/// let mut bv = bits[2 .. 6].to_bitvec();
/// assert_eq!(bv, bits![1; 4]);
/// assert_eq!(bv.as_raw_slice()[0], data);
///
/// bv.force_align();
/// assert_eq!(bv, bits![1; 4]);
/// // BitVec does not specify the value of dead bits in its buffer.
/// assert_eq!(bv.as_raw_slice()[0] & 0xF0, 0xF0);
/// ```
#[inline]
pub fn force_align(&mut self) {
let mut bitspan = self.bitspan;
let len = bitspan.len();
let head = self.bitspan.head();
if head == BitIdx::MIN {
return;
}
let head = head.into_inner() as usize;
let last = head + len;
unsafe {
bitspan.set_head(BitIdx::MIN);
bitspan.set_len(last);
bitspan
.into_bitslice_mut()
.copy_within_unchecked(head .., 0);
bitspan.set_len(len);
}
self.bitspan = bitspan;
}
/// Sets the starting-bit index of the span descriptor.
///
/// ## Safety
///
/// The new `head` value must not cause the final bits of the bit-vector to
/// depart allocated memory.
pub(crate) unsafe fn set_head(&mut self, new_head: BitIdx<T::Mem>) {
self.bitspan.set_head(new_head);
}
/// Sets a bit-vector’s length without checking that it fits in the
/// allocated capacity.
///
/// ## Safety
///
/// `new_len` must not exceed `self.capacity()`.
pub(crate) unsafe fn set_len_unchecked(&mut self, new_len: usize) {
self.bitspan.set_len(new_len);
}
/// Asserts that a length can be encoded into the bit-vector handle.
///
/// ## Panics
///
/// This panics if `len` is too large to encode into a `BitSpan`.
#[inline]
fn assert_len_encodable(len: usize) {
assert!(
BitSpan::<Const, T, O>::len_encodable(len),
"bit-vector capacity exceeded: {} > {}",
len,
BitSlice::<T, O>::MAX_BITS,
);
}
/// Reserves some memory through the underlying vector.
///
/// ## Parameters
///
/// - `&mut self`
/// - `additional`: The amount of additional space required after
/// `self.len()` in the allocation.
/// - `func`: A function that manipulates the memory reservation of the
/// underlying vector.
///
/// ## Behavior
///
/// `func` should perform the appropriate action to allocate space for at
/// least `additional` more bits. After it returns, the underlying vector is
/// extended with zero-initialized elements until `self.len() + additional`
/// bits have been given initialized memory.
#[inline]
fn do_reservation(
&mut self,
additional: usize,
func: impl FnOnce(&mut Vec<T>, usize),
) {
let len = self.len();
let new_len = len.saturating_add(additional);
Self::assert_len_encodable(new_len);
let (head, elts) = (self.bitspan.head(), self.bitspan.elements());
let new_elts =
crate::mem::elts::<T>(head.into_inner() as usize + new_len);
let extra_elts = new_elts - elts;
self.with_vec(|vec| {
func(&mut **vec, extra_elts);
// Ensure that any new elements are initialized.
vec.resize_with(new_elts, || <T as BitStore>::ZERO);
});
}
/// Briefly constructs an ordinary `Vec` controlling the buffer, allowing
/// operations to be applied to the memory allocation.
///
/// ## Parameters
///
/// - `&mut self`
/// - `func`: A function which may interact with the memory allocation.
///
/// After `func` runs, `self` is updated with the temporary `Vec`’s address
/// and capacity.
#[inline]
fn with_vec<F, R>(&mut self, func: F) -> R
where F: FnOnce(&mut ManuallyDrop<Vec<T>>) -> R {
let mut vec = unsafe { ptr::read(self) }
.into_vec()
.pipe(ManuallyDrop::new);
let out = func(&mut vec);
unsafe {
self.bitspan.set_address(vec.as_mut_ptr().into_address());
}
self.capacity = vec.capacity();
out
}
}