use super::{IntoOwned, DerefTake};
use std::mem::ManuallyDrop;
pub unsafe trait Take<T: ?Sized> : Sized {
fn take_sized(self) -> T
where T: Sized
{
self.take_unsized(|src| unsafe {
(src as *const _ as *const T).read()
})
}
fn take_owned(self) -> T::Owned
where T: IntoOwned
{
self.take_unsized(|src| unsafe { T::into_owned_unchecked(src) })
}
fn take_unsized<F,R>(self, f: F) -> R
where F: FnOnce(&mut ManuallyDrop<T>) -> R;
}
unsafe impl<T> Take<T> for T {
fn take_unsized<F,R>(self, f: F) -> R
where F: FnOnce(&mut ManuallyDrop<T>) -> R
{
let mut this = ManuallyDrop::new(self);
f(&mut this)
}
}
unsafe impl<T> Take<T> for ManuallyDrop<T> {
fn take_unsized<F,R>(self, f: F) -> R
where F: FnOnce(&mut ManuallyDrop<T>) -> R
{
self.deref_take_unsized(f)
}
}
unsafe impl<T: ?Sized + IntoOwned> Take<T> for Box<T> {
fn take_unsized<F,R>(self, f: F) -> R
where F: FnOnce(&mut ManuallyDrop<T>) -> R
{
self.deref_take_unsized(f)
}
}
unsafe impl<T> Take<[T]> for Vec<T> {
fn take_unsized<F,R>(self, f: F) -> R
where F: FnOnce(&mut ManuallyDrop<[T]>) -> R
{
self.deref_take_unsized(f)
}
}