Skip to main content

bitvec/ptr/
span.rs

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