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