Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #![feature(marker_trait_attr)]
- #[marker] trait CanBeUsedWithReinterpretAs {}
- impl<T> CanBeUsedWithReinterpretAs for Box<T> {}
- impl<T> CanBeUsedWithReinterpretAs for &mut T {}
- impl<T> CanBeUsedWithReinterpretAs for &T {}
- impl<T> CanBeUsedWithReinterpretAs for Owned<T> {}
- #[marker] unsafe trait ReinterpretAs<T>
- where Self: CanBeUsedWithReinterpretAs, T: CanBeUsedWithReinterpretAs
- {}
- struct Owned<T>(T);
- unsafe impl<T> ReinterpretAs<Box<T>> for Box<T> {}
- unsafe impl<'a, T, U> ReinterpretAs<&'a mut T> for &'a mut U
- where Box<U>: ReinterpretAs<Box<T>>
- {}
- unsafe impl<'a, T, U> ReinterpretAs<&'a T> for &'a U
- where &'a mut U: ReinterpretAs<&'a mut T>
- {}
- unsafe impl<T, U> ReinterpretAs<Owned<T>> for Owned<U>
- where for<'a> &'a U: ReinterpretAs<&'a T>
- {}
- unsafe impl<'a, T, U> ReinterpretAs<Owned<&'a T>> for Owned<&'a U>
- where &'a U: ReinterpretAs<&'a T>
- {}
- unsafe impl<'a, T, U> ReinterpretAs<Owned<&'a mut T>> for Owned<&'a mut U>
- where &'a mut U: ReinterpretAs<&'a mut T>
- {}
- unsafe impl<T, U> ReinterpretAs<Owned<Box<T>>> for Owned<Box<U>>
- where Box<U>: ReinterpretAs<Box<T>>
- {}
- unsafe impl<T> ReinterpretAs<Box<T>> for Box<[T; 1]> {}
- unsafe impl<T> ReinterpretAs<Box<[T; 1]>> for Box<T> {}
- use std::mem::{align_of, forget, size_of};
- use std::ptr;
- fn reinterpret<T, U>(x: T) -> U
- where Owned<T>: ReinterpretAs<Owned<U>>
- {
- assert!(size_of::<U>() <= size_of::<T>(),
- "the `ReinterpretAs` implementation that let you call this is unsound");
- let p = &x as *const T as *const U;
- forget(x);
- if align_of::<U>() >= align_of::<T>() {
- unsafe { ptr::read(p) }
- } else {
- unsafe { ptr::read_unaligned(p) }
- }
- }
- macro_rules! reinterpret_primitives_as_bytes {
- ($($t:ty,)+) => ($(
- unsafe impl<'a> ReinterpretAs<&'a mut [u8; size_of::<$t>()]> for &'a mut $t {}
- unsafe impl ReinterpretAs<Owned<$t>> for Owned<[u8; size_of::<$t>()]> {}
- )+)
- }
- reinterpret_primitives_as_bytes! {
- u8, u16, u32, u64, u128, usize,
- i8, i16, i32, i64, i128, isize,
- }
- macro_rules! reinterpret_primitives_change_sign {
- ($([$s:ty,$u:ty])+) => ($(
- unsafe impl ReinterpretAs<Box<$s>> for Box<$u> {}
- unsafe impl ReinterpretAs<Box<$u>> for Box<$s> {}
- )+)
- }
- reinterpret_primitives_change_sign! {
- [u8, i8]
- [u16, i16]
- [u32, i32]
- [u64, i64]
- [u128, i128]
- [usize, isize]
- }
- pub fn foo1(x: [u8; 16]) -> [u32; 4] { unsafe { std::mem::transmute(x) } }
- pub fn foo2(x: u32) -> [u8; 4] { unsafe { std::mem::transmute(x) } }
- pub fn foo3(x: u32) -> [u8; 4] { reinterpret::<u32, [u8; 4]>(x) }
- pub fn foo4(x: &u128) -> &i128 { unsafe { std::mem::transmute(x) } }
- pub fn foo5(x: &u128) -> &i128 { reinterpret::<&u128, &i128>(x) }
- pub fn foo6(x: Box<u128>) -> Box<i128> { reinterpret::<Box<u128>, Box<i128>>(x) }
- unsafe impl ReinterpretAs<Owned<i32>> for Owned<u128> {}
- pub fn foo7(x: u128) -> i32 { reinterpret::<u128, i32>(x) }
- //fn main() {
- // let _: u16 = reinterpret::<u8, u16>(0_u8);
- //}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement