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::cmp::Ordering;
11use core::ffi::c_void;
12use core::fmt::{self, Debug, Display};
13use core::hash::{Hash, Hasher};
14use core::marker::PhantomData;
15use core::mem::{self, MaybeUninit};
16use core::ops::{Deref, DerefMut};
17use core::pin::Pin;
18#[cfg(feature = "std")]
19use std::io::{self, IoSlice, Read, Seek, SeekFrom, Write};
20
21#[repr(C)]
23pub struct UniquePtr<T>
24where
25 T: UniquePtrTarget,
26{
27 repr: MaybeUninit<*mut c_void>,
28 ty: PhantomData<T>,
29}
30
31impl<T> UniquePtr<T>
32where
33 T: UniquePtrTarget,
34{
35 pub fn null() -> Self {
39 UniquePtr {
40 repr: T::__null(),
41 ty: PhantomData,
42 }
43 }
44
45 pub fn new(value: T) -> Self
47 where
48 T: ExternType<Kind = Trivial>,
49 {
50 UniquePtr {
51 repr: T::__new(value),
52 ty: PhantomData,
53 }
54 }
55
56 pub fn is_null(&self) -> bool {
60 self.as_ptr().is_null()
61 }
62
63 pub fn as_ref(&self) -> Option<&T> {
66 let ptr = self.as_ptr();
67 unsafe { ptr.as_ref() }
68 }
69
70 pub fn as_mut(&mut self) -> Option<Pin<&mut T>> {
73 let ptr = self.as_mut_ptr();
74 unsafe {
75 let mut_reference = ptr.as_mut()?;
76 Some(Pin::new_unchecked(mut_reference))
77 }
78 }
79
80 pub fn pin_mut(&mut self) -> Pin<&mut T> {
87 match self.as_mut() {
88 Some(target) => target,
89 None => panic!(
90 "called pin_mut on a null UniquePtr<{}>",
91 display(T::__typename),
92 ),
93 }
94 }
95
96 pub fn as_ptr(&self) -> *const T {
99 unsafe { T::__get(self.repr) }
100 }
101
102 pub fn as_mut_ptr(&self) -> *mut T {
110 self.as_ptr() as *mut T
111 }
112
113 pub fn into_raw(self) -> *mut T {
117 let ptr = unsafe { T::__release(self.repr) };
118 mem::forget(self);
119 ptr
120 }
121
122 pub unsafe fn from_raw(raw: *mut T) -> Self {
131 UniquePtr {
132 repr: unsafe { T::__raw(raw) },
133 ty: PhantomData,
134 }
135 }
136}
137
138unsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}
139unsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}
140
141impl<T> Unpin for UniquePtr<T> where T: UniquePtrTarget {}
144
145impl<T> Drop for UniquePtr<T>
146where
147 T: UniquePtrTarget,
148{
149 fn drop(&mut self) {
150 unsafe { T::__drop(self.repr) }
151 }
152}
153
154impl<T> Deref for UniquePtr<T>
155where
156 T: UniquePtrTarget,
157{
158 type Target = T;
159
160 fn deref(&self) -> &Self::Target {
161 match self.as_ref() {
162 Some(target) => target,
163 None => panic!(
164 "called deref on a null UniquePtr<{}>",
165 display(T::__typename),
166 ),
167 }
168 }
169}
170
171impl<T> DerefMut for UniquePtr<T>
172where
173 T: UniquePtrTarget + Unpin,
174{
175 fn deref_mut(&mut self) -> &mut Self::Target {
176 match self.as_mut() {
177 Some(target) => Pin::into_inner(target),
178 None => panic!(
179 "called deref_mut on a null UniquePtr<{}>",
180 display(T::__typename),
181 ),
182 }
183 }
184}
185
186impl<T> Debug for UniquePtr<T>
187where
188 T: Debug + UniquePtrTarget,
189{
190 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
191 match self.as_ref() {
192 None => formatter.write_str("nullptr"),
193 Some(value) => Debug::fmt(value, formatter),
194 }
195 }
196}
197
198impl<T> Display for UniquePtr<T>
199where
200 T: Display + UniquePtrTarget,
201{
202 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
203 match self.as_ref() {
204 None => formatter.write_str("nullptr"),
205 Some(value) => Display::fmt(value, formatter),
206 }
207 }
208}
209
210impl<T> PartialEq for UniquePtr<T>
211where
212 T: PartialEq + UniquePtrTarget,
213{
214 fn eq(&self, other: &Self) -> bool {
215 self.as_ref() == other.as_ref()
216 }
217}
218
219impl<T> Eq for UniquePtr<T> where T: Eq + UniquePtrTarget {}
220
221impl<T> PartialOrd for UniquePtr<T>
222where
223 T: PartialOrd + UniquePtrTarget,
224{
225 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
226 PartialOrd::partial_cmp(&self.as_ref(), &other.as_ref())
227 }
228}
229
230impl<T> Ord for UniquePtr<T>
231where
232 T: Ord + UniquePtrTarget,
233{
234 fn cmp(&self, other: &Self) -> Ordering {
235 Ord::cmp(&self.as_ref(), &other.as_ref())
236 }
237}
238
239impl<T> Hash for UniquePtr<T>
240where
241 T: Hash + UniquePtrTarget,
242{
243 fn hash<H>(&self, hasher: &mut H)
244 where
245 H: Hasher,
246 {
247 self.as_ref().hash(hasher);
248 }
249}
250
251#[cfg(feature = "std")]
255impl<T> Read for UniquePtr<T>
256where
257 for<'a> Pin<&'a mut T>: Read,
258 T: UniquePtrTarget,
259{
260 #[inline]
261 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
262 self.pin_mut().read(buf)
263 }
264
265 #[inline]
266 fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
267 self.pin_mut().read_to_end(buf)
268 }
269
270 #[inline]
271 fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
272 self.pin_mut().read_to_string(buf)
273 }
274
275 #[inline]
276 fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
277 self.pin_mut().read_exact(buf)
278 }
279
280 }
283
284#[cfg(feature = "std")]
288impl<T> Seek for UniquePtr<T>
289where
290 for<'a> Pin<&'a mut T>: Seek,
291 T: UniquePtrTarget,
292{
293 #[inline]
294 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
295 self.pin_mut().seek(pos)
296 }
297
298 #[inline]
299 fn rewind(&mut self) -> io::Result<()> {
300 self.pin_mut().rewind()
301 }
302
303 #[inline]
304 fn stream_position(&mut self) -> io::Result<u64> {
305 self.pin_mut().stream_position()
306 }
307
308 #[cfg(seek_relative)]
309 #[allow(clippy::incompatible_msrv)]
310 #[inline]
311 fn seek_relative(&mut self, offset: i64) -> io::Result<()> {
312 self.pin_mut().seek_relative(offset)
313 }
314
315 }
318
319#[cfg(feature = "std")]
323impl<T> Write for UniquePtr<T>
324where
325 for<'a> Pin<&'a mut T>: Write,
326 T: UniquePtrTarget,
327{
328 #[inline]
329 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
330 self.pin_mut().write(buf)
331 }
332
333 #[inline]
334 fn write_vectored(&mut self, bufs: &[IoSlice]) -> io::Result<usize> {
335 self.pin_mut().write_vectored(bufs)
336 }
337
338 #[inline]
339 fn flush(&mut self) -> io::Result<()> {
340 self.pin_mut().flush()
341 }
342
343 #[inline]
344 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
345 self.pin_mut().write_all(buf)
346 }
347
348 #[inline]
349 fn write_fmt(&mut self, fmt: fmt::Arguments) -> io::Result<()> {
350 self.pin_mut().write_fmt(fmt)
351 }
352
353 }
356
357pub unsafe trait UniquePtrTarget {
383 #[doc(hidden)]
384 fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
385 #[doc(hidden)]
386 fn __null() -> MaybeUninit<*mut c_void>;
387 #[doc(hidden)]
388 fn __new(value: Self) -> MaybeUninit<*mut c_void>
389 where
390 Self: Sized,
391 {
392 let _ = value;
395 unreachable!()
396 }
397 #[doc(hidden)]
398 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void>;
399 #[doc(hidden)]
400 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self;
401 #[doc(hidden)]
402 unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self;
403 #[doc(hidden)]
404 unsafe fn __drop(repr: MaybeUninit<*mut c_void>);
405}
406
407extern "C" {
408 #[link_name = "cxxbridge1$unique_ptr$std$string$null"]
409 fn unique_ptr_std_string_null(this: *mut MaybeUninit<*mut c_void>);
410 #[link_name = "cxxbridge1$unique_ptr$std$string$raw"]
411 fn unique_ptr_std_string_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxString);
412 #[link_name = "cxxbridge1$unique_ptr$std$string$get"]
413 fn unique_ptr_std_string_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxString;
414 #[link_name = "cxxbridge1$unique_ptr$std$string$release"]
415 fn unique_ptr_std_string_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxString;
416 #[link_name = "cxxbridge1$unique_ptr$std$string$drop"]
417 fn unique_ptr_std_string_drop(this: *mut MaybeUninit<*mut c_void>);
418}
419
420unsafe impl UniquePtrTarget for CxxString {
421 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
422 f.write_str("CxxString")
423 }
424 fn __null() -> MaybeUninit<*mut c_void> {
425 let mut repr = MaybeUninit::uninit();
426 unsafe {
427 unique_ptr_std_string_null(&mut repr);
428 }
429 repr
430 }
431 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
432 let mut repr = MaybeUninit::uninit();
433 unsafe { unique_ptr_std_string_raw(&mut repr, raw) }
434 repr
435 }
436 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
437 unsafe { unique_ptr_std_string_get(&repr) }
438 }
439 unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self {
440 unsafe { unique_ptr_std_string_release(&mut repr) }
441 }
442 unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) {
443 unsafe { unique_ptr_std_string_drop(&mut repr) }
444 }
445}
446
447unsafe impl<T> UniquePtrTarget for CxxVector<T>
448where
449 T: VectorElement,
450{
451 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
452 write!(f, "CxxVector<{}>", display(T::__typename))
453 }
454 fn __null() -> MaybeUninit<*mut c_void> {
455 T::__unique_ptr_null()
456 }
457 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
458 unsafe { T::__unique_ptr_raw(raw) }
459 }
460 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
461 unsafe { T::__unique_ptr_get(repr) }
462 }
463 unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self {
464 unsafe { T::__unique_ptr_release(repr) }
465 }
466 unsafe fn __drop(repr: MaybeUninit<*mut c_void>) {
467 unsafe { T::__unique_ptr_drop(repr) }
468 }
469}