/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bitvec-1.0.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 | 815k | pub(crate) unsafe fn new_unchecked( |
201 | 815k | addr: Address<M, T>, |
202 | 815k | head: BitIdx<T::Mem>, |
203 | 815k | bits: usize, |
204 | 815k | ) -> Self { |
205 | 815k | let addr = addr.to_const().cast::<u8>(); |
206 | | |
207 | 815k | let head = head.into_inner() as usize; |
208 | 815k | let ptr_data = addr as usize & Self::PTR_ADDR_MASK; |
209 | 815k | let ptr_head = head >> Self::LEN_HEAD_BITS; |
210 | | |
211 | 815k | let len_head = head & Self::LEN_HEAD_MASK; |
212 | 815k | 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 | 815k | let ptr_raw = ptr_data | ptr_head; |
223 | 815k | let ptr = addr.wrapping_add(ptr_raw.wrapping_sub(addr as usize)); |
224 | | |
225 | 815k | Self { |
226 | 815k | ptr: NonNull::new_unchecked(ptr.cast::<()>() as *mut ()), |
227 | 815k | len: len_bits | len_head, |
228 | 815k | ..Self::EMPTY |
229 | 815k | } |
230 | 815k | } 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 | 202k | pub(crate) unsafe fn new_unchecked( | 201 | 202k | addr: Address<M, T>, | 202 | 202k | head: BitIdx<T::Mem>, | 203 | 202k | bits: usize, | 204 | 202k | ) -> Self { | 205 | 202k | let addr = addr.to_const().cast::<u8>(); | 206 | | | 207 | 202k | let head = head.into_inner() as usize; | 208 | 202k | let ptr_data = addr as usize & Self::PTR_ADDR_MASK; | 209 | 202k | let ptr_head = head >> Self::LEN_HEAD_BITS; | 210 | | | 211 | 202k | let len_head = head & Self::LEN_HEAD_MASK; | 212 | 202k | 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 | 202k | let ptr_raw = ptr_data | ptr_head; | 223 | 202k | let ptr = addr.wrapping_add(ptr_raw.wrapping_sub(addr as usize)); | 224 | | | 225 | 202k | Self { | 226 | 202k | ptr: NonNull::new_unchecked(ptr.cast::<()>() as *mut ()), | 227 | 202k | len: len_bits | len_head, | 228 | 202k | ..Self::EMPTY | 229 | 202k | } | 230 | 202k | } |
<bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::new_unchecked Line | Count | Source | 200 | 203k | pub(crate) unsafe fn new_unchecked( | 201 | 203k | addr: Address<M, T>, | 202 | 203k | head: BitIdx<T::Mem>, | 203 | 203k | bits: usize, | 204 | 203k | ) -> Self { | 205 | 203k | let addr = addr.to_const().cast::<u8>(); | 206 | | | 207 | 203k | let head = head.into_inner() as usize; | 208 | 203k | let ptr_data = addr as usize & Self::PTR_ADDR_MASK; | 209 | 203k | let ptr_head = head >> Self::LEN_HEAD_BITS; | 210 | | | 211 | 203k | let len_head = head & Self::LEN_HEAD_MASK; | 212 | 203k | 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 | 203k | let ptr_raw = ptr_data | ptr_head; | 223 | 203k | let ptr = addr.wrapping_add(ptr_raw.wrapping_sub(addr as usize)); | 224 | | | 225 | 203k | Self { | 226 | 203k | ptr: NonNull::new_unchecked(ptr.cast::<()>() as *mut ()), | 227 | 203k | len: len_bits | len_head, | 228 | 203k | ..Self::EMPTY | 229 | 203k | } | 230 | 203k | } |
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 | 410k | pub(crate) unsafe fn new_unchecked( | 201 | 410k | addr: Address<M, T>, | 202 | 410k | head: BitIdx<T::Mem>, | 203 | 410k | bits: usize, | 204 | 410k | ) -> Self { | 205 | 410k | let addr = addr.to_const().cast::<u8>(); | 206 | | | 207 | 410k | let head = head.into_inner() as usize; | 208 | 410k | let ptr_data = addr as usize & Self::PTR_ADDR_MASK; | 209 | 410k | let ptr_head = head >> Self::LEN_HEAD_BITS; | 210 | | | 211 | 410k | let len_head = head & Self::LEN_HEAD_MASK; | 212 | 410k | 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 | 410k | let ptr_raw = ptr_data | ptr_head; | 223 | 410k | let ptr = addr.wrapping_add(ptr_raw.wrapping_sub(addr as usize)); | 224 | | | 225 | 410k | Self { | 226 | 410k | ptr: NonNull::new_unchecked(ptr.cast::<()>() as *mut ()), | 227 | 410k | len: len_bits | len_head, | 228 | 410k | ..Self::EMPTY | 229 | 410k | } | 230 | 410k | } |
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 | 846k | pub(crate) fn address(&self) -> Address<M, T> { |
252 | 846k | Address::new(unsafe { |
253 | 846k | NonNull::new_unchecked( |
254 | 846k | (self.ptr.as_ptr() as usize & Self::PTR_ADDR_MASK) as *mut T, |
255 | | ) |
256 | | }) |
257 | 846k | } 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 | 101k | pub(crate) fn address(&self) -> Address<M, T> { | 252 | 101k | Address::new(unsafe { | 253 | 101k | NonNull::new_unchecked( | 254 | 101k | (self.ptr.as_ptr() as usize & Self::PTR_ADDR_MASK) as *mut T, | 255 | | ) | 256 | | }) | 257 | 101k | } |
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 | 332k | pub(crate) fn address(&self) -> Address<M, T> { | 252 | 332k | Address::new(unsafe { | 253 | 332k | NonNull::new_unchecked( | 254 | 332k | (self.ptr.as_ptr() as usize & Self::PTR_ADDR_MASK) as *mut T, | 255 | | ) | 256 | | }) | 257 | 332k | } |
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 | 413k | pub(crate) fn address(&self) -> Address<M, T> { | 252 | 413k | Address::new(unsafe { | 253 | 413k | NonNull::new_unchecked( | 254 | 413k | (self.ptr.as_ptr() as usize & Self::PTR_ADDR_MASK) as *mut T, | 255 | | ) | 256 | | }) | 257 | 413k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::address |
258 | | |
259 | | /// Overwrites the data pointer with a new address. This method does not |
260 | | /// perform safety checks on the new pointer. |
261 | | /// |
262 | | /// # Parameters |
263 | | /// |
264 | | /// - `&mut self` |
265 | | /// - `ptr`: The new address of the `BitSpan`’s domain. |
266 | | /// |
267 | | /// # Safety |
268 | | /// |
269 | | /// None. The invariants of [`::new`] must be checked at the caller. |
270 | | /// |
271 | | /// [`::new`]: Self::new |
272 | | #[cfg(feature = "alloc")] |
273 | 0 | pub(crate) unsafe fn set_address(&mut self, addr: Address<M, T>) { |
274 | 0 | let mut addr_value = addr.to_const() as usize; |
275 | 0 | addr_value &= Self::PTR_ADDR_MASK; |
276 | 0 | addr_value |= self.ptr.as_ptr() as usize & Self::PTR_HEAD_MASK; |
277 | 0 | self.ptr = NonNull::new_unchecked(addr_value as *mut ()) |
278 | 0 | } |
279 | | |
280 | | /// Gets the starting bit index of the referent region. |
281 | | /// |
282 | | /// # Parameters |
283 | | /// |
284 | | /// - `&self` |
285 | | /// |
286 | | /// # Returns |
287 | | /// |
288 | | /// A [`BitIdx`] of the first live bit in the element at the |
289 | | /// [`self.address()`] address. |
290 | | /// |
291 | | /// [`BitIdx`]: crate::index::BitIdx |
292 | | /// [`self.address()`]: Self::address |
293 | 1.80M | pub(crate) fn head(&self) -> BitIdx<T::Mem> { |
294 | 1.80M | let ptr = self.ptr.as_ptr() as usize; |
295 | 1.80M | let ptr_head = (ptr & Self::PTR_HEAD_MASK) << Self::LEN_HEAD_BITS; |
296 | 1.80M | let len_head = self.len & Self::LEN_HEAD_MASK; |
297 | 1.80M | unsafe { BitIdx::new_unchecked((ptr_head | len_head) as u8) } |
298 | 1.80M | } 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 | 293 | 101k | pub(crate) fn head(&self) -> BitIdx<T::Mem> { | 294 | 101k | let ptr = self.ptr.as_ptr() as usize; | 295 | 101k | let ptr_head = (ptr & Self::PTR_HEAD_MASK) << Self::LEN_HEAD_BITS; | 296 | 101k | let len_head = self.len & Self::LEN_HEAD_MASK; | 297 | 101k | unsafe { BitIdx::new_unchecked((ptr_head | len_head) as u8) } | 298 | 101k | } |
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 | 293 | 784k | pub(crate) fn head(&self) -> BitIdx<T::Mem> { | 294 | 784k | let ptr = self.ptr.as_ptr() as usize; | 295 | 784k | let ptr_head = (ptr & Self::PTR_HEAD_MASK) << Self::LEN_HEAD_BITS; | 296 | 784k | let len_head = self.len & Self::LEN_HEAD_MASK; | 297 | 784k | unsafe { BitIdx::new_unchecked((ptr_head | len_head) as u8) } | 298 | 784k | } |
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 | 293 | 915k | pub(crate) fn head(&self) -> BitIdx<T::Mem> { | 294 | 915k | let ptr = self.ptr.as_ptr() as usize; | 295 | 915k | let ptr_head = (ptr & Self::PTR_HEAD_MASK) << Self::LEN_HEAD_BITS; | 296 | 915k | let len_head = self.len & Self::LEN_HEAD_MASK; | 297 | 915k | unsafe { BitIdx::new_unchecked((ptr_head | len_head) as u8) } | 298 | 915k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::head |
299 | | |
300 | | /// Writes a new `head` value into the pointer, with no other effects. |
301 | | /// |
302 | | /// # Parameters |
303 | | /// |
304 | | /// - `&mut self` |
305 | | /// - `head`: A new starting index. |
306 | | /// |
307 | | /// # Effects |
308 | | /// |
309 | | /// `head` is written into the `.head` logical field, without affecting |
310 | | /// `.addr` or `.bits`. |
311 | | #[cfg(feature = "alloc")] |
312 | 0 | pub(crate) unsafe fn set_head(&mut self, head: BitIdx<T::Mem>) { |
313 | 0 | let head = head.into_inner() as usize; |
314 | 0 | let mut ptr = self.ptr.as_ptr() as usize; |
315 | | |
316 | 0 | ptr &= Self::PTR_ADDR_MASK; |
317 | 0 | ptr |= head >> Self::LEN_HEAD_BITS; |
318 | 0 | self.ptr = NonNull::new_unchecked(ptr as *mut ()); |
319 | | |
320 | 0 | self.len &= !Self::LEN_HEAD_MASK; |
321 | 0 | self.len |= head & Self::LEN_HEAD_MASK; |
322 | 0 | } |
323 | | |
324 | | /// Gets the number of live bits in the described region. |
325 | | /// |
326 | | /// # Parameters |
327 | | /// |
328 | | /// - `&self` |
329 | | /// |
330 | | /// # Returns |
331 | | /// |
332 | | /// A count of how many live bits the region pointer describes. |
333 | 2.48M | pub(crate) fn len(&self) -> usize { |
334 | 2.48M | self.len >> Self::LEN_HEAD_BITS |
335 | 2.48M | } 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 | 333 | 489k | pub(crate) fn len(&self) -> usize { | 334 | 489k | self.len >> Self::LEN_HEAD_BITS | 335 | 489k | } |
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 | 333 | 271k | pub(crate) fn len(&self) -> usize { | 334 | 271k | self.len >> Self::LEN_HEAD_BITS | 335 | 271k | } |
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 | 333 | 1.72M | pub(crate) fn len(&self) -> usize { | 334 | 1.72M | self.len >> Self::LEN_HEAD_BITS | 335 | 1.72M | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::len |
336 | | |
337 | | /// Sets the `.bits` logical member to a new value. |
338 | | /// |
339 | | /// # Parameters |
340 | | /// |
341 | | /// - `&mut self` |
342 | | /// - `len`: A new bit length. This must not be greater than |
343 | | /// [`REGION_MAX_BITS`]. |
344 | | /// |
345 | | /// # Effects |
346 | | /// |
347 | | /// The `new_len` value is written directly into the `.bits` logical field. |
348 | | /// |
349 | | /// [`REGION_MAX_BITS`]: Self::REGION_MAX_BITS |
350 | 6.14k | pub(crate) unsafe fn set_len(&mut self, new_len: usize) { |
351 | 6.14k | if cfg!(debug_assertions) { |
352 | 0 | *self = Self::new(self.address(), self.head(), new_len).unwrap(); |
353 | 0 | } |
354 | 6.14k | else { |
355 | 6.14k | self.len &= Self::LEN_HEAD_MASK; |
356 | 6.14k | self.len |= new_len << Self::LEN_HEAD_BITS; |
357 | 6.14k | } |
358 | 6.14k | } <bitvec::ptr::span::BitSpan<wyz::comu::Const, u8, bitvec::order::Msb0>>::set_len Line | Count | Source | 350 | 6.14k | pub(crate) unsafe fn set_len(&mut self, new_len: usize) { | 351 | 6.14k | if cfg!(debug_assertions) { | 352 | 0 | *self = Self::new(self.address(), self.head(), new_len).unwrap(); | 353 | 0 | } | 354 | 6.14k | else { | 355 | 6.14k | self.len &= Self::LEN_HEAD_MASK; | 356 | 6.14k | self.len |= new_len << Self::LEN_HEAD_BITS; | 357 | 6.14k | } | 358 | 6.14k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::set_len |
359 | | |
360 | | /// Gets the three logical components of the pointer. |
361 | | /// |
362 | | /// The encoding is not public API, and direct field access is never |
363 | | /// supported. |
364 | | /// |
365 | | /// # Parameters |
366 | | /// |
367 | | /// - `&self` |
368 | | /// |
369 | | /// # Returns |
370 | | /// |
371 | | /// - `.0`: The base address of the referent memory region. |
372 | | /// - `.1`: The index of the first live bit in the first element of the |
373 | | /// region. |
374 | | /// - `.2`: The number of live bits in the region. |
375 | 0 | pub(crate) fn raw_parts(&self) -> (Address<M, T>, BitIdx<T::Mem>, usize) { |
376 | 0 | (self.address(), self.head(), self.len()) |
377 | 0 | } |
378 | | } |
379 | | |
380 | | /// Virtual fields. |
381 | | impl<M, T, O> BitSpan<M, T, O> |
382 | | where |
383 | | M: Mutability, |
384 | | T: BitStore, |
385 | | O: BitOrder, |
386 | | { |
387 | | /// Computes the number of elements, starting at [`self.address()`], that |
388 | | /// the region touches. |
389 | | /// |
390 | | /// # Parameters |
391 | | /// |
392 | | /// - `&self` |
393 | | /// |
394 | | /// # Returns |
395 | | /// |
396 | | /// The count of all elements, starting at [`self.address()`], that contain |
397 | | /// live bits included in the referent region. |
398 | | /// |
399 | | /// [`self.address()`]: Self::address |
400 | 407k | pub(crate) fn elements(&self) -> usize { |
401 | 407k | crate::mem::elts::<T>(self.len() + self.head().into_inner() as usize) |
402 | 407k | } 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 | 400 | 226k | pub(crate) fn elements(&self) -> usize { | 401 | 226k | crate::mem::elts::<T>(self.len() + self.head().into_inner() as usize) | 402 | 226k | } |
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 | 400 | 181k | pub(crate) fn elements(&self) -> usize { | 401 | 181k | crate::mem::elts::<T>(self.len() + self.head().into_inner() as usize) | 402 | 181k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::elements |
403 | | |
404 | | /// Computes the tail index for the first dead bit after the live bits. |
405 | | /// |
406 | | /// # Parameters |
407 | | /// |
408 | | /// - `&self` |
409 | | /// |
410 | | /// # Returns |
411 | | /// |
412 | | /// A `BitEnd` that is the index of the first dead bit after the last live |
413 | | /// bit in the last element. This will almost always be in the range `1 ..= |
414 | | /// T::Mem::BITS`. |
415 | | /// |
416 | | /// It will be zero only when `self` is empty. |
417 | 407k | pub(crate) fn tail(&self) -> BitEnd<T::Mem> { |
418 | 407k | let (head, len) = (self.head(), self.len()); |
419 | 407k | let (_, tail) = head.span(len); |
420 | 407k | tail |
421 | 407k | } 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 | 417 | 226k | pub(crate) fn tail(&self) -> BitEnd<T::Mem> { | 418 | 226k | let (head, len) = (self.head(), self.len()); | 419 | 226k | let (_, tail) = head.span(len); | 420 | 226k | tail | 421 | 226k | } |
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 | 417 | 181k | pub(crate) fn tail(&self) -> BitEnd<T::Mem> { | 418 | 181k | let (head, len) = (self.head(), self.len()); | 419 | 181k | let (_, tail) = head.span(len); | 420 | 181k | tail | 421 | 181k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::tail |
422 | | } |
423 | | |
424 | | /// Conversions. |
425 | | impl<M, T, O> BitSpan<M, T, O> |
426 | | where |
427 | | M: Mutability, |
428 | | T: BitStore, |
429 | | O: BitOrder, |
430 | | { |
431 | | /// Casts the span to another element type. |
432 | | /// |
433 | | /// This does not alter the encoded value of the pointer! It only |
434 | | /// reinterprets the element type, and the encoded value may shift |
435 | | /// significantly in the result type. Use with caution. |
436 | 473k | pub(crate) fn cast<U>(self) -> BitSpan<M, U, O> |
437 | 473k | where U: BitStore { |
438 | 473k | let Self { ptr, len, .. } = self; |
439 | 473k | BitSpan { |
440 | 473k | ptr, |
441 | 473k | len, |
442 | 473k | ..BitSpan::EMPTY |
443 | 473k | } |
444 | 473k | } 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 | 436 | 303k | pub(crate) fn cast<U>(self) -> BitSpan<M, U, O> | 437 | 303k | where U: BitStore { | 438 | 303k | let Self { ptr, len, .. } = self; | 439 | 303k | BitSpan { | 440 | 303k | ptr, | 441 | 303k | len, | 442 | 303k | ..BitSpan::EMPTY | 443 | 303k | } | 444 | 303k | } |
<bitvec::ptr::span::BitSpan<wyz::comu::Mut, bitvec::access::BitSafeU8, bitvec::order::Msb0>>::cast::<u8> Line | Count | Source | 436 | 101k | pub(crate) fn cast<U>(self) -> BitSpan<M, U, O> | 437 | 101k | where U: BitStore { | 438 | 101k | let Self { ptr, len, .. } = self; | 439 | 101k | BitSpan { | 440 | 101k | ptr, | 441 | 101k | len, | 442 | 101k | ..BitSpan::EMPTY | 443 | 101k | } | 444 | 101k | } |
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 | 436 | 69.3k | pub(crate) fn cast<U>(self) -> BitSpan<M, U, O> | 437 | 69.3k | where U: BitStore { | 438 | 69.3k | let Self { ptr, len, .. } = self; | 439 | 69.3k | BitSpan { | 440 | 69.3k | ptr, | 441 | 69.3k | len, | 442 | 69.3k | ..BitSpan::EMPTY | 443 | 69.3k | } | 444 | 69.3k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::cast::<_> |
445 | | |
446 | | /// Reäligns a bit-span to a different base memory type. |
447 | | /// |
448 | | /// ## Original |
449 | | /// |
450 | | /// [`slice::align_to`](https://doc.rust-lang.org/std/primitive.slice.html#method.align_to) |
451 | | /// |
452 | | /// ## Safety |
453 | | /// |
454 | | /// `U` must have the same type family as `T`. It is illegal to use this |
455 | | /// method to cast away alias safeties such as an atomic or `Cell` wrapper. |
456 | 0 | pub(crate) unsafe fn align_to<U>(self) -> (Self, BitSpan<M, U, O>, Self) |
457 | 0 | where U: BitStore { |
458 | | /* This function body implements the algorithm locally, rather than |
459 | | * delegating to the standard library’s `<[T]>::align_to::<U>` |
460 | | * function, because that requires use of memory references, and |
461 | | * `BitSpan` does not require that its values be valid for |
462 | | * dereference. |
463 | | */ |
464 | 0 | let this = self.to_bitptr(); |
465 | | // Counter for how many bits remain in the span. |
466 | 0 | let mut rem = self.len(); |
467 | | // The *byte* alignment of `U`. |
468 | 0 | let align = mem::align_of::<U>(); |
469 | | // 1. Get the number of bits between `self.head()` and the start of a |
470 | | // `[U]` region. |
471 | 0 | let step = this.align_offset(align); |
472 | | // If this count is more than the available bits, quit. |
473 | 0 | if step > rem { |
474 | 0 | return (self, BitSpan::EMPTY, Self::EMPTY); |
475 | 0 | } |
476 | 0 | let left = this.span_unchecked(step); |
477 | 0 | rem -= step; |
478 | | |
479 | 0 | let mid_base = |
480 | 0 | this.add(step).address().cast::<U>().pipe(|addr| { |
481 | 0 | BitPtr::<M, U, O>::new_unchecked(addr, BitIdx::MIN) |
482 | 0 | }); |
483 | 0 | let mid_elts = rem >> <U::Mem as BitRegister>::INDX; |
484 | 0 | let excess = rem & <U::Mem as BitRegister>::MASK as usize; |
485 | 0 | let step = rem - excess; |
486 | 0 | let mid = mid_base.span_unchecked(step); |
487 | | |
488 | 0 | let right_base = |
489 | 0 | mid_base.address().add(mid_elts).cast::<T>().pipe(|addr| { |
490 | 0 | BitPtr::<M, T, O>::new_unchecked(addr, BitIdx::MIN) |
491 | 0 | }); |
492 | 0 | let right = right_base.span_unchecked(excess); |
493 | | |
494 | 0 | (left, mid, right) |
495 | 0 | } |
496 | | |
497 | | /// Casts a mutable bit-slice pointer into its structural representation. |
498 | 906k | pub(crate) fn from_bitslice_ptr_mut(raw: *mut BitSlice<T, O>) -> Self { |
499 | 906k | let BitSpan { ptr, len, .. } = |
500 | 906k | BitSpan::from_bitslice_ptr(raw as *const BitSlice<T, O>); |
501 | 906k | Self { |
502 | 906k | ptr, |
503 | 906k | len, |
504 | 906k | ..Self::EMPTY |
505 | 906k | } |
506 | 906k | } 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 | 498 | 505k | pub(crate) fn from_bitslice_ptr_mut(raw: *mut BitSlice<T, O>) -> Self { | 499 | 505k | let BitSpan { ptr, len, .. } = | 500 | 505k | BitSpan::from_bitslice_ptr(raw as *const BitSlice<T, O>); | 501 | 505k | Self { | 502 | 505k | ptr, | 503 | 505k | len, | 504 | 505k | ..Self::EMPTY | 505 | 505k | } | 506 | 505k | } |
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 | 498 | 401k | pub(crate) fn from_bitslice_ptr_mut(raw: *mut BitSlice<T, O>) -> Self { | 499 | 401k | let BitSpan { ptr, len, .. } = | 500 | 401k | BitSpan::from_bitslice_ptr(raw as *const BitSlice<T, O>); | 501 | 401k | Self { | 502 | 401k | ptr, | 503 | 401k | len, | 504 | 401k | ..Self::EMPTY | 505 | 401k | } | 506 | 401k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::from_bitslice_ptr_mut |
507 | | |
508 | | /// Converts the span descriptor into a raw `BitSlice` pointer. |
509 | | /// |
510 | | /// This is a noöp. |
511 | 1.46M | pub(crate) fn into_bitslice_ptr(self) -> *const BitSlice<T, O> { |
512 | 1.46M | let Self { ptr, len, .. } = self; |
513 | 1.46M | ptr::slice_from_raw_parts(ptr.as_ptr(), len) as *const BitSlice<T, O> |
514 | 1.46M | } 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 | 511 | 744k | pub(crate) fn into_bitslice_ptr(self) -> *const BitSlice<T, O> { | 512 | 744k | let Self { ptr, len, .. } = self; | 513 | 744k | ptr::slice_from_raw_parts(ptr.as_ptr(), len) as *const BitSlice<T, O> | 514 | 744k | } |
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 | 511 | 304k | pub(crate) fn into_bitslice_ptr(self) -> *const BitSlice<T, O> { | 512 | 304k | let Self { ptr, len, .. } = self; | 513 | 304k | ptr::slice_from_raw_parts(ptr.as_ptr(), len) as *const BitSlice<T, O> | 514 | 304k | } |
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 | 511 | 416k | pub(crate) fn into_bitslice_ptr(self) -> *const BitSlice<T, O> { | 512 | 416k | let Self { ptr, len, .. } = self; | 513 | 416k | ptr::slice_from_raw_parts(ptr.as_ptr(), len) as *const BitSlice<T, O> | 514 | 416k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::into_bitslice_ptr |
515 | | |
516 | | /// Converts the span descriptor into a shared `BitSlice` reference. |
517 | | /// |
518 | | /// This is a noöp. |
519 | | /// |
520 | | /// ## Safety |
521 | | /// |
522 | | /// The span must describe memory that is safe to dereference, and to which |
523 | | /// no `&mut BitSlice` references exist. |
524 | 416k | pub(crate) unsafe fn into_bitslice_ref<'a>(self) -> &'a BitSlice<T, O> { |
525 | 416k | &*self.into_bitslice_ptr() |
526 | 416k | } 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 | 524 | 416k | pub(crate) unsafe fn into_bitslice_ref<'a>(self) -> &'a BitSlice<T, O> { | 525 | 416k | &*self.into_bitslice_ptr() | 526 | 416k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::into_bitslice_ref |
527 | | |
528 | | /// Produces a bit-pointer to the start of the span. |
529 | | /// |
530 | | /// This is **not** a noöp: the base address and starting bit index are |
531 | | /// decoded into the bit-pointer structure. |
532 | 438k | pub(crate) fn to_bitptr(self) -> BitPtr<M, T, O> { |
533 | 438k | unsafe { BitPtr::new_unchecked(self.address(), self.head()) } |
534 | 438k | } 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 | 532 | 101k | pub(crate) fn to_bitptr(self) -> BitPtr<M, T, O> { | 533 | 101k | unsafe { BitPtr::new_unchecked(self.address(), self.head()) } | 534 | 101k | } |
<bitvec::ptr::span::BitSpan<wyz::comu::Mut, u8, bitvec::order::Msb0>>::to_bitptr Line | Count | Source | 532 | 106k | pub(crate) fn to_bitptr(self) -> BitPtr<M, T, O> { | 533 | 106k | unsafe { BitPtr::new_unchecked(self.address(), self.head()) } | 534 | 106k | } |
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 | 532 | 231k | pub(crate) fn to_bitptr(self) -> BitPtr<M, T, O> { | 533 | 231k | unsafe { BitPtr::new_unchecked(self.address(), self.head()) } | 534 | 231k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<_, _, _>>::to_bitptr |
535 | | |
536 | | /// Produces a bit-pointer range to either end of the span. |
537 | | /// |
538 | | /// This is **not** a noöp: all three logical fields are decoded in order to |
539 | | /// construct the range. |
540 | 0 | pub(crate) fn to_bitptr_range(self) -> BitPtrRange<M, T, O> { |
541 | 0 | let start = self.to_bitptr(); |
542 | 0 | let end = unsafe { start.add(self.len()) }; |
543 | 0 | BitPtrRange { start, end } |
544 | 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 |
545 | | |
546 | | /// Converts the span descriptor into an `Address<>` generic pointer. |
547 | | /// |
548 | | /// This is a noöp. |
549 | 0 | pub(crate) fn to_bitslice_addr(self) -> Address<M, BitSlice<T, O>> { |
550 | 0 | (self.into_bitslice_ptr() as *mut BitSlice<T, O>) |
551 | 0 | .pipe(|ptr| unsafe { NonNull::new_unchecked(ptr) }) |
552 | 0 | .pipe(Address::new) |
553 | 0 | } |
554 | | |
555 | | /// Converts the span descriptor into a `Reference<>` generic handle. |
556 | | /// |
557 | | /// This is a noöp. |
558 | 0 | pub(crate) fn to_bitslice<'a>(self) -> Reference<'a, M, BitSlice<T, O>> |
559 | 0 | where Address<M, BitSlice<T, O>>: Referential<'a> { |
560 | 0 | unsafe { self.to_bitslice_addr().to_ref() } |
561 | 0 | } |
562 | | } |
563 | | |
564 | | /// Conversions. |
565 | | impl<T, O> BitSpan<Const, T, O> |
566 | | where |
567 | | T: BitStore, |
568 | | O: BitOrder, |
569 | | { |
570 | | /// Creates a `Const` span descriptor from a `const` bit-slice pointer. |
571 | 3.00M | pub(crate) fn from_bitslice_ptr(raw: *const BitSlice<T, O>) -> Self { |
572 | 3.00M | let slice_nn = match NonNull::new(raw as *const [()] as *mut [()]) { |
573 | 3.00M | Some(nn) => nn, |
574 | 0 | None => return Self::EMPTY, |
575 | | }; |
576 | 3.00M | let ptr = slice_nn.cast::<()>(); |
577 | 3.00M | let len = unsafe { slice_nn.as_ref() }.len(); |
578 | 3.00M | Self { |
579 | 3.00M | ptr, |
580 | 3.00M | len, |
581 | 3.00M | ..Self::EMPTY |
582 | 3.00M | } |
583 | 3.00M | } 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 | 571 | 776k | pub(crate) fn from_bitslice_ptr(raw: *const BitSlice<T, O>) -> Self { | 572 | 776k | let slice_nn = match NonNull::new(raw as *const [()] as *mut [()]) { | 573 | 776k | Some(nn) => nn, | 574 | 0 | None => return Self::EMPTY, | 575 | | }; | 576 | 776k | let ptr = slice_nn.cast::<()>(); | 577 | 776k | let len = unsafe { slice_nn.as_ref() }.len(); | 578 | 776k | Self { | 579 | 776k | ptr, | 580 | 776k | len, | 581 | 776k | ..Self::EMPTY | 582 | 776k | } | 583 | 776k | } |
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 | 571 | 2.22M | pub(crate) fn from_bitslice_ptr(raw: *const BitSlice<T, O>) -> Self { | 572 | 2.22M | let slice_nn = match NonNull::new(raw as *const [()] as *mut [()]) { | 573 | 2.22M | Some(nn) => nn, | 574 | 0 | None => return Self::EMPTY, | 575 | | }; | 576 | 2.22M | let ptr = slice_nn.cast::<()>(); | 577 | 2.22M | let len = unsafe { slice_nn.as_ref() }.len(); | 578 | 2.22M | Self { | 579 | 2.22M | ptr, | 580 | 2.22M | len, | 581 | 2.22M | ..Self::EMPTY | 582 | 2.22M | } | 583 | 2.22M | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, _, _>>::from_bitslice_ptr |
584 | | } |
585 | | |
586 | | /// Conversions. |
587 | | impl<T, O> BitSpan<Mut, T, O> |
588 | | where |
589 | | T: BitStore, |
590 | | O: BitOrder, |
591 | | { |
592 | | /// Converts the span descriptor into a raw mutable `BitSlice` pointer. |
593 | | /// |
594 | | /// This is a noöp. |
595 | 1.04M | pub(crate) fn into_bitslice_ptr_mut(self) -> *mut BitSlice<T, O> { |
596 | 1.04M | self.into_bitslice_ptr() as *mut BitSlice<T, O> |
597 | 1.04M | } 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 | 595 | 744k | pub(crate) fn into_bitslice_ptr_mut(self) -> *mut BitSlice<T, O> { | 596 | 744k | self.into_bitslice_ptr() as *mut BitSlice<T, O> | 597 | 744k | } |
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 | 595 | 304k | pub(crate) fn into_bitslice_ptr_mut(self) -> *mut BitSlice<T, O> { | 596 | 304k | self.into_bitslice_ptr() as *mut BitSlice<T, O> | 597 | 304k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, _, _>>::into_bitslice_ptr_mut |
598 | | |
599 | | /// Converts the span descriptor into an exclusive `BitSlice` reference. |
600 | | /// |
601 | | /// This is a noöp. |
602 | | /// |
603 | | /// ## Safety |
604 | | /// |
605 | | /// The span must describe memory that is safe to dereference. In addition, |
606 | | /// no other `BitSlice` reference of any kind (`&` or `&mut`) may exist. |
607 | 1.04M | pub(crate) unsafe fn into_bitslice_mut<'a>(self) -> &'a mut BitSlice<T, O> { |
608 | 1.04M | &mut *self.into_bitslice_ptr_mut() |
609 | 1.04M | } 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 | 607 | 744k | pub(crate) unsafe fn into_bitslice_mut<'a>(self) -> &'a mut BitSlice<T, O> { | 608 | 744k | &mut *self.into_bitslice_ptr_mut() | 609 | 744k | } |
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 | 607 | 304k | pub(crate) unsafe fn into_bitslice_mut<'a>(self) -> &'a mut BitSlice<T, O> { | 608 | 304k | &mut *self.into_bitslice_ptr_mut() | 609 | 304k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, _, _>>::into_bitslice_mut |
610 | | } |
611 | | |
612 | | /// Utilities. |
613 | | impl<M, T, O> BitSpan<M, T, O> |
614 | | where |
615 | | M: Mutability, |
616 | | T: BitStore, |
617 | | O: BitOrder, |
618 | | { |
619 | | /// Checks if a requested length can be encoded into the `BitSpan`. |
620 | | /// |
621 | | /// This is `len <= Self::REGION_MAX_BITS`. |
622 | | #[cfg(feature = "alloc")] |
623 | 0 | pub(crate) fn len_encodable(len: usize) -> bool { |
624 | 0 | len <= Self::REGION_MAX_BITS |
625 | 0 | } |
626 | | |
627 | | /// Renders the pointer structure into a formatter for use during |
628 | | /// higher-level type [`Debug`] implementations. |
629 | | /// |
630 | | /// # Parameters |
631 | | /// |
632 | | /// - `&self` |
633 | | /// - `fmt`: The formatter into which the pointer is rendered. |
634 | | /// - `name`: The suffix of the structure rendering its pointer. The `Bit` |
635 | | /// prefix is applied to the object type name in this format. |
636 | | /// - `fields`: Any additional fields in the object’s debug info to be |
637 | | /// rendered. |
638 | | /// |
639 | | /// # Returns |
640 | | /// |
641 | | /// The result of formatting the pointer into the receiver. |
642 | | /// |
643 | | /// # Behavior |
644 | | /// |
645 | | /// This function writes `Bit{name}<{ord}, {type}> {{ {fields } }}` into the |
646 | | /// `fmt` formatter, where `{fields}` includes the address, head index, and |
647 | | /// bit length of the pointer, as well as any additional fields provided by |
648 | | /// the caller. |
649 | | /// |
650 | | /// Higher types in the crate should use this function to drive their |
651 | | /// [`Debug`] implementations, and then use [`BitSlice`]’s list formatters |
652 | | /// to display their buffer contents. |
653 | | /// |
654 | | /// [`BitSlice`]: crate::slice::BitSlice |
655 | | /// [`Debug`]: core::fmt::Debug |
656 | 0 | pub(crate) fn render<'a>( |
657 | 0 | &'a self, |
658 | 0 | fmt: &'a mut Formatter, |
659 | 0 | name: &'a str, |
660 | 0 | fields: impl IntoIterator<Item = &'a (&'a str, &'a dyn Debug)>, |
661 | 0 | ) -> fmt::Result { |
662 | 0 | write!( |
663 | 0 | fmt, |
664 | 0 | "Bit{}<{}, {}>", |
665 | | name, |
666 | 0 | any::type_name::<T::Mem>(), |
667 | 0 | any::type_name::<O>(), |
668 | 0 | )?; |
669 | 0 | let mut builder = fmt.debug_struct(""); |
670 | 0 | builder |
671 | 0 | .field("addr", &self.address().fmt_pointer()) |
672 | 0 | .field("head", &self.head().fmt_binary()) |
673 | 0 | .field("bits", &self.len()); |
674 | 0 | for (name, value) in fields { |
675 | 0 | builder.field(name, value); |
676 | 0 | } |
677 | 0 | builder.finish() |
678 | 0 | } |
679 | | } |
680 | | |
681 | | #[cfg(not(tarpaulin_include))] |
682 | | impl<M, T, O> Clone for BitSpan<M, T, O> |
683 | | where |
684 | | M: Mutability, |
685 | | T: BitStore, |
686 | | O: BitOrder, |
687 | | { |
688 | | #[inline] |
689 | 0 | fn clone(&self) -> Self { |
690 | 0 | *self |
691 | 0 | } |
692 | | } |
693 | | |
694 | | impl<M1, M2, O, T1, T2> PartialEq<BitSpan<M2, T2, O>> for BitSpan<M1, T1, O> |
695 | | where |
696 | | M1: Mutability, |
697 | | M2: Mutability, |
698 | | O: BitOrder, |
699 | | T1: BitStore, |
700 | | T2: BitStore, |
701 | | { |
702 | | #[inline] |
703 | 0 | fn eq(&self, other: &BitSpan<M2, T2, O>) -> bool { |
704 | 0 | let (addr_a, head_a, bits_a) = self.raw_parts(); |
705 | 0 | let (addr_b, head_b, bits_b) = other.raw_parts(); |
706 | 0 | bits_of::<T1::Mem>() == bits_of::<T2::Mem>() |
707 | 0 | && addr_a.to_const() as usize == addr_b.to_const() as usize |
708 | 0 | && head_a.into_inner() == head_b.into_inner() |
709 | 0 | && bits_a == bits_b |
710 | 0 | } |
711 | | } |
712 | | |
713 | | impl<T, O> From<&BitSlice<T, O>> for BitSpan<Const, T, O> |
714 | | where |
715 | | T: BitStore, |
716 | | O: BitOrder, |
717 | | { |
718 | | #[inline] |
719 | 181k | fn from(bits: &BitSlice<T, O>) -> Self { |
720 | 181k | Self::from_bitslice_ptr(bits) |
721 | 181k | } 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 | 719 | 181k | fn from(bits: &BitSlice<T, O>) -> Self { | 720 | 181k | Self::from_bitslice_ptr(bits) | 721 | 181k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Const, _, _> as core::convert::From<&bitvec::slice::BitSlice<_, _>>>::from |
722 | | } |
723 | | |
724 | | impl<T, O> From<&mut BitSlice<T, O>> for BitSpan<Mut, T, O> |
725 | | where |
726 | | T: BitStore, |
727 | | O: BitOrder, |
728 | | { |
729 | | #[inline] |
730 | 226k | fn from(bits: &mut BitSlice<T, O>) -> Self { |
731 | 226k | Self::from_bitslice_ptr_mut(bits) |
732 | 226k | } 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 | 730 | 226k | fn from(bits: &mut BitSlice<T, O>) -> Self { | 731 | 226k | Self::from_bitslice_ptr_mut(bits) | 732 | 226k | } |
Unexecuted instantiation: <bitvec::ptr::span::BitSpan<wyz::comu::Mut, _, _> as core::convert::From<&mut bitvec::slice::BitSlice<_, _>>>::from |
733 | | } |
734 | | |
735 | | #[cfg(not(tarpaulin_include))] |
736 | | impl<M, T, O> Default for BitSpan<M, T, O> |
737 | | where |
738 | | M: Mutability, |
739 | | T: BitStore, |
740 | | O: BitOrder, |
741 | | { |
742 | | #[inline] |
743 | 0 | fn default() -> Self { |
744 | 0 | Self::EMPTY |
745 | 0 | } |
746 | | } |
747 | | |
748 | | impl<M, T, O> Debug for BitSpan<M, T, O> |
749 | | where |
750 | | M: Mutability, |
751 | | T: BitStore, |
752 | | O: BitOrder, |
753 | | { |
754 | | #[inline] |
755 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
756 | 0 | self.render(fmt, "Span", None) |
757 | 0 | } |
758 | | } |
759 | | |
760 | | impl<M, T, O> Pointer for BitSpan<M, T, O> |
761 | | where |
762 | | M: Mutability, |
763 | | T: BitStore, |
764 | | O: BitOrder, |
765 | | { |
766 | | #[inline] |
767 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
768 | 0 | Pointer::fmt(&self.address(), fmt)?; |
769 | 0 | fmt.write_str("(")?; |
770 | 0 | Binary::fmt(&self.head(), fmt)?; |
771 | 0 | fmt.write_str(")[")?; |
772 | 0 | Display::fmt(&self.len(), fmt)?; |
773 | 0 | fmt.write_str("]") |
774 | 0 | } |
775 | | } |
776 | | |
777 | | impl<M, T, O> Copy for BitSpan<M, T, O> |
778 | | where |
779 | | M: Mutability, |
780 | | T: BitStore, |
781 | | O: BitOrder, |
782 | | { |
783 | | } |
784 | | |
785 | | /// An error produced when creating `BitSpan` encoded references. |
786 | | #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] |
787 | | pub enum BitSpanError<T> |
788 | | where T: BitStore |
789 | | { |
790 | | /// A null pointer was provided. |
791 | | Null(NullPtrError), |
792 | | /// The base element pointer is not aligned. |
793 | | Misaligned(MisalignError<T>), |
794 | | /// The requested length exceeds the `BitSpan` length ceiling. |
795 | | TooLong(usize), |
796 | | /// The requested address is too high, and wraps to zero. |
797 | | TooHigh(*const T), |
798 | | } |
799 | | |
800 | | #[cfg(not(tarpaulin_include))] |
801 | | impl<T> From<BitPtrError<T>> for BitSpanError<T> |
802 | | where T: BitStore |
803 | | { |
804 | | #[inline] |
805 | 0 | fn from(err: BitPtrError<T>) -> Self { |
806 | 0 | match err { |
807 | 0 | BitPtrError::Null(err) => Self::Null(err), |
808 | 0 | BitPtrError::Misaligned(err) => Self::Misaligned(err), |
809 | | } |
810 | 0 | } |
811 | | } |
812 | | |
813 | | #[cfg(not(tarpaulin_include))] |
814 | | impl<T> From<MisalignError<T>> for BitSpanError<T> |
815 | | where T: BitStore |
816 | | { |
817 | | #[inline] |
818 | 0 | fn from(err: MisalignError<T>) -> Self { |
819 | 0 | Self::Misaligned(err) |
820 | 0 | } |
821 | | } |
822 | | |
823 | | #[cfg(not(tarpaulin_include))] |
824 | | impl<T> Debug for BitSpanError<T> |
825 | | where T: BitStore |
826 | | { |
827 | | #[inline] |
828 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
829 | 0 | write!(fmt, "BitSpanError<{}>::", any::type_name::<T::Mem>())?; |
830 | 0 | match self { |
831 | 0 | Self::Null(err) => fmt.debug_tuple("Null").field(&err).finish(), |
832 | 0 | Self::Misaligned(err) => { |
833 | 0 | fmt.debug_tuple("Misaligned").field(&err).finish() |
834 | | }, |
835 | 0 | Self::TooLong(len) => fmt.debug_tuple("TooLong").field(len).finish(), |
836 | 0 | Self::TooHigh(addr) => { |
837 | 0 | fmt.debug_tuple("TooHigh").field(addr).finish() |
838 | | }, |
839 | | } |
840 | 0 | } Unexecuted instantiation: <bitvec::ptr::span::BitSpanError<u8> as core::fmt::Debug>::fmt Unexecuted instantiation: <bitvec::ptr::span::BitSpanError<_> as core::fmt::Debug>::fmt |
841 | | } |
842 | | |
843 | | #[cfg(not(tarpaulin_include))] |
844 | | impl<T> Display for BitSpanError<T> |
845 | | where T: BitStore |
846 | | { |
847 | | #[inline] |
848 | 0 | fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { |
849 | 0 | match self { |
850 | 0 | Self::Null(err) => Display::fmt(err, fmt), |
851 | 0 | Self::Misaligned(err) => Display::fmt(err, fmt), |
852 | 0 | Self::TooLong(len) => write!( |
853 | 0 | fmt, |
854 | 0 | "Length {} is too long to encode in a bit-slice, which can \ |
855 | 0 | only accept {} bits", |
856 | | len, |
857 | | BitSpan::<Const, T, Lsb0>::REGION_MAX_BITS, |
858 | | ), |
859 | 0 | Self::TooHigh(addr) => write!( |
860 | 0 | fmt, |
861 | 0 | "Address {:p} is too high, and produces a span that wraps \ |
862 | 0 | around to the zero address.", |
863 | | addr, |
864 | | ), |
865 | | } |
866 | 0 | } |
867 | | } |
868 | | |
869 | | unsafe impl<T> Send for BitSpanError<T> where T: BitStore {} |
870 | | |
871 | | unsafe impl<T> Sync for BitSpanError<T> where T: BitStore {} |
872 | | |
873 | | #[cfg(feature = "std")] |
874 | | impl<T> std::error::Error for BitSpanError<T> where T: BitStore {} |