133d722a9Sopenharmony_ciuse crate::shared_ptr::{SharedPtr, SharedPtrTarget}; 233d722a9Sopenharmony_ciuse crate::string::CxxString; 333d722a9Sopenharmony_ciuse core::ffi::c_void; 433d722a9Sopenharmony_ciuse core::fmt::{self, Debug}; 533d722a9Sopenharmony_ciuse core::marker::PhantomData; 633d722a9Sopenharmony_ciuse core::mem::MaybeUninit; 733d722a9Sopenharmony_ci 833d722a9Sopenharmony_ci/// Binding to C++ `std::weak_ptr<T>`. 933d722a9Sopenharmony_ci/// 1033d722a9Sopenharmony_ci/// The typical way to construct a WeakPtr from Rust is by [downgrading] from a 1133d722a9Sopenharmony_ci/// SharedPtr. 1233d722a9Sopenharmony_ci/// 1333d722a9Sopenharmony_ci/// [downgrading]: crate::SharedPtr::downgrade 1433d722a9Sopenharmony_ci#[repr(C)] 1533d722a9Sopenharmony_cipub struct WeakPtr<T> 1633d722a9Sopenharmony_ciwhere 1733d722a9Sopenharmony_ci T: WeakPtrTarget, 1833d722a9Sopenharmony_ci{ 1933d722a9Sopenharmony_ci repr: [MaybeUninit<*mut c_void>; 2], 2033d722a9Sopenharmony_ci ty: PhantomData<T>, 2133d722a9Sopenharmony_ci} 2233d722a9Sopenharmony_ci 2333d722a9Sopenharmony_ciimpl<T> WeakPtr<T> 2433d722a9Sopenharmony_ciwhere 2533d722a9Sopenharmony_ci T: WeakPtrTarget, 2633d722a9Sopenharmony_ci{ 2733d722a9Sopenharmony_ci /// Makes a new WeakPtr wrapping a null pointer. 2833d722a9Sopenharmony_ci /// 2933d722a9Sopenharmony_ci /// Matches the behavior of default-constructing a std::weak\_ptr. 3033d722a9Sopenharmony_ci pub fn null() -> Self { 3133d722a9Sopenharmony_ci let mut weak_ptr = MaybeUninit::<WeakPtr<T>>::uninit(); 3233d722a9Sopenharmony_ci let new = weak_ptr.as_mut_ptr().cast(); 3333d722a9Sopenharmony_ci unsafe { 3433d722a9Sopenharmony_ci T::__null(new); 3533d722a9Sopenharmony_ci weak_ptr.assume_init() 3633d722a9Sopenharmony_ci } 3733d722a9Sopenharmony_ci } 3833d722a9Sopenharmony_ci 3933d722a9Sopenharmony_ci /// Upgrades a non-owning reference into an owning reference if possible, 4033d722a9Sopenharmony_ci /// otherwise to a null reference. 4133d722a9Sopenharmony_ci /// 4233d722a9Sopenharmony_ci /// Matches the behavior of [std::weak_ptr\<T\>::lock](https://en.cppreference.com/w/cpp/memory/weak_ptr/lock). 4333d722a9Sopenharmony_ci pub fn upgrade(&self) -> SharedPtr<T> 4433d722a9Sopenharmony_ci where 4533d722a9Sopenharmony_ci T: SharedPtrTarget, 4633d722a9Sopenharmony_ci { 4733d722a9Sopenharmony_ci let this = self as *const Self as *const c_void; 4833d722a9Sopenharmony_ci let mut shared_ptr = MaybeUninit::<SharedPtr<T>>::uninit(); 4933d722a9Sopenharmony_ci let new = shared_ptr.as_mut_ptr().cast(); 5033d722a9Sopenharmony_ci unsafe { 5133d722a9Sopenharmony_ci T::__upgrade(this, new); 5233d722a9Sopenharmony_ci shared_ptr.assume_init() 5333d722a9Sopenharmony_ci } 5433d722a9Sopenharmony_ci } 5533d722a9Sopenharmony_ci} 5633d722a9Sopenharmony_ci 5733d722a9Sopenharmony_ciunsafe impl<T> Send for WeakPtr<T> where T: Send + Sync + WeakPtrTarget {} 5833d722a9Sopenharmony_ciunsafe impl<T> Sync for WeakPtr<T> where T: Send + Sync + WeakPtrTarget {} 5933d722a9Sopenharmony_ci 6033d722a9Sopenharmony_ciimpl<T> Clone for WeakPtr<T> 6133d722a9Sopenharmony_ciwhere 6233d722a9Sopenharmony_ci T: WeakPtrTarget, 6333d722a9Sopenharmony_ci{ 6433d722a9Sopenharmony_ci fn clone(&self) -> Self { 6533d722a9Sopenharmony_ci let mut weak_ptr = MaybeUninit::<WeakPtr<T>>::uninit(); 6633d722a9Sopenharmony_ci let new = weak_ptr.as_mut_ptr().cast(); 6733d722a9Sopenharmony_ci let this = self as *const Self as *mut c_void; 6833d722a9Sopenharmony_ci unsafe { 6933d722a9Sopenharmony_ci T::__clone(this, new); 7033d722a9Sopenharmony_ci weak_ptr.assume_init() 7133d722a9Sopenharmony_ci } 7233d722a9Sopenharmony_ci } 7333d722a9Sopenharmony_ci} 7433d722a9Sopenharmony_ci 7533d722a9Sopenharmony_ciimpl<T> Drop for WeakPtr<T> 7633d722a9Sopenharmony_ciwhere 7733d722a9Sopenharmony_ci T: WeakPtrTarget, 7833d722a9Sopenharmony_ci{ 7933d722a9Sopenharmony_ci fn drop(&mut self) { 8033d722a9Sopenharmony_ci let this = self as *mut Self as *mut c_void; 8133d722a9Sopenharmony_ci unsafe { T::__drop(this) } 8233d722a9Sopenharmony_ci } 8333d722a9Sopenharmony_ci} 8433d722a9Sopenharmony_ci 8533d722a9Sopenharmony_ciimpl<T> Debug for WeakPtr<T> 8633d722a9Sopenharmony_ciwhere 8733d722a9Sopenharmony_ci T: Debug + WeakPtrTarget + SharedPtrTarget, 8833d722a9Sopenharmony_ci{ 8933d722a9Sopenharmony_ci fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 9033d722a9Sopenharmony_ci Debug::fmt(&self.upgrade(), formatter) 9133d722a9Sopenharmony_ci } 9233d722a9Sopenharmony_ci} 9333d722a9Sopenharmony_ci 9433d722a9Sopenharmony_ci/// Trait bound for types which may be used as the `T` inside of a `WeakPtr<T>` 9533d722a9Sopenharmony_ci/// in generic code. 9633d722a9Sopenharmony_ci/// 9733d722a9Sopenharmony_ci/// This trait has no publicly callable or implementable methods. Implementing 9833d722a9Sopenharmony_ci/// it outside of the CXX codebase is not supported. 9933d722a9Sopenharmony_cipub unsafe trait WeakPtrTarget { 10033d722a9Sopenharmony_ci #[doc(hidden)] 10133d722a9Sopenharmony_ci fn __typename(f: &mut fmt::Formatter) -> fmt::Result; 10233d722a9Sopenharmony_ci #[doc(hidden)] 10333d722a9Sopenharmony_ci unsafe fn __null(new: *mut c_void); 10433d722a9Sopenharmony_ci #[doc(hidden)] 10533d722a9Sopenharmony_ci unsafe fn __clone(this: *const c_void, new: *mut c_void); 10633d722a9Sopenharmony_ci #[doc(hidden)] 10733d722a9Sopenharmony_ci unsafe fn __downgrade(shared: *const c_void, new: *mut c_void); 10833d722a9Sopenharmony_ci #[doc(hidden)] 10933d722a9Sopenharmony_ci unsafe fn __upgrade(weak: *const c_void, shared: *mut c_void); 11033d722a9Sopenharmony_ci #[doc(hidden)] 11133d722a9Sopenharmony_ci unsafe fn __drop(this: *mut c_void); 11233d722a9Sopenharmony_ci} 11333d722a9Sopenharmony_ci 11433d722a9Sopenharmony_cimacro_rules! impl_weak_ptr_target { 11533d722a9Sopenharmony_ci ($segment:expr, $name:expr, $ty:ty) => { 11633d722a9Sopenharmony_ci unsafe impl WeakPtrTarget for $ty { 11733d722a9Sopenharmony_ci fn __typename(f: &mut fmt::Formatter) -> fmt::Result { 11833d722a9Sopenharmony_ci f.write_str($name) 11933d722a9Sopenharmony_ci } 12033d722a9Sopenharmony_ci unsafe fn __null(new: *mut c_void) { 12133d722a9Sopenharmony_ci extern "C" { 12233d722a9Sopenharmony_ci attr! { 12333d722a9Sopenharmony_ci #[link_name = concat!("cxxbridge1$std$weak_ptr$", $segment, "$null")] 12433d722a9Sopenharmony_ci fn __null(new: *mut c_void); 12533d722a9Sopenharmony_ci } 12633d722a9Sopenharmony_ci } 12733d722a9Sopenharmony_ci unsafe { __null(new) } 12833d722a9Sopenharmony_ci } 12933d722a9Sopenharmony_ci unsafe fn __clone(this: *const c_void, new: *mut c_void) { 13033d722a9Sopenharmony_ci extern "C" { 13133d722a9Sopenharmony_ci attr! { 13233d722a9Sopenharmony_ci #[link_name = concat!("cxxbridge1$std$weak_ptr$", $segment, "$clone")] 13333d722a9Sopenharmony_ci fn __clone(this: *const c_void, new: *mut c_void); 13433d722a9Sopenharmony_ci } 13533d722a9Sopenharmony_ci } 13633d722a9Sopenharmony_ci unsafe { __clone(this, new) } 13733d722a9Sopenharmony_ci } 13833d722a9Sopenharmony_ci unsafe fn __downgrade(shared: *const c_void, weak: *mut c_void) { 13933d722a9Sopenharmony_ci extern "C" { 14033d722a9Sopenharmony_ci attr! { 14133d722a9Sopenharmony_ci #[link_name = concat!("cxxbridge1$std$weak_ptr$", $segment, "$downgrade")] 14233d722a9Sopenharmony_ci fn __downgrade(shared: *const c_void, weak: *mut c_void); 14333d722a9Sopenharmony_ci } 14433d722a9Sopenharmony_ci } 14533d722a9Sopenharmony_ci unsafe { __downgrade(shared, weak) } 14633d722a9Sopenharmony_ci } 14733d722a9Sopenharmony_ci unsafe fn __upgrade(weak: *const c_void, shared: *mut c_void) { 14833d722a9Sopenharmony_ci extern "C" { 14933d722a9Sopenharmony_ci attr! { 15033d722a9Sopenharmony_ci #[link_name = concat!("cxxbridge1$std$weak_ptr$", $segment, "$upgrade")] 15133d722a9Sopenharmony_ci fn __upgrade(weak: *const c_void, shared: *mut c_void); 15233d722a9Sopenharmony_ci } 15333d722a9Sopenharmony_ci } 15433d722a9Sopenharmony_ci unsafe { __upgrade(weak, shared) } 15533d722a9Sopenharmony_ci } 15633d722a9Sopenharmony_ci unsafe fn __drop(this: *mut c_void) { 15733d722a9Sopenharmony_ci extern "C" { 15833d722a9Sopenharmony_ci attr! { 15933d722a9Sopenharmony_ci #[link_name = concat!("cxxbridge1$std$weak_ptr$", $segment, "$drop")] 16033d722a9Sopenharmony_ci fn __drop(this: *mut c_void); 16133d722a9Sopenharmony_ci } 16233d722a9Sopenharmony_ci } 16333d722a9Sopenharmony_ci unsafe { __drop(this) } 16433d722a9Sopenharmony_ci } 16533d722a9Sopenharmony_ci } 16633d722a9Sopenharmony_ci }; 16733d722a9Sopenharmony_ci} 16833d722a9Sopenharmony_ci 16933d722a9Sopenharmony_cimacro_rules! impl_weak_ptr_target_for_primitive { 17033d722a9Sopenharmony_ci ($ty:ident) => { 17133d722a9Sopenharmony_ci impl_weak_ptr_target!(stringify!($ty), stringify!($ty), $ty); 17233d722a9Sopenharmony_ci }; 17333d722a9Sopenharmony_ci} 17433d722a9Sopenharmony_ci 17533d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(bool); 17633d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(u8); 17733d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(u16); 17833d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(u32); 17933d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(u64); 18033d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(usize); 18133d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(i8); 18233d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(i16); 18333d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(i32); 18433d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(i64); 18533d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(isize); 18633d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(f32); 18733d722a9Sopenharmony_ciimpl_weak_ptr_target_for_primitive!(f64); 18833d722a9Sopenharmony_ci 18933d722a9Sopenharmony_ciimpl_weak_ptr_target!("string", "CxxString", CxxString); 190