use std::borrow::Borrow;
use std::ffi::{CStr, OsStr};
use std::marker::PhantomData;
use std::mem;
use std::path::Path;
use std::ptr;
use std::rc::Rc;
use std::sync::Arc;
pub unsafe trait ConstDeref {
type Target : ?Sized;
fn const_deref(&self) -> &Self::Target;
}
unsafe impl<T : ?Sized> ConstDeref for Rc<T> {
type Target = T;
fn const_deref(&self) -> &T { self }
}
unsafe impl<T : ?Sized> ConstDeref for Arc<T> {
type Target = T;
fn const_deref(&self) -> &T { self }
}
unsafe impl<T : ConstDeref + ?Sized> ConstDeref for Box<T> {
type Target = T::Target;
fn const_deref(&self) -> &T::Target {
(**self).const_deref()
}
}
pub trait TwoStepShared<OWNED, BORROWED : ?Sized> {
fn new_two_step() -> Self;
unsafe fn deref_holder(&mut self) -> &mut Option<OWNED>;
}
macro_rules! twostepwrapper { ($outer:ident, $inner:ident) => {
pub struct $outer<T, B : ?Sized>($inner<Option<T>>, PhantomData<B>);
impl<T, B : ?Sized> Clone for $outer<T, B> {
fn clone(&self) -> Self {
$outer(self.0.clone(), PhantomData)
}
}
impl<T, B : ?Sized> TwoStepShared<T, B> for $outer<T, B>
where T : SafeBorrow<B> {
fn new_two_step() -> Self {
$outer($inner::new(None), PhantomData)
}
unsafe fn deref_holder(&mut self) -> &mut Option<T> {
$inner::get_mut(&mut self.0)
.expect("Two-step wrapper already cloned")
}
}
} }
twostepwrapper!(TwoStepRc, Rc);
twostepwrapper!(TwoStepArc, Arc);
pub const MAX_INTERNAL_BORROW_DISPLACEMENT: usize = 2048;
pub unsafe trait SafeBorrow<T : ?Sized>: Borrow<T> {
fn borrow_replacement<'a>(ptr: &'a T) -> &'a T;
}
unsafe impl<T : ?Sized> SafeBorrow<T> for T {
fn borrow_replacement(ptr: &T) -> &T { ptr }
}
unsafe impl<B, T> SafeBorrow<[B]> for T where T : Borrow<[B]> {
fn borrow_replacement(_: &[B]) -> &[B] {
&[]
}
}
unsafe impl<T> SafeBorrow<str> for T where T : Borrow<str> {
fn borrow_replacement(_: &str) -> &str { "" }
}
unsafe impl<T> SafeBorrow<CStr> for T
where T : Borrow<CStr> {
fn borrow_replacement(_: &CStr) -> &CStr {
Default::default()
}
}
unsafe impl<T> SafeBorrow<OsStr> for T
where T : Borrow<OsStr> {
fn borrow_replacement(_: &OsStr) -> &OsStr {
OsStr::new("")
}
}
unsafe impl<T> SafeBorrow<Path> for T
where T : Borrow<Path> {
fn borrow_replacement(_: &Path) -> &Path {
Path::new("")
}
}
pub unsafe trait PointerFirstRef : Copy { }
unsafe impl<T : Sized> PointerFirstRef for *const T { }
unsafe impl<T> PointerFirstRef for *const [T] { }
unsafe impl PointerFirstRef for *const str { }
unsafe impl PointerFirstRef for *const ::std::ffi::CStr { }
unsafe impl PointerFirstRef for *const ::std::ffi::OsStr { }
unsafe impl PointerFirstRef for *const ::std::path::Path { }
pub unsafe trait SharedFrom<T> {
fn shared_from(t: T) -> Self;
}
unsafe impl <T> SharedFrom<Rc<T>> for Rc<T> {
fn shared_from(t: Rc<T>) -> Rc<T> { t }
}
unsafe impl <T> SharedFrom<Arc<T>> for Arc<T> {
fn shared_from(t: Arc<T>) -> Arc<T> { t }
}
pub unsafe trait OwnedStorage<A, B> : Default {
fn allocate_a(&mut self, value: A) -> *mut ();
fn allocate_b(&mut self, value: B) -> *mut ();
unsafe fn get_ptr_a<'a>(&'a self, ptr: *mut ()) -> &'a A;
unsafe fn get_ptr_b<'a>(&'a self, ptr: *mut ()) -> &'a B;
unsafe fn get_mut_a<'a>(&'a mut self, ptr: *mut ()) -> &'a mut A;
unsafe fn get_mut_b<'a>(&'a mut self, ptr: *mut ()) -> &'a mut B;
unsafe fn deallocate_a(&mut self, ptr: *mut ());
unsafe fn deallocate_b(&mut self, ptr: *mut ());
unsafe fn deallocate_into_a(&mut self, ptr: *mut ()) -> A;
unsafe fn deallocate_into_b(&mut self, ptr: *mut ()) -> B;
fn is_internal_storage() -> bool;
}
#[derive(Clone, Copy, Debug)]
pub struct InlineStorage<A, B>(InlineStorageImpl<A, B>);
#[derive(Clone, Copy, Debug)]
enum InlineStorageImpl<A, B> {
None,
A(A),
B(B),
}
impl<A, B> Default for InlineStorage<A, B> {
fn default() -> Self {
InlineStorage(InlineStorageImpl::None)
}
}
unsafe impl<A, B> OwnedStorage<A, B> for InlineStorage<A, B> {
#[inline]
fn allocate_a(&mut self, value: A) -> *mut () {
self.0 = InlineStorageImpl::A(value);
2usize as *mut ()
}
#[inline]
fn allocate_b(&mut self, value: B) -> *mut () {
self.0 = InlineStorageImpl::B(value);
2usize as *mut ()
}
#[inline]
unsafe fn get_ptr_a<'a>(&'a self, _: *mut ()) -> &'a A {
match self.0 {
InlineStorageImpl::A(ref r) => r,
_ => unreachable!(),
}
}
#[inline]
unsafe fn get_ptr_b<'a>(&'a self, _: *mut ()) -> &'a B {
match self.0 {
InlineStorageImpl::B(ref r) => r,
_ => unreachable!(),
}
}
#[inline]
unsafe fn get_mut_a<'a>(&'a mut self, _: *mut ()) -> &'a mut A {
match self.0 {
InlineStorageImpl::A(ref mut r) => r,
_ => unreachable!(),
}
}
#[inline]
unsafe fn get_mut_b<'a>(&'a mut self, _: *mut ()) -> &'a mut B {
match self.0 {
InlineStorageImpl::B(ref mut r) => r,
_ => unreachable!(),
}
}
#[inline]
unsafe fn deallocate_a(&mut self, _: *mut ()) { }
#[inline]
unsafe fn deallocate_b(&mut self, _: *mut ()) { }
#[inline]
unsafe fn deallocate_into_a(&mut self, _: *mut ()) -> A {
match mem::replace(&mut self.0, InlineStorageImpl::None) {
InlineStorageImpl::A(v) => v,
_ => unreachable!(),
}
}
#[inline]
unsafe fn deallocate_into_b(&mut self, _: *mut ()) -> B {
match mem::replace(&mut self.0, InlineStorageImpl::None) {
InlineStorageImpl::B(v) => v,
_ => unreachable!(),
}
}
#[inline]
fn is_internal_storage() -> bool { true }
}
type Aligned<T> = ([*const();0], T);
#[derive(Debug, Clone, Copy, Default)]
pub struct BoxedStorage;
unsafe impl<A, B> OwnedStorage<A, B> for BoxedStorage {
#[inline]
fn allocate_a(&mut self, value: A) -> *mut () {
if mem::size_of::<A>() > 0 {
let boxed: Box<Aligned<A>> = Box::new(([], value));
let address = Box::into_raw(boxed);
unsafe { &mut (*address).1 as *mut A as *mut () }
} else {
2 as *mut ()
}
}
#[inline]
fn allocate_b(&mut self, value: B) -> *mut () {
if mem::size_of::<B>() > 0 {
let boxed: Box<Aligned<B>> = Box::new(([], value));
let address = Box::into_raw(boxed);
unsafe { &mut (*address).1 as *mut B as *mut () }
} else {
2 as *mut ()
}
}
#[inline]
unsafe fn get_ptr_a<'a>(&'a self, ptr: *mut ()) -> &'a A {
&(*(ptr as *const Aligned<A>)).1
}
#[inline]
unsafe fn get_ptr_b<'a>(&'a self, ptr: *mut ()) -> &'a B {
&(*(ptr as *const Aligned<B>)).1
}
#[inline]
unsafe fn get_mut_a<'a>(&'a mut self, ptr: *mut ()) -> &'a mut A {
&mut(*(ptr as *mut Aligned<A>)).1
}
#[inline]
unsafe fn get_mut_b<'a>(&'a mut self, ptr: *mut ()) -> &'a mut B {
&mut(*(ptr as *mut Aligned<B>)).1
}
#[inline]
unsafe fn deallocate_a(&mut self, ptr: *mut ()) {
if mem::size_of::<A>() > 0 {
drop(Box::from_raw(ptr as *mut Aligned<A>))
}
}
#[inline]
unsafe fn deallocate_b(&mut self, ptr: *mut ()) {
if mem::size_of::<B>() > 0 {
drop(Box::from_raw(ptr as *mut B))
}
}
#[inline]
unsafe fn deallocate_into_a(&mut self, ptr: *mut ()) -> A {
if mem::size_of::<A>() > 0 {
let t = *Box::from_raw(ptr as *mut Aligned<A>);
t.1
} else {
ptr::read(ptr as *mut A)
}
}
#[inline]
unsafe fn deallocate_into_b(&mut self, ptr: *mut ()) -> B {
if mem::size_of::<B>() > 0 {
let t = *Box::from_raw(ptr as *mut Aligned<B>);
t.1
} else {
ptr::read(ptr as *mut B)
}
}
#[inline]
fn is_internal_storage() -> bool { false }
}
pub unsafe trait PtrWrite<T : ?Sized> : Copy {
fn new() -> Self;
fn store_ptr(&mut self, t: *const T);
}
unsafe impl<T : ?Sized> PtrWrite<T> for () {
#[inline(always)]
fn new() -> Self { () }
#[inline(always)]
fn store_ptr(&mut self, _: *const T) { }
}
unsafe impl<T : ?Sized> PtrWrite<T> for *const T {
#[inline(always)]
fn new() -> Self {
unsafe { mem::uninitialized() }
}
#[inline(always)]
fn store_ptr(&mut self, t: *const T) {
*self = t;
}
}
pub unsafe trait PtrRead<T : ?Sized> : PtrWrite<T> {
fn get_ptr(&self) -> *const T;
}
unsafe impl<T : ?Sized> PtrRead<T> for *const T {
#[inline(always)]
fn get_ptr(&self) -> *const T {
*self
}
}
#[allow(missing_docs)]
#[doc(hidden)]
pub trait RefParent {
type Owned : ?Sized;
unsafe fn supercow_ref_drop(&mut self);
}