bitvec/boxed/
api.rs

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