Skip to main content

libutils_pointer/
mod.rs

1//^
2//^ HEAD
3//^
4
5//> HEAD -> NO_STD
6#![no_std]
7
8//> HEAD -> FEATURES
9#![feature(const_destruct)]
10#![feature(const_option_ops)]
11#![feature(const_trait_impl)]
12#![feature(const_closures)]
13#![feature(const_try)]
14#![feature(const_default)]
15#![feature(const_convert)]
16#![feature(ptr_mask)]
17
18//> HEAD -> MODULES
19mod comparisons;
20mod conversions;
21#[cfg(test)]
22mod tests;
23
24//> HEAD -> CORE
25use core::{
26    ptr::{
27        NonNull,
28        null,
29        null_mut
30    },
31    fmt::{
32        Debug,
33        Formatter,
34        Result as Format
35    },
36    any::type_name,
37    marker::Destruct
38};
39
40
41//^
42//^ POINTER
43//^
44
45//> POINTER -> STRUCT
46pub struct Pointer<Type> {
47    to: Option<NonNull<Type>>
48}
49
50//> POINTER -> IMPLEMENTATION
51impl<Type> Pointer<Type> {
52    #[inline]
53    pub const fn is_null(self) -> bool {return self.to.is_none()}
54    #[inline]
55    pub fn address(self) -> usize {return self.to.map(|pointer| pointer.addr().into()).unwrap_or_default()}
56    #[inline]
57    pub const fn add(self, count: usize) -> Pointer<Type> {return Self {
58        to: self.to.map(const |pointer| unsafe {pointer.add(count)})
59    }}
60    #[inline]
61    pub const fn sub(self, count: usize) -> Pointer<Type> {return Self {
62        to: self.to.map(const |pointer| unsafe {pointer.sub(count)})
63    }}
64    #[inline]
65    pub const unsafe fn read(self) -> Option<Type> {return Some(unsafe {self.to?.read()})}
66    #[inline]
67    pub const fn as_ptr(self) -> *const Type {return match self.to {
68        None => null(),
69        Some(pointer) => pointer.as_ptr()
70    }}
71    #[inline]
72    pub const fn as_ptr_mut(self) -> *mut Type {return match self.to {
73        None => null_mut(),
74        Some(pointer) => pointer.as_ptr()
75    }}
76    #[inline]
77    pub const fn get<'lifetime>(self) -> Option<&'lifetime Type> {return self.to.map(const |pointer| unsafe {pointer.as_ref()})}
78    #[inline]
79    pub const fn get_mut<'lifetime>(self) -> Option<&'lifetime mut Type> {return self.to.map(const |mut pointer| unsafe {pointer.as_mut()})}
80    #[inline]
81    pub const fn take(self) -> Option<NonNull<Type>> {return self.to}
82    #[inline]
83    pub fn is_aligned(self) -> bool {return self.address() % align_of::<Type>() == 0}
84    #[inline]
85    pub const fn cast<Other>(self) -> Pointer<Other> {return Pointer {
86        to: self.to.map(const |pointer| pointer.cast())
87    }}
88    #[inline]
89    pub fn mask(self, mask: usize) -> Pointer<Type> {Pointer::from(self.to.map(|pointer| pointer.as_ptr()).unwrap_or(null_mut()).mask(mask))}
90}
91
92//> POINTER -> IMPLEMENTATION WITH DESTRUCT
93const impl<Type: [const] Destruct> Pointer<Type> {
94    #[inline]
95    pub unsafe fn write(self, value: Type) -> () {if let Some(pointer) = self.to {unsafe {pointer.write(value)}}}
96    #[inline]
97    pub unsafe fn replace(self, with: Type) -> Option<Type> {return Some(unsafe {self.to?.replace(with)})}
98}
99
100//> POINTER -> CLONE
101impl<Type> Clone for Pointer<Type> {
102    fn clone(&self) -> Self {return Self {
103        to: self.to.clone()
104    }}
105}
106
107//> POINTER -> COPY
108impl<Type> Copy for Pointer<Type> {}
109
110//> POINTER -> DEBUG
111impl<Type: Debug> Debug for Pointer<Type> {
112    fn fmt(&self, formatter: &mut Formatter<'_>) -> Format {write!(formatter, "*{}", type_name::<Type>())}
113}
114
115//> POINTER -> DEFAULT
116const impl<Type> Default for Pointer<Type> {
117    fn default() -> Self {return Self {
118        to: None
119    }}
120}
121
122//> POINTER -> SEND
123unsafe impl<Type> Send for Pointer<Type> {}
124
125//> POINTER -> SYNC
126unsafe impl<Type> Sync for Pointer<Type> {}