mirror of
https://github.com/topjohnwu/cxx.git
synced 2025-02-19 07:38:02 +00:00
Add downgrade conversion from SharedPtr to WeakPtr
This commit is contained in:
parent
215e77fbec
commit
85b6bc4a39
@ -1797,6 +1797,13 @@ fn write_weak_ptr(out: &mut OutFile, ident: &RustName) {
|
||||
);
|
||||
writeln!(out, " ::new (ptr) ::std::weak_ptr<{}>(self);", inner);
|
||||
writeln!(out, "}}");
|
||||
writeln!(
|
||||
out,
|
||||
"void cxxbridge1$weak_ptr${}$downgrade(const ::std::shared_ptr<{}>& shared, ::std::weak_ptr<{}> *weak) noexcept {{",
|
||||
instance, inner, inner,
|
||||
);
|
||||
writeln!(out, " ::new (weak) ::std::weak_ptr<{}>(shared);", inner);
|
||||
writeln!(out, "}}");
|
||||
writeln!(
|
||||
out,
|
||||
"void cxxbridge1$weak_ptr${}$drop(::std::weak_ptr<{}> *self) noexcept {{",
|
||||
|
@ -1242,6 +1242,7 @@ fn expand_weak_ptr(ident: &RustName, types: &Types, explicit_impl: Option<&Impl>
|
||||
let prefix = format!("cxxbridge1$weak_ptr${}$", ident.to_symbol(types));
|
||||
let link_null = format!("{}null", prefix);
|
||||
let link_clone = format!("{}clone", prefix);
|
||||
let link_downgrade = format!("{}downgrade", prefix);
|
||||
let link_drop = format!("{}drop", prefix);
|
||||
|
||||
let begin_span =
|
||||
@ -1266,6 +1267,13 @@ fn expand_weak_ptr(ident: &RustName, types: &Types, explicit_impl: Option<&Impl>
|
||||
}
|
||||
__clone(this, new);
|
||||
}
|
||||
unsafe fn __downgrade(shared: *const ::std::ffi::c_void, weak: *mut ::std::ffi::c_void) {
|
||||
extern "C" {
|
||||
#[link_name = #link_downgrade]
|
||||
fn __downgrade(shared: *const ::std::ffi::c_void, weak: *mut ::std::ffi::c_void);
|
||||
}
|
||||
__downgrade(shared, weak);
|
||||
}
|
||||
unsafe fn __drop(this: *mut ::std::ffi::c_void) {
|
||||
extern "C" {
|
||||
#[link_name = #link_drop]
|
||||
|
@ -520,6 +520,11 @@ static_assert(sizeof(std::string) <= kMaxExpectedWordsInString * sizeof(void *),
|
||||
std::weak_ptr<CXX_TYPE> *ptr) noexcept { \
|
||||
new (ptr) std::weak_ptr<CXX_TYPE>(self); \
|
||||
} \
|
||||
void cxxbridge1$std$weak_ptr$##RUST_TYPE##$downgrade( \
|
||||
const std::shared_ptr<CXX_TYPE> &shared, \
|
||||
std::weak_ptr<CXX_TYPE> *weak) noexcept { \
|
||||
new (weak) std::weak_ptr<CXX_TYPE>(shared); \
|
||||
} \
|
||||
void cxxbridge1$std$weak_ptr$##RUST_TYPE##$drop( \
|
||||
const std::weak_ptr<CXX_TYPE> *self) noexcept { \
|
||||
self->~weak_ptr(); \
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::kind::Trivial;
|
||||
use crate::string::CxxString;
|
||||
use crate::weak_ptr::{WeakPtr, WeakPtrTarget};
|
||||
use crate::ExternType;
|
||||
use core::ffi::c_void;
|
||||
use core::fmt::{self, Debug, Display};
|
||||
@ -61,6 +62,24 @@ where
|
||||
let this = self as *const Self as *const c_void;
|
||||
unsafe { T::__get(this).as_ref() }
|
||||
}
|
||||
|
||||
/// Constructs new WeakPtr as a non-owning reference to the object managed
|
||||
/// by `self`. If `self` manages no object, the WeakPtr manages no object
|
||||
/// too.
|
||||
///
|
||||
/// Matches the behavior of [std::weak_ptr\<T\>::weak_ptr(const std::shared_ptr\<T\> \&)](https://en.cppreference.com/w/cpp/memory/weak_ptr/weak_ptr).
|
||||
pub fn downgrade(self: &SharedPtr<T>) -> WeakPtr<T>
|
||||
where
|
||||
T: WeakPtrTarget,
|
||||
{
|
||||
let this = self as *const Self as *const c_void;
|
||||
let mut weak_ptr = MaybeUninit::<WeakPtr<T>>::uninit();
|
||||
let new = weak_ptr.as_mut_ptr().cast();
|
||||
unsafe {
|
||||
T::__downgrade(this, new);
|
||||
weak_ptr.assume_init()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for SharedPtr<T> where T: Send + Sync + SharedPtrTarget {}
|
||||
|
@ -5,6 +5,11 @@ use core::marker::PhantomData;
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
/// Binding to C++ `std::weak_ptr<T>`.
|
||||
///
|
||||
/// The typical way to construct a WeakPtr from Rust is by [downgrading] from a
|
||||
/// SharedPtr.
|
||||
///
|
||||
/// [downgrading]: crate::SharedPtr::downgrade
|
||||
#[repr(C)]
|
||||
pub struct WeakPtr<T>
|
||||
where
|
||||
@ -69,6 +74,8 @@ pub unsafe trait WeakPtrTarget {
|
||||
#[doc(hidden)]
|
||||
unsafe fn __clone(this: *const c_void, new: *mut c_void);
|
||||
#[doc(hidden)]
|
||||
unsafe fn __downgrade(shared: *const c_void, new: *mut c_void);
|
||||
#[doc(hidden)]
|
||||
unsafe fn __drop(this: *mut c_void);
|
||||
}
|
||||
|
||||
@ -94,6 +101,15 @@ macro_rules! impl_weak_ptr_target {
|
||||
}
|
||||
__clone(this, new);
|
||||
}
|
||||
unsafe fn __downgrade(shared: *const c_void, weak: *mut c_void) {
|
||||
extern "C" {
|
||||
attr! {
|
||||
#[link_name = concat!("cxxbridge1$std$weak_ptr$", $segment, "$downgrade")]
|
||||
fn __downgrade(shared: *const c_void, weak: *mut c_void);
|
||||
}
|
||||
}
|
||||
__downgrade(shared, weak);
|
||||
}
|
||||
unsafe fn __drop(this: *mut c_void) {
|
||||
extern "C" {
|
||||
attr! {
|
||||
|
Loading…
x
Reference in New Issue
Block a user