scientific/types/
ptr.rs

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}