133d722a9Sopenharmony_ciuse crate::cxx_vector::{CxxVector, VectorElement}; 233d722a9Sopenharmony_ciuse crate::fmt::display; 333d722a9Sopenharmony_ciuse crate::kind::Trivial; 433d722a9Sopenharmony_ciuse crate::string::CxxString; 533d722a9Sopenharmony_ciuse crate::ExternType; 633d722a9Sopenharmony_ciuse core::ffi::c_void; 733d722a9Sopenharmony_ciuse core::fmt::{self, Debug, Display}; 833d722a9Sopenharmony_ciuse core::marker::PhantomData; 933d722a9Sopenharmony_ciuse core::mem::{self, MaybeUninit}; 1033d722a9Sopenharmony_ciuse core::ops::{Deref, DerefMut}; 1133d722a9Sopenharmony_ciuse core::pin::Pin; 1233d722a9Sopenharmony_ci 1333d722a9Sopenharmony_ci/// Binding to C++ `std::unique_ptr<T, std::default_delete<T>>`. 1433d722a9Sopenharmony_ci#[repr(C)] 1533d722a9Sopenharmony_cipub struct UniquePtr<T> 1633d722a9Sopenharmony_ciwhere 1733d722a9Sopenharmony_ci T: UniquePtrTarget, 1833d722a9Sopenharmony_ci{ 1933d722a9Sopenharmony_ci repr: MaybeUninit<*mut c_void>, 2033d722a9Sopenharmony_ci ty: PhantomData<T>, 2133d722a9Sopenharmony_ci} 2233d722a9Sopenharmony_ci 2333d722a9Sopenharmony_ciimpl<T> UniquePtr<T> 2433d722a9Sopenharmony_ciwhere 2533d722a9Sopenharmony_ci T: UniquePtrTarget, 2633d722a9Sopenharmony_ci{ 2733d722a9Sopenharmony_ci /// Makes a new UniquePtr wrapping a null pointer. 2833d722a9Sopenharmony_ci /// 2933d722a9Sopenharmony_ci /// Matches the behavior of default-constructing a std::unique\_ptr. 3033d722a9Sopenharmony_ci pub fn null() -> Self { 3133d722a9Sopenharmony_ci UniquePtr { 3233d722a9Sopenharmony_ci repr: T::__null(), 3333d722a9Sopenharmony_ci ty: PhantomData, 3433d722a9Sopenharmony_ci } 3533d722a9Sopenharmony_ci } 3633d722a9Sopenharmony_ci 3733d722a9Sopenharmony_ci /// Allocates memory on the heap and makes a UniquePtr pointing to it. 3833d722a9Sopenharmony_ci pub fn new(value: T) -> Self 3933d722a9Sopenharmony_ci where 4033d722a9Sopenharmony_ci T: ExternType<Kind = Trivial>, 4133d722a9Sopenharmony_ci { 4233d722a9Sopenharmony_ci UniquePtr { 4333d722a9Sopenharmony_ci repr: T::__new(value), 4433d722a9Sopenharmony_ci ty: PhantomData, 4533d722a9Sopenharmony_ci } 4633d722a9Sopenharmony_ci } 4733d722a9Sopenharmony_ci 4833d722a9Sopenharmony_ci /// Checks whether the UniquePtr does not own an object. 4933d722a9Sopenharmony_ci /// 5033d722a9Sopenharmony_ci /// This is the opposite of [std::unique_ptr\<T\>::operator bool](https://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool). 5133d722a9Sopenharmony_ci pub fn is_null(&self) -> bool { 5233d722a9Sopenharmony_ci let ptr = unsafe { T::__get(self.repr) }; 5333d722a9Sopenharmony_ci ptr.is_null() 5433d722a9Sopenharmony_ci } 5533d722a9Sopenharmony_ci 5633d722a9Sopenharmony_ci /// Returns a reference to the object owned by this UniquePtr if any, 5733d722a9Sopenharmony_ci /// otherwise None. 5833d722a9Sopenharmony_ci pub fn as_ref(&self) -> Option<&T> { 5933d722a9Sopenharmony_ci unsafe { T::__get(self.repr).as_ref() } 6033d722a9Sopenharmony_ci } 6133d722a9Sopenharmony_ci 6233d722a9Sopenharmony_ci /// Returns a mutable pinned reference to the object owned by this UniquePtr 6333d722a9Sopenharmony_ci /// if any, otherwise None. 6433d722a9Sopenharmony_ci pub fn as_mut(&mut self) -> Option<Pin<&mut T>> { 6533d722a9Sopenharmony_ci unsafe { 6633d722a9Sopenharmony_ci let mut_reference = (T::__get(self.repr) as *mut T).as_mut()?; 6733d722a9Sopenharmony_ci Some(Pin::new_unchecked(mut_reference)) 6833d722a9Sopenharmony_ci } 6933d722a9Sopenharmony_ci } 7033d722a9Sopenharmony_ci 7133d722a9Sopenharmony_ci /// Returns a mutable pinned reference to the object owned by this 7233d722a9Sopenharmony_ci /// UniquePtr. 7333d722a9Sopenharmony_ci /// 7433d722a9Sopenharmony_ci /// # Panics 7533d722a9Sopenharmony_ci /// 7633d722a9Sopenharmony_ci /// Panics if the UniquePtr holds a null pointer. 7733d722a9Sopenharmony_ci pub fn pin_mut(&mut self) -> Pin<&mut T> { 7833d722a9Sopenharmony_ci match self.as_mut() { 7933d722a9Sopenharmony_ci Some(target) => target, 8033d722a9Sopenharmony_ci None => panic!( 8133d722a9Sopenharmony_ci "called pin_mut on a null UniquePtr<{}>", 8233d722a9Sopenharmony_ci display(T::__typename), 8333d722a9Sopenharmony_ci ), 8433d722a9Sopenharmony_ci } 8533d722a9Sopenharmony_ci } 8633d722a9Sopenharmony_ci 8733d722a9Sopenharmony_ci /// Consumes the UniquePtr, releasing its ownership of the heap-allocated T. 8833d722a9Sopenharmony_ci /// 8933d722a9Sopenharmony_ci /// Matches the behavior of [std::unique_ptr\<T\>::release](https://en.cppreference.com/w/cpp/memory/unique_ptr/release). 9033d722a9Sopenharmony_ci pub fn into_raw(self) -> *mut T { 9133d722a9Sopenharmony_ci let ptr = unsafe { T::__release(self.repr) }; 9233d722a9Sopenharmony_ci mem::forget(self); 9333d722a9Sopenharmony_ci ptr 9433d722a9Sopenharmony_ci } 9533d722a9Sopenharmony_ci 9633d722a9Sopenharmony_ci /// Constructs a UniquePtr retaking ownership of a pointer previously 9733d722a9Sopenharmony_ci /// obtained from `into_raw`. 9833d722a9Sopenharmony_ci /// 9933d722a9Sopenharmony_ci /// # Safety 10033d722a9Sopenharmony_ci /// 10133d722a9Sopenharmony_ci /// This function is unsafe because improper use may lead to memory 10233d722a9Sopenharmony_ci /// problems. For example a double-free may occur if the function is called 10333d722a9Sopenharmony_ci /// twice on the same raw pointer. 10433d722a9Sopenharmony_ci pub unsafe fn from_raw(raw: *mut T) -> Self { 10533d722a9Sopenharmony_ci UniquePtr { 10633d722a9Sopenharmony_ci repr: unsafe { T::__raw(raw) }, 10733d722a9Sopenharmony_ci ty: PhantomData, 10833d722a9Sopenharmony_ci } 10933d722a9Sopenharmony_ci } 11033d722a9Sopenharmony_ci} 11133d722a9Sopenharmony_ci 11233d722a9Sopenharmony_ciunsafe impl<T> Send for UniquePtr<T> where T: Send + UniquePtrTarget {} 11333d722a9Sopenharmony_ciunsafe impl<T> Sync for UniquePtr<T> where T: Sync + UniquePtrTarget {} 11433d722a9Sopenharmony_ci 11533d722a9Sopenharmony_ci// UniquePtr is not a self-referential type and is safe to move out of a Pin, 11633d722a9Sopenharmony_ci// regardless whether the pointer's target is Unpin. 11733d722a9Sopenharmony_ciimpl<T> Unpin for UniquePtr<T> where T: UniquePtrTarget {} 11833d722a9Sopenharmony_ci 11933d722a9Sopenharmony_ciimpl<T> Drop for UniquePtr<T> 12033d722a9Sopenharmony_ciwhere 12133d722a9Sopenharmony_ci T: UniquePtrTarget, 12233d722a9Sopenharmony_ci{ 12333d722a9Sopenharmony_ci fn drop(&mut self) { 12433d722a9Sopenharmony_ci unsafe { T::__drop(self.repr) } 12533d722a9Sopenharmony_ci } 12633d722a9Sopenharmony_ci} 12733d722a9Sopenharmony_ci 12833d722a9Sopenharmony_ciimpl<T> Deref for UniquePtr<T> 12933d722a9Sopenharmony_ciwhere 13033d722a9Sopenharmony_ci T: UniquePtrTarget, 13133d722a9Sopenharmony_ci{ 13233d722a9Sopenharmony_ci type Target = T; 13333d722a9Sopenharmony_ci 13433d722a9Sopenharmony_ci fn deref(&self) -> &Self::Target { 13533d722a9Sopenharmony_ci match self.as_ref() { 13633d722a9Sopenharmony_ci Some(target) => target, 13733d722a9Sopenharmony_ci None => panic!( 13833d722a9Sopenharmony_ci "called deref on a null UniquePtr<{}>", 13933d722a9Sopenharmony_ci display(T::__typename), 14033d722a9Sopenharmony_ci ), 14133d722a9Sopenharmony_ci } 14233d722a9Sopenharmony_ci } 14333d722a9Sopenharmony_ci} 14433d722a9Sopenharmony_ci 14533d722a9Sopenharmony_ciimpl<T> DerefMut for UniquePtr<T> 14633d722a9Sopenharmony_ciwhere 14733d722a9Sopenharmony_ci T: UniquePtrTarget + Unpin, 14833d722a9Sopenharmony_ci{ 14933d722a9Sopenharmony_ci fn deref_mut(&mut self) -> &mut Self::Target { 15033d722a9Sopenharmony_ci match self.as_mut() { 15133d722a9Sopenharmony_ci Some(target) => Pin::into_inner(target), 15233d722a9Sopenharmony_ci None => panic!( 15333d722a9Sopenharmony_ci "called deref_mut on a null UniquePtr<{}>", 15433d722a9Sopenharmony_ci display(T::__typename), 15533d722a9Sopenharmony_ci ), 15633d722a9Sopenharmony_ci } 15733d722a9Sopenharmony_ci } 15833d722a9Sopenharmony_ci} 15933d722a9Sopenharmony_ci 16033d722a9Sopenharmony_ciimpl<T> Debug for UniquePtr<T> 16133d722a9Sopenharmony_ciwhere 16233d722a9Sopenharmony_ci T: Debug + UniquePtrTarget, 16333d722a9Sopenharmony_ci{ 16433d722a9Sopenharmony_ci fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 16533d722a9Sopenharmony_ci match self.as_ref() { 16633d722a9Sopenharmony_ci None => formatter.write_str("nullptr"), 16733d722a9Sopenharmony_ci Some(value) => Debug::fmt(value, formatter), 16833d722a9Sopenharmony_ci } 16933d722a9Sopenharmony_ci } 17033d722a9Sopenharmony_ci} 17133d722a9Sopenharmony_ci 17233d722a9Sopenharmony_ciimpl<T> Display for UniquePtr<T> 17333d722a9Sopenharmony_ciwhere 17433d722a9Sopenharmony_ci T: Display + UniquePtrTarget, 17533d722a9Sopenharmony_ci{ 17633d722a9Sopenharmony_ci fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 17733d722a9Sopenharmony_ci match self.as_ref() { 17833d722a9Sopenharmony_ci None => formatter.write_str("nullptr"), 17933d722a9Sopenharmony_ci Some(value) => Display::fmt(value, formatter), 18033d722a9Sopenharmony_ci } 18133d722a9Sopenharmony_ci } 18233d722a9Sopenharmony_ci} 18333d722a9Sopenharmony_ci 18433d722a9Sopenharmony_ci/// Trait bound for types which may be used as the `T` inside of a 18533d722a9Sopenharmony_ci/// `UniquePtr<T>` in generic code. 18633d722a9Sopenharmony_ci/// 18733d722a9Sopenharmony_ci/// This trait has no publicly callable or implementable methods. Implementing 18833d722a9Sopenharmony_ci/// it outside of the CXX codebase is not supported. 18933d722a9Sopenharmony_ci/// 19033d722a9Sopenharmony_ci/// # Example 19133d722a9Sopenharmony_ci/// 19233d722a9Sopenharmony_ci/// A bound `T: UniquePtrTarget` may be necessary when manipulating 19333d722a9Sopenharmony_ci/// [`UniquePtr`] in generic code. 19433d722a9Sopenharmony_ci/// 19533d722a9Sopenharmony_ci/// ``` 19633d722a9Sopenharmony_ci/// use cxx::memory::{UniquePtr, UniquePtrTarget}; 19733d722a9Sopenharmony_ci/// use std::fmt::Display; 19833d722a9Sopenharmony_ci/// 19933d722a9Sopenharmony_ci/// pub fn take_generic_ptr<T>(ptr: UniquePtr<T>) 20033d722a9Sopenharmony_ci/// where 20133d722a9Sopenharmony_ci/// T: UniquePtrTarget + Display, 20233d722a9Sopenharmony_ci/// { 20333d722a9Sopenharmony_ci/// println!("the unique_ptr points to: {}", *ptr); 20433d722a9Sopenharmony_ci/// } 20533d722a9Sopenharmony_ci/// ``` 20633d722a9Sopenharmony_ci/// 20733d722a9Sopenharmony_ci/// Writing the same generic function without a `UniquePtrTarget` trait bound 20833d722a9Sopenharmony_ci/// would not compile. 20933d722a9Sopenharmony_cipub unsafe trait UniquePtrTarget { 21033d722a9Sopenharmony_ci #[doc(hidden)] 21133d722a9Sopenharmony_ci fn __typename(f: &mut fmt::Formatter) -> fmt::Result; 21233d722a9Sopenharmony_ci #[doc(hidden)] 21333d722a9Sopenharmony_ci fn __null() -> MaybeUninit<*mut c_void>; 21433d722a9Sopenharmony_ci #[doc(hidden)] 21533d722a9Sopenharmony_ci fn __new(value: Self) -> MaybeUninit<*mut c_void> 21633d722a9Sopenharmony_ci where 21733d722a9Sopenharmony_ci Self: Sized, 21833d722a9Sopenharmony_ci { 21933d722a9Sopenharmony_ci // Opaque C types do not get this method because they can never exist by 22033d722a9Sopenharmony_ci // value on the Rust side of the bridge. 22133d722a9Sopenharmony_ci let _ = value; 22233d722a9Sopenharmony_ci unreachable!() 22333d722a9Sopenharmony_ci } 22433d722a9Sopenharmony_ci #[doc(hidden)] 22533d722a9Sopenharmony_ci unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void>; 22633d722a9Sopenharmony_ci #[doc(hidden)] 22733d722a9Sopenharmony_ci unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self; 22833d722a9Sopenharmony_ci #[doc(hidden)] 22933d722a9Sopenharmony_ci unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self; 23033d722a9Sopenharmony_ci #[doc(hidden)] 23133d722a9Sopenharmony_ci unsafe fn __drop(repr: MaybeUninit<*mut c_void>); 23233d722a9Sopenharmony_ci} 23333d722a9Sopenharmony_ci 23433d722a9Sopenharmony_ciextern "C" { 23533d722a9Sopenharmony_ci #[link_name = "cxxbridge1$unique_ptr$std$string$null"] 23633d722a9Sopenharmony_ci fn unique_ptr_std_string_null(this: *mut MaybeUninit<*mut c_void>); 23733d722a9Sopenharmony_ci #[link_name = "cxxbridge1$unique_ptr$std$string$raw"] 23833d722a9Sopenharmony_ci fn unique_ptr_std_string_raw(this: *mut MaybeUninit<*mut c_void>, raw: *mut CxxString); 23933d722a9Sopenharmony_ci #[link_name = "cxxbridge1$unique_ptr$std$string$get"] 24033d722a9Sopenharmony_ci fn unique_ptr_std_string_get(this: *const MaybeUninit<*mut c_void>) -> *const CxxString; 24133d722a9Sopenharmony_ci #[link_name = "cxxbridge1$unique_ptr$std$string$release"] 24233d722a9Sopenharmony_ci fn unique_ptr_std_string_release(this: *mut MaybeUninit<*mut c_void>) -> *mut CxxString; 24333d722a9Sopenharmony_ci #[link_name = "cxxbridge1$unique_ptr$std$string$drop"] 24433d722a9Sopenharmony_ci fn unique_ptr_std_string_drop(this: *mut MaybeUninit<*mut c_void>); 24533d722a9Sopenharmony_ci} 24633d722a9Sopenharmony_ci 24733d722a9Sopenharmony_ciunsafe impl UniquePtrTarget for CxxString { 24833d722a9Sopenharmony_ci fn __typename(f: &mut fmt::Formatter) -> fmt::Result { 24933d722a9Sopenharmony_ci f.write_str("CxxString") 25033d722a9Sopenharmony_ci } 25133d722a9Sopenharmony_ci fn __null() -> MaybeUninit<*mut c_void> { 25233d722a9Sopenharmony_ci let mut repr = MaybeUninit::uninit(); 25333d722a9Sopenharmony_ci unsafe { 25433d722a9Sopenharmony_ci unique_ptr_std_string_null(&mut repr); 25533d722a9Sopenharmony_ci } 25633d722a9Sopenharmony_ci repr 25733d722a9Sopenharmony_ci } 25833d722a9Sopenharmony_ci unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> { 25933d722a9Sopenharmony_ci let mut repr = MaybeUninit::uninit(); 26033d722a9Sopenharmony_ci unsafe { unique_ptr_std_string_raw(&mut repr, raw) } 26133d722a9Sopenharmony_ci repr 26233d722a9Sopenharmony_ci } 26333d722a9Sopenharmony_ci unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self { 26433d722a9Sopenharmony_ci unsafe { unique_ptr_std_string_get(&repr) } 26533d722a9Sopenharmony_ci } 26633d722a9Sopenharmony_ci unsafe fn __release(mut repr: MaybeUninit<*mut c_void>) -> *mut Self { 26733d722a9Sopenharmony_ci unsafe { unique_ptr_std_string_release(&mut repr) } 26833d722a9Sopenharmony_ci } 26933d722a9Sopenharmony_ci unsafe fn __drop(mut repr: MaybeUninit<*mut c_void>) { 27033d722a9Sopenharmony_ci unsafe { unique_ptr_std_string_drop(&mut repr) } 27133d722a9Sopenharmony_ci } 27233d722a9Sopenharmony_ci} 27333d722a9Sopenharmony_ci 27433d722a9Sopenharmony_ciunsafe impl<T> UniquePtrTarget for CxxVector<T> 27533d722a9Sopenharmony_ciwhere 27633d722a9Sopenharmony_ci T: VectorElement, 27733d722a9Sopenharmony_ci{ 27833d722a9Sopenharmony_ci fn __typename(f: &mut fmt::Formatter) -> fmt::Result { 27933d722a9Sopenharmony_ci write!(f, "CxxVector<{}>", display(T::__typename)) 28033d722a9Sopenharmony_ci } 28133d722a9Sopenharmony_ci fn __null() -> MaybeUninit<*mut c_void> { 28233d722a9Sopenharmony_ci T::__unique_ptr_null() 28333d722a9Sopenharmony_ci } 28433d722a9Sopenharmony_ci unsafe fn __raw(raw: *mut Self) -> MaybeUninit<*mut c_void> { 28533d722a9Sopenharmony_ci unsafe { T::__unique_ptr_raw(raw) } 28633d722a9Sopenharmony_ci } 28733d722a9Sopenharmony_ci unsafe fn __get(repr: MaybeUninit<*mut c_void>) -> *const Self { 28833d722a9Sopenharmony_ci unsafe { T::__unique_ptr_get(repr) } 28933d722a9Sopenharmony_ci } 29033d722a9Sopenharmony_ci unsafe fn __release(repr: MaybeUninit<*mut c_void>) -> *mut Self { 29133d722a9Sopenharmony_ci unsafe { T::__unique_ptr_release(repr) } 29233d722a9Sopenharmony_ci } 29333d722a9Sopenharmony_ci unsafe fn __drop(repr: MaybeUninit<*mut c_void>) { 29433d722a9Sopenharmony_ci unsafe { T::__unique_ptr_drop(repr) } 29533d722a9Sopenharmony_ci } 29633d722a9Sopenharmony_ci} 297