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
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 #[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