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