use std::marker::PhantomData; use std::mem::replace; use std::mem::size_of; use std::mem::transmute; use std::ops::Deref; use std::ops::DerefMut; use std::ptr::NonNull; pub use std::os::raw::c_int as int; pub type Opaque = [usize; 0]; pub trait Delete where Self: Sized + 'static, { fn delete(&'static mut self) -> (); } /// Pointer to object allocated on the C++ heap. The pointer may be null. #[repr(transparent)] #[derive(Debug)] pub struct UniquePtr(Option<&'static mut T>) where T: Delete; impl UniquePtr where T: Delete, { pub fn null() -> Self { Self(None) } pub fn new(r: &'static mut T) -> Self { Self(Some(r)) } pub unsafe fn from_raw(p: *mut T) -> Self { transmute(p) } pub fn into_raw(self) -> *mut T { unsafe { transmute(self) } } pub fn unwrap(self) -> UniqueRef { let p = self.into_raw(); assert!(!p.is_null()); unsafe { UniqueRef::from_raw(p) } } } impl Deref for UniquePtr where T: Delete, { type Target = Option<&'static mut T>; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for UniquePtr where T: Delete, { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl Drop for UniquePtr where T: Delete, { fn drop(&mut self) { if let Some(v) = self.0.take() { Delete::delete(v) } } } /// Pointer to object allocated on the C++ heap. The pointer may not be null. #[repr(transparent)] #[derive(Debug)] pub struct UniqueRef(&'static mut T) where T: Delete; impl UniqueRef where T: Delete, { pub fn new(r: &'static mut T) -> Self { Self(r) } pub unsafe fn from_raw(p: *mut T) -> Self { transmute(NonNull::new(p)) } pub fn into_raw(self) -> *mut T { unsafe { transmute(self) } } } impl Deref for UniqueRef where T: Delete, { type Target = &'static mut T; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for UniqueRef where T: Delete, { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } impl Drop for UniqueRef where T: Delete, { fn drop(&mut self) { let inner = replace(&mut self.0, unsafe { transmute(NonNull::<&'static mut T>::dangling()) }); Delete::delete(inner) } } #[derive(Copy, Clone, Debug)] #[repr(transparent)] pub struct CxxVTable(pub *const Opaque); #[derive(Copy, Clone, Debug)] pub struct RustVTable(pub *const Opaque, pub PhantomData); #[derive(Debug)] pub struct FieldOffset(usize, PhantomData); unsafe impl Send for FieldOffset where F: Send {} unsafe impl Sync for FieldOffset where F: Sync {} impl Copy for FieldOffset {} impl Clone for FieldOffset { fn clone(&self) -> Self { Self(self.0, self.1) } } impl FieldOffset { pub fn from_ptrs(embedder_ptr: *const E, field_ptr: *const F) -> Self { let embedder_addr = embedder_ptr as usize; let field_addr = field_ptr as usize; assert!(field_addr >= embedder_addr); assert!((field_addr + size_of::()) <= (embedder_addr + size_of::())); Self(field_addr - embedder_addr, PhantomData) } pub unsafe fn to_embedder(self, field: &F) -> &E { (((field as *const _ as usize) - self.0) as *const E) .as_ref() .unwrap() } pub unsafe fn to_embedder_mut(self, field: &mut F) -> &mut E { (((field as *mut _ as usize) - self.0) as *mut E) .as_mut() .unwrap() } }