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