/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bitvec-1.1.1/src/ptr/span.rs
Line | Count | Source |
1 | | #![doc = include_str!("../../doc/ptr/span.md")] |
2 | | |
3 | | use core::{ |
4 | | any, |
5 | | fmt::{ |
6 | | self, |
7 | | Binary, |
8 | | Debug, |
9 | | Display, |
10 | | Formatter, |
11 | | Pointer, |
12 | | }, |
13 | | marker::PhantomData, |
14 | | mem, |
15 | | ptr::{ |
16 | | self, |
17 | | NonNull, |
18 | | }, |
19 | | }; |
20 | | |
21 | | use tap::Pipe; |
22 | | use wyz::{ |
23 | | comu::{ |
24 | | Address, |
25 | | Const, |
26 | | Mut, |
27 | | Mutability, |
28 | | NullPtrError, |
29 | | Reference, |
30 | | Referential, |
31 | | }, |
32 | | fmt::FmtForward, |
33 | | }; |
34 | | |
35 | | use super::{ |
36 | | BitPtr, |
37 | | BitPtrError, |
38 | | BitPtrRange, |
39 | | MisalignError, |
40 | | }; |
41 | | use crate::{ |
42 | | index::{ |
43 | | BitEnd, |
44 | | BitIdx, |
45 | | }, |
46 | | mem::{ |
47 | | bits_of, |
48 | | BitRegister, |
49 | | }, |
50 | | order::{ |
51 | | BitOrder, |
52 | | Lsb0, |
53 | | }, |
54 | | slice::BitSlice, |
55 | | store::BitStore, |
56 | | }; |
57 | | |
58 | | #[doc = include_str!("../../doc/ptr/BitSpan.md")] |
59 | | pub(crate) struct BitSpan<M = Const, T = usize, O = Lsb0> |
60 | | where |
61 | | M: Mutability, |
62 | | T: BitStore, |
63 | | O: BitOrder, |
64 | | { |
65 | | /// The element address in which the base bit lives. |
66 | | ptr: NonNull<()>, |
67 | | /// The length of the span, in bits. This must be typed as `()` because it |
68 | | /// cannot be directly dereferenced, and will not have valid values for |
69 | | /// `NonNull<T>`. |
70 | | len: usize, |
71 | | /// The bit-ordering within elements used to translate indices to real bits. |
72 | | _or: PhantomData<O>, |
73 | | /// This is functionally an element-slice pointer. |
74 | | _ty: PhantomData<Address<M, [T]>>, |
75 | | } |
76 | | |
77 | | impl<M, T, O> BitSpan<M, T, O> |
78 | | where |
79 | | M: Mutability, |
80 | | T: BitStore, |
81 | | O: BitOrder, |
82 | | { |
83 | | /// The canonical empty span. This always uses the dangling address for `T`. |
84 | | pub(crate) const EMPTY: Self = Self { |
85 | | ptr: NonNull::<T>::dangling().cast::<()>(), |
86 | | len: 0, |
87 | | _or: PhantomData, |
88 | | _ty: PhantomData, |
89 | | }; |
90 | | /// The number of least-significant bits in `.len` needed to hold the low |
91 | | /// bits of the head `BitIdx` cursor. |
92 | | /// |
93 | | /// This is always 3 until Rust adds a target architecture whose bytes are |
94 | | /// not 8 bits. |
95 | | pub(crate) const LEN_HEAD_BITS: usize = 3; |
96 | | /// Marks the bits of `.len` that store some of the `.head()` logical field. |
97 | | pub(crate) const LEN_HEAD_MASK: usize = 0b111; |
98 | | /// Marks the bits of `.ptr` that store the `.addr()` logical field. |
99 | | pub(crate) const PTR_ADDR_MASK: usize = !0 << Self::PTR_HEAD_BITS; |
100 | | /// The number of least-significant bits in `.ptr` needed to hold the high |
101 | | /// bits of the head `BitIdx` cursor. |
102 | | pub(crate) const PTR_HEAD_BITS: usize = |
103 | | <T::Mem as BitRegister>::INDX as usize - Self::LEN_HEAD_BITS; |
104 | | /// Marks the bits of `.ptr` that store some of the `.head()` logical field. |
105 | | pub(crate) const PTR_HEAD_MASK: usize = !Self::PTR_ADDR_MASK; |
106 | | /// The inclusive-maximum number of bits that a `BitSpan` can cover. This |
107 | | /// value is therefore one higher than the maximum *index* that can be used |
108 | | /// to select a bit within a span. |
109 | | pub(crate) const REGION_MAX_BITS: usize = !0 >> Self::LEN_HEAD_BITS; |
110 | | /// The inclusive-maximum number of memory elements that a bit-span can |
111 | | /// cover. |
112 | | /// |
113 | | /// This is the number of elements required to store `REGION_MAX_BITS` bits, |
114 | | /// plus one because a region could begin away from the zeroth bit and thus |
115 | | /// continue into the next element at the end. |
116 | | /// |
117 | | /// Since the region is ⅛th the domain of a `usize` counter already, this |
118 | | /// number is guaranteed to be well below the limits of both arithmetic and |
119 | | /// Rust’s own ceiling constraints on memory region descriptors. |
120 | | pub(crate) const REGION_MAX_ELTS: usize = |
121 | | crate::mem::elts::<T::Mem>(Self::REGION_MAX_BITS) + 1; |
122 | | } |
123 | | |
124 | | /// Constructors. |
125 | | impl<M, T, O> BitSpan<M, T, O> |
126 | | where |
127 | | M: Mutability, |
128 | | T: BitStore, |
129 | | O: BitOrder, |
130 | | { |
131 | | /// Constructs an empty `BitSpan` at an allocated address. |
132 | | /// |
133 | | /// This is used when the region has no contents, but the pointer |
134 | | /// information must be retained and cannot be canonicalized. |
135 | | /// |
136 | | /// ## Parameters |
137 | | /// |
138 | | /// - `addr`: Some address of a `T` allocation. It must be valid in the |
139 | | /// caller’s memory regime. |
140 | | /// |
141 | | /// ## Returns |
142 | | /// |
143 | | /// A zero-length `BitSpan` based at `addr`. |
144 | | #[cfg(feature = "alloc")] |
145 | 0 | pub(crate) fn uninhabited(addr: Address<M, T>) -> Self { |
146 | 0 | Self { |
147 | 0 | ptr: addr.into_inner().cast::<()>(), |
148 | 0 | ..Self::EMPTY |
149 | 0 | } |
150 | 0 | } |
151 | | |
152 | | /// Creates a new bit-span from its logical components. |
153 | | /// |
154 | | /// ## Parameters |
155 | | /// |
156 | | /// - `addr`: The base address of the memory region in which the bit-span |
157 | | /// resides. |
158 | | /// - `head`: The index of the initial bit within `*addr`. |
159 | | /// - `bits`: The number of bits contained in the bit-span. |
160 | | /// |
161 | | /// ## Returns |
162 | | /// |
163 | | /// This fails in the following conditions: |
164 | | /// |
165 | | /// - `bits` is greater than `REGION_MAX_BITS` |
166 | | /// - `addr` is not aligned to `T`. |
167 | | /// - `addr + elts(bits)` wraps around the address space |
168 | | /// |
169 | | /// The `Address` type already enforces the non-null requirement. |
170 | 0 | pub(crate) fn new( |
171 | 0 | addr: Address<M, T>, |
172 | 0 | head: BitIdx<T::Mem>, |
173 | 0 | bits: usize, |
174 | 0 | ) -> Result<Self, BitSpanError<T>> { |
175 | 0 | if bits > Self::REGION_MAX_BITS { |
176 | 0 | return Err(BitSpanError::TooLong(bits)); |
177 | 0 | } |
178 | 0 | let base = BitPtr::<M, T, O>::new(addr, head)?; |
179 | 0 | let last = base.wrapping_add(bits); |
180 | 0 | if last < base { |
181 | 0 | return Err(BitSpanError::TooHigh(addr.to_const())); |
182 | 0 | } |
183 | | |
184 | 0 | Ok(unsafe { Self::new_unchecked(addr, head, bits) }) |
185 | 0 | } |
186 | | |
187 | | /// Creates a new bit-span from its components, without any validity checks. |
188 | | /// |
189 | | /// ## Safety |
190 | | /// |
191 | | /// The caller must ensure that the arguments satisfy all the requirements |
192 | | /// outlined in [`::new()`]. The easiest way to ensure this is to only use |
193 | | /// this function to construct bit-spans from values extracted from |
194 | | /// bit-spans previously constructed through `::new()`. |
195 | | /// |
196 | | /// This function **only** performs the value encoding. Invalid lengths will |
197 | | /// truncate, and invalid addresses may cause memory unsafety. |
198 | | /// |
199 | | /// [`::new()`]: Self::new |
200 | 1.00M | pub(crate) unsafe fn new_unchecked( |
201 | 1.00M | addr: Address<M, T>, |
202 | 1.00M | head: BitIdx<T::Mem>, |
203 | 1.00M | bits: usize, |
204 | 1.00M | ) -> Self { |
205 | 1.00M | let addr = addr.to_const().cast::<u8>(); |
206 | | |
207 | 1.00M | let head = head.into_inner() as usize; |
208 | 1.00M | let ptr_data = addr as usize & Self::PTR_ADDR_MASK; |
209 | 1.00M | let ptr_head = head >> Self::LEN_HEAD_BITS; |
210 | | |
211 | 1.00M | let len_head = head & Self::LEN_HEAD_MASK; |
212 | 1.00M | let len_bits = bits << Self::LEN_HEAD_BITS; |
213 | | |
214 | | /* See <https://github.com/bitvecto-rs/bitvec/issues/135#issuecomment-986357842>. |
215 | | * This attempts to retain inbound provenance information and may help |
216 | | * Miri better understand pointer operations this module performs. |
217 | | * |
218 | | * This performs `a + (p - a)` in `addr`’s provenance zone, which is |
219 | | * numerically equivalent to `p` but does not require conjuring a new, |
220 | | * uninformed, pointer value. |
221 | | */ |
222 | 1.00M | let ptr_raw = ptr_data | ptr_head; |
223 | 1.00M | let ptr = addr.wrapping_add(ptr_raw.wrapping_sub(addr as usize)); |
224 | | |
225 | 1.00M | Self { |
226 | 1.00M | ptr: NonNull::new_unchecked(ptr.cast::<()>() as *mut ()), |
227 | 1.00M | len: len_bits | len_head, |
228 | 1.00M | ..Self::EMPTY |
229 | 1.00M | } |
230 | 1.00M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::new_unchecked <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::new_unchecked Line | Count | Source | 200 | 248k | pub(crate) unsafe fn new_unchecked( | 201 | 248k | addr: Address<M, T>, | 202 | 248k | head: BitIdx<T::Mem>, | 203 | 248k | bits: usize, | 204 | 248k | ) -> Self { | 205 | 248k | let addr = addr.to_const().cast::<u8>(); | 206 | | | 207 | 248k | let head = head.into_inner() as usize; | 208 | 248k | let ptr_data = addr as usize & Self::PTR_ADDR_MASK; | 209 | 248k | let ptr_head = head >> Self::LEN_HEAD_BITS; | 210 | | | 211 | 248k | let len_head = head & Self::LEN_HEAD_MASK; | 212 | 248k | let len_bits = bits << Self::LEN_HEAD_BITS; | 213 | | | 214 | | /* See <https://github.com/bitvecto-rs/bitvec/issues/135#issuecomment-986357842>. | 215 | | * This attempts to retain inbound provenance information and may help | 216 | | * Miri better understand pointer operations this module performs. | 217 | | * | 218 | | * This performs `a + (p - a)` in `addr`’s provenance zone, which is | 219 | | * numerically equivalent to `p` but does not require conjuring a new, | 220 | | * uninformed, pointer value. | 221 | | */ | 222 | 248k | let ptr_raw = ptr_data | ptr_head; | 223 | 248k | let ptr = addr.wrapping_add(ptr_raw.wrapping_sub(addr as usize)); | 224 | | | 225 | 248k | Self { | 226 | 248k | ptr: NonNull::new_unchecked(ptr.cast::<()>() as *mut ()), | 227 | 248k | len: len_bits | len_head, | 228 | 248k | ..Self::EMPTY | 229 | 248k | } | 230 | 248k | } |
<bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::new_unchecked Line | Count | Source | 200 | 250k | pub(crate) unsafe fn new_unchecked( | 201 | 250k | addr: Address<M, T>, | 202 | 250k | head: BitIdx<T::Mem>, | 203 | 250k | bits: usize, | 204 | 250k | ) -> Self { | 205 | 250k | let addr = addr.to_const().cast::<u8>(); | 206 | | | 207 | 250k | let head = head.into_inner() as usize; | 208 | 250k | let ptr_data = addr as usize & Self::PTR_ADDR_MASK; | 209 | 250k | let ptr_head = head >> Self::LEN_HEAD_BITS; | 210 | | | 211 | 250k | let len_head = head & Self::LEN_HEAD_MASK; | 212 | 250k | let len_bits = bits << Self::LEN_HEAD_BITS; | 213 | | | 214 | | /* See <https://github.com/bitvecto-rs/bitvec/issues/135#issuecomment-986357842>. | 215 | | * This attempts to retain inbound provenance information and may help | 216 | | * Miri better understand pointer operations this module performs. | 217 | | * | 218 | | * This performs `a + (p - a)` in `addr`’s provenance zone, which is | 219 | | * numerically equivalent to `p` but does not require conjuring a new, | 220 | | * uninformed, pointer value. | 221 | | */ | 222 | 250k | let ptr_raw = ptr_data | ptr_head; | 223 | 250k | let ptr = addr.wrapping_add(ptr_raw.wrapping_sub(addr as usize)); | 224 | | | 225 | 250k | Self { | 226 | 250k | ptr: NonNull::new_unchecked(ptr.cast::<()>() as *mut ()), | 227 | 250k | len: len_bits | len_head, | 228 | 250k | ..Self::EMPTY | 229 | 250k | } | 230 | 250k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::new_unchecked <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::new_unchecked Line | Count | Source | 200 | 504k | pub(crate) unsafe fn new_unchecked( | 201 | 504k | addr: Address<M, T>, | 202 | 504k | head: BitIdx<T::Mem>, | 203 | 504k | bits: usize, | 204 | 504k | ) -> Self { | 205 | 504k | let addr = addr.to_const().cast::<u8>(); | 206 | | | 207 | 504k | let head = head.into_inner() as usize; | 208 | 504k | let ptr_data = addr as usize & Self::PTR_ADDR_MASK; | 209 | 504k | let ptr_head = head >> Self::LEN_HEAD_BITS; | 210 | | | 211 | 504k | let len_head = head & Self::LEN_HEAD_MASK; | 212 | 504k | let len_bits = bits << Self::LEN_HEAD_BITS; | 213 | | | 214 | | /* See <https://github.com/bitvecto-rs/bitvec/issues/135#issuecomment-986357842>. | 215 | | * This attempts to retain inbound provenance information and may help | 216 | | * Miri better understand pointer operations this module performs. | 217 | | * | 218 | | * This performs `a + (p - a)` in `addr`’s provenance zone, which is | 219 | | * numerically equivalent to `p` but does not require conjuring a new, | 220 | | * uninformed, pointer value. | 221 | | */ | 222 | 504k | let ptr_raw = ptr_data | ptr_head; | 223 | 504k | let ptr = addr.wrapping_add(ptr_raw.wrapping_sub(addr as usize)); | 224 | | | 225 | 504k | Self { | 226 | 504k | ptr: NonNull::new_unchecked(ptr.cast::<()>() as *mut ()), | 227 | 504k | len: len_bits | len_head, | 228 | 504k | ..Self::EMPTY | 229 | 504k | } | 230 | 504k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::new_unchecked |
231 | | } |
232 | | |
233 | | /// Encoded fields. |
234 | | impl<M, T, O> BitSpan<M, T, O> |
235 | | where |
236 | | M: Mutability, |
237 | | T: BitStore, |
238 | | O: BitOrder, |
239 | | { |
240 | | /// Gets the base element address of the referent region. |
241 | | /// |
242 | | /// # Parameters |
243 | | /// |
244 | | /// - `&self` |
245 | | /// |
246 | | /// # Returns |
247 | | /// |
248 | | /// The address of the starting element of the memory region. This address |
249 | | /// is weakly typed so that it can be cast by call sites to the most useful |
250 | | /// access type. |
251 | 1.04M | pub(crate) fn address(&self) -> Address<M, T> { |
252 | 1.04M | let ptr = self.ptr.as_ptr().cast::<u8>(); |
253 | 1.04M | let addr = ptr as usize; |
254 | 1.04M | let ptr = ptr |
255 | 1.04M | .wrapping_add(addr & Self::PTR_ADDR_MASK) |
256 | 1.04M | .wrapping_sub(addr) |
257 | 1.04M | .cast::<T>(); |
258 | 1.04M | Address::new(unsafe { NonNull::new_unchecked(ptr) }) |
259 | 1.04M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::address <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::address Line | Count | Source | 251 | 124k | pub(crate) fn address(&self) -> Address<M, T> { | 252 | 124k | let ptr = self.ptr.as_ptr().cast::<u8>(); | 253 | 124k | let addr = ptr as usize; | 254 | 124k | let ptr = ptr | 255 | 124k | .wrapping_add(addr & Self::PTR_ADDR_MASK) | 256 | 124k | .wrapping_sub(addr) | 257 | 124k | .cast::<T>(); | 258 | 124k | Address::new(unsafe { NonNull::new_unchecked(ptr) }) | 259 | 124k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::address <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::address Line | Count | Source | 251 | 409k | pub(crate) fn address(&self) -> Address<M, T> { | 252 | 409k | let ptr = self.ptr.as_ptr().cast::<u8>(); | 253 | 409k | let addr = ptr as usize; | 254 | 409k | let ptr = ptr | 255 | 409k | .wrapping_add(addr & Self::PTR_ADDR_MASK) | 256 | 409k | .wrapping_sub(addr) | 257 | 409k | .cast::<T>(); | 258 | 409k | Address::new(unsafe { NonNull::new_unchecked(ptr) }) | 259 | 409k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::address <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::address Line | Count | Source | 251 | 507k | pub(crate) fn address(&self) -> Address<M, T> { | 252 | 507k | let ptr = self.ptr.as_ptr().cast::<u8>(); | 253 | 507k | let addr = ptr as usize; | 254 | 507k | let ptr = ptr | 255 | 507k | .wrapping_add(addr & Self::PTR_ADDR_MASK) | 256 | 507k | .wrapping_sub(addr) | 257 | 507k | .cast::<T>(); | 258 | 507k | Address::new(unsafe { NonNull::new_unchecked(ptr) }) | 259 | 507k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::address |
260 | | |
261 | | /// Overwrites the data pointer with a new address. This method does not |
262 | | /// perform safety checks on the new pointer. |
263 | | /// |
264 | | /// # Parameters |
265 | | /// |
266 | | /// - `&mut self` |
267 | | /// - `ptr`: The new address of the `BitSpan`’s domain. |
268 | | /// |
269 | | /// # Safety |
270 | | /// |
271 | | /// None. The invariants of [`::new`] must be checked at the caller. |
272 | | /// |
273 | | /// [`::new`]: Self::new |
274 | | #[cfg(feature = "alloc")] |
275 | 0 | pub(crate) unsafe fn set_address(&mut self, addr: Address<M, T>) { |
276 | 0 | let mut addr_value = addr.to_const() as usize; |
277 | 0 | addr_value &= Self::PTR_ADDR_MASK; |
278 | 0 | addr_value |= self.ptr.as_ptr() as usize & Self::PTR_HEAD_MASK; |
279 | 0 | self.ptr = NonNull::new_unchecked(addr_value as *mut ()) |
280 | 0 | } |
281 | | |
282 | | /// Gets the starting bit index of the referent region. |
283 | | /// |
284 | | /// # Parameters |
285 | | /// |
286 | | /// - `&self` |
287 | | /// |
288 | | /// # Returns |
289 | | /// |
290 | | /// A [`BitIdx`] of the first live bit in the element at the |
291 | | /// [`self.address()`] address. |
292 | | /// |
293 | | /// [`BitIdx`]: crate::index::BitIdx |
294 | | /// [`self.address()`]: Self::address |
295 | 2.21M | pub(crate) fn head(&self) -> BitIdx<T::Mem> { |
296 | 2.21M | let ptr = self.ptr.as_ptr() as usize; |
297 | 2.21M | let ptr_head = (ptr & Self::PTR_HEAD_MASK) << Self::LEN_HEAD_BITS; |
298 | 2.21M | let len_head = self.len & Self::LEN_HEAD_MASK; |
299 | 2.21M | unsafe { BitIdx::new_unchecked((ptr_head | len_head) as u8) } |
300 | 2.21M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::head <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::head Line | Count | Source | 295 | 124k | pub(crate) fn head(&self) -> BitIdx<T::Mem> { | 296 | 124k | let ptr = self.ptr.as_ptr() as usize; | 297 | 124k | let ptr_head = (ptr & Self::PTR_HEAD_MASK) << Self::LEN_HEAD_BITS; | 298 | 124k | let len_head = self.len & Self::LEN_HEAD_MASK; | 299 | 124k | unsafe { BitIdx::new_unchecked((ptr_head | len_head) as u8) } | 300 | 124k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::head <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::head Line | Count | Source | 295 | 960k | pub(crate) fn head(&self) -> BitIdx<T::Mem> { | 296 | 960k | let ptr = self.ptr.as_ptr() as usize; | 297 | 960k | let ptr_head = (ptr & Self::PTR_HEAD_MASK) << Self::LEN_HEAD_BITS; | 298 | 960k | let len_head = self.len & Self::LEN_HEAD_MASK; | 299 | 960k | unsafe { BitIdx::new_unchecked((ptr_head | len_head) as u8) } | 300 | 960k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::head <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::head Line | Count | Source | 295 | 1.13M | pub(crate) fn head(&self) -> BitIdx<T::Mem> { | 296 | 1.13M | let ptr = self.ptr.as_ptr() as usize; | 297 | 1.13M | let ptr_head = (ptr & Self::PTR_HEAD_MASK) << Self::LEN_HEAD_BITS; | 298 | 1.13M | let len_head = self.len & Self::LEN_HEAD_MASK; | 299 | 1.13M | unsafe { BitIdx::new_unchecked((ptr_head | len_head) as u8) } | 300 | 1.13M | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::head |
301 | | |
302 | | /// Writes a new `head` value into the pointer, with no other effects. |
303 | | /// |
304 | | /// # Parameters |
305 | | /// |
306 | | /// - `&mut self` |
307 | | /// - `head`: A new starting index. |
308 | | /// |
309 | | /// # Effects |
310 | | /// |
311 | | /// `head` is written into the `.head` logical field, without affecting |
312 | | /// `.addr` or `.bits`. |
313 | | #[cfg(feature = "alloc")] |
314 | 0 | pub(crate) unsafe fn set_head(&mut self, head: BitIdx<T::Mem>) { |
315 | 0 | let head = head.into_inner() as usize; |
316 | 0 | let mut ptr = self.ptr.as_ptr() as usize; |
317 | | |
318 | 0 | ptr &= Self::PTR_ADDR_MASK; |
319 | 0 | ptr |= head >> Self::LEN_HEAD_BITS; |
320 | 0 | self.ptr = NonNull::new_unchecked(ptr as *mut ()); |
321 | | |
322 | 0 | self.len &= !Self::LEN_HEAD_MASK; |
323 | 0 | self.len |= head & Self::LEN_HEAD_MASK; |
324 | 0 | } |
325 | | |
326 | | /// Gets the number of live bits in the described region. |
327 | | /// |
328 | | /// # Parameters |
329 | | /// |
330 | | /// - `&self` |
331 | | /// |
332 | | /// # Returns |
333 | | /// |
334 | | /// A count of how many live bits the region pointer describes. |
335 | 3.05M | pub(crate) fn len(&self) -> usize { |
336 | 3.05M | self.len >> Self::LEN_HEAD_BITS |
337 | 3.05M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::len <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::len Line | Count | Source | 335 | 596k | pub(crate) fn len(&self) -> usize { | 336 | 596k | self.len >> Self::LEN_HEAD_BITS | 337 | 596k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, bitvec::access::BitSafeU8>>::len <bitvec::ptr::span::BitSpan<wyz::comu::Const, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::len Line | Count | Source | 335 | 333k | pub(crate) fn len(&self) -> usize { | 336 | 333k | self.len >> Self::LEN_HEAD_BITS | 337 | 333k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::len <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::len Line | Count | Source | 335 | 2.12M | pub(crate) fn len(&self) -> usize { | 336 | 2.12M | self.len >> Self::LEN_HEAD_BITS | 337 | 2.12M | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::len |
338 | | |
339 | | /// Sets the `.bits` logical member to a new value. |
340 | | /// |
341 | | /// # Parameters |
342 | | /// |
343 | | /// - `&mut self` |
344 | | /// - `len`: A new bit length. This must not be greater than |
345 | | /// [`REGION_MAX_BITS`]. |
346 | | /// |
347 | | /// # Effects |
348 | | /// |
349 | | /// The `new_len` value is written directly into the `.bits` logical field. |
350 | | /// |
351 | | /// [`REGION_MAX_BITS`]: Self::REGION_MAX_BITS |
352 | 9.73k | pub(crate) unsafe fn set_len(&mut self, new_len: usize) { |
353 | 9.73k | if cfg!(debug_assertions) { |
354 | 0 | *self = Self::new(self.address(), self.head(), new_len).unwrap(); |
355 | 0 | } |
356 | 9.73k | else { |
357 | 9.73k | self.len &= Self::LEN_HEAD_MASK; |
358 | 9.73k | self.len |= new_len << Self::LEN_HEAD_BITS; |
359 | 9.73k | } |
360 | 9.73k | } <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::set_len Line | Count | Source | 352 | 9.73k | pub(crate) unsafe fn set_len(&mut self, new_len: usize) { | 353 | 9.73k | if cfg!(debug_assertions) { | 354 | 0 | *self = Self::new(self.address(), self.head(), new_len).unwrap(); | 355 | 0 | } | 356 | 9.73k | else { | 357 | 9.73k | self.len &= Self::LEN_HEAD_MASK; | 358 | 9.73k | self.len |= new_len << Self::LEN_HEAD_BITS; | 359 | 9.73k | } | 360 | 9.73k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::set_len |
361 | | |
362 | | /// Gets the three logical components of the pointer. |
363 | | /// |
364 | | /// The encoding is not public API, and direct field access is never |
365 | | /// supported. |
366 | | /// |
367 | | /// # Parameters |
368 | | /// |
369 | | /// - `&self` |
370 | | /// |
371 | | /// # Returns |
372 | | /// |
373 | | /// - `.0`: The base address of the referent memory region. |
374 | | /// - `.1`: The index of the first live bit in the first element of the |
375 | | /// region. |
376 | | /// - `.2`: The number of live bits in the region. |
377 | 0 | pub(crate) fn raw_parts(&self) -> (Address<M, T>, BitIdx<T::Mem>, usize) { |
378 | 0 | (self.address(), self.head(), self.len()) |
379 | 0 | } |
380 | | } |
381 | | |
382 | | /// Virtual fields. |
383 | | impl<M, T, O> BitSpan<M, T, O> |
384 | | where |
385 | | M: Mutability, |
386 | | T: BitStore, |
387 | | O: BitOrder, |
388 | | { |
389 | | /// Computes the number of elements, starting at [`self.address()`], that |
390 | | /// the region touches. |
391 | | /// |
392 | | /// # Parameters |
393 | | /// |
394 | | /// - `&self` |
395 | | /// |
396 | | /// # Returns |
397 | | /// |
398 | | /// The count of all elements, starting at [`self.address()`], that contain |
399 | | /// live bits included in the referent region. |
400 | | /// |
401 | | /// [`self.address()`]: Self::address |
402 | 501k | pub(crate) fn elements(&self) -> usize { |
403 | 501k | crate::mem::elts::<T>(self.len() + self.head().into_inner() as usize) |
404 | 501k | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::elements <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::elements Line | Count | Source | 402 | 275k | pub(crate) fn elements(&self) -> usize { | 403 | 275k | crate::mem::elts::<T>(self.len() + self.head().into_inner() as usize) | 404 | 275k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::elements <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::elements Line | Count | Source | 402 | 225k | pub(crate) fn elements(&self) -> usize { | 403 | 225k | crate::mem::elts::<T>(self.len() + self.head().into_inner() as usize) | 404 | 225k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::elements |
405 | | |
406 | | /// Computes the tail index for the first dead bit after the live bits. |
407 | | /// |
408 | | /// # Parameters |
409 | | /// |
410 | | /// - `&self` |
411 | | /// |
412 | | /// # Returns |
413 | | /// |
414 | | /// A `BitEnd` that is the index of the first dead bit after the last live |
415 | | /// bit in the last element. This will almost always be in the range `1 ..= |
416 | | /// T::Mem::BITS`. |
417 | | /// |
418 | | /// It will be zero only when `self` is empty. |
419 | 501k | pub(crate) fn tail(&self) -> BitEnd<T::Mem> { |
420 | 501k | let (head, len) = (self.head(), self.len()); |
421 | 501k | let (_, tail) = head.span(len); |
422 | 501k | tail |
423 | 501k | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::tail <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::tail Line | Count | Source | 419 | 275k | pub(crate) fn tail(&self) -> BitEnd<T::Mem> { | 420 | 275k | let (head, len) = (self.head(), self.len()); | 421 | 275k | let (_, tail) = head.span(len); | 422 | 275k | tail | 423 | 275k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::tail <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::tail Line | Count | Source | 419 | 225k | pub(crate) fn tail(&self) -> BitEnd<T::Mem> { | 420 | 225k | let (head, len) = (self.head(), self.len()); | 421 | 225k | let (_, tail) = head.span(len); | 422 | 225k | tail | 423 | 225k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::tail |
424 | | } |
425 | | |
426 | | /// Conversions. |
427 | | impl<M, T, O> BitSpan<M, T, O> |
428 | | where |
429 | | M: Mutability, |
430 | | T: BitStore, |
431 | | O: BitOrder, |
432 | | { |
433 | | /// Casts the span to another element type. |
434 | | /// |
435 | | /// This does not alter the encoded value of the pointer! It only |
436 | | /// reinterprets the element type, and the encoded value may shift |
437 | | /// significantly in the result type. Use with caution. |
438 | 582k | pub(crate) fn cast<U>(self) -> BitSpan<M, U, O> |
439 | 582k | where U: BitStore { |
440 | 582k | let Self { ptr, len, .. } = self; |
441 | 582k | BitSpan { |
442 | 582k | ptr, |
443 | 582k | len, |
444 | 582k | ..BitSpan::EMPTY |
445 | 582k | } |
446 | 582k | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::cast::<bitvec::access::BitSafeU8> Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::cast::<u8> <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::cast::<bitvec::access::BitSafeU8> Line | Count | Source | 438 | 372k | pub(crate) fn cast<U>(self) -> BitSpan<M, U, O> | 439 | 372k | where U: BitStore { | 440 | 372k | let Self { ptr, len, .. } = self; | 441 | 372k | BitSpan { | 442 | 372k | ptr, | 443 | 372k | len, | 444 | 372k | ..BitSpan::EMPTY | 445 | 372k | } | 446 | 372k | } |
<bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::cast::<u8> Line | Count | Source | 438 | 124k | pub(crate) fn cast<U>(self) -> BitSpan<M, U, O> | 439 | 124k | where U: BitStore { | 440 | 124k | let Self { ptr, len, .. } = self; | 441 | 124k | BitSpan { | 442 | 124k | ptr, | 443 | 124k | len, | 444 | 124k | ..BitSpan::EMPTY | 445 | 124k | } | 446 | 124k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::cast::<bitvec::access::BitSafeU8> <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::cast::<bitvec::access::BitSafeU8> Line | Count | Source | 438 | 85.9k | pub(crate) fn cast<U>(self) -> BitSpan<M, U, O> | 439 | 85.9k | where U: BitStore { | 440 | 85.9k | let Self { ptr, len, .. } = self; | 441 | 85.9k | BitSpan { | 442 | 85.9k | ptr, | 443 | 85.9k | len, | 444 | 85.9k | ..BitSpan::EMPTY | 445 | 85.9k | } | 446 | 85.9k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::cast::<_> |
447 | | |
448 | | /// Reäligns a bit-span to a different base memory type. |
449 | | /// |
450 | | /// ## Original |
451 | | /// |
452 | | /// [`slice::align_to`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to) |
453 | | /// |
454 | | /// ## Safety |
455 | | /// |
456 | | /// `U` must have the same type family as `T`. It is illegal to use this |
457 | | /// method to cast away alias safeties such as an atomic or `Cell` wrapper. |
458 | 0 | pub(crate) unsafe fn align_to<U>(self) -> (Self, BitSpan<M, U, O>, Self) |
459 | 0 | where U: BitStore { |
460 | | /* This function body implements the algorithm locally, rather than |
461 | | * delegating to the standard library’s `<[T]>::align_to::<U>` |
462 | | * function, because that requires use of memory references, and |
463 | | * `BitSpan` does not require that its values be valid for |
464 | | * dereference. |
465 | | */ |
466 | 0 | let this = self.to_bitptr(); |
467 | | // Counter for how many bits remain in the span. |
468 | 0 | let mut rem = self.len(); |
469 | | // The *byte* alignment of `U`. |
470 | 0 | let align = mem::align_of::<U>(); |
471 | | // 1. Get the number of bits between `self.head()` and the start of a |
472 | | // `[U]` region. |
473 | 0 | let step = this.align_offset(align); |
474 | | // If this count is more than the available bits, quit. |
475 | 0 | if step > rem { |
476 | 0 | return (self, BitSpan::EMPTY, Self::EMPTY); |
477 | 0 | } |
478 | 0 | let left = this.span_unchecked(step); |
479 | 0 | rem -= step; |
480 | | |
481 | 0 | let mid_base = |
482 | 0 | this.add(step).address().cast::<U>().pipe(|addr| { |
483 | 0 | BitPtr::<M, U, O>::new_unchecked(addr, BitIdx::MIN) |
484 | 0 | }); |
485 | 0 | let mid_elts = rem >> <U::Mem as BitRegister>::INDX; |
486 | 0 | let excess = rem & <U::Mem as BitRegister>::MASK as usize; |
487 | 0 | let step = rem - excess; |
488 | 0 | let mid = mid_base.span_unchecked(step); |
489 | | |
490 | 0 | let right_base = |
491 | 0 | mid_base.address().add(mid_elts).cast::<T>().pipe(|addr| { |
492 | 0 | BitPtr::<M, T, O>::new_unchecked(addr, BitIdx::MIN) |
493 | 0 | }); |
494 | 0 | let right = right_base.span_unchecked(excess); |
495 | | |
496 | 0 | (left, mid, right) |
497 | 0 | } |
498 | | |
499 | | /// Casts a mutable bit-slice pointer into its structural representation. |
500 | 1.11M | pub(crate) fn from_bitslice_ptr_mut(raw: *mut BitSlice<T, O>) -> Self { |
501 | 1.11M | let BitSpan { ptr, len, .. } = |
502 | 1.11M | BitSpan::from_bitslice_ptr(raw as *const BitSlice<T, O>); |
503 | 1.11M | Self { |
504 | 1.11M | ptr, |
505 | 1.11M | len, |
506 | 1.11M | ..Self::EMPTY |
507 | 1.11M | } |
508 | 1.11M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::from_bitslice_ptr_mut <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::from_bitslice_ptr_mut Line | Count | Source | 500 | 620k | pub(crate) fn from_bitslice_ptr_mut(raw: *mut BitSlice<T, O>) -> Self { | 501 | 620k | let BitSpan { ptr, len, .. } = | 502 | 620k | BitSpan::from_bitslice_ptr(raw as *const BitSlice<T, O>); | 503 | 620k | Self { | 504 | 620k | ptr, | 505 | 620k | len, | 506 | 620k | ..Self::EMPTY | 507 | 620k | } | 508 | 620k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::from_bitslice_ptr_mut <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::from_bitslice_ptr_mut Line | Count | Source | 500 | 495k | pub(crate) fn from_bitslice_ptr_mut(raw: *mut BitSlice<T, O>) -> Self { | 501 | 495k | let BitSpan { ptr, len, .. } = | 502 | 495k | BitSpan::from_bitslice_ptr(raw as *const BitSlice<T, O>); | 503 | 495k | Self { | 504 | 495k | ptr, | 505 | 495k | len, | 506 | 495k | ..Self::EMPTY | 507 | 495k | } | 508 | 495k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::from_bitslice_ptr_mut |
509 | | |
510 | | /// Converts the span descriptor into a raw `BitSlice` pointer. |
511 | | /// |
512 | | /// This is a noöp. |
513 | 1.80M | pub(crate) fn into_bitslice_ptr(self) -> *const BitSlice<T, O> { |
514 | 1.80M | let Self { ptr, len, .. } = self; |
515 | 1.80M | ptr::slice_from_raw_parts(ptr.as_ptr(), len) as *const BitSlice<T, O> |
516 | 1.80M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::into_bitslice_ptr <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::into_bitslice_ptr Line | Count | Source | 513 | 916k | pub(crate) fn into_bitslice_ptr(self) -> *const BitSlice<T, O> { | 514 | 916k | let Self { ptr, len, .. } = self; | 515 | 916k | ptr::slice_from_raw_parts(ptr.as_ptr(), len) as *const BitSlice<T, O> | 516 | 916k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::into_bitslice_ptr <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::into_bitslice_ptr Line | Count | Source | 513 | 374k | pub(crate) fn into_bitslice_ptr(self) -> *const BitSlice<T, O> { | 514 | 374k | let Self { ptr, len, .. } = self; | 515 | 374k | ptr::slice_from_raw_parts(ptr.as_ptr(), len) as *const BitSlice<T, O> | 516 | 374k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::into_bitslice_ptr <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::into_bitslice_ptr Line | Count | Source | 513 | 514k | pub(crate) fn into_bitslice_ptr(self) -> *const BitSlice<T, O> { | 514 | 514k | let Self { ptr, len, .. } = self; | 515 | 514k | ptr::slice_from_raw_parts(ptr.as_ptr(), len) as *const BitSlice<T, O> | 516 | 514k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::into_bitslice_ptr |
517 | | |
518 | | /// Converts the span descriptor into a shared `BitSlice` reference. |
519 | | /// |
520 | | /// This is a noöp. |
521 | | /// |
522 | | /// ## Safety |
523 | | /// |
524 | | /// The span must describe memory that is safe to dereference, and to which |
525 | | /// no `&mut BitSlice` references exist. |
526 | 514k | pub(crate) unsafe fn into_bitslice_ref<'a>(self) -> &'a BitSlice<T, O> { |
527 | 514k | &*self.into_bitslice_ptr() |
528 | 514k | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::into_bitslice_ref <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::into_bitslice_ref Line | Count | Source | 526 | 514k | pub(crate) unsafe fn into_bitslice_ref<'a>(self) -> &'a BitSlice<T, O> { | 527 | 514k | &*self.into_bitslice_ptr() | 528 | 514k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::into_bitslice_ref |
529 | | |
530 | | /// Produces a bit-pointer to the start of the span. |
531 | | /// |
532 | | /// This is **not** a noöp: the base address and starting bit index are |
533 | | /// decoded into the bit-pointer structure. |
534 | 539k | pub(crate) fn to_bitptr(self) -> BitPtr<M, T, O> { |
535 | 539k | unsafe { BitPtr::new_unchecked(self.address(), self.head()) } |
536 | 539k | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::to_bitptr <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::to_bitptr Line | Count | Source | 534 | 124k | pub(crate) fn to_bitptr(self) -> BitPtr<M, T, O> { | 535 | 124k | unsafe { BitPtr::new_unchecked(self.address(), self.head()) } | 536 | 124k | } |
<bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::to_bitptr Line | Count | Source | 534 | 133k | pub(crate) fn to_bitptr(self) -> BitPtr<M, T, O> { | 535 | 133k | unsafe { BitPtr::new_unchecked(self.address(), self.head()) } | 536 | 133k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::to_bitptr <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::to_bitptr Line | Count | Source | 534 | 281k | pub(crate) fn to_bitptr(self) -> BitPtr<M, T, O> { | 535 | 281k | unsafe { BitPtr::new_unchecked(self.address(), self.head()) } | 536 | 281k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::to_bitptr |
537 | | |
538 | | /// Produces a bit-pointer range to either end of the span. |
539 | | /// |
540 | | /// This is **not** a noöp: all three logical fields are decoded in order to |
541 | | /// construct the range. |
542 | 0 | pub(crate) fn to_bitptr_range(self) -> BitPtrRange<M, T, O> { |
543 | 0 | let start = self.to_bitptr(); |
544 | 0 | let end = unsafe { start.add(self.len()) }; |
545 | 0 | BitPtrRange { start, end } |
546 | 0 | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::to_bitptr_range Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::to_bitptr_range Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::to_bitptr_range |
547 | | |
548 | | /// Converts the span descriptor into an `Address<>` generic pointer. |
549 | | /// |
550 | | /// This is a noöp. |
551 | 0 | pub(crate) fn to_bitslice_addr(self) -> Address<M, BitSlice<T, O>> { |
552 | 0 | (self.into_bitslice_ptr() as *mut BitSlice<T, O>) |
553 | 0 | .pipe(|ptr| unsafe { NonNull::new_unchecked(ptr) }) |
554 | 0 | .pipe(Address::new) |
555 | 0 | } |
556 | | |
557 | | /// Converts the span descriptor into a `Reference<>` generic handle. |
558 | | /// |
559 | | /// This is a noöp. |
560 | 0 | pub(crate) fn to_bitslice<'a>(self) -> Reference<'a, M, BitSlice<T, O>> |
561 | 0 | where Address<M, BitSlice<T, O>>: Referential<'a> { |
562 | 0 | unsafe { self.to_bitslice_addr().to_ref() } |
563 | 0 | } |
564 | | } |
565 | | |
566 | | /// Conversions. |
567 | | impl<T, O> BitSpan<Const, T, O> |
568 | | where |
569 | | T: BitStore, |
570 | | O: BitOrder, |
571 | | { |
572 | | /// Creates a `Const` span descriptor from a `const` bit-slice pointer. |
573 | 3.70M | pub(crate) fn from_bitslice_ptr(raw: *const BitSlice<T, O>) -> Self { |
574 | 3.70M | let slice_nn = match NonNull::new(raw as *const [()] as *mut [()]) { |
575 | 3.70M | Some(nn) => nn, |
576 | 0 | None => return Self::EMPTY, |
577 | | }; |
578 | 3.70M | let ptr = slice_nn.cast::<()>(); |
579 | 3.70M | let len = unsafe { slice_nn.as_ref() }.len(); |
580 | 3.70M | Self { |
581 | 3.70M | ptr, |
582 | 3.70M | len, |
583 | 3.70M | ..Self::EMPTY |
584 | 3.70M | } |
585 | 3.70M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, bitvec::access::BitSafeU8>>::from_bitslice_ptr <bitvec::ptr::span::BitSpan<wyz::comu::Const, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::from_bitslice_ptr Line | Count | Source | 573 | 954k | pub(crate) fn from_bitslice_ptr(raw: *const BitSlice<T, O>) -> Self { | 574 | 954k | let slice_nn = match NonNull::new(raw as *const [()] as *mut [()]) { | 575 | 954k | Some(nn) => nn, | 576 | 0 | None => return Self::EMPTY, | 577 | | }; | 578 | 954k | let ptr = slice_nn.cast::<()>(); | 579 | 954k | let len = unsafe { slice_nn.as_ref() }.len(); | 580 | 954k | Self { | 581 | 954k | ptr, | 582 | 954k | len, | 583 | 954k | ..Self::EMPTY | 584 | 954k | } | 585 | 954k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8>>::from_bitslice_ptr <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::from_bitslice_ptr Line | Count | Source | 573 | 2.75M | pub(crate) fn from_bitslice_ptr(raw: *const BitSlice<T, O>) -> Self { | 574 | 2.75M | let slice_nn = match NonNull::new(raw as *const [()] as *mut [()]) { | 575 | 2.75M | Some(nn) => nn, | 576 | 0 | None => return Self::EMPTY, | 577 | | }; | 578 | 2.75M | let ptr = slice_nn.cast::<()>(); | 579 | 2.75M | let len = unsafe { slice_nn.as_ref() }.len(); | 580 | 2.75M | Self { | 581 | 2.75M | ptr, | 582 | 2.75M | len, | 583 | 2.75M | ..Self::EMPTY | 584 | 2.75M | } | 585 | 2.75M | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, _, _>>::from_bitslice_ptr |
586 | | } |
587 | | |
588 | | /// Conversions. |
589 | | impl<T, O> BitSpan<Mut, T, O> |
590 | | where |
591 | | T: BitStore, |
592 | | O: BitOrder, |
593 | | { |
594 | | /// Converts the span descriptor into a raw mutable `BitSlice` pointer. |
595 | | /// |
596 | | /// This is a noöp. |
597 | 1.29M | pub(crate) fn into_bitslice_ptr_mut(self) -> *mut BitSlice<T, O> { |
598 | 1.29M | self.into_bitslice_ptr() as *mut BitSlice<T, O> |
599 | 1.29M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::into_bitslice_ptr_mut <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::into_bitslice_ptr_mut Line | Count | Source | 597 | 916k | pub(crate) fn into_bitslice_ptr_mut(self) -> *mut BitSlice<T, O> { | 598 | 916k | self.into_bitslice_ptr() as *mut BitSlice<T, O> | 599 | 916k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::into_bitslice_ptr_mut <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::into_bitslice_ptr_mut Line | Count | Source | 597 | 374k | pub(crate) fn into_bitslice_ptr_mut(self) -> *mut BitSlice<T, O> { | 598 | 374k | self.into_bitslice_ptr() as *mut BitSlice<T, O> | 599 | 374k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, _, _>>::into_bitslice_ptr_mut |
600 | | |
601 | | /// Converts the span descriptor into an exclusive `BitSlice` reference. |
602 | | /// |
603 | | /// This is a noöp. |
604 | | /// |
605 | | /// ## Safety |
606 | | /// |
607 | | /// The span must describe memory that is safe to dereference. In addition, |
608 | | /// no other `BitSlice` reference of any kind (`&` or `&mut`) may exist. |
609 | 1.29M | pub(crate) unsafe fn into_bitslice_mut<'a>(self) -> &'a mut BitSlice<T, O> { |
610 | 1.29M | &mut *self.into_bitslice_ptr_mut() |
611 | 1.29M | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8>>::into_bitslice_mut <bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::into_bitslice_mut Line | Count | Source | 609 | 916k | pub(crate) unsafe fn into_bitslice_mut<'a>(self) -> &'a mut BitSlice<T, O> { | 610 | 916k | &mut *self.into_bitslice_ptr_mut() | 611 | 916k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8>>::into_bitslice_mut <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::into_bitslice_mut Line | Count | Source | 609 | 374k | pub(crate) unsafe fn into_bitslice_mut<'a>(self) -> &'a mut BitSlice<T, O> { | 610 | 374k | &mut *self.into_bitslice_ptr_mut() | 611 | 374k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, _, _>>::into_bitslice_mut |
612 | | } |
613 | | |
614 | | /// Utilities. |
615 | | impl<M, T, O> BitSpan<M, T, O> |
616 | | where |
617 | | M: Mutability, |
618 | | T: BitStore, |
619 | | O: BitOrder, |
620 | | { |
621 | | /// Checks if a requested length can be encoded into the `BitSpan`. |
622 | | /// |
623 | | /// This is `len <= Self::REGION_MAX_BITS`. |
624 | | #[cfg(feature = "alloc")] |
625 | 0 | pub(crate) fn len_encodable(len: usize) -> bool { |
626 | 0 | len <= Self::REGION_MAX_BITS |
627 | 0 | } |
628 | | |
629 | | /// Renders the pointer structure into a formatter for use during |
630 | | /// higher-level type [`Debug`] implementations. |
631 | | /// |
632 | | /// # Parameters |
633 | | /// |
634 | | /// - `&self` |
635 | | /// - `fmt`: The formatter into which the pointer is rendered. |
636 | | /// - `name`: The suffix of the structure rendering its pointer. The `Bit` |
637 | | /// prefix is applied to the object type name in this format. |
638 | | /// - `fields`: Any additional fields in the object’s debug info to be |
639 | | /// rendered. |
640 | | /// |
641 | | /// # Returns |
642 | | /// |
643 | | /// The result of formatting the pointer into the receiver. |
644 | | /// |
645 | | /// # Behavior |
646 | | /// |
647 | | /// This function writes `Bit{name}<{ord}, {type}> {{ {fields } }}` into the |
648 | | /// `fmt` formatter, where `{fields}` includes the address, head index, and |
649 | | /// bit length of the pointer, as well as any additional fields provided by |
650 | | /// the caller. |
651 | | /// |
652 | | /// Higher types in the crate should use this function to drive their |
653 | | /// [`Debug`] implementations, and then use [`BitSlice`]’s list formatters |
654 | | /// to display their buffer contents. |
655 | | /// |
656 | | /// [`BitSlice`]: crate::slice::BitSlice |
657 | | /// [`Debug`]: core::fmt::Debug |
658 | 0 | pub(crate) fn render<'a>( |
659 | 0 | &'a self, |
660 | 0 | fmt: &'a mut Formatter, |
661 | 0 | name: &'a str, |
662 | 0 | fields: impl IntoIterator<Item = &'a (&'a str, &'a dyn Debug)>, |
663 | 0 | ) -> fmt::Result { |
664 | 0 | write!( |
665 | 0 | fmt, |
666 | 0 | "Bit{}<{}, {}>", |
667 | | name, |
668 | 0 | any::type_name::<T::Mem>(), |
669 | 0 | any::type_name::<O>(), |
670 | 0 | )?; |
671 | 0 | let mut builder = fmt.debug_struct(""); |
672 | 0 | builder |
673 | 0 | .field("addr", &self.address().fmt_pointer()) |
674 | 0 | .field("head", &self.head().fmt_binary()) |
675 | 0 | .field("bits", &self.len()); |
676 | 0 | for (name, value) in fields { |
677 | 0 | builder.field(name, value); |
678 | 0 | } |
679 | 0 | builder.finish() |
680 | 0 | } |
681 | | } |
682 | | |
683 | | #[cfg(not(tarpaulin_include))] |
684 | | impl<M, T, O> Clone for BitSpan<M, T, O> |
685 | | where |
686 | | M: Mutability, |
687 | | T: BitStore, |
688 | | O: BitOrder, |
689 | | { |
690 | | #[inline] |
691 | 0 | fn clone(&self) -> Self { |
692 | 0 | *self |
693 | 0 | } |
694 | | } |
695 | | |
696 | | impl<M1, M2, O, T1, T2> PartialEq<BitSpan<M2, T2, O>> for BitSpan<M1, T1, O> |
697 | | where |
698 | | M1: Mutability, |
699 | | M2: Mutability, |
700 | | O: BitOrder, |
701 | | T1: BitStore, |
702 | | T2: BitStore, |
703 | | { |
704 | | #[inline] |
705 | 0 | fn eq(&self, other: &BitSpan<M2, T2, O>) -> bool { |
706 | 0 | let (addr_a, head_a, bits_a) = self.raw_parts(); |
707 | 0 | let (addr_b, head_b, bits_b) = other.raw_parts(); |
708 | 0 | bits_of::<T1::Mem>() == bits_of::<T2::Mem>() |
709 | 0 | && addr_a.to_const() as usize == addr_b.to_const() as usize |
710 | 0 | && head_a.into_inner() == head_b.into_inner() |
711 | 0 | && bits_a == bits_b |
712 | 0 | } |
713 | | } |
714 | | |
715 | | impl<T, O> From<&BitSlice<T, O>> for BitSpan<Const, T, O> |
716 | | where |
717 | | T: BitStore, |
718 | | O: BitOrder, |
719 | | { |
720 | | #[inline] |
721 | 225k | fn from(bits: &BitSlice<T, O>) -> Self { |
722 | 225k | Self::from_bitslice_ptr(bits) |
723 | 225k | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8> as core::convert::From<&bitvec::slice::BitSlice<u8>>>::from <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0> as core::convert::From<&bitvec::slice::BitSlice<u8, bitvec::order::Msb0>>>::from Line | Count | Source | 721 | 225k | fn from(bits: &BitSlice<T, O>) -> Self { | 722 | 225k | Self::from_bitslice_ptr(bits) | 723 | 225k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, _, _> as core::convert::From<&bitvec::slice::BitSlice<_, _>>>::from |
724 | | } |
725 | | |
726 | | impl<T, O> From<&mut BitSlice<T, O>> for BitSpan<Mut, T, O> |
727 | | where |
728 | | T: BitStore, |
729 | | O: BitOrder, |
730 | | { |
731 | | #[inline] |
732 | 275k | fn from(bits: &mut BitSlice<T, O>) -> Self { |
733 | 275k | Self::from_bitslice_ptr_mut(bits) |
734 | 275k | } Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8> as core::convert::From<&mut bitvec::slice::BitSlice<u8>>>::from <bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0> as core::convert::From<&mut bitvec::slice::BitSlice<u8, bitvec::order::Msb0>>>::from Line | Count | Source | 732 | 275k | fn from(bits: &mut BitSlice<T, O>) -> Self { | 733 | 275k | Self::from_bitslice_ptr_mut(bits) | 734 | 275k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, _, _> as core::convert::From<&mut bitvec::slice::BitSlice<_, _>>>::from |
735 | | } |
736 | | |
737 | | #[cfg(not(tarpaulin_include))] |
738 | | impl<M, T, O> Default for BitSpan<M, T, O> |
739 | | where |
740 | | M: Mutability, |
741 | | T: BitStore, |
742 | | O: BitOrder, |
743 | | { |
744 | | #[inline] |
745 | 0 | fn default() -> Self { |
746 | 0 | Self::EMPTY |
747 | 0 | } |
748 | | } |
749 | | |
750 | | impl<M, T, O> Debug for BitSpan<M, T, O> |
751 | | where |
752 | | M: Mutability, |
753 | | T: BitStore, |
754 | | O: BitOrder, |
755 | | { |
756 | | #[inline] |
757 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
758 | 0 | self.render(fmt, "Span", None) |
759 | 0 | } |
760 | | } |
761 | | |
762 | | impl<M, T, O> Pointer for BitSpan<M, T, O> |
763 | | where |
764 | | M: Mutability, |
765 | | T: BitStore, |
766 | | O: BitOrder, |
767 | | { |
768 | | #[inline] |
769 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
770 | 0 | Pointer::fmt(&self.address(), fmt)?; |
771 | 0 | fmt.write_str("(")?; |
772 | 0 | Binary::fmt(&self.head(), fmt)?; |
773 | 0 | fmt.write_str(")[")?; |
774 | 0 | Display::fmt(&self.len(), fmt)?; |
775 | 0 | fmt.write_str("]") |
776 | 0 | } |
777 | | } |
778 | | |
779 | | impl<M, T, O> Copy for BitSpan<M, T, O> |
780 | | where |
781 | | M: Mutability, |
782 | | T: BitStore, |
783 | | O: BitOrder, |
784 | | { |
785 | | } |
786 | | |
787 | | /// An error produced when creating `BitSpan` encoded references. |
788 | | #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] |
789 | | pub enum BitSpanError<T> |
790 | | where T: BitStore |
791 | | { |
792 | | /// A null pointer was provided. |
793 | | Null(NullPtrError), |
794 | | /// The base element pointer is not aligned. |
795 | | Misaligned(MisalignError<T>), |
796 | | /// The requested length exceeds the `BitSpan` length ceiling. |
797 | | TooLong(usize), |
798 | | /// The requested address is too high, and wraps to zero. |
799 | | TooHigh(*const T), |
800 | | } |
801 | | |
802 | | #[cfg(not(tarpaulin_include))] |
803 | | impl<T> From<BitPtrError<T>> for BitSpanError<T> |
804 | | where T: BitStore |
805 | | { |
806 | | #[inline] |
807 | 0 | fn from(err: BitPtrError<T>) -> Self { |
808 | 0 | match err { |
809 | 0 | BitPtrError::Null(err) => Self::Null(err), |
810 | 0 | BitPtrError::Misaligned(err) => Self::Misaligned(err), |
811 | | } |
812 | 0 | } |
813 | | } |
814 | | |
815 | | #[cfg(not(tarpaulin_include))] |
816 | | impl<T> From<MisalignError<T>> for BitSpanError<T> |
817 | | where T: BitStore |
818 | | { |
819 | | #[inline] |
820 | 0 | fn from(err: MisalignError<T>) -> Self { |
821 | 0 | Self::Misaligned(err) |
822 | 0 | } |
823 | | } |
824 | | |
825 | | #[cfg(not(tarpaulin_include))] |
826 | | impl<T> Debug for BitSpanError<T> |
827 | | where T: BitStore |
828 | | { |
829 | | #[inline] |
830 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
831 | 0 | write!(fmt, "BitSpanError<{}>::", any::type_name::<T::Mem>())?; |
832 | 0 | match self { |
833 | 0 | Self::Null(err) => fmt.debug_tuple("Null").field(&err).finish(), |
834 | 0 | Self::Misaligned(err) => { |
835 | 0 | fmt.debug_tuple("Misaligned").field(&err).finish() |
836 | | }, |
837 | 0 | Self::TooLong(len) => fmt.debug_tuple("TooLong").field(len).finish(), |
838 | 0 | Self::TooHigh(addr) => { |
839 | 0 | fmt.debug_tuple("TooHigh").field(addr).finish() |
840 | | }, |
841 | | } |
842 | 0 | } Unexecuted instantiation: <bitvec::ptr::span::BitSpanError<u8> as core::fmt::Debug>::fmt Unexecuted instantiation: <bitvec::ptr::span::BitSpanError<_> as core::fmt::Debug>::fmt |
843 | | } |
844 | | |
845 | | #[cfg(not(tarpaulin_include))] |
846 | | impl<T> Display for BitSpanError<T> |
847 | | where T: BitStore |
848 | | { |
849 | | #[inline] |
850 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
851 | 0 | match self { |
852 | 0 | Self::Null(err) => Display::fmt(err, fmt), |
853 | 0 | Self::Misaligned(err) => Display::fmt(err, fmt), |
854 | 0 | Self::TooLong(len) => write!( |
855 | 0 | fmt, |
856 | 0 | "Length {} is too long to encode in a bit-slice, which can \ |
857 | 0 | only accept {} bits", |
858 | | len, |
859 | | BitSpan::<Const, T, Lsb0>::REGION_MAX_BITS, |
860 | | ), |
861 | 0 | Self::TooHigh(addr) => write!( |
862 | 0 | fmt, |
863 | 0 | "Address {:p} is too high, and produces a span that wraps \ |
864 | 0 | around to the zero address.", |
865 | | addr, |
866 | | ), |
867 | | } |
868 | 0 | } |
869 | | } |
870 | | |
871 | | unsafe impl<T> Send for BitSpanError<T> where T: BitStore {} |
872 | | |
873 | | unsafe impl<T> Sync for BitSpanError<T> where T: BitStore {} |
874 | | |
875 | | #[cfg(feature = "std")] |
876 | | impl<T> std::error::Error for BitSpanError<T> where T: BitStore {} |