pub trait Upcast { fn upcast(self) -> T; } pub trait IntoUsize { fn into_usize(self) -> usize; } macro_rules! gen_upcast { ($from:ty => $into:ty) => { impl Upcast<$into> for $from { fn upcast(self) -> $into { self as $into } } } } // Unsigned gen_upcast!(u8 => u8); gen_upcast!(u8 => u16); gen_upcast!(u8 => u32); gen_upcast!(u8 => u64); gen_upcast!(u16 => u16); gen_upcast!(u16 => u32); gen_upcast!(u16 => u64); gen_upcast!(u32 => u32); gen_upcast!(u32 => u64); gen_upcast!(u64 => u64); // Signed gen_upcast!(i8 => i8); gen_upcast!(i8 => i16); gen_upcast!(i8 => i32); gen_upcast!(i8 => i64); gen_upcast!(i16 => i16); gen_upcast!(i16 => i32); gen_upcast!(i16 => i64); gen_upcast!(i32 => i32); gen_upcast!(i32 => i64); gen_upcast!(i64 => i64); // Pointer Sized gen_upcast!(u8 => usize); gen_upcast!(i8 => isize); gen_upcast!(u16 => usize); gen_upcast!(i16 => isize); #[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))] gen_upcast!(u32 => usize); #[cfg(any(target_pointer_width = "64", target_pointer_width = "32"))] gen_upcast!(i32 => isize); gen_upcast!(isize => isize); gen_upcast!(usize => usize); impl IntoUsize for usize { fn into_usize(self) -> usize { self } } impl IntoUsize for *const T { fn into_usize(self) -> usize { self as usize } } impl IntoUsize for *mut T { fn into_usize(self) -> usize { self as usize } } impl IntoUsize for &T { fn into_usize(self) -> usize { self as *const _ as usize } } impl IntoUsize for &mut T { fn into_usize(self) -> usize { self as *mut _ as usize } }