#![warn(missing_docs)]
pub use stable_deref_trait::{
CloneStableDeref as CloneStableAddress, StableDeref as StableAddress,
};
use std::mem;
pub struct OwningRef<O, T: ?Sized> {
owner: O,
reference: *const T,
}
pub struct OwningRefMut<O, T: ?Sized> {
owner: O,
reference: *mut T,
}
pub trait Erased {}
impl<T> Erased for T {}
#[allow(unused_lifetimes)]
pub unsafe trait IntoErased<'a> {
type Erased;
fn into_erased(self) -> Self::Erased;
}
#[allow(unused_lifetimes)]
pub unsafe trait IntoErasedSend<'a> {
type Erased: Send;
fn into_erased_send(self) -> Self::Erased;
}
#[allow(unused_lifetimes)]
pub unsafe trait IntoErasedSendSync<'a> {
type Erased: Send + Sync;
fn into_erased_send_sync(self) -> Self::Erased;
}
impl<O, T: ?Sized> OwningRef<O, T> {
pub fn new(o: O) -> Self
where
O: StableAddress,
O: Deref<Target = T>,
{
OwningRef { reference: &*o, owner: o }
}
pub unsafe fn new_assert_stable_address(o: O) -> Self
where
O: Deref<Target = T>,
{
OwningRef { reference: &*o, owner: o }
}
pub fn map<F, U: ?Sized>(self, f: F) -> OwningRef<O, U>
where
O: StableAddress,
F: FnOnce(&T) -> &U,
{
OwningRef { reference: f(&self), owner: self.owner }
}
pub fn try_map<F, U: ?Sized, E>(self, f: F) -> Result<OwningRef<O, U>, E>
where
O: StableAddress,
F: FnOnce(&T) -> Result<&U, E>,
{
Ok(OwningRef { reference: f(&self)?, owner: self.owner })
}
pub unsafe fn map_owner<F, P>(self, f: F) -> OwningRef<P, T>
where
O: StableAddress,
P: StableAddress,
F: FnOnce(O) -> P,
{
OwningRef { reference: self.reference, owner: f(self.owner) }
}
pub fn map_owner_box(self) -> OwningRef<Box<O>, T> {
OwningRef { reference: self.reference, owner: Box::new(self.owner) }
}
pub fn erase_owner<'a>(self) -> OwningRef<O::Erased, T>
where
O: IntoErased<'a>,
{
OwningRef { reference: self.reference, owner: self.owner.into_erased() }
}
pub fn erase_send_owner<'a>(self) -> OwningRef<O::Erased, T>
where
O: IntoErasedSend<'a>,
{
OwningRef { reference: self.reference, owner: self.owner.into_erased_send() }
}
pub fn erase_send_sync_owner<'a>(self) -> OwningRef<O::Erased, T>
where
O: IntoErasedSendSync<'a>,
{
OwningRef { reference: self.reference, owner: self.owner.into_erased_send_sync() }
}
pub fn owner(&self) -> &O {
&self.owner
}
pub fn into_inner(self) -> O {
self.owner
}
}
impl<O, T: ?Sized> OwningRefMut<O, T> {
pub fn new(mut o: O) -> Self
where
O: StableAddress,
O: DerefMut<Target = T>,
{
OwningRefMut { reference: &mut *o, owner: o }
}
pub unsafe fn new_assert_stable_address(mut o: O) -> Self
where
O: DerefMut<Target = T>,
{
OwningRefMut { reference: &mut *o, owner: o }
}
pub fn map<F, U: ?Sized>(mut self, f: F) -> OwningRef<O, U>
where
O: StableAddress,
F: FnOnce(&mut T) -> &U,
{
OwningRef { reference: f(&mut self), owner: self.owner }
}
pub fn map_mut<F, U: ?Sized>(mut self, f: F) -> OwningRefMut<O, U>
where
O: StableAddress,
F: FnOnce(&mut T) -> &mut U,
{
OwningRefMut { reference: f(&mut self), owner: self.owner }
}
pub fn try_map<F, U: ?Sized, E>(mut self, f: F) -> Result<OwningRef<O, U>, E>
where
O: StableAddress,
F: FnOnce(&mut T) -> Result<&U, E>,
{
Ok(OwningRef { reference: f(&mut self)?, owner: self.owner })
}
pub fn try_map_mut<F, U: ?Sized, E>(mut self, f: F) -> Result<OwningRefMut<O, U>, E>
where
O: StableAddress,
F: FnOnce(&mut T) -> Result<&mut U, E>,
{
Ok(OwningRefMut { reference: f(&mut self)?, owner: self.owner })
}
pub unsafe fn map_owner<F, P>(self, f: F) -> OwningRefMut<P, T>
where
O: StableAddress,
P: StableAddress,
F: FnOnce(O) -> P,
{
OwningRefMut { reference: self.reference, owner: f(self.owner) }
}
pub fn map_owner_box(self) -> OwningRefMut<Box<O>, T> {
OwningRefMut { reference: self.reference, owner: Box::new(self.owner) }
}
pub fn erase_owner<'a>(self) -> OwningRefMut<O::Erased, T>
where
O: IntoErased<'a>,
{
OwningRefMut { reference: self.reference, owner: self.owner.into_erased() }
}
pub fn owner(&self) -> &O {
&self.owner
}
pub fn into_inner(self) -> O {
self.owner
}
}
use std::ops::{Deref, DerefMut};
pub struct OwningHandle<O, H>
where
O: StableAddress,
H: Deref,
{
handle: H,
_owner: O,
}
impl<O, H> Deref for OwningHandle<O, H>
where
O: StableAddress,
H: Deref,
{
type Target = H::Target;
fn deref(&self) -> &H::Target {
self.handle.deref()
}
}
unsafe impl<O, H> StableAddress for OwningHandle<O, H>
where
O: StableAddress,
H: StableAddress,
{
}
impl<O, H> DerefMut for OwningHandle<O, H>
where
O: StableAddress,
H: DerefMut,
{
fn deref_mut(&mut self) -> &mut H::Target {
self.handle.deref_mut()
}
}
pub trait ToHandle {
type Handle: Deref;
unsafe fn to_handle(x: *const Self) -> Self::Handle;
}
pub trait ToHandleMut {
type HandleMut: DerefMut;
unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut;
}
impl<O, H> OwningHandle<O, H>
where
O: StableAddress<Target: ToHandle<Handle = H>>,
H: Deref,
{
pub fn new(o: O) -> Self {
OwningHandle::new_with_fn(o, |x| unsafe { O::Target::to_handle(x) })
}
}
impl<O, H> OwningHandle<O, H>
where
O: StableAddress<Target: ToHandleMut<HandleMut = H>>,
H: DerefMut,
{
pub fn new_mut(o: O) -> Self {
OwningHandle::new_with_fn(o, |x| unsafe { O::Target::to_handle_mut(x) })
}
}
impl<O, H> OwningHandle<O, H>
where
O: StableAddress,
H: Deref,
{
pub fn new_with_fn<F>(o: O, f: F) -> Self
where
F: FnOnce(*const O::Target) -> H,
{
let h: H;
{
h = f(o.deref() as *const O::Target);
}
OwningHandle { handle: h, _owner: o }
}
pub fn try_new<F, E>(o: O, f: F) -> Result<Self, E>
where
F: FnOnce(*const O::Target) -> Result<H, E>,
{
let h: H;
{
h = f(o.deref() as *const O::Target)?;
}
Ok(OwningHandle { handle: h, _owner: o })
}
}
use std::borrow::Borrow;
use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use std::convert::From;
use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
use std::marker::{Send, Sync};
impl<O, T: ?Sized> Deref for OwningRef<O, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.reference }
}
}
impl<O, T: ?Sized> Deref for OwningRefMut<O, T> {
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.reference }
}
}
impl<O, T: ?Sized> DerefMut for OwningRefMut<O, T> {
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.reference }
}
}
unsafe impl<O, T: ?Sized> StableAddress for OwningRef<O, T> {}
impl<O, T: ?Sized> AsRef<T> for OwningRef<O, T> {
fn as_ref(&self) -> &T {
&*self
}
}
impl<O, T: ?Sized> AsRef<T> for OwningRefMut<O, T> {
fn as_ref(&self) -> &T {
&*self
}
}
impl<O, T: ?Sized> AsMut<T> for OwningRefMut<O, T> {
fn as_mut(&mut self) -> &mut T {
&mut *self
}
}
impl<O, T: ?Sized> Borrow<T> for OwningRef<O, T> {
fn borrow(&self) -> &T {
&*self
}
}
impl<O, T: ?Sized> From<O> for OwningRef<O, T>
where
O: StableAddress,
O: Deref<Target = T>,
{
fn from(owner: O) -> Self {
OwningRef::new(owner)
}
}
impl<O, T: ?Sized> From<O> for OwningRefMut<O, T>
where
O: StableAddress,
O: DerefMut<Target = T>,
{
fn from(owner: O) -> Self {
OwningRefMut::new(owner)
}
}
impl<O, T: ?Sized> From<OwningRefMut<O, T>> for OwningRef<O, T>
where
O: StableAddress,
O: DerefMut<Target = T>,
{
fn from(other: OwningRefMut<O, T>) -> Self {
OwningRef { owner: other.owner, reference: other.reference }
}
}
impl<O, T: ?Sized> Debug for OwningRef<O, T>
where
O: Debug,
T: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "OwningRef {{ owner: {:?}, reference: {:?} }}", self.owner(), &**self)
}
}
impl<O, T: ?Sized> Debug for OwningRefMut<O, T>
where
O: Debug,
T: Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "OwningRefMut {{ owner: {:?}, reference: {:?} }}", self.owner(), &**self)
}
}
impl<O, T: ?Sized> Clone for OwningRef<O, T>
where
O: CloneStableAddress,
{
fn clone(&self) -> Self {
OwningRef { owner: self.owner.clone(), reference: self.reference }
}
}
unsafe impl<O, T: ?Sized> CloneStableAddress for OwningRef<O, T> where O: CloneStableAddress {}
unsafe impl<O, T: ?Sized> Send for OwningRef<O, T>
where
O: Send,
for<'a> &'a T: Send,
{
}
unsafe impl<O, T: ?Sized> Sync for OwningRef<O, T>
where
O: Sync,
for<'a> &'a T: Sync,
{
}
unsafe impl<O, T: ?Sized> Send for OwningRefMut<O, T>
where
O: Send,
for<'a> &'a mut T: Send,
{
}
unsafe impl<O, T: ?Sized> Sync for OwningRefMut<O, T>
where
O: Sync,
for<'a> &'a mut T: Sync,
{
}
impl Debug for dyn Erased {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<Erased>",)
}
}
impl<O, T: ?Sized> PartialEq for OwningRef<O, T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
(&*self as &T).eq(&*other as &T)
}
}
impl<O, T: ?Sized> Eq for OwningRef<O, T> where T: Eq {}
impl<O, T: ?Sized> PartialOrd for OwningRef<O, T>
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(&*self as &T).partial_cmp(&*other as &T)
}
}
impl<O, T: ?Sized> Ord for OwningRef<O, T>
where
T: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
(&*self as &T).cmp(&*other as &T)
}
}
impl<O, T: ?Sized> Hash for OwningRef<O, T>
where
T: Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
(&*self as &T).hash(state);
}
}
impl<O, T: ?Sized> PartialEq for OwningRefMut<O, T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
(&*self as &T).eq(&*other as &T)
}
}
impl<O, T: ?Sized> Eq for OwningRefMut<O, T> where T: Eq {}
impl<O, T: ?Sized> PartialOrd for OwningRefMut<O, T>
where
T: PartialOrd,
{
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
(&*self as &T).partial_cmp(&*other as &T)
}
}
impl<O, T: ?Sized> Ord for OwningRefMut<O, T>
where
T: Ord,
{
fn cmp(&self, other: &Self) -> Ordering {
(&*self as &T).cmp(&*other as &T)
}
}
impl<O, T: ?Sized> Hash for OwningRefMut<O, T>
where
T: Hash,
{
fn hash<H: Hasher>(&self, state: &mut H) {
(&*self as &T).hash(state);
}
}
use std::boxed::Box;
use std::cell::{Ref, RefCell, RefMut};
use std::rc::Rc;
use std::sync::Arc;
use std::sync::{MutexGuard, RwLockReadGuard, RwLockWriteGuard};
impl<T: 'static> ToHandle for RefCell<T> {
type Handle = Ref<'static, T>;
unsafe fn to_handle(x: *const Self) -> Self::Handle {
(*x).borrow()
}
}
impl<T: 'static> ToHandleMut for RefCell<T> {
type HandleMut = RefMut<'static, T>;
unsafe fn to_handle_mut(x: *const Self) -> Self::HandleMut {
(*x).borrow_mut()
}
}
pub type BoxRef<T, U = T> = OwningRef<Box<T>, U>;
pub type VecRef<T, U = T> = OwningRef<Vec<T>, U>;
pub type StringRef = OwningRef<String, str>;
pub type RcRef<T, U = T> = OwningRef<Rc<T>, U>;
pub type ArcRef<T, U = T> = OwningRef<Arc<T>, U>;
pub type RefRef<'a, T, U = T> = OwningRef<Ref<'a, T>, U>;
pub type RefMutRef<'a, T, U = T> = OwningRef<RefMut<'a, T>, U>;
pub type MutexGuardRef<'a, T, U = T> = OwningRef<MutexGuard<'a, T>, U>;
pub type RwLockReadGuardRef<'a, T, U = T> = OwningRef<RwLockReadGuard<'a, T>, U>;
pub type RwLockWriteGuardRef<'a, T, U = T> = OwningRef<RwLockWriteGuard<'a, T>, U>;
pub type BoxRefMut<T, U = T> = OwningRefMut<Box<T>, U>;
pub type VecRefMut<T, U = T> = OwningRefMut<Vec<T>, U>;
pub type StringRefMut = OwningRefMut<String, str>;
pub type RefMutRefMut<'a, T, U = T> = OwningRefMut<RefMut<'a, T>, U>;
pub type MutexGuardRefMut<'a, T, U = T> = OwningRefMut<MutexGuard<'a, T>, U>;
pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRef<RwLockWriteGuard<'a, T>, U>;
unsafe impl<'a, T: 'a> IntoErased<'a> for Box<T> {
type Erased = Box<dyn Erased + 'a>;
fn into_erased(self) -> Self::Erased {
self
}
}
unsafe impl<'a, T: 'a> IntoErased<'a> for Rc<T> {
type Erased = Rc<dyn Erased + 'a>;
fn into_erased(self) -> Self::Erased {
self
}
}
unsafe impl<'a, T: 'a> IntoErased<'a> for Arc<T> {
type Erased = Arc<dyn Erased + 'a>;
fn into_erased(self) -> Self::Erased {
self
}
}
unsafe impl<'a, T: Send + 'a> IntoErasedSend<'a> for Box<T> {
type Erased = Box<dyn Erased + Send + 'a>;
fn into_erased_send(self) -> Self::Erased {
self
}
}
unsafe impl<'a, T: Send + 'a> IntoErasedSendSync<'a> for Box<T> {
type Erased = Box<dyn Erased + Sync + Send + 'a>;
fn into_erased_send_sync(self) -> Self::Erased {
let result: Box<dyn Erased + Send + 'a> = self;
unsafe { mem::transmute(result) }
}
}
unsafe impl<'a, T: Send + Sync + 'a> IntoErasedSendSync<'a> for Arc<T> {
type Erased = Arc<dyn Erased + Send + Sync + 'a>;
fn into_erased_send_sync(self) -> Self::Erased {
self
}
}
pub type ErasedBoxRef<U> = OwningRef<Box<dyn Erased>, U>;
pub type ErasedRcRef<U> = OwningRef<Rc<dyn Erased>, U>;
pub type ErasedArcRef<U> = OwningRef<Arc<dyn Erased>, U>;
pub type ErasedBoxRefMut<U> = OwningRefMut<Box<dyn Erased>, U>;
#[cfg(test)]
mod tests;