1use crate::cxx_vector::{CxxVector, VectorElement};
2use crate::fmt::display;
3use crate::kind::Trivial;
4use crate::string::CxxString;
5use crate::ExternType;
6#[cfg(feature = "std")]
7use alloc::string::String;
8#[cfg(feature = "std")]
9use alloc::vec::Vec;
10use core::ffi::c_void;
11use core::fmt::{self, Debug, Display};
12use core::marker::PhantomData;
13use core::mem::{self, MaybeUninit};
14use core::ops::{Deref, DerefMut};
15use core::pin::Pin;
16#[cfg(feature = "std")]
17use std::io::{self, IoSlice, Read, Write};
18
19#[repr(C)]
21pub struct UniquePtr<T>
22where
23 T: UniquePtrTarget,
24{
25 repr: MaybeUninit<*mut c_void>,
26 ty: PhantomData<T>,
27}
28
29impl<T> UniquePtr<T>
30where
31 T: UniquePtrTarget,
32{
33 pub fn null() -> Self {
37 UniquePtr {
38 repr: T::__null(),
39 ty: PhantomData,
40 }
41 }
42
43 pub fn new(value: T) -> Self
45 where
46 T: ExternType<Kind = Trivial>,
47 {
48 UniquePtr {
49 repr: T::__new(value),
50 ty: PhantomData,
51 }
52 }
53
54 pub fn is_null(&self) -> bool {
58 self.as_ptr().is_null()
59 }
60
61 pub fn as_ref(&self) -> Option<&T> {
64 let ptr = self.as_ptr();
65 unsafe { ptr.as_ref() }
66 }
67
68 pub fn as_mut(&mut self) -> Option<Pin<&mut T>> {
71 let ptr = self.as_mut_ptr();
72 unsafe {
73 let mut_reference = ptr.as_mut()?;
74 Some(Pin::new_unchecked(mut_reference))
75 }
76 }
77
78 pub fn pin_mut(&mut self) -> Pin<&mut T> {
85 match self.as_mut() {
86 Some(target) => target,
87 None => panic!(
88 "called pin_mut on a null UniquePtr<{}>",
89 display(T::__typename),
90 ),
91 }
92 }
93
94 pub fn as_ptr(&self) -> *const T {
97 unsafe { T::__get(self.repr) }
98 }
99
100 pub fn as_mut_ptr(&self) -> *mut T {
108 self.as_ptr() as *mut T
109 }
110
111 pub fn into_raw(self) -> *mut T {
115 let ptr = unsafe { T::__release(self.repr) };
116 mem::forget(self);
117 ptr
118 }
119
120 pub unsafe fn from_raw(raw: *mut T) -> Self {
129 UniquePtr {
130 repr: unsafe { T::__raw(raw) },
131 ty: PhantomData,
132 }
133 }
134}
135
136unsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}
137unsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}
138
139impl<T> Unpin for UniquePtr<T> where T: UniquePtrTarget {}
142
143impl<T> Drop for UniquePtr<T>
144where
145 T: UniquePtrTarget,
146{
147 fn drop(&mut self) {
148 unsafe { T::__drop(self.repr) }
149 }
150}
151
152impl<T> Deref for UniquePtr<T>
153where
154 T: UniquePtrTarget,
155{
156 type Target = T;
157
158 fn deref(&self) -> &Self::Target {
159 match self.as_ref() {
160 Some(target) => target,
161 None => panic!(
162 "called deref on a null UniquePtr<{}>",
163 display(T::__typename),
164 ),
165 }
166 }
167}
168
169impl<T> DerefMut for UniquePtr<T>
170where
171 T: UniquePtrTarget + Unpin,
172{
173 fn deref_mut(&mut self) -> &mut Self::Target {
174 match self.as_mut() {
175 Some(target) => Pin::into_inner(target),
176 None => panic!(
177 "called deref_mut on a null UniquePtr<{}>",
178 display(T::__typename),
179 ),
180 }
181 }
182}
183
184impl<T> Debug for UniquePtr<T>
185where
186 T: Debug + UniquePtrTarget,
187{
188 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
189 match self.as_ref() {
190 None => formatter.write_str("nullptr"),
191 Some(value) => Debug::fmt(value, formatter),
192 }
193 }
194}
195
196impl<T> Display for UniquePtr<T>
197where
198 T: Display + UniquePtrTarget,
199{
200 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
201 match self.as_ref() {
202 None => formatter.write_str("nullptr"),
203 Some(value) => Display::fmt(value, formatter),
204 }
205 }
206}
207
208#[cfg(feature = "std")]
212impl<T> Read for UniquePtr<T>
213where
214 for<'a> Pin<&'a mut T>: Read,
215 T: UniquePtrTarget,
216{
217 #[inline]
218 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
219 self.pin_mut().read(buf)
220 }
221
222 #[inline]
223 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
224 self.pin_mut().read_to_end(buf)
225 }
226
227 #[inline]
228 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
229 self.pin_mut().read_to_string(buf)
230 }
231
232 #[inline]
233 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
234 self.pin_mut().read_exact(buf)
235 }
236
237 }
240
241#[cfg(feature = "std")]
245impl<T> Write for UniquePtr<T>
246where
247 for<'a> Pin<&'a mut T>: Write,
248 T: UniquePtrTarget,
249{
250 #[inline]
251 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
252 self.pin_mut().write(buf)
253 }
254
255 #[inline]
256 fn write_vectored(&mut self, bufs: &[IoSlice]) -> io::Result<usize> {
257 self.pin_mut().write_vectored(bufs)
258 }
259
260 #[inline]
261 fn flush(&mut self) -> io::Result<()> {
262 self.pin_mut().flush()
263 }
264
265 #[inline]
266 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
267 self.pin_mut().write_all(buf)
268 }
269
270 #[inline]
271 fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
272 self.pin_mut().write_fmt(fmt)
273 }
274
275 }
278
279pub unsafe trait UniquePtrTarget {
305 #[doc(hidden)]
306 fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
307 #[doc(hidden)]
308 fn __null() -> MaybeUninit<*mut c_void>;
309 #[doc(hidden)]
310 fn __new(value: Self) -> MaybeUninit<*mut c_void>
311 where
312 Self: Sized,
313 {
314 let _ = value;
317 unreachable!()
318 }
319 #[doc(hidden)]
320 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void>;
321 #[doc(hidden)]
322 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self;
323 #[doc(hidden)]
324 unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self;
325 #[doc(hidden)]
326 unsafe fn __drop(repr: MaybeUninit<*mut c_void>);
327}
328
329extern "C" {
330 #[link_name = "cxxbridge1$unique_ptr$std$string$null"]
331 fn unique_ptr_std_string_null(this: *mut MaybeUninit<*mut c_void>);
332 #[link_name = "cxxbridge1$unique_ptr$std$string$raw"]
333 fn unique_ptr_std_string_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxString);
334 #[link_name = "cxxbridge1$unique_ptr$std$string$get"]
335 fn unique_ptr_std_string_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxString;
336 #[link_name = "cxxbridge1$unique_ptr$std$string$release"]
337 fn unique_ptr_std_string_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxString;
338 #[link_name = "cxxbridge1$unique_ptr$std$string$drop"]
339 fn unique_ptr_std_string_drop(this: *mut MaybeUninit<*mut c_void>);
340}
341
342unsafe impl UniquePtrTarget for CxxString {
343 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
344 f.write_str("CxxString")
345 }
346 fn __null() -> MaybeUninit<*mut c_void> {
347 let mut repr = MaybeUninit::uninit();
348 unsafe {
349 unique_ptr_std_string_null(&mut repr);
350 }
351 repr
352 }
353 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
354 let mut repr = MaybeUninit::uninit();
355 unsafe { unique_ptr_std_string_raw(&mut repr, raw) }
356 repr
357 }
358 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
359 unsafe { unique_ptr_std_string_get(&repr) }
360 }
361 unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self {
362 unsafe { unique_ptr_std_string_release(&mut repr) }
363 }
364 unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) {
365 unsafe { unique_ptr_std_string_drop(&mut repr) }
366 }
367}
368
369unsafe impl<T> UniquePtrTarget for CxxVector<T>
370where
371 T: VectorElement,
372{
373 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
374 write!(f, "CxxVector<{}>", display(T::__typename))
375 }
376 fn __null() -> MaybeUninit<*mut c_void> {
377 T::__unique_ptr_null()
378 }
379 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
380 unsafe { T::__unique_ptr_raw(raw) }
381 }
382 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
383 unsafe { T::__unique_ptr_get(repr) }
384 }
385 unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self {
386 unsafe { T::__unique_ptr_release(repr) }
387 }
388 unsafe fn __drop(repr: MaybeUninit<*mut c_void>) {
389 unsafe { T::__unique_ptr_drop(repr) }
390 }
391}