1use core::{cell::UnsafeCell, fmt, marker::PhantomData, mem::MaybeUninit, ptr::NonNull};
13
14#[derive(Eq, Hash, Ord, PartialEq, PartialOrd)]
18pub struct Out<'a, T: ?Sized> {
19 ptr: NonNull<T>,
20 _marker: PhantomData<&'a UnsafeCell<T>>,
21}
22impl<'a, T: ?Sized> Out<'a, T> {
23 #[inline]
27 pub unsafe fn nullable(ptr: *mut T) -> Option<Self> {
28 Some(Self {
29 ptr: NonNull::new(ptr)?,
30 _marker: PhantomData,
31 })
32 }
33 #[inline]
37 pub unsafe fn nonnull(ptr: *mut T) -> Self {
38 if cfg!(debug_assertions) {
39 assert!(!ptr.is_null());
40 }
41 Self {
42 ptr: unsafe { NonNull::new_unchecked(ptr) },
43 _marker: PhantomData,
44 }
45 }
46 #[inline]
47 pub fn from_mut(r: &'a mut T) -> Self {
48 unsafe { Self::nonnull(r) }
54 }
55 #[inline]
56 pub fn as_mut_ptr(&mut self) -> *mut T {
57 self.ptr.as_ptr()
58 }
59}
60impl<'a, T> Out<'a, T> {
61 #[inline]
62 pub fn from_uninit_mut(r: &'a mut MaybeUninit<T>) -> Self {
63 unsafe { Self::nonnull(r.as_mut_ptr()) }
68 }
69 #[inline]
70 pub fn write(&mut self, t: T) {
71 unsafe {
72 self.ptr.as_ptr().write(t);
73 }
74 }
75}
76impl<'a, T, const N: usize> Out<'a, [T; N]> {
77 #[inline]
78 pub fn as_slice_mut<'b>(&'b mut self) -> Out<'b, [T]> {
79 unsafe {
80 let ptr: *mut [T; N] = self.as_mut_ptr();
81 Out::from_raw_parts(ptr.cast::<T>(), N)
82 }
83 }
84}
85impl<'a, T> Out<'a, [T]> {
86 pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
90 let ptr = if len == 0 {
93 core::ptr::dangling_mut::<T>()
94 } else {
95 ptr
96 };
97 unsafe { Self::nonnull(core::ptr::slice_from_raw_parts_mut(ptr, len)) }
98 }
99 pub fn len(&self) -> usize {
100 self.ptr.as_ptr().len()
101 }
102 pub fn is_empty(&self) -> bool {
103 self.len() == 0
104 }
105 #[inline]
107 pub fn split_at_checked<'b>(&'b mut self, n: usize) -> Option<[Out<'b, [T]>; 2]> {
108 let l = self.ptr.len();
109 if n > l {
110 return None;
111 }
112 Some([
113 Out {
114 ptr: unsafe {
115 NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut(
116 self.ptr.as_mut_ptr(),
117 n,
118 ))
119 },
120 _marker: PhantomData,
121 },
122 Out {
123 ptr: unsafe {
124 NonNull::new_unchecked(core::ptr::slice_from_raw_parts_mut(
125 self.ptr.as_mut_ptr().add(n),
126 l - n,
127 ))
128 },
129 _marker: PhantomData,
130 },
131 ])
132 }
133 #[inline]
134 pub fn copy_from_slice(&mut self, src: &[T])
135 where
136 T: Copy,
137 {
138 assert_eq!(
139 self.ptr.len(),
140 src.len(),
141 "Out::copy_from_slice size mismatch"
142 );
143 unsafe {
144 self.ptr
153 .as_mut_ptr()
154 .copy_from_nonoverlapping(src.as_ptr(), src.len());
155 }
156 }
157 pub fn copy_common_length_from_slice(&mut self, src: &[T]) -> usize
158 where
159 T: Copy,
160 {
161 let l = src.len().min(self.len());
162 self.split_at_checked(l).unwrap()[0].copy_from_slice(&src[..l]);
163 l
164 }
165 pub fn subslice<'b>(&'b mut self, start: usize, end: usize) -> Out<'b, [T]> {
167 assert!(start <= end);
168 assert!(end <= self.len());
169 unsafe { Self::from_raw_parts(self.as_mut_ptr().as_mut_ptr().add(start), end - start) }
170 }
171 pub fn index<'b>(&'b mut self, i: usize) -> Out<'b, T> {
172 assert!(i <= self.len());
173 unsafe { Out::nonnull(self.as_mut_ptr().as_mut_ptr().add(i)) }
174 }
175}
176impl<T: plain::Plain> Out<'_, [T]> {
178 pub fn zero(&mut self) {
179 let l = self.ptr.len();
180 unsafe {
181 self.ptr.as_mut_ptr().write_bytes(0, l)
185 }
186 }
187 #[inline]
188 pub fn cast_slice_to<'b, U>(mut self) -> Out<'b, [U]>
189 where
190 T: CastSlice<U>,
191 {
192 assert_eq!(self.as_mut_ptr().as_mut_ptr() as usize % align_of::<U>(), 0);
193
194 let byte_length = self.as_mut_ptr().len() * size_of::<T>();
195
196 unsafe {
197 Out::from_raw_parts(
198 self.as_mut_ptr().as_mut_ptr().cast(),
199 byte_length / size_of::<U>(),
200 )
201 }
202 }
203}
204pub unsafe trait CastSlice<U> {}
206unsafe impl CastSlice<i8> for u8 {}
207unsafe impl CastSlice<u8> for i8 {}
208unsafe impl CastSlice<u8> for u8 {}
209unsafe impl CastSlice<i8> for i8 {}
210
211impl<T: ?Sized> fmt::Pointer for Out<'_, T> {
212 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 write!(f, "{:p}", self.ptr)
214 }
215}
216impl<T: ?Sized> fmt::Debug for Out<'_, T> {
217 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218 write!(f, "[Out: {:p}]", self.ptr)
219 }
220}
221pub unsafe trait OutProject {}
226
227impl<'a, T: ?Sized> Out<'a, T> {
228 pub unsafe fn with_lifetime_of<'b, U: ?Sized>(mut self, u: &'b U) -> Out<'b, T> {
229 unsafe { Out::nonnull(self.as_mut_ptr()) }
230 }
231}