use crate::llapi::cast_bytes;
use crate::types::int;
use crate::types::uint;
const_trait! {
pub(crate) const trait Cast<T> {
fn cast(self) -> T;
}
}
impl<const N: usize> int<N> {
#[inline]
pub(crate) const fn from_bool(other: bool) -> Self {
Self::from_u8(other as u8)
}
}
impl<const N: usize> uint<N> {
#[inline]
pub(crate) const fn from_bool(other: bool) -> Self {
Self::from_u8(other as u8)
}
}
const_trait_if! {
#[feature("const_traits")]
impl<const N: usize, const M: usize> const Cast<int<M>> for int<N> {
#[inline]
fn cast(self) -> int<M> {
int::from_ne_bytes(cast_bytes::<false, N, M>(self.to_ne_bytes()))
}
}
#[feature("const_traits")]
impl<const N: usize, const M: usize> const Cast<uint<M>> for int<N> {
#[inline]
fn cast(self) -> uint<M> {
int::<M>::cast_unsigned(Cast::cast(self))
}
}
#[feature("const_traits")]
impl<const N: usize, const M: usize> const Cast<int<M>> for uint<N> {
#[inline]
fn cast(self) -> int<M> {
uint::<M>::cast_signed(Cast::cast(self))
}
}
#[feature("const_traits")]
impl<const N: usize, const M: usize> const Cast<uint<M>> for uint<N> {
#[inline]
fn cast(self) -> uint<M> {
uint::from_ne_bytes(cast_bytes::<true, N, M>(self.to_ne_bytes()))
}
}
}
macro_rules! implement {
($type:ty, $uint:literal, $from:ident, $into:ident) => {
const _: () = {
const M: usize = ::core::mem::size_of::<$type>();
impl<const N: usize> int<N> {
#[doc(hidden)] #[inline]
pub const fn $from(other: $type) -> Self {
Self::from_ne_bytes(cast_bytes::<$uint, M, N>(other.to_ne_bytes()))
}
#[doc(hidden)] #[inline]
pub const fn $into(self) -> $type {
<$type>::from_ne_bytes(cast_bytes::<false, N, M>(self.to_ne_bytes()))
}
}
impl<const N: usize> uint<N> {
#[doc(hidden)] #[inline]
pub const fn $from(other: $type) -> Self {
Self::from_ne_bytes(cast_bytes::<$uint, M, N>(other.to_ne_bytes()))
}
#[doc(hidden)] #[inline]
pub const fn $into(self) -> $type {
<$type>::from_ne_bytes(cast_bytes::<true, N, M>(self.to_ne_bytes()))
}
}
const_trait_if! {
#[feature("const_traits")]
impl<const N: usize> const Cast<$type> for int<N> {
#[inline]
fn cast(self) -> $type {
int::$into(self)
}
}
#[feature("const_traits")]
impl<const N: usize> const Cast<$type> for uint<N> {
#[inline]
fn cast(self) -> $type {
uint::$into(self)
}
}
#[feature("const_traits")]
impl<const N: usize> const Cast<int<N>> for $type {
#[inline]
fn cast(self) -> int<N> {
int::$from(self)
}
}
#[feature("const_traits")]
impl<const N: usize> const Cast<uint<N>> for $type {
#[inline]
fn cast(self) -> uint<N> {
uint::$from(self)
}
}
}
};
};
}
implement!(u8, true, from_u8, into_u8);
implement!(u16, true, from_u16, into_u16);
implement!(u32, true, from_u32, into_u32);
implement!(u64, true, from_u64, into_u64);
implement!(u128, true, from_u128, into_u128);
implement!(usize, true, from_usize, into_usize);
implement!(i8, false, from_i8, into_i8);
implement!(i16, false, from_i16, into_i16);
implement!(i32, false, from_i32, into_i32);
implement!(i64, false, from_i64, into_i64);
implement!(i128, false, from_i128, into_i128);
implement!(isize, false, from_isize, into_isize);