Skip to main content

lv_std/unsafe_std/ptrs/
raw_ptr.rs

1use std::alloc::{alloc, alloc_zeroed, dealloc, Layout};
2use std::any::TypeId;
3use std::fmt::Debug;
4use std::marker::{PhantomData};
5use std::mem::{transmute, transmute_copy};
6use std::ops::{Deref, DerefMut};
7use std::ptr::copy_nonoverlapping;
8use crate::forbid_void;
9use crate::unsafe_std::ptrs::into_raw_ptr::IntoRawPtr;
10use super::*;
11
12
13#[repr(transparent)]
14#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
15pub struct RawPtr<T: ?Sized> {
16    ptr: *mut T,
17    _marker: PhantomData<T>,
18}
19
20impl<T: Sized> RawPtr<T> {
21
22    const NULL: RawPtr<T> = RawPtr::null();
23
24    #[inline(always)]
25    pub const fn null() -> RawPtr<T> {
26        Self {
27            ptr: 0 as *mut T,
28            _marker: PhantomData,
29        }
30    }
31
32
33    #[inline(always)]
34    pub unsafe fn alloc() -> RawPtr<T> {
35        Self {
36            ptr: alloc_zeroed(Layout::new::<T>()) as *mut T,
37            _marker: PhantomData,
38        }
39    }
40
41    #[inline(always)]
42    pub unsafe fn calloc(amount: usize) -> RawPtr<T> {
43        Self {
44            ptr: alloc_zeroed(Layout::array::<T>(amount).unwrap()) as *mut T,
45            _marker: PhantomData,
46        }
47    }
48
49    #[inline(always)]
50    pub unsafe fn malloc(size: usize) -> RawPtr<T> {
51        Self {
52            ptr: alloc(Layout::array::<u8>(size).unwrap()) as *mut T,
53            _marker: PhantomData,
54        }
55    }
56
57    #[inline(always)]
58    pub const unsafe fn index<'a>(self, index: isize) -> &'a T {
59        &*self.ptr.offset(index)
60    }
61
62    #[inline(always)]
63    pub const unsafe fn index_mut<'a>(self, index: isize) -> &'a mut T {
64        &mut *self.ptr.offset(index)
65    }
66
67    #[inline(always)]
68    pub const unsafe fn copy_to(self, other: &mut Self) {
69        copy_nonoverlapping(self.ptr, other.ptr, size_of::<T>());
70    }
71
72    #[inline(always)]
73    pub unsafe fn mem_copy_to<D : IntoRawPtr>(self, other: D, size: usize)
74    where <D as IntoRawPtr>::Pointee: 'static
75    {
76        copy_nonoverlapping(self.ptr, other.to_ptr().cast().ptr, size)
77    }
78
79    #[inline(always)]
80    pub unsafe fn assign(mut self, value: T) {
81        *self.ptr = value;
82    }
83
84    #[inline(always)]
85    pub unsafe fn assign_cast<D: 'static>(mut self, value: D) {
86        forbid_void!(D);
87        self.assign(transmute_copy(&value));
88    }
89
90    #[inline(always)]
91    pub unsafe fn assign_check(mut self, value: T) -> ptr_utils::PtrState {
92        if self.ptr.is_null() {
93            ptr_utils::PtrState::Null
94        }  else {
95            *self.ptr = value;
96            ptr_utils::PtrState::Val
97        }
98    }
99
100    #[inline(always)]
101    pub const unsafe fn cast_raw<U>(self) -> *mut U {
102        transmute(self.ptr)
103    }
104
105    #[inline(always)]
106    pub const unsafe fn cast_const_raw<U>(mut self) -> *const U {
107        transmute(self.ptr)
108    }
109
110    #[inline(always)]
111    pub const unsafe fn cast<U>(self) -> RawPtr<U> {
112        transmute(self)
113    }
114}
115
116impl<T: ?Sized> RawPtr<T> {
117
118
119
120    #[inline(always)]
121    pub const fn new(value: &mut T) -> RawPtr<T> {
122        Self {
123            ptr: value as *mut T,
124            _marker: PhantomData,
125        }
126    }
127
128
129    #[inline(always)]
130    pub const unsafe fn from_raw(raw: *mut T) -> RawPtr<T> {
131        transmute(raw)
132    }
133
134
135
136
137    #[inline(always)]
138    pub unsafe fn free(self) {
139        dealloc(self.ptr as *mut u8, Layout::new::<Self>());
140    }
141
142
143
144
145    #[inline(always)]
146    pub const fn get_const_raw(self) -> *const T {
147        self.ptr as *const T
148    }
149
150    #[inline(always)]
151    pub const fn is_null(self) -> bool {
152        self.ptr.is_null()
153    }
154
155    #[inline(always)]
156    pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
157        self.ptr.as_ref()
158    }
159
160    #[inline(always)]
161    pub const unsafe fn as_mut<'a>(mut self) -> Option<&'a mut T> {
162        self.ptr.as_mut()
163    }
164
165    #[inline(always)]
166    pub const unsafe fn as_raw(self) -> Option<*mut T> {
167        if self.ptr.is_null() {
168            None
169        } else {
170            Some(self.ptr)
171        }
172    }
173
174    #[inline(always)]
175    pub const unsafe fn as_const_raw(self) -> Option<*const T> {
176        if self.ptr.is_null() {
177            None
178        } else {
179            Some(self.ptr as  *const T)
180        }
181    }
182    
183    /*
184    #[inline(always)]
185    pub const unsafe fn mut_cast_const(self) -> raw_const_ptr::RawConstPtr<T> {
186        transmute(self)
187    }
188    */
189
190
191
192    #[inline(always)]
193    pub const unsafe fn cast_ref<'a, U>(self) -> &'a U {
194        transmute(self.ptr as *const U)
195    }
196
197    #[inline(always)]
198    pub const unsafe fn cast_mut<'a, U>(mut self) -> &'a mut U {
199        transmute(self.ptr as *mut U)
200    }
201
202
203    #[inline(always)]
204    pub const unsafe fn to_owned(&self) -> RawPtr<T> {
205        RawPtr::<T>::from_raw(self.ptr)
206    }
207}
208
209impl<T> Deref for RawPtr<T> {
210    type Target = T;
211
212    #[inline(always)]
213    fn deref(&self) -> &Self::Target {
214        unsafe { transmute(self.ptr) }
215    }
216}
217
218impl<T> DerefMut for RawPtr<T> {
219
220    #[inline(always)]
221    fn deref_mut(&mut self) -> &mut Self::Target {
222        unsafe { transmute(self.ptr) }
223    }
224}
225
226impl<T: ?Sized> From<*mut T> for RawPtr<T> {
227
228    #[inline(always)]
229    fn from(value: *mut T) -> Self {
230        unsafe { transmute(value) }
231    }
232}
233
234impl<T: ?Sized> From<*const T> for RawPtr<T> {
235
236    #[inline(always)]
237    fn from(value: *const T) -> Self {
238        unsafe { transmute(value) }
239    }
240}
241
242impl<T: Sized> Clone for RawPtr<T> {
243
244    fn clone(&self) -> Self {
245        unsafe {
246            let mut new_ptr = RawPtr::alloc();
247            self.to_owned().copy_to(&mut new_ptr);
248            new_ptr
249        }
250    }
251}
252
253impl<T: Sized> Copy for RawPtr<T> {}
254unsafe impl<T: ?Sized> Send for RawPtr<T> {}
255
256#[cfg(test)]
257mod tests {
258
259    #[cfg(test)]
260    mod ptr {
261        use std::fmt::Debug;
262        use std::mem::transmute;
263        use super::super::*;
264
265        #[test]
266        fn new_and_null() {
267
268            let mut x = 32;
269            let p_x: RawPtr<i32> = RawPtr::new(&mut x);
270            unsafe { assert_eq!(*p_x, 32); }
271
272            let thin_null: *mut () = std::ptr::null_mut();
273            let wide_null: *mut dyn Debug = thin_null as *mut dyn Debug;
274
275            let p_null: RawPtr<i32> = RawPtr::NULL;
276            unsafe {
277                assert_eq!(p_null, transmute(std::ptr::null_mut::<RawPtr<i32>>()));
278            }
279        }
280    }
281}
282
283