use core::mem::{transmute_copy, ManuallyDrop};
pub unsafe trait UintCast {
type Uint;
}
#[inline]
pub fn into_uint<T>(color: T) -> T::Uint
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
unsafe { transmute_copy(&ManuallyDrop::new(color)) }
}
#[inline]
pub fn from_uint<T>(uint: T::Uint) -> T
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
unsafe { transmute_copy(&ManuallyDrop::new(uint)) }
}
#[inline]
pub fn into_uint_ref<T>(value: &T) -> &T::Uint
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
let value: *const T = value;
unsafe { &*value.cast::<T::Uint>() }
}
#[inline]
pub fn from_uint_ref<T>(value: &T::Uint) -> &T
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
let value: *const T::Uint = value;
unsafe { &*value.cast::<T>() }
}
#[inline]
pub fn into_uint_mut<T>(value: &mut T) -> &mut T::Uint
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
let value: *mut T = value;
unsafe { &mut *value.cast::<T::Uint>() }
}
#[inline]
pub fn from_uint_mut<T>(value: &mut T::Uint) -> &mut T
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
let value: *mut T::Uint = value;
unsafe { &mut *value.cast::<T>() }
}
#[inline]
pub fn into_uint_array<T, const N: usize>(values: [T; N]) -> [T::Uint; N]
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
unsafe { transmute_copy(&ManuallyDrop::new(values)) }
}
#[inline]
pub fn from_uint_array<T, const N: usize>(values: [T::Uint; N]) -> [T; N]
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
unsafe { transmute_copy(&ManuallyDrop::new(values)) }
}
#[inline]
pub fn into_uint_slice<T>(values: &[T]) -> &[T::Uint]
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
unsafe { core::slice::from_raw_parts(values.as_ptr().cast::<T::Uint>(), values.len()) }
}
#[inline]
pub fn from_uint_slice<T>(values: &[T::Uint]) -> &[T]
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
unsafe { core::slice::from_raw_parts(values.as_ptr().cast::<T>(), values.len()) }
}
#[inline]
pub fn into_uint_slice_mut<T>(values: &mut [T]) -> &mut [T::Uint]
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
unsafe { core::slice::from_raw_parts_mut(values.as_mut_ptr().cast::<T::Uint>(), values.len()) }
}
#[inline]
pub fn from_uint_slice_mut<T>(values: &mut [T::Uint]) -> &mut [T]
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
unsafe { core::slice::from_raw_parts_mut(values.as_mut_ptr().cast::<T>(), values.len()) }
}
#[cfg(feature = "alloc")]
#[inline]
pub fn into_uint_slice_box<T>(values: alloc::boxed::Box<[T]>) -> alloc::boxed::Box<[T::Uint]>
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
let raw: *mut [T::Uint] = into_uint_slice_mut(alloc::boxed::Box::leak(values));
unsafe { alloc::boxed::Box::from_raw(raw) }
}
#[cfg(feature = "alloc")]
#[inline]
pub fn from_uint_slice_box<T>(values: alloc::boxed::Box<[T::Uint]>) -> alloc::boxed::Box<[T]>
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
let raw: *mut [T] = from_uint_slice_mut(alloc::boxed::Box::leak(values));
unsafe { alloc::boxed::Box::from_raw(raw) }
}
#[cfg(feature = "alloc")]
#[inline]
pub fn into_uint_vec<T>(values: alloc::vec::Vec<T>) -> alloc::vec::Vec<T::Uint>
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
let mut values = ManuallyDrop::new(values);
let raw = values.as_mut_ptr();
unsafe {
alloc::vec::Vec::from_raw_parts(raw.cast::<T::Uint>(), values.len(), values.capacity())
}
}
#[cfg(feature = "alloc")]
#[inline]
pub fn from_uint_vec<T>(values: alloc::vec::Vec<T::Uint>) -> alloc::vec::Vec<T>
where
T: UintCast,
{
assert_eq!(core::mem::size_of::<T::Uint>(), core::mem::size_of::<T>());
assert_eq!(core::mem::align_of::<T::Uint>(), core::mem::align_of::<T>());
let mut values = ManuallyDrop::new(values);
let raw = values.as_mut_ptr();
unsafe { alloc::vec::Vec::from_raw_parts(raw.cast::<T>(), values.len(), values.capacity()) }
}