use crate::{ConvTo, Rounding};
use core::convert::Infallible;
#[macro_export]
macro_rules! impl_via_identity {
($x:ty) => {
impl $crate::ConvExact<$x> for $x {
type Error = ::core::convert::Infallible;
#[inline]
fn conv_exact(x: $x) -> Self {
x
}
#[inline]
fn try_conv_exact(x: $x) -> Result<Self, Self::Error> {
Ok(x)
}
}
};
($x:ty $(, $xx:tt)* $(,)?) => {
$crate::impl_via_identity!($x);
$crate::impl_via_identity!($($xx),*);
};
}
#[rustfmt::skip]
impl_via_identity!(
u8, u16, u32, u64, u128, usize,
i8, i16, i32, i64, i128, isize,
f32, f64,
);
#[macro_export]
macro_rules! impl_via_from {
($x:ty: $y:ty) => {
impl $crate::ConvExact<$x> for $y {
type Error = ::core::convert::Infallible;
#[inline]
fn conv_exact(x: $x) -> $y {
<$y>::from(x)
}
#[inline]
fn try_conv_exact(x: $x) -> Result<Self, Self::Error> {
Ok(<$y>::from(x))
}
}
};
($x:ty: $y:ty, $($yy:ty),+) => {
$crate::impl_via_from!($x: $y);
$crate::impl_via_from!($x: $($yy),+);
};
}
impl_via_from!(i8: f32, f64, i16, i32, i64, i128, isize);
impl_via_from!(i16: f32, f64, i32, i64, i128, isize);
impl_via_from!(i32: f64, i64, i128);
impl_via_from!(i64: i128);
impl_via_from!(u8: f32, f64, i16, i32, i64, i128, isize);
impl_via_from!(u8: u16, u32, u64, u128, usize);
impl_via_from!(u16: f32, f64, i32, i64, i128, u32, u64, u128, usize);
impl_via_from!(u32: f64, i64, i128, u64, u128);
impl_via_from!(u64: i128, u128);
impl<R: Rounding, S, T: ConvTo<S, R> + Copy + Default, const N: usize> ConvTo<[S; N], R>
for [T; N]
{
type Error = T::Error;
#[inline]
fn try_conv_to(mode: R, ss: [S; N]) -> Result<Self, Self::Error> {
let mut tt = [T::default(); N];
for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
*t = T::try_conv_to(mode, s)?;
}
Ok(tt)
}
#[inline]
fn conv_to(mode: R, ss: [S; N]) -> Self {
let mut tt = [T::default(); N];
for (s, t) in IntoIterator::into_iter(ss).zip(tt.iter_mut()) {
*t = T::conv_to(mode, s);
}
tt
}
}
impl<R: Rounding> ConvTo<(), R> for () {
type Error = Infallible;
#[inline]
fn try_conv_to(_: R, _: ()) -> Result<Self, Self::Error> {
Ok(())
}
#[inline]
fn conv_to(_: R, _: ()) -> Self {}
}
impl<R: Rounding, S0, T0: ConvTo<S0, R>> ConvTo<(S0,), R> for (T0,) {
type Error = T0::Error;
#[inline]
fn try_conv_to(mode: R, ss: (S0,)) -> Result<Self, Self::Error> {
Ok((T0::try_conv_to(mode, ss.0)?,))
}
#[inline]
fn conv_to(mode: R, ss: (S0,)) -> Self {
(T0::conv_to(mode, ss.0),)
}
}
impl<R: Rounding, S0, S1, T0: ConvTo<S0, R>, T1: ConvTo<S1, R>> ConvTo<(S0, S1), R> for (T0, T1) {
type Error = R::MaximumError;
#[inline]
fn try_conv_to(mode: R, ss: (S0, S1)) -> Result<Self, Self::Error> {
Ok((
T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
))
}
#[inline]
fn conv_to(mode: R, ss: (S0, S1)) -> Self {
(T0::conv_to(mode, ss.0), T1::conv_to(mode, ss.1))
}
}
impl<R: Rounding, S0, S1, S2, T0: ConvTo<S0, R>, T1: ConvTo<S1, R>, T2: ConvTo<S2, R>>
ConvTo<(S0, S1, S2), R> for (T0, T1, T2)
{
type Error = R::MaximumError;
#[inline]
fn try_conv_to(mode: R, ss: (S0, S1, S2)) -> Result<Self, Self::Error> {
Ok((
T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
T2::try_conv_to(mode, ss.2).map_err(Into::into)?,
))
}
#[inline]
fn conv_to(mode: R, ss: (S0, S1, S2)) -> Self {
(
T0::conv_to(mode, ss.0),
T1::conv_to(mode, ss.1),
T2::conv_to(mode, ss.2),
)
}
}
impl<
R: Rounding,
S0,
S1,
S2,
S3,
T0: ConvTo<S0, R>,
T1: ConvTo<S1, R>,
T2: ConvTo<S2, R>,
T3: ConvTo<S3, R>,
> ConvTo<(S0, S1, S2, S3), R> for (T0, T1, T2, T3)
{
type Error = R::MaximumError;
#[inline]
fn try_conv_to(mode: R, ss: (S0, S1, S2, S3)) -> Result<Self, Self::Error> {
Ok((
T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
T2::try_conv_to(mode, ss.2).map_err(Into::into)?,
T3::try_conv_to(mode, ss.3).map_err(Into::into)?,
))
}
#[inline]
fn conv_to(mode: R, ss: (S0, S1, S2, S3)) -> Self {
(
T0::conv_to(mode, ss.0),
T1::conv_to(mode, ss.1),
T2::conv_to(mode, ss.2),
T3::conv_to(mode, ss.3),
)
}
}
impl<
R: Rounding,
S0,
S1,
S2,
S3,
S4,
T0: ConvTo<S0, R>,
T1: ConvTo<S1, R>,
T2: ConvTo<S2, R>,
T3: ConvTo<S3, R>,
T4: ConvTo<S4, R>,
> ConvTo<(S0, S1, S2, S3, S4), R> for (T0, T1, T2, T3, T4)
{
type Error = R::MaximumError;
#[inline]
fn try_conv_to(mode: R, ss: (S0, S1, S2, S3, S4)) -> Result<Self, Self::Error> {
Ok((
T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
T2::try_conv_to(mode, ss.2).map_err(Into::into)?,
T3::try_conv_to(mode, ss.3).map_err(Into::into)?,
T4::try_conv_to(mode, ss.4).map_err(Into::into)?,
))
}
#[inline]
fn conv_to(mode: R, ss: (S0, S1, S2, S3, S4)) -> Self {
(
T0::conv_to(mode, ss.0),
T1::conv_to(mode, ss.1),
T2::conv_to(mode, ss.2),
T3::conv_to(mode, ss.3),
T4::conv_to(mode, ss.4),
)
}
}
impl<R: Rounding, S0, S1, S2, S3, S4, S5, T0, T1, T2, T3, T4, T5>
ConvTo<(S0, S1, S2, S3, S4, S5), R> for (T0, T1, T2, T3, T4, T5)
where
T0: ConvTo<S0, R>,
T1: ConvTo<S1, R>,
T2: ConvTo<S2, R>,
T3: ConvTo<S3, R>,
T4: ConvTo<S4, R>,
T5: ConvTo<S5, R>,
{
type Error = R::MaximumError;
#[inline]
fn try_conv_to(mode: R, ss: (S0, S1, S2, S3, S4, S5)) -> Result<Self, Self::Error> {
Ok((
T0::try_conv_to(mode, ss.0).map_err(Into::into)?,
T1::try_conv_to(mode, ss.1).map_err(Into::into)?,
T2::try_conv_to(mode, ss.2).map_err(Into::into)?,
T3::try_conv_to(mode, ss.3).map_err(Into::into)?,
T4::try_conv_to(mode, ss.4).map_err(Into::into)?,
T5::try_conv_to(mode, ss.5).map_err(Into::into)?,
))
}
#[inline]
fn conv_to(mode: R, ss: (S0, S1, S2, S3, S4, S5)) -> Self {
(
T0::conv_to(mode, ss.0),
T1::conv_to(mode, ss.1),
T2::conv_to(mode, ss.2),
T3::conv_to(mode, ss.3),
T4::conv_to(mode, ss.4),
T5::conv_to(mode, ss.5),
)
}
}