1use core::fmt::Write;
2use core::ops::{Deref, DerefMut, Index, IndexMut, Range};
3use core::ptr::{copy_nonoverlapping, NonNull};
4use core::slice::from_raw_parts;
5
6#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
7#[repr(transparent)]
8pub(crate) struct Ptr {
9 ptr: NonNull<u8>,
10}
11
12impl Ptr {
13 #[inline]
14 const fn new_ptr(ptr: *const u8) -> NonNull<u8> {
15 unsafe { NonNull::new_unchecked(ptr.cast_mut()) }
16 }
17
18 #[inline]
19 pub(crate) const fn new(slice: &[u8]) -> Ptr {
20 Ptr {
21 ptr: Self::new_ptr(slice.as_ptr()),
22 }
23 }
24
25 #[inline]
26 pub(crate) fn new_mut(slice: &mut [u8]) -> Ptr {
27 Ptr {
28 ptr: Self::new_ptr(slice.as_mut_ptr()),
29 }
30 }
31
32 #[inline]
33 pub(crate) const fn new_invalid() -> Ptr {
34 Ptr {
35 ptr: NonNull::dangling(),
36 }
37 }
38
39 #[inline]
40 pub(crate) fn offset(self, count: isize) -> Ptr {
41 Ptr {
42 ptr: Self::new_ptr(unsafe { self.ptr.as_ptr().offset(count) }),
43 }
44 }
45
46 #[inline]
47 pub(crate) fn copy_to_nonoverlapping(self, len: isize, to: Ptr, offset: isize) {
48 unsafe {
49 copy_nonoverlapping(
50 self.ptr.as_ptr(),
51 to.ptr.as_ptr().offset(offset),
52 len as usize,
53 );
54 }
55 }
56
57 #[inline]
58 pub(crate) fn as_slice(&self, len: isize) -> &[u8] {
59 unsafe { from_raw_parts(self.ptr.as_ptr(), len as usize) }
60 }
61
62 #[inline]
63 pub(crate) fn offset_from(self, other: Ptr) -> isize {
64 unsafe { self.ptr.as_ptr().offset_from(other.ptr.as_ptr()) }
65 }
66
67 #[inline]
68 pub(crate) fn inc(&mut self) {
69 self.ptr = Self::new_ptr(unsafe { self.ptr.as_ptr().add(1) });
70 }
71
72 #[inline]
73 pub(crate) fn dec(&mut self) {
74 self.ptr = Self::new_ptr(unsafe { self.ptr.as_ptr().sub(1) });
75 }
76
77 #[inline]
78 pub(crate) fn write_char<W: Write>(
79 self,
80 f: &mut W,
81 offset: isize,
82 ) -> Result<(), core::fmt::Error> {
83 f.write_char((b'0' + (self[offset] as u8)).into())
84 }
85
86 #[inline]
87 pub(crate) fn write_chars<W: Write>(
88 self,
89 f: &mut W,
90 range: Range<isize>,
91 ) -> Result<(), core::fmt::Error> {
92 for i in range {
93 f.write_char((b'0' + (self[i] as u8)).into())?;
94 }
95 Ok(())
96 }
97}
98
99impl Index<isize> for Ptr {
100 type Output = i8;
101
102 #[inline]
103 fn index(&self, index: isize) -> &Self::Output {
104 unsafe { &*self.ptr.as_ptr().cast::<i8>().offset(index) }
105 }
106}
107
108impl IndexMut<isize> for Ptr {
109 #[inline]
110 fn index_mut(&mut self, index: isize) -> &mut Self::Output {
111 unsafe { &mut *self.ptr.as_ptr().cast::<i8>().offset(index) }
112 }
113}
114
115impl Deref for Ptr {
116 type Target = i8;
117
118 #[inline]
119 fn deref(&self) -> &Self::Target {
120 self.index(0)
121 }
122}
123
124impl DerefMut for Ptr {
125 #[inline]
126 fn deref_mut(&mut self) -> &mut Self::Target {
127 self.index_mut(0)
128 }
129}