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