Function bitvec::slice::from_raw_parts
source · [−]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
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 forlen
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 itsT
portion must be aligned. Both of these conditions are checked during safe construction of theBitPtr
, andunsafe
construction of it must not violate them. Doing so will cause incorrect behavior in the crate.
data
must point tolen
consecutive bits within properly initialized memory elementsT
.- The memory referenced by the returned slice must not be mutated for the
duration of the lifetime
'a
, except ifT
is an atomic or aCell
type. len
cannot exceedBitSlice::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.