cxx/
unique_ptr.rs
1use crate::cxx_vector::{CxxVector, VectorElement};
2use crate::fmt::display;
3use crate::kind::Trivial;
4use crate::string::CxxString;
5use crate::ExternType;
6use core::ffi::c_void;
7use core::fmt::{self, Debug, Display};
8use core::marker::PhantomData;
9use core::mem::{self, MaybeUninit};
10use core::ops::{Deref, DerefMut};
11use core::pin::Pin;
12
13#[repr(C)]
15pub struct UniquePtr<T>
16where
17 T: UniquePtrTarget,
18{
19 repr: MaybeUninit<*mut c_void>,
20 ty: PhantomData<T>,
21}
22
23impl<T> UniquePtr<T>
24where
25 T: UniquePtrTarget,
26{
27 pub fn null() -> Self {
31 UniquePtr {
32 repr: T::__null(),
33 ty: PhantomData,
34 }
35 }
36
37 pub fn new(value: T) -> Self
39 where
40 T: ExternType<Kind = Trivial>,
41 {
42 UniquePtr {
43 repr: T::__new(value),
44 ty: PhantomData,
45 }
46 }
47
48 pub fn is_null(&self) -> bool {
52 let ptr = unsafe { T::__get(self.repr) };
53 ptr.is_null()
54 }
55
56 pub fn as_ref(&self) -> Option<&T> {
59 unsafe { T::__get(self.repr).as_ref() }
60 }
61
62 pub fn as_mut(&mut self) -> Option<Pin<&mut T>> {
65 unsafe {
66 let mut_reference = (T::__get(self.repr) as *mut T).as_mut()?;
67 Some(Pin::new_unchecked(mut_reference))
68 }
69 }
70
71 pub fn pin_mut(&mut self) -> Pin<&mut T> {
78 match self.as_mut() {
79 Some(target) => target,
80 None => panic!(
81 "called pin_mut on a null UniquePtr<{}>",
82 display(T::__typename),
83 ),
84 }
85 }
86
87 pub fn into_raw(self) -> *mut T {
91 let ptr = unsafe { T::__release(self.repr) };
92 mem::forget(self);
93 ptr
94 }
95
96 pub unsafe fn from_raw(raw: *mut T) -> Self {
105 UniquePtr {
106 repr: unsafe { T::__raw(raw) },
107 ty: PhantomData,
108 }
109 }
110}
111
112unsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {}
113unsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {}
114
115impl<T> Unpin for UniquePtr<T> where T: UniquePtrTarget {}
118
119impl<T> Drop for UniquePtr<T>
120where
121 T: UniquePtrTarget,
122{
123 fn drop(&mut self) {
124 unsafe { T::__drop(self.repr) }
125 }
126}
127
128impl<T> Deref for UniquePtr<T>
129where
130 T: UniquePtrTarget,
131{
132 type Target = T;
133
134 fn deref(&self) -> &Self::Target {
135 match self.as_ref() {
136 Some(target) => target,
137 None => panic!(
138 "called deref on a null UniquePtr<{}>",
139 display(T::__typename),
140 ),
141 }
142 }
143}
144
145impl<T> DerefMut for UniquePtr<T>
146where
147 T: UniquePtrTarget + Unpin,
148{
149 fn deref_mut(&mut self) -> &mut Self::Target {
150 match self.as_mut() {
151 Some(target) => Pin::into_inner(target),
152 None => panic!(
153 "called deref_mut on a null UniquePtr<{}>",
154 display(T::__typename),
155 ),
156 }
157 }
158}
159
160impl<T> Debug for UniquePtr<T>
161where
162 T: Debug + UniquePtrTarget,
163{
164 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
165 match self.as_ref() {
166 None => formatter.write_str("nullptr"),
167 Some(value) => Debug::fmt(value, formatter),
168 }
169 }
170}
171
172impl<T> Display for UniquePtr<T>
173where
174 T: Display + UniquePtrTarget,
175{
176 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
177 match self.as_ref() {
178 None => formatter.write_str("nullptr"),
179 Some(value) => Display::fmt(value, formatter),
180 }
181 }
182}
183
184pub unsafe trait UniquePtrTarget {
210 #[doc(hidden)]
211 fn __typename(f: &mut fmt::Formatter) -> fmt::Result;
212 #[doc(hidden)]
213 fn __null() -> MaybeUninit<*mut c_void>;
214 #[doc(hidden)]
215 fn __new(value: Self) -> MaybeUninit<*mut c_void>
216 where
217 Self: Sized,
218 {
219 let _ = value;
222 unreachable!()
223 }
224 #[doc(hidden)]
225 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void>;
226 #[doc(hidden)]
227 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self;
228 #[doc(hidden)]
229 unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self;
230 #[doc(hidden)]
231 unsafe fn __drop(repr: MaybeUninit<*mut c_void>);
232}
233
234extern "C" {
235 #[link_name = "cxxbridge1$unique_ptr$std$string$null"]
236 fn unique_ptr_std_string_null(this: *mut MaybeUninit<*mut c_void>);
237 #[link_name = "cxxbridge1$unique_ptr$std$string$raw"]
238 fn unique_ptr_std_string_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxString);
239 #[link_name = "cxxbridge1$unique_ptr$std$string$get"]
240 fn unique_ptr_std_string_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxString;
241 #[link_name = "cxxbridge1$unique_ptr$std$string$release"]
242 fn unique_ptr_std_string_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxString;
243 #[link_name = "cxxbridge1$unique_ptr$std$string$drop"]
244 fn unique_ptr_std_string_drop(this: *mut MaybeUninit<*mut c_void>);
245}
246
247unsafe impl UniquePtrTarget for CxxString {
248 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
249 f.write_str("CxxString")
250 }
251 fn __null() -> MaybeUninit<*mut c_void> {
252 let mut repr = MaybeUninit::uninit();
253 unsafe {
254 unique_ptr_std_string_null(&mut repr);
255 }
256 repr
257 }
258 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
259 let mut repr = MaybeUninit::uninit();
260 unsafe { unique_ptr_std_string_raw(&mut repr, raw) }
261 repr
262 }
263 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
264 unsafe { unique_ptr_std_string_get(&repr) }
265 }
266 unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self {
267 unsafe { unique_ptr_std_string_release(&mut repr) }
268 }
269 unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) {
270 unsafe { unique_ptr_std_string_drop(&mut repr) }
271 }
272}
273
274unsafe impl<T> UniquePtrTarget for CxxVector<T>
275where
276 T: VectorElement,
277{
278 fn __typename(f: &mut fmt::Formatter) -> fmt::Result {
279 write!(f, "CxxVector<{}>", display(T::__typename))
280 }
281 fn __null() -> MaybeUninit<*mut c_void> {
282 T::__unique_ptr_null()
283 }
284 unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> {
285 unsafe { T::__unique_ptr_raw(raw) }
286 }
287 unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self {
288 unsafe { T::__unique_ptr_get(repr) }
289 }
290 unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self {
291 unsafe { T::__unique_ptr_release(repr) }
292 }
293 unsafe fn __drop(repr: MaybeUninit<*mut c_void>) {
294 unsafe { T::__unique_ptr_drop(repr) }
295 }
296}