bitvec/boxed/api.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
//! Port of the `Box<[T]>` inherent API.
use core::mem;
use tap::Tap;
use super::BitBox;
use crate::{
order::BitOrder,
ptr::BitSpan,
slice::BitSlice,
store::BitStore,
vec::BitVec,
};
impl<T, O> BitBox<T, O>
where
T: BitStore,
O: BitOrder,
{
/// Constructs a bit-box from a raw bit-slice pointer.
///
/// This converts a `*mut BitSlice` pointer that had previously been
/// produced by either [`::into_raw()`] or [`::leak()`] and restores the
/// bit-box containing it.
///
/// ## Original
///
/// [`Box::from_raw`](alloc::boxed::Box::from_raw)
///
/// ## Safety
///
/// You must only call this function on pointers produced by leaking a prior
/// `BitBox`; you may not modify the value of a pointer returned by
/// [`::into_raw()`], nor may you conjure pointer values of your own. Doing
/// so will corrupt the allocator state.
///
/// You must only call this function on any given leaked pointer at most
/// once. Not calling it at all will merely render the allocated memory
/// unreachable for the duration of the program runtime, a normal (and safe)
/// memory leak. Calling it once restores ordinary functionality, and
/// ensures ordinary destruction at or before program termination. However,
/// calling it more than once on the same pointer will introduce data races,
/// use-after-free, and/or double-free errors.
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bb = bitbox![0; 80];
/// let ptr: *mut BitSlice = BitBox::into_raw(bb);
/// let bb = unsafe { BitBox::from_raw(ptr) };
/// // unsafe { BitBox::from_raw(ptr) }; // UAF crash!
/// ```
///
/// [`::into_raw()`]: Self::into_raw
/// [`::leak()`]: Self::leak
#[inline]
pub unsafe fn from_raw(raw: *mut BitSlice<T, O>) -> Self {
Self {
bitspan: BitSpan::from_bitslice_ptr_mut(raw),
}
}
/// Consumes the bit-box, returning a raw bit-slice pointer.
///
/// Bit-slice pointers are always correctly encoded and non-null. The
/// referent region is dereferenceäble *as a `BitSlice` for the remainder of
/// the program, or until it is first passed to [`::from_raw()`], whichever
/// comes first. Once the pointer is first passed to `::from_raw()`, all
/// copies of that pointer become invalid to dereference.
///
/// ## Original
///
/// [`Box::into_raw`](alloc::boxed::Box::into_raw)
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bb = bitbox![0; 80];
/// let ptr = BitBox::into_raw(bb);
/// let bb = unsafe { BitBox::from_raw(ptr) };
/// ```
///
/// You **may not** deällocate pointers produced by this function through
/// any other means.
///
/// [`::from_raw()`]: Self::from_raw
#[inline]
pub fn into_raw(this: Self) -> *mut BitSlice<T, O> {
Self::leak(this)
}
/// Deliberately leaks the allocated memory, returning an
/// `&'static mut BitSlice` reference.
///
/// This differs from [`::into_raw()`] in that the reference is safe to use
/// and can be tracked by the Rust borrow-checking system. Like the
/// bit-slice pointer produced by `::into_raw()`, this reference can be
/// un-leaked by passing it into [`::from_raw()`] to reclaim the memory.
///
/// ## Original
///
/// [`Box::leak`](alloc::boxed::Box::leak)
///
/// ## Examples
///
/// ```rust
/// use bitvec::prelude::*;
///
/// let bb = bitbox![0; 80];
/// let static_ref: &'static mut BitSlice = BitBox::leak(bb);
///
/// static_ref.set(0, true);
/// assert!(static_ref[0]);
/// let _ = unsafe {
/// BitBox::from_raw(static_ref)
/// };
/// ```
///
/// [`::from_raw()`]: Self::from_raw
/// [`::into_raw()`]: Self::into_raw
#[inline]
pub fn leak<'a>(this: Self) -> &'a mut BitSlice<T, O>
where T: 'a {
unsafe { this.bitspan.into_bitslice_mut() }.tap(|_| mem::forget(this))
}
#[inline]
#[doc(hidden)]
#[cfg(not(tarpaulin_include))]
#[deprecated = "use `.into_bitvec()` instead"]
pub fn into_vec(self) -> BitVec<T, O> {
self.into_bitvec()
}
}