Coverage Report

Created: 2025-10-13 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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 {}