pub unsafe fn from_raw_parts<'a, O, T>(
    data: BitPtr<Const, O, T>,
    len: usize
) -> Result<&'a BitSlice<O, T>, BitSpanError<T>> where
    O: BitOrder,
    T: BitStore
Expand description

Forms a bit-slice from a bit-pointer and a length.

The len argument is the number of bits, not the number of bytes or elements.

Original

slice::from_raw_parts

API Differences

This takes a BitPtr as its base address, rather than a raw *Bit pointer, as bitvec does not provide raw pointers to individual bits.

It returns a Result, because the len argument may be invalid to encode into a &BitSlice reference.

Safety

Behavior is undefined if any of the following conditions are violated:

  • data must be valid for reads for len many bits, and it must be properly aligned. This means in particular:
    • The entire memory range of this slice must be contained within a single allocated object! Slices can never span across multiple allocated objects. See below for an example incorrectly not taking this into account.
    • data must be non-null, and its T portion must be aligned. Both of these conditions are checked during safe construction of the BitPtr, and unsafe construction of it must not violate them. Doing so will cause incorrect behavior in the crate.
  • data must point to len consecutive bits within properly initialized memory elements T.
  • The memory referenced by the returned slice must not be mutated for the duration of the lifetime 'a, except if T is an atomic or a Cell type.
  • len cannot exceed BitSlice::MAX_BITS.

Caveat

The lifetime for the returned slice is inferred from its usage. To prevent accidental misuse, it’s suggested to tie the lifetime to whichever source lifetime is safe in the context, such as by providing a helper function taking the lifetime of a host value for the slice, or by explicit annotation.

Examples

use bitvec::prelude::*;
use bitvec::slice as bv_slice;

let x = 42u8;
let bitptr = BitPtr::from(&x);
let bits: &BitSlice<LocalBits, _> = unsafe {
  bv_slice::from_raw_parts(bitptr, 8)
}
.unwrap();
assert_eq!(bits, x.view_bits::<LocalBits>());

Incorrect Usage

The following join_slices function is unsound ⚠️

use bitvec::prelude::*;
use bitvec::slice as bv_slice;

fn join_bitslices<'a, O, T>(
  fst: &'a BitSlice<O, T>,
  snd: &'a BitSlice<O, T>,
) -> &'a BitSlice<O, T>
where O: BitOrder, T: BitStore {
  let fst_end = unsafe {
    fst.as_bitptr().wrapping_add(fst.len())
  };
  let snd_start = snd.as_bitptr();
  assert_eq!(snd_start, fst_end, "Slices must be adjacent");
  unsafe {
    bv_slice::from_raw_parts(fst.as_bitptr(), fst.len() + snd.len())
  }
  .unwrap()
}

let a = [0u8; 3];
let b = [!0u8; 3];
let c = join_bitslices(
  a.view_bits::<LocalBits>(),
  b.view_bits::<LocalBits>(),
);

In this example, the compiler may elect to place a and b in adjacent stack slots, but because they are still separate allocation regions, it is illegal for a single region descriptor to be created over both of them.