use std::mem::ManuallyDrop;
use std::ops::{Deref, DerefMut};
pub trait ShallowCopy {
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self>;
}
use std::sync::Arc;
impl<T> ShallowCopy for Arc<T>
where
T: ?Sized,
{
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
ManuallyDrop::new(Arc::from_raw(&**self as *const _))
}
}
use std::rc::Rc;
impl<T> ShallowCopy for Rc<T>
where
T: ?Sized,
{
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
ManuallyDrop::new(Rc::from_raw(&**self as *const _))
}
}
impl<T> ShallowCopy for Box<T>
where
T: ?Sized,
{
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
ManuallyDrop::new(Box::from_raw(&**self as *const _ as *mut _))
}
}
impl<T> ShallowCopy for Option<T>
where
T: ShallowCopy,
{
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
ManuallyDrop::new(if let Some(value) = self {
Some(ManuallyDrop::into_inner(value.shallow_copy()))
} else {
None
})
}
}
impl ShallowCopy for String {
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
let buf = self.as_bytes().as_ptr();
let len = self.len();
let cap = self.capacity();
ManuallyDrop::new(String::from_raw_parts(buf as *mut _, len, cap))
}
}
impl<T> ShallowCopy for Vec<T> {
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
let ptr = self.as_ptr() as *mut _;
let len = self.len();
let cap = self.capacity();
ManuallyDrop::new(Vec::from_raw_parts(ptr, len, cap))
}
}
#[cfg(feature = "bytes")]
impl ShallowCopy for bytes::Bytes {
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
let len = self.len();
let buf: &'static [u8] = std::slice::from_raw_parts(self.as_ptr(), len);
ManuallyDrop::new(bytes::Bytes::from_static(buf))
}
}
impl<'a, T> ShallowCopy for &'a T
where
T: ?Sized,
{
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
ManuallyDrop::new(&*self)
}
}
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, Default)]
#[repr(transparent)]
pub struct CopyValue<T>(T);
impl<T: Copy> From<T> for CopyValue<T> {
fn from(t: T) -> Self {
CopyValue(t)
}
}
impl<T> ShallowCopy for CopyValue<T>
where
T: Copy,
{
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
ManuallyDrop::new(CopyValue(self.0))
}
}
impl<T> Deref for CopyValue<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for CopyValue<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
macro_rules! impl_shallow_copy_for_copy_primitives {
($($t:ty)*) => ($(
impl ShallowCopy for $t {
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
ManuallyDrop::new(*self)
}
}
)*)
}
impl_shallow_copy_for_copy_primitives!(() bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64);
macro_rules! tuple_impls {
($(
$Tuple:ident {
$(($idx:tt) -> $T:ident)+
}
)+) => {
$(
impl<$($T:ShallowCopy),+> ShallowCopy for ($($T,)+) {
unsafe fn shallow_copy(&self) -> ManuallyDrop<Self> {
ManuallyDrop::new(($(ManuallyDrop::into_inner(self.$idx.shallow_copy()),)+))
}
}
)+
}
}
tuple_impls! {
Tuple1 {
(0) -> A
}
Tuple2 {
(0) -> A
(1) -> B
}
Tuple3 {
(0) -> A
(1) -> B
(2) -> C
}
Tuple4 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
}
Tuple5 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
}
Tuple6 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
}
Tuple7 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
}
Tuple8 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
}
Tuple9 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
(8) -> I
}
Tuple10 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
(8) -> I
(9) -> J
}
Tuple11 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
(8) -> I
(9) -> J
(10) -> K
}
Tuple12 {
(0) -> A
(1) -> B
(2) -> C
(3) -> D
(4) -> E
(5) -> F
(6) -> G
(7) -> H
(8) -> I
(9) -> J
(10) -> K
(11) -> L
}
}