use core::mem::{ManuallyDrop, transmute, transmute_copy};
#[inline]
#[track_caller]
pub const unsafe fn transmute_generic<T, U>(value: T) -> U {
assert!(size_of::<T>() == size_of::<U>());
unsafe { transmute_copy::<ManuallyDrop<T>, U>(&ManuallyDrop::new(value)) }
}
#[inline]
#[track_caller]
pub const unsafe fn transmute_ref<T, U>(value: &T) -> &U {
assert!(size_of::<T>() >= size_of::<U>());
assert!(align_of::<T>() >= align_of::<U>());
unsafe { transmute::<&T, &U>(value) }
}
#[inline]
#[track_caller]
pub const unsafe fn transmute_mut<T, U>(value: &mut T) -> &mut U {
assert!(size_of::<T>() >= size_of::<U>());
assert!(align_of::<T>() >= align_of::<U>());
unsafe { transmute::<&mut T, &mut U>(value) }
}
#[cfg(test)]
mod tests {
use crate::utils::{transmute_generic, transmute_mut, transmute_ref};
#[test]
fn test_transmute_generic() {
assert_eq!(unsafe { transmute_generic::<i32, u32>(1984) }, 1984);
}
#[test]
fn test_transmute_ref() {
assert_eq!(unsafe { transmute_ref::<i32, u32>(&1984) }, &1984);
}
#[test]
fn test_transmute_mut() {
let mut value = 1984;
assert_eq!(unsafe { transmute_mut::<i32, u32>(&mut value) }, &mut 1984);
}
}