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