lv_std/unsafe_std/ptrs/
raw_ptr.rs1use 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 #[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