bitvec/ptr/
single.rs

1#![doc = include_str!("../../doc/ptr/single.md")]
2
3use core::{
4	any,
5	cmp,
6	convert::TryFrom,
7	fmt::{
8		self,
9		Debug,
10		Display,
11		Formatter,
12		Pointer,
13	},
14	hash::{
15		Hash,
16		Hasher,
17	},
18	marker::PhantomData,
19	ptr,
20};
21
22use tap::{
23	Pipe,
24	TryConv,
25};
26use wyz::{
27	comu::{
28		Address,
29		Const,
30		Frozen,
31		Mut,
32		Mutability,
33		NullPtrError,
34	},
35	fmt::FmtForward,
36};
37
38use super::{
39	check_alignment,
40	AddressExt,
41	BitPtrRange,
42	BitRef,
43	BitSpan,
44	BitSpanError,
45	MisalignError,
46};
47use crate::{
48	access::BitAccess,
49	devel as dvl,
50	index::BitIdx,
51	mem,
52	order::{
53		BitOrder,
54		Lsb0,
55	},
56	store::BitStore,
57};
58
59#[repr(C, packed)]
60#[doc = include_str!("../../doc/ptr/BitPtr.md")]
61pub struct BitPtr<M = Const, T = usize, O = Lsb0>
62where
63	M: Mutability,
64	T: BitStore,
65	O: BitOrder,
66{
67	/// Memory addresses must be well-aligned and non-null.
68	///
69	/// This is not actually a requirement of `BitPtr`, but it is a requirement
70	/// of `BitSpan`, and it is extended across the entire crate for
71	/// consistency.
72	ptr: Address<M, T>,
73	/// The index of the referent bit within `*addr`.
74	bit: BitIdx<T::Mem>,
75	/// The ordering used to select the bit at `head` in `*addr`.
76	_or: PhantomData<O>,
77}
78
79impl<M, T, O> BitPtr<M, T, O>
80where
81	M: Mutability,
82	T: BitStore,
83	O: BitOrder,
84{
85	/// The canonical dangling pointer. This selects the starting bit of the
86	/// canonical dangling pointer for `T`.
87	pub const DANGLING: Self = Self {
88		ptr: Address::DANGLING,
89		bit: BitIdx::MIN,
90		_or: PhantomData,
91	};
92
93	/// Loads the address field, sidestepping any alignment problems.
94	///
95	/// This is the only safe way to access `(&self).ptr`. Do not perform field
96	/// access on `.ptr` through a reference except through this method.
97	#[inline]
98	fn get_addr(&self) -> Address<M, T> {
99		unsafe { ptr::addr_of!(self.ptr).read_unaligned() }
100	}
101
102	/// Tries to construct a `BitPtr` from a memory location and a bit index.
103	///
104	/// ## Parameters
105	///
106	/// - `ptr`: The address of a memory element. `Address` wraps raw pointers
107	///   or references, and enforces that they are not null. `BitPtr`
108	///   additionally requires that the address be well-aligned to its type;
109	///   misaligned addresses cause this to return an error.
110	/// - `bit`: The index of the selected bit within `*ptr`.
111	///
112	/// ## Returns
113	///
114	/// This returns an error if `ptr` is not aligned to `T`; otherwise, it
115	/// returns a new bit-pointer structure to the given element and bit.
116	///
117	/// You should typically prefer to use constructors that take directly from
118	/// a memory reference or pointer, such as the `TryFrom<*T>`
119	/// implementations, the `From<&/mut T>` implementations, or the
120	/// [`::from_ref()`], [`::from_mut()`], [`::from_slice()`], or
121	/// [`::from_slice_mut()`] functions.
122	///
123	/// [`::from_mut()`]: Self::from_mut
124	/// [`::from_ref()`]: Self::from_ref
125	/// [`::from_slice()`]: Self::from_slice
126	/// [`::from_slice_mut()`]: Self::from_slice_mut
127	#[inline]
128	pub fn new(
129		ptr: Address<M, T>,
130		bit: BitIdx<T::Mem>,
131	) -> Result<Self, MisalignError<T>> {
132		Ok(Self {
133			ptr: check_alignment(ptr)?,
134			bit,
135			..Self::DANGLING
136		})
137	}
138
139	/// Constructs a `BitPtr` from an address and head index, without checking
140	/// the address for validity.
141	///
142	/// ## Parameters
143	///
144	/// - `addr`: The memory address to use in the bit-pointer. See the Safety
145	///   section.
146	/// - `head`: The index of the bit in `*addr` that this bit-pointer selects.
147	///
148	/// ## Returns
149	///
150	/// A new bit-pointer composed of the parameters. No validity checking is
151	/// performed.
152	///
153	/// ## Safety
154	///
155	/// The `Address` type imposes a non-null requirement. `BitPtr` additionally
156	/// requires that `addr` is well-aligned for `T`, and presumes that the
157	/// caller has ensured this with [`bv_ptr::check_alignment`][0]. If this is
158	/// not the case, then the program is incorrect, and subsequent behavior is
159	/// not specified.
160	///
161	/// [0]: crate::ptr::check_alignment.
162	#[inline]
163	pub unsafe fn new_unchecked(
164		ptr: Address<M, T>,
165		bit: BitIdx<T::Mem>,
166	) -> Self {
167		if cfg!(debug_assertions) {
168			Self::new(ptr, bit).unwrap()
169		}
170		else {
171			Self {
172				ptr,
173				bit,
174				..Self::DANGLING
175			}
176		}
177	}
178
179	/// Gets the address of the base storage element.
180	#[inline]
181	pub fn address(self) -> Address<M, T> {
182		self.get_addr()
183	}
184
185	/// Gets the `BitIdx` that selects the bit within the memory element.
186	#[inline]
187	pub fn bit(self) -> BitIdx<T::Mem> {
188		self.bit
189	}
190
191	/// Decomposes a bit-pointer into its element address and bit index.
192	///
193	/// ## Parameters
194	///
195	/// - `self`
196	///
197	/// ## Returns
198	///
199	/// - `.0`: The memory address in which the referent bit is located.
200	/// - `.1`: The index of the referent bit in `*.0` according to the `O` type
201	///   parameter.
202	#[inline]
203	pub fn raw_parts(self) -> (Address<M, T>, BitIdx<T::Mem>) {
204		(self.address(), self.bit())
205	}
206
207	/// Converts a bit-pointer into a span descriptor by attaching a length
208	/// counter (in bits).
209	///
210	/// ## Parameters
211	///
212	/// - `self`: The base address of the produced span.
213	/// - `bits`: The length, in bits, of the span.
214	///
215	/// ## Returns
216	///
217	/// A span descriptor beginning at `self` and ending (exclusive) at `self +
218	/// bits`. This fails if it is unable to encode the requested span into a
219	/// descriptor.
220	pub(crate) fn span(
221		self,
222		bits: usize,
223	) -> Result<BitSpan<M, T, O>, BitSpanError<T>> {
224		BitSpan::new(self.ptr, self.bit, bits)
225	}
226
227	/// Converts a bit-pointer into a span descriptor, without performing
228	/// encoding validity checks.
229	///
230	/// ## Parameters
231	///
232	/// - `self`: The base address of the produced span.
233	/// - `bits`: The length, in bits, of the span.
234	///
235	/// ## Returns
236	///
237	/// An encoded span descriptor of `self` and `bits`. Note that no validity
238	/// checks are performed!
239	///
240	/// ## Safety
241	///
242	/// The caller must ensure that the rules of `BitSpan::new` are not
243	/// violated. Typically this method should only be used on parameters that
244	/// have already passed through `BitSpan::new` and are known to be good.
245	pub(crate) unsafe fn span_unchecked(self, bits: usize) -> BitSpan<M, T, O> {
246		BitSpan::new_unchecked(self.get_addr(), self.bit, bits)
247	}
248
249	/// Produces a bit-pointer range beginning at `self` (inclusive) and ending
250	/// at `self + count` (exclusive).
251	///
252	/// ## Safety
253	///
254	/// `self + count` must be within the same provenance region as `self`. The
255	/// first bit past the end of an allocation is included in provenance
256	/// regions, though it is not dereferenceable and will not be dereferenced.
257	///
258	/// It is unsound to *even construct* a pointer that departs the provenance
259	/// region, even if that pointer is never dereferenced!
260	pub(crate) unsafe fn range(self, count: usize) -> BitPtrRange<M, T, O> {
261		(self .. self.add(count)).into()
262	}
263
264	/// Removes write permissions from a bit-pointer.
265	#[inline]
266	pub fn to_const(self) -> BitPtr<Const, T, O> {
267		let Self {
268			ptr: addr,
269			bit: head,
270			..
271		} = self;
272		BitPtr {
273			ptr: addr.immut(),
274			bit: head,
275			..BitPtr::DANGLING
276		}
277	}
278
279	/// Adds write permissions to a bit-pointer.
280	///
281	/// ## Safety
282	///
283	/// This pointer must have been derived from a `*mut` pointer.
284	#[inline]
285	pub unsafe fn to_mut(self) -> BitPtr<Mut, T, O> {
286		let Self {
287			ptr: addr,
288			bit: head,
289			..
290		} = self;
291		BitPtr {
292			ptr: addr.assert_mut(),
293			bit: head,
294			..BitPtr::DANGLING
295		}
296	}
297
298	/// Freezes a bit-pointer, forbidding direct mutation.
299	///
300	/// This is used as a necessary prerequisite to all mutation of memory.
301	/// `BitPtr` uses an implementation scoped to `Frozen<_>` to perform
302	/// alias-aware writes; see below.
303	pub(crate) fn freeze(self) -> BitPtr<Frozen<M>, T, O> {
304		let Self {
305			ptr: addr,
306			bit: head,
307			..
308		} = self;
309		BitPtr {
310			ptr: addr.freeze(),
311			bit: head,
312			..BitPtr::DANGLING
313		}
314	}
315}
316
317impl<T, O> BitPtr<Const, T, O>
318where
319	T: BitStore,
320	O: BitOrder,
321{
322	/// Constructs a `BitPtr` to the zeroth bit in a single element.
323	#[inline]
324	pub fn from_ref(elem: &T) -> Self {
325		unsafe { Self::new_unchecked(elem.into(), BitIdx::MIN) }
326	}
327
328	/// Constructs a `BitPtr` to the zeroth bit in the zeroth element of a
329	/// slice.
330	///
331	/// This method is distinct from `Self::from_ref(&elem[0])`, because it
332	/// ensures that the returned bit-pointer has provenance over the entire
333	/// slice. Indexing within a slice narrows the provenance range, and makes
334	/// departure from the subslice, *even within the original slice*, illegal.
335	#[inline]
336	pub fn from_slice(slice: &[T]) -> Self {
337		unsafe {
338			Self::new_unchecked(slice.as_ptr().into_address(), BitIdx::MIN)
339		}
340	}
341
342	/// Gets a raw pointer to the memory element containing the selected bit.
343	#[inline]
344	#[cfg(not(tarpaulin_include))]
345	pub fn pointer(&self) -> *const T {
346		self.get_addr().to_const()
347	}
348}
349
350impl<T, O> BitPtr<Mut, T, O>
351where
352	T: BitStore,
353	O: BitOrder,
354{
355	/// Constructs a mutable `BitPtr` to the zeroth bit in a single element.
356	#[inline]
357	pub fn from_mut(elem: &mut T) -> Self {
358		unsafe { Self::new_unchecked(elem.into(), BitIdx::MIN) }
359	}
360
361	/// Constructs a `BitPtr` to the zeroth bit in the zeroth element of a
362	/// mutable slice.
363	///
364	/// This method is distinct from `Self::from_mut(&mut elem[0])`, because it
365	/// ensures that the returned bit-pointer has provenance over the entire
366	/// slice. Indexing within a slice narrows the provenance range, and makes
367	/// departure from the subslice, *even within the original slice*, illegal.
368	#[inline]
369	pub fn from_mut_slice(slice: &mut [T]) -> Self {
370		unsafe {
371			Self::new_unchecked(slice.as_mut_ptr().into_address(), BitIdx::MIN)
372		}
373	}
374
375	/// Constructs a mutable `BitPtr` to the zeroth bit in the zeroth element of
376	/// a slice.
377	///
378	/// This method is distinct from `Self::from_mut(&mut elem[0])`, because it
379	/// ensures that the returned bit-pointer has provenance over the entire
380	/// slice. Indexing within a slice narrows the provenance range, and makes
381	/// departure from the subslice, *even within the original slice*, illegal.
382	#[inline]
383	pub fn from_slice_mut(slice: &mut [T]) -> Self {
384		unsafe {
385			Self::new_unchecked(slice.as_mut_ptr().into_address(), BitIdx::MIN)
386		}
387	}
388
389	/// Gets a raw pointer to the memory location containing the selected bit.
390	#[inline]
391	#[cfg(not(tarpaulin_include))]
392	pub fn pointer(&self) -> *mut T {
393		self.get_addr().to_mut()
394	}
395}
396
397/// Port of the `*bool` inherent API.
398impl<M, T, O> BitPtr<M, T, O>
399where
400	M: Mutability,
401	T: BitStore,
402	O: BitOrder,
403{
404	/// Tests if a bit-pointer is the null value.
405	///
406	/// This is always false, as a `BitPtr` is a `NonNull` internally. Use
407	/// `Option<BitPtr>` to express the potential for a null pointer.
408	///
409	/// ## Original
410	///
411	/// [`pointer::is_null`](https://doc.rust-lang.org/std/primitive.pointer.html#method.is_null)
412	#[inline]
413	#[deprecated = "`BitPtr` is never null"]
414	pub fn is_null(self) -> bool {
415		false
416	}
417
418	/// Casts to a `BitPtr` with a different storage parameter.
419	///
420	/// This is not free! In order to maintain value integrity, it encodes a
421	/// `BitSpan` encoded descriptor with its value, casts that, then decodes
422	/// into a `BitPtr` of the target type. If `T` and `U` have different
423	/// `::Mem` associated types, then this may change the selected bit in
424	/// memory. This is an unavoidable cost of the addressing and encoding
425	/// schemes.
426	///
427	/// ## Original
428	///
429	/// [`pointer::cast`](https://doc.rust-lang.org/std/primitive.pointer.html#method.cast)
430	#[inline]
431	pub fn cast<U>(self) -> BitPtr<M, U, O>
432	where U: BitStore {
433		let (addr, head, _) =
434			unsafe { self.span_unchecked(1) }.cast::<U>().raw_parts();
435		unsafe { BitPtr::new_unchecked(addr, head) }
436	}
437
438	/// Decomposes a bit-pointer into its address and head-index components.
439	///
440	/// ## Original
441	///
442	/// [`pointer::to_raw_parts`](https://doc.rust-lang.org/std/primitive.pointer.html#method.to_raw_parts)
443	///
444	/// ## API Differences
445	///
446	/// The original method is unstable as of 1.54.0; however, because `BitPtr`
447	/// already has a similar API, the name is optimistically stabilized here.
448	/// Prefer [`.raw_parts()`] until the original inherent stabilizes.
449	///
450	/// [`.raw_parts()`]: Self::raw_parts
451	#[inline]
452	#[cfg(not(tarpaulin_include))]
453	pub fn to_raw_parts(self) -> (Address<M, T>, BitIdx<T::Mem>) {
454		self.raw_parts()
455	}
456
457	/// Produces a proxy reference to the referent bit.
458	///
459	/// Because `BitPtr` guarantees that it is non-null and well-aligned, this
460	/// never returns `None`. However, this is still unsafe to call on any
461	/// bit-pointers created from conjured values rather than known references.
462	///
463	/// ## Original
464	///
465	/// [`pointer::as_ref`](https://doc.rust-lang.org/std/primitive.pointer.html#method.as_ref)
466	///
467	/// ## API Differences
468	///
469	/// This produces a proxy type rather than a true reference. The proxy
470	/// implements `Deref<Target = bool>`, and can be converted to `&bool` with
471	/// a reborrow `&*`.
472	///
473	/// ## Safety
474	///
475	/// Since `BitPtr` does not permit null or misaligned pointers, this method
476	/// will always dereference the pointer in order to create the proxy. As
477	/// such, you must ensure the following conditions are met:
478	///
479	/// - the pointer must be dereferenceable as defined in the standard library
480	///   documentation
481	/// - the pointer must point to an initialized instance of `T`
482	/// - you must ensure that no other pointer will race to modify the referent
483	///   location while this call is reading from memory to produce the proxy
484	///
485	/// ## Examples
486	///
487	/// ```rust
488	/// use bitvec::prelude::*;
489	///
490	/// let data = 1u8;
491	/// let ptr = BitPtr::<_, _, Lsb0>::from_ref(&data);
492	/// let val = unsafe { ptr.as_ref() }.unwrap();
493	/// assert!(*val);
494	/// ```
495	#[inline]
496	pub unsafe fn as_ref<'a>(self) -> Option<BitRef<'a, Const, T, O>> {
497		Some(BitRef::from_bitptr(self.to_const()))
498	}
499
500	/// Creates a new bit-pointer at a specified offset from the original.
501	///
502	/// `count` is in units of bits.
503	///
504	/// ## Original
505	///
506	/// [`pointer::offset`](https://doc.rust-lang.org/std/primitive.pointer.html#method.offset)
507	///
508	/// ## Safety
509	///
510	/// `BitPtr` is implemented with Rust raw pointers internally, and is
511	/// subject to all of Rust’s rules about provenance and permission tracking.
512	/// You must abide by the safety rules established in the original method,
513	/// to which this internally delegates.
514	///
515	/// Additionally, `bitvec` imposes its own rules: while Rust cannot observe
516	/// provenance beyond an element or byte level, `bitvec` demands that
517	/// `&mut BitSlice` have exclusive view over all bits it observes. You must
518	/// not produce a bit-pointer that departs a `BitSlice` region and intrudes
519	/// on any `&mut BitSlice`’s handle, and you must not produce a
520	/// write-capable bit-pointer that intrudes on a `&BitSlice` handle that
521	/// expects its contents to be immutable.
522	///
523	/// Note that it is illegal to *construct* a bit-pointer that invalidates
524	/// any of these rules. If you wish to defer safety-checking to the point of
525	/// dereferencing, and allow the temporary construction *but not*
526	/// *dereference* of illegal `BitPtr`s, use [`.wrapping_offset()`] instead.
527	///
528	/// ## Examples
529	///
530	/// ```rust
531	/// use bitvec::prelude::*;
532	///
533	/// let data = 5u8;
534	/// let ptr = BitPtr::<_, _, Lsb0>::from_ref(&data);
535	/// unsafe {
536	///   assert!(ptr.read());
537	///   assert!(!ptr.offset(1).read());
538	///   assert!(ptr.offset(2).read());
539	/// }
540	/// ```
541	///
542	/// [`.wrapping_offset()`]: Self::wrapping_offset
543	#[inline]
544	#[must_use = "returns a new bit-pointer rather than modifying its argument"]
545	pub unsafe fn offset(self, count: isize) -> Self {
546		let (elts, head) = self.bit.offset(count);
547		Self::new_unchecked(self.ptr.offset(elts), head)
548	}
549
550	/// Creates a new bit-pointer at a specified offset from the original.
551	///
552	/// `count` is in units of bits.
553	///
554	/// ## Original
555	///
556	/// [`pointer::wrapping_offset`](https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset)
557	///
558	/// ## API Differences
559	///
560	/// `bitvec` makes it explicitly illegal to wrap a pointer around the high
561	/// end of the address space, because it is incapable of representing a null
562	/// pointer.
563	///
564	/// However, `<*T>::wrapping_offset` has additional properties as a result
565	/// of its tolerance for wrapping the address space: it tolerates departing
566	/// a provenance region, and is not unsafe to use to *create* a bit-pointer
567	/// that is outside the bounds of its original provenance.
568	///
569	/// ## Safety
570	///
571	/// This function is safe to use because the bit-pointers it creates defer
572	/// their provenance checks until the point of dereference. As such, you
573	/// can safely use this to perform arbitrary pointer arithmetic that Rust
574	/// considers illegal in ordinary arithmetic, as long as you do not
575	/// dereference the bit-pointer until it has been brought in bounds of the
576	/// originating provenance region.
577	///
578	/// This means that, to the Rust rule engine,
579	/// `let z = x.wrapping_add(y as usize).wrapping_sub(x as usize);` is not
580	/// equivalent to `y`, but `z` is safe to construct, and
581	/// `z.wrapping_add(x as usize).wrapping_sub(y as usize)` produces a
582	/// bit-pointer that *is* equivalent to `x`.
583	///
584	/// See the documentation of the original method for more details about
585	/// provenance regions, and the distinctions that the optimizer makes about
586	/// them.
587	///
588	/// ## Examples
589	///
590	/// ```rust
591	/// use bitvec::prelude::*;
592	///
593	/// let data = 0u32;
594	/// let mut ptr = BitPtr::<_, _, Lsb0>::from_ref(&data);
595	/// let end = ptr.wrapping_offset(32);
596	/// while ptr < end {
597	///   # #[cfg(feature = "std")] {
598	///   println!("{}", unsafe { ptr.read() });
599	///   # }
600	///   ptr = ptr.wrapping_offset(3);
601	/// }
602	/// ```
603	#[inline]
604	#[must_use = "returns a new bit-pointer rather than modifying its argument"]
605	pub fn wrapping_offset(self, count: isize) -> Self {
606		let (elts, head) = self.bit.offset(count);
607		unsafe { Self::new_unchecked(self.ptr.wrapping_offset(elts), head) }
608	}
609
610	/// Calculates the distance (in bits) between two bit-pointers.
611	///
612	/// This method is the inverse of [`.offset()`].
613	///
614	/// ## Original
615	///
616	/// [`pointer::offset_from`](https://doc.rust-lang.org/std/primitive.pointer.html#method.offset_from)
617	///
618	/// ## API Differences
619	///
620	/// The base pointer may have a different `BitStore` type parameter, as long
621	/// as they share an underlying memory type. This is necessary in order to
622	/// accommodate aliasing markers introduced between when an origin pointer
623	/// was taken and when `self` compared against it.
624	///
625	/// ## Safety
626	///
627	/// Both `self` and `origin` **must** be drawn from the same provenance
628	/// region. This means that they must be created from the same Rust
629	/// allocation, whether with `let` or the allocator API, and must be in the
630	/// (inclusive) range `base ..= base + len`. The first bit past the end of
631	/// a region can be addressed, just not dereferenced.
632	///
633	/// See the original `<*T>::offset_from` for more details on region safety.
634	///
635	/// ## Examples
636	///
637	/// ```rust
638	/// use bitvec::prelude::*;
639	///
640	/// let data = 0u32;
641	/// let base = BitPtr::<_, _, Lsb0>::from_ref(&data);
642	/// let low = unsafe { base.add(10) };
643	/// let high = unsafe { low.add(15) };
644	/// unsafe {
645	///   assert_eq!(high.offset_from(low), 15);
646	///   assert_eq!(low.offset_from(high), -15);
647	///   assert_eq!(low.offset(15), high);
648	///   assert_eq!(high.offset(-15), low);
649	/// }
650	/// ```
651	///
652	/// While this method is safe to *construct* bit-pointers that depart a
653	/// provenance region, it remains illegal to *dereference* those pointers!
654	///
655	/// This usage is incorrect, and a program that contains it is not
656	/// well-formed.
657	///
658	/// ```rust,no_run
659	/// use bitvec::prelude::*;
660	///
661	/// let a = 0u8;
662	/// let b = !0u8;
663	///
664	/// let a_ptr = BitPtr::<_, _, Lsb0>::from_ref(&a);
665	/// let b_ptr = BitPtr::<_, _, Lsb0>::from_ref(&b);
666	/// let diff = (b_ptr.pointer() as isize)
667	///   .wrapping_sub(a_ptr.pointer() as isize)
668	///   // Remember: raw pointers are byte-stepped,
669	///   // but bit-pointers are bit-stepped.
670	///   .wrapping_mul(8);
671	/// // This pointer to `b` has `a`’s provenance:
672	/// let b_ptr_2 = a_ptr.wrapping_offset(diff);
673	///
674	/// // They are *arithmetically* equal:
675	/// assert_eq!(b_ptr, b_ptr_2);
676	/// // But it is still undefined behavior to cross provenances!
677	/// assert_eq!(0, unsafe { b_ptr_2.offset_from(b_ptr) });
678	/// ```
679	///
680	/// [`.offset()`]: Self::offset
681	#[inline]
682	pub unsafe fn offset_from<U>(self, origin: BitPtr<M, U, O>) -> isize
683	where U: BitStore<Mem = T::Mem> {
684		self.get_addr()
685			.cast::<T::Mem>()
686			.offset_from(origin.get_addr().cast::<T::Mem>())
687			.wrapping_mul(mem::bits_of::<T::Mem>() as isize)
688			.wrapping_add(self.bit.into_inner() as isize)
689			.wrapping_sub(origin.bit.into_inner() as isize)
690	}
691
692	/// Adjusts a bit-pointer upwards in memory. This is equivalent to
693	/// `.offset(count as isize)`.
694	///
695	/// `count` is in units of bits.
696	///
697	/// ## Original
698	///
699	/// [`pointer::add`](https://doc.rust-lang.org/std/primitive.pointer.html#method.add)
700	///
701	/// ## Safety
702	///
703	/// See [`.offset()`](Self::offset).
704	#[inline]
705	#[must_use = "returns a new bit-pointer rather than modifying its argument"]
706	pub unsafe fn add(self, count: usize) -> Self {
707		self.offset(count as isize)
708	}
709
710	/// Adjusts a bit-pointer downwards in memory. This is equivalent to
711	/// `.offset((count as isize).wrapping_neg())`.
712	///
713	/// `count` is in units of bits.
714	///
715	/// ## Original
716	///
717	/// [`pointer::sub`](https://doc.rust-lang.org/std/primitive.pointer.html#method.sub)
718	///
719	/// ## Safety
720	///
721	/// See [`.offset()`](Self::offset).
722	#[inline]
723	#[must_use = "returns a new bit-pointer rather than modifying its argument"]
724	pub unsafe fn sub(self, count: usize) -> Self {
725		self.offset((count as isize).wrapping_neg())
726	}
727
728	/// Adjusts a bit-pointer upwards in memory, using wrapping semantics. This
729	/// is equivalent to `.wrapping_offset(count as isize)`.
730	///
731	/// `count` is in units of bits.
732	///
733	/// ## Original
734	///
735	/// [`pointer::wrapping_add`](https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_add)
736	///
737	/// ## Safety
738	///
739	/// See [`.wrapping_offset()`](Self::wrapping_offset).
740	#[inline]
741	#[must_use = "returns a new bit-pointer rather than modifying its argument"]
742	pub fn wrapping_add(self, count: usize) -> Self {
743		self.wrapping_offset(count as isize)
744	}
745
746	/// Adjusts a bit-pointer downwards in memory, using wrapping semantics.
747	/// This is equivalent to
748	/// `.wrapping_offset((count as isize).wrapping_neg())`.
749	///
750	/// `count` is in units of bits.
751	///
752	/// ## Original
753	///
754	/// [`pointer::wrapping_add`](https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_add)
755	///
756	/// ## Safety
757	///
758	/// See [`.wrapping_offset()`](Self::wrapping_offset).
759	#[inline]
760	#[must_use = "returns a new bit-pointer rather than modifying its argument"]
761	pub fn wrapping_sub(self, count: usize) -> Self {
762		self.wrapping_offset((count as isize).wrapping_neg())
763	}
764
765	/// Reads the bit from `*self`.
766	///
767	/// ## Original
768	///
769	/// [`pointer::read`](https://doc.rust-lang.org/std/primitive.pointer.html#method.read)
770	///
771	/// ## Safety
772	///
773	/// See [`ptr::read`](crate::ptr::read).
774	#[inline]
775	pub unsafe fn read(self) -> bool {
776		(*self.ptr.to_const()).load_value().get_bit::<O>(self.bit)
777	}
778
779	/// Reads the bit from `*self` using a volatile load.
780	///
781	/// Prefer using a crate such as [`voladdress`][0] to manage volatile I/O
782	/// and use `bitvec` only on the local objects it provides. Individual I/O
783	/// operations for individual bits are likely not the behavior you want.
784	///
785	/// ## Original
786	///
787	/// [`pointer::read_volatile`](https://doc.rust-lang.org/std/primitive.pointer.html#method.read_volatile)
788	///
789	/// ## Safety
790	///
791	/// See [`ptr::read_volatile`](crate::ptr::read_volatile).
792	///
793	/// [0]: https://docs.rs/voladdress/later/voladdress
794	#[inline]
795	pub unsafe fn read_volatile(self) -> bool {
796		self.ptr.to_const().read_volatile().get_bit::<O>(self.bit)
797	}
798
799	/// Reads the bit from `*self` using an unaligned memory access.
800	///
801	/// `BitPtr` forbids unaligned addresses. If you have such an address, you
802	/// must perform your memory accesses on the raw element, and only use
803	/// `bitvec` on a well-aligned stack temporary. This method should never be
804	/// necessary.
805	///
806	/// ## Original
807	///
808	/// [`pointer::read_unaligned`](https://doc.rust-lang.org/std/primitive.pointer.html#method.read_unaligned)
809	///
810	/// ## Safety
811	///
812	/// See [`ptr::read_unaligned`](crate::ptr::read_unaligned)
813	#[inline]
814	#[deprecated = "`BitPtr` does not have unaligned addresses"]
815	pub unsafe fn read_unaligned(self) -> bool {
816		self.ptr.to_const().read_unaligned().get_bit::<O>(self.bit)
817	}
818
819	/// Copies `count` bits from `self` to `dest`. The source and destination
820	/// may overlap.
821	///
822	/// Note that overlap is only defined when `O` and `O2` are the same type.
823	/// If they differ, then `bitvec` does not define overlap, and assumes that
824	/// they are wholly discrete in memory.
825	///
826	/// ## Original
827	///
828	/// [`pointer::copy_to`](https://doc.rust-lang.org/std/primitive.pointer.html#method.copy_to)
829	///
830	/// ## Safety
831	///
832	/// See [`ptr::copy`](crate::ptr::copy).
833	#[inline]
834	#[cfg(not(tarpaulin_include))]
835	pub unsafe fn copy_to<T2, O2>(self, dest: BitPtr<Mut, T2, O2>, count: usize)
836	where
837		T2: BitStore,
838		O2: BitOrder,
839	{
840		super::copy(self.to_const(), dest, count);
841	}
842
843	/// Copies `count` bits from `self` to `dest`. The source and destination
844	/// may *not* overlap.
845	///
846	/// ## Original
847	///
848	/// [`pointer::copy_to_nonoverlapping`](https://doc.rust-lang.org/std/primitive.pointer.html#method.copy_to_nonoverlapping)
849	///
850	/// ## Safety
851	///
852	/// See [`ptr::copy_nonoverlapping`](crate::ptr::copy_nonoverlapping).
853	#[inline]
854	#[cfg(not(tarpaulin_include))]
855	pub unsafe fn copy_to_nonoverlapping<T2, O2>(
856		self,
857		dest: BitPtr<Mut, T2, O2>,
858		count: usize,
859	) where
860		T2: BitStore,
861		O2: BitOrder,
862	{
863		super::copy_nonoverlapping(self.to_const(), dest, count);
864	}
865
866	/// Computes the offset (in bits) that needs to be applied to the
867	/// bit-pointer in order to make it aligned to the given *byte* alignment.
868	///
869	/// “Alignment” here means that the bit-pointer selects the starting bit of
870	/// a memory location whose address satisfies the requested alignment.
871	///
872	/// `align` is measured in **bytes**. If you wish to align your bit-pointer
873	/// to a specific fraction (½, ¼, or ⅛ of one byte), please file an issue
874	/// and I will work on adding this functionality.
875	///
876	/// ## Original
877	///
878	/// [`pointer::align_offset`](https://doc.rust-lang.org/std/primitive.pointer.html#method.align_offset)
879	///
880	/// ## Notes
881	///
882	/// If the base-element address of the bit-pointer is already aligned to
883	/// `align`, then this will return the bit-offset required to select the
884	/// first bit of the successor element.
885	///
886	/// If it is not possible to align the bit-pointer, then the implementation
887	/// returns `usize::MAX`.
888	///
889	/// The return value is measured in bits, not `T` elements or bytes. The
890	/// only thing you can do with it is pass it into [`.add()`] or
891	/// [`.wrapping_add()`].
892	///
893	/// Note from the standard library: It is permissible for the implementation
894	/// to *always* return `usize::MAX`. Only your algorithm’s performance can
895	/// depend on getting a usable offset here; it must be correct independently
896	/// of this function providing a useful value.
897	///
898	/// ## Safety
899	///
900	/// There are no guarantees whatsoëver that offsetting the bit-pointer will
901	/// not overflow or go beyond the allocation that the bit-pointer selects.
902	/// It is up to the caller to ensure that the returned offset is correct in
903	/// all terms other than alignment.
904	///
905	/// ## Panics
906	///
907	/// This method panics if `align` is not a power of two.
908	///
909	/// ## Examples
910	///
911	/// ```rust
912	/// use bitvec::prelude::*;
913	///
914	/// let data = [0u8; 3];
915	/// let ptr = BitPtr::<_, _, Lsb0>::from_slice(&data);
916	/// let ptr = unsafe { ptr.add(2) };
917	/// let count = ptr.align_offset(2);
918	/// assert!(count >= 6);
919	/// ```
920	///
921	/// [`.add()`]: Self::add
922	/// [`.wrapping_add()`]: Self::wrapping_add
923	#[inline]
924	pub fn align_offset(self, align: usize) -> usize {
925		let width = mem::bits_of::<T::Mem>();
926		match (
927			self.ptr.to_const().align_offset(align),
928			self.bit.into_inner() as usize,
929		) {
930			(0, 0) => 0,
931			(0, head) => align * mem::bits_of::<u8>() - head,
932			(usize::MAX, _) => usize::MAX,
933			(elts, head) => elts.wrapping_mul(width).wrapping_sub(head),
934		}
935	}
936}
937
938/// Port of the `*mut bool` inherent API.
939impl<T, O> BitPtr<Mut, T, O>
940where
941	T: BitStore,
942	O: BitOrder,
943{
944	/// Produces a proxy reference to the referent bit.
945	///
946	/// Because `BitPtr` guarantees that it is non-null and well-aligned, this
947	/// never returns `None`. However, this is still unsafe to call on any
948	/// bit-pointers created from conjured values rather than known references.
949	///
950	/// ## Original
951	///
952	/// [`pointer::as_mut`](https://doc.rust-lang.org/std/primitive.pointer.html#method.as_mut)
953	///
954	/// ## API Differences
955	///
956	/// This produces a proxy type rather than a true reference. The proxy
957	/// implements `DerefMut<Target = bool>`, and can be converted to
958	/// `&mut bool` with a reborrow `&mut *`.
959	///
960	/// Writes to the proxy are not reflected in the proxied location until the
961	/// proxy is destroyed, either through `Drop` or its [`.commit()`] method.
962	///
963	/// ## Safety
964	///
965	/// Since `BitPtr` does not permit null or misaligned pointers, this method
966	/// will always dereference the pointer in order to create the proxy. As
967	/// such, you must ensure the following conditions are met:
968	///
969	/// - the pointer must be dereferenceable as defined in the standard library
970	///   documentation
971	/// - the pointer must point to an initialized instance of `T`
972	/// - you must ensure that no other pointer will race to modify the referent
973	///   location while this call is reading from memory to produce the proxy
974	/// - you must ensure that no other `bitvec` handle targets the referent bit
975	///
976	/// ## Examples
977	///
978	/// ```rust
979	/// use bitvec::prelude::*;
980	///
981	/// let mut data = 0u8;
982	/// let ptr = BitPtr::<_, _, Lsb0>::from_mut(&mut data);
983	/// let mut val = unsafe { ptr.as_mut() }.unwrap();
984	/// assert!(!*val);
985	/// *val = true;
986	/// assert!(*val);
987	/// ```
988	///
989	/// [`.commit()`]: crate::ptr::BitRef::commit
990	#[inline]
991	pub unsafe fn as_mut<'a>(self) -> Option<BitRef<'a, Mut, T, O>> {
992		Some(BitRef::from_bitptr(self))
993	}
994
995	/// Copies `count` bits from the region starting at `src` to the region
996	/// starting at `self`.
997	///
998	/// The regions are free to overlap; the implementation will detect overlap
999	/// and correctly avoid it.
1000	///
1001	/// Note: this has the *opposite* argument order from [`ptr::copy`]: `self`
1002	/// is the destination, not the source.
1003	///
1004	/// ## Original
1005	///
1006	/// [`pointer::copy_from`](https://doc.rust-lang.org/std/primitive.pointer.html#method.copy_from)
1007	///
1008	/// ## Safety
1009	///
1010	/// See [`ptr::copy`].
1011	///
1012	/// [`ptr::copy`]: crate::ptr::copy
1013	#[inline]
1014	#[cfg(not(tarpaulin_include))]
1015	pub unsafe fn copy_from<T2, O2>(
1016		self,
1017		src: BitPtr<Const, T2, O2>,
1018		count: usize,
1019	) where
1020		T2: BitStore,
1021		O2: BitOrder,
1022	{
1023		src.copy_to(self, count);
1024	}
1025
1026	/// Copies `count` bits from the region starting at `src` to the region
1027	/// starting at `self`.
1028	///
1029	/// Unlike [`.copy_from()`], the two regions may *not* overlap; this method
1030	/// does not attempt to detect overlap and thus may have a slight
1031	/// performance boost over the overlap-handling `.copy_from()`.
1032	///
1033	/// Note: this has the *opposite* argument order from
1034	/// [`ptr::copy_nonoverlapping`]: `self` is the destination, not the source.
1035	///
1036	/// ## Original
1037	///
1038	/// [`pointer::copy_from_nonoverlapping`](https://doc.rust-lang.org/std/primitive.pointer.html#method.copy_from_nonoverlapping)
1039	///
1040	/// ## Safety
1041	///
1042	/// See [`ptr::copy_nonoverlapping`].
1043	///
1044	/// [`.copy_from()`]: Self::copy_from
1045	#[inline]
1046	#[cfg(not(tarpaulin_include))]
1047	pub unsafe fn copy_from_nonoverlapping<T2, O2>(
1048		self,
1049		src: BitPtr<Const, T2, O2>,
1050		count: usize,
1051	) where
1052		T2: BitStore,
1053		O2: BitOrder,
1054	{
1055		src.copy_to_nonoverlapping(self, count);
1056	}
1057
1058	/// Runs the destructor of the referent value.
1059	///
1060	/// `bool` has no destructor; this function does nothing.
1061	///
1062	/// ## Original
1063	///
1064	/// [`pointer::drop_in_place`](https://doc.rust-lang.org/std/primitive.pointer.html#method.drop_in_place)
1065	///
1066	/// ## Safety
1067	///
1068	/// See [`ptr::drop_in_place`].
1069	///
1070	/// [`ptr::drop_in_place`]: crate::ptr::drop_in_place
1071	#[inline]
1072	#[deprecated = "this has no effect, and should not be called"]
1073	pub fn drop_in_place(self) {}
1074
1075	/// Writes a new bit into the given location.
1076	///
1077	/// ## Original
1078	///
1079	/// [`pointer::write`](https://doc.rust-lang.org/std/primitive.pointer.html#method.write)
1080	///
1081	/// ## Safety
1082	///
1083	/// See [`ptr::write`].
1084	///
1085	/// [`ptr::write`]: crate::ptr::write
1086	#[inline]
1087	pub unsafe fn write(self, value: bool) {
1088		self.replace(value);
1089	}
1090
1091	/// Writes a new bit using volatile I/O operations.
1092	///
1093	/// Because processors do not generally have single-bit read or write
1094	/// instructions, this must perform a volatile read of the entire memory
1095	/// location, perform the write locally, then perform another volatile write
1096	/// to the entire location. These three steps are guaranteed to be
1097	/// sequential with respect to each other, but are not guaranteed to be
1098	/// atomic.
1099	///
1100	/// Volatile operations are intended to act on I/O memory, and are *only*
1101	/// guaranteed not to be elided or reördered by the compiler across other
1102	/// I/O operations.
1103	///
1104	/// You should not use `bitvec` to act on volatile memory. You should use a
1105	/// crate specialized for volatile I/O work, such as [`voladdr`], and use it
1106	/// to explicitly manage the I/O and ask it to perform `bitvec` work only on
1107	/// the local snapshot of a volatile location.
1108	///
1109	/// ## Original
1110	///
1111	/// [`pointer::write_volatile`](https://doc.rust-lang.org/std/primitive.pointer.html#method.write_volatile)
1112	///
1113	/// ## Safety
1114	///
1115	/// See [`ptr::write_volatile`].
1116	///
1117	/// [`ptr::write_volatile`]: crate::ptr::write_volatile
1118	/// [`voladdr`]: https://docs.rs/voladdr/latest/voladdr
1119	#[inline]
1120	#[allow(clippy::needless_borrow)] // Clippy is wrong.
1121	pub unsafe fn write_volatile(self, value: bool) {
1122		let ptr = self.ptr.to_mut();
1123		let mut tmp = ptr.read_volatile();
1124		Self::new_unchecked((&mut tmp).into(), self.bit).write(value);
1125		ptr.write_volatile(tmp);
1126	}
1127
1128	/// Writes a bit into memory, tolerating unaligned addresses.
1129	///
1130	/// `BitPtr` does not have unaligned addresses. `BitPtr` itself is capable
1131	/// of operating on misaligned addresses, but elects to disallow use of them
1132	/// in keeping with the rest of `bitvec`’s requirements.
1133	///
1134	/// ## Original
1135	///
1136	/// [`pointer::write_unaligned`](https://doc.rust-lang.org/std/primitive.pointer.html#method.write_unaligned)
1137	///
1138	/// ## Safety
1139	///
1140	/// See [`ptr::write_unaligned`].
1141	///
1142	/// [`ptr::write_unaligned`]: crate::ptr::write_unaligned
1143	#[inline]
1144	#[allow(clippy::needless_borrow)] // Clippy is wrong.
1145	#[deprecated = "`BitPtr` does not have unaligned addresses"]
1146	pub unsafe fn write_unaligned(self, value: bool) {
1147		let ptr = self.ptr.to_mut();
1148		let mut tmp = ptr.read_unaligned();
1149		Self::new_unchecked((&mut tmp).into(), self.bit).write(value);
1150		ptr.write_unaligned(tmp);
1151	}
1152
1153	/// Replaces the bit at `*self` with a new value, returning the previous
1154	/// value.
1155	///
1156	/// ## Original
1157	///
1158	/// [`pointer::replace`](https://doc.rust-lang.org/std/primitive.pointer.html#method.replace)
1159	///
1160	/// ## Safety
1161	///
1162	/// See [`ptr::replace`].
1163	///
1164	/// [`ptr::replace`]: crate::ptr::replace
1165	#[inline]
1166	pub unsafe fn replace(self, value: bool) -> bool {
1167		self.freeze().frozen_write_bit(value)
1168	}
1169
1170	/// Swaps the bits at two mutable locations.
1171	///
1172	/// ## Original
1173	///
1174	/// [`pointer::swap`](https://doc.rust-lang.org/std/primitive.pointer.html#method.swap)
1175	///
1176	/// ## Safety
1177	///
1178	/// See [`ptr::swap`].
1179	///
1180	/// [`ptr::swap`]: crate::ptr::swap
1181	#[inline]
1182	pub unsafe fn swap<T2, O2>(self, with: BitPtr<Mut, T2, O2>)
1183	where
1184		T2: BitStore,
1185		O2: BitOrder,
1186	{
1187		self.write(with.replace(self.read()));
1188	}
1189}
1190
1191impl<M, T, O> BitPtr<Frozen<M>, T, O>
1192where
1193	M: Mutability,
1194	T: BitStore,
1195	O: BitOrder,
1196{
1197	/// Writes through a bit-pointer that has had its mutability permission
1198	/// removed.
1199	///
1200	/// This is used to allow `BitPtr<Const, _, AliasSafe<T>>` pointers, which
1201	/// are not `Mut` but may still modify memory, to do so.
1202	pub(crate) unsafe fn frozen_write_bit(self, value: bool) -> bool {
1203		(*self.ptr.cast::<T::Access>().to_const())
1204			.write_bit::<O>(self.bit, value)
1205	}
1206}
1207
1208#[cfg(not(tarpaulin_include))]
1209impl<M, T, O> Clone for BitPtr<M, T, O>
1210where
1211	M: Mutability,
1212	T: BitStore,
1213	O: BitOrder,
1214{
1215	#[inline]
1216	fn clone(&self) -> Self {
1217		Self {
1218			ptr: self.get_addr(),
1219			..*self
1220		}
1221	}
1222}
1223
1224impl<M, T, O> Eq for BitPtr<M, T, O>
1225where
1226	M: Mutability,
1227	T: BitStore,
1228	O: BitOrder,
1229{
1230}
1231
1232impl<M, T, O> Ord for BitPtr<M, T, O>
1233where
1234	M: Mutability,
1235	T: BitStore,
1236	O: BitOrder,
1237{
1238	#[inline]
1239	fn cmp(&self, other: &Self) -> cmp::Ordering {
1240		self.partial_cmp(other).expect(
1241			"BitPtr has a total ordering when type parameters are identical",
1242		)
1243	}
1244}
1245
1246impl<M1, M2, T1, T2, O> PartialEq<BitPtr<M2, T2, O>> for BitPtr<M1, T1, O>
1247where
1248	M1: Mutability,
1249	M2: Mutability,
1250	T1: BitStore,
1251	T2: BitStore,
1252	O: BitOrder,
1253{
1254	#[inline]
1255	fn eq(&self, other: &BitPtr<M2, T2, O>) -> bool {
1256		if !dvl::match_store::<T1::Mem, T2::Mem>() {
1257			return false;
1258		}
1259		self.get_addr().to_const() as usize
1260			== other.get_addr().to_const() as usize
1261			&& self.bit.into_inner() == other.bit.into_inner()
1262	}
1263}
1264
1265impl<M1, M2, T1, T2, O> PartialOrd<BitPtr<M2, T2, O>> for BitPtr<M1, T1, O>
1266where
1267	M1: Mutability,
1268	M2: Mutability,
1269	T1: BitStore,
1270	T2: BitStore,
1271	O: BitOrder,
1272{
1273	#[inline]
1274	fn partial_cmp(&self, other: &BitPtr<M2, T2, O>) -> Option<cmp::Ordering> {
1275		if !dvl::match_store::<T1::Mem, T2::Mem>() {
1276			return None;
1277		}
1278		match (self.get_addr().to_const() as usize)
1279			.cmp(&(other.get_addr().to_const() as usize))
1280		{
1281			cmp::Ordering::Equal => {
1282				self.bit.into_inner().partial_cmp(&other.bit.into_inner())
1283			},
1284			ord => Some(ord),
1285		}
1286	}
1287}
1288
1289#[cfg(not(tarpaulin_include))]
1290impl<T, O> From<&T> for BitPtr<Const, T, O>
1291where
1292	T: BitStore,
1293	O: BitOrder,
1294{
1295	#[inline]
1296	fn from(elem: &T) -> Self {
1297		Self::from_ref(elem)
1298	}
1299}
1300
1301#[cfg(not(tarpaulin_include))]
1302impl<T, O> From<&mut T> for BitPtr<Mut, T, O>
1303where
1304	T: BitStore,
1305	O: BitOrder,
1306{
1307	#[inline]
1308	fn from(elem: &mut T) -> Self {
1309		Self::from_mut(elem)
1310	}
1311}
1312
1313impl<T, O> TryFrom<*const T> for BitPtr<Const, T, O>
1314where
1315	T: BitStore,
1316	O: BitOrder,
1317{
1318	type Error = BitPtrError<T>;
1319
1320	#[inline]
1321	fn try_from(elem: *const T) -> Result<Self, Self::Error> {
1322		elem.try_conv::<Address<Const, T>>()?
1323			.pipe(|ptr| Self::new(ptr, BitIdx::MIN))?
1324			.pipe(Ok)
1325	}
1326}
1327
1328impl<T, O> TryFrom<*mut T> for BitPtr<Mut, T, O>
1329where
1330	T: BitStore,
1331	O: BitOrder,
1332{
1333	type Error = BitPtrError<T>;
1334
1335	#[inline]
1336	fn try_from(elem: *mut T) -> Result<Self, Self::Error> {
1337		elem.try_conv::<Address<Mut, T>>()?
1338			.pipe(|ptr| Self::new(ptr, BitIdx::MIN))?
1339			.pipe(Ok)
1340	}
1341}
1342
1343impl<M, T, O> Debug for BitPtr<M, T, O>
1344where
1345	M: Mutability,
1346	T: BitStore,
1347	O: BitOrder,
1348{
1349	#[inline]
1350	fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
1351		write!(
1352			fmt,
1353			"{} Bit<{}, {}>",
1354			M::RENDER,
1355			any::type_name::<T>(),
1356			any::type_name::<O>(),
1357		)?;
1358		Pointer::fmt(self, fmt)
1359	}
1360}
1361
1362impl<M, T, O> Pointer for BitPtr<M, T, O>
1363where
1364	M: Mutability,
1365	T: BitStore,
1366	O: BitOrder,
1367{
1368	#[inline]
1369	fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
1370		fmt.debug_tuple("")
1371			.field(&self.get_addr().fmt_pointer())
1372			.field(&self.bit.fmt_binary())
1373			.finish()
1374	}
1375}
1376
1377#[cfg(not(tarpaulin_include))]
1378impl<M, T, O> Hash for BitPtr<M, T, O>
1379where
1380	M: Mutability,
1381	T: BitStore,
1382	O: BitOrder,
1383{
1384	#[inline]
1385	fn hash<H>(&self, state: &mut H)
1386	where H: Hasher {
1387		self.get_addr().hash(state);
1388		self.bit.hash(state);
1389	}
1390}
1391
1392impl<M, T, O> Copy for BitPtr<M, T, O>
1393where
1394	M: Mutability,
1395	T: BitStore,
1396	O: BitOrder,
1397{
1398}
1399
1400/// Errors produced by invalid bit-pointer components.
1401#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1402pub enum BitPtrError<T>
1403where T: BitStore
1404{
1405	/// Attempted to construct a bit-pointer with the null element address.
1406	Null(NullPtrError),
1407	/// Attempted to construct a bit-pointer with an address not aligned for the
1408	/// element type.
1409	Misaligned(MisalignError<T>),
1410}
1411
1412#[cfg(not(tarpaulin_include))]
1413impl<T> From<MisalignError<T>> for BitPtrError<T>
1414where T: BitStore
1415{
1416	#[inline]
1417	fn from(err: MisalignError<T>) -> Self {
1418		Self::Misaligned(err)
1419	}
1420}
1421
1422#[cfg(not(tarpaulin_include))]
1423impl<T> From<NullPtrError> for BitPtrError<T>
1424where T: BitStore
1425{
1426	#[inline]
1427	fn from(err: NullPtrError) -> Self {
1428		Self::Null(err)
1429	}
1430}
1431
1432#[cfg(not(tarpaulin_include))]
1433impl<T> Display for BitPtrError<T>
1434where T: BitStore
1435{
1436	#[inline]
1437	fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
1438		match self {
1439			Self::Null(err) => Display::fmt(err, fmt),
1440			Self::Misaligned(err) => Display::fmt(err, fmt),
1441		}
1442	}
1443}
1444
1445#[cfg(feature = "std")]
1446impl<T> std::error::Error for BitPtrError<T> where T: BitStore {}