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}