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 {}