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()
	}
}