wedged 0.1.1

A robust and generalized library for Geometric Algebra in Rust.
Documentation
use super::*;

//
// Dimension casting
//

impl<T:AllocBlade<N1,G>+Zero, N1:Dim, G:Dim> SimpleBlade<T,N1,G> {

    #[doc = cast_dim_doc!()]
    pub fn cast_dim_generic<N2:Dim>(self, n:N2) -> SimpleBlade<T,N2,G> where T:AllocBlade<N2,G> {
        SimpleBlade::from_inner_unchecked(self.into_inner().cast_dim_generic(n))
    }

    #[doc = cast_dim_doc!()]
    pub fn cast_dim_dyn(self, n:usize) -> SimpleBlade<T,Dyn,G> where T:AllocBlade<Dyn,G> {
        SimpleBlade::from_inner_unchecked(self.into_inner().cast_dim_dyn(n))
    }

    #[doc = cast_dim_doc!()]
    pub fn cast_dim<N2:DimName>(self) -> SimpleBlade<T,N2,G> where T:AllocBlade<N2,G> {
        SimpleBlade::from_inner_unchecked(self.into_inner().cast_dim())
    }

}

macro_rules! impl_dim_cast {
    ($Ty:ident<T:$Alloc:ident,$N1:ident $(, $N:ident)*> -> $N2:ident) => {
        impl<T:$Alloc<$N1 $(,$N)*>+Zero, $N1:Dim $(, $N:Dim)*> $Ty<T, $N1 $(,$N)*> {

            #[doc = cast_dim_doc!()]
            pub fn cast_dim_generic_unchecked<N2:Dim>(self, n:N2) -> $Ty<T, $N2 $(,$N)*> where
                T:$Alloc<$N2 $(,$N)*>
            {
                $Ty::from_inner_unchecked(self.into_inner().cast_dim_generic(n))
            }

            #[doc = cast_dim_doc!()]
            pub fn cast_dim_dyn_unchecked(self, n:usize) -> $Ty<T, Dyn $(,$N)*> where
                T:$Alloc<Dyn $(,$N)*>
            {
                $Ty::from_inner_unchecked(self.into_inner().cast_dim_dyn(n))
            }

            #[doc = cast_dim_doc!()]
            pub fn cast_dim_unchecked<N2:DimName>(self) -> $Ty<T, $N2 $(,$N)*> where
                T:$Alloc<$N2 $(,$N)*>
            {
                $Ty::from_inner_unchecked(self.into_inner().cast_dim())
            }

            #[doc = cast_dim_doc!()]
            pub fn cast_dim<N2:DimName>(self) -> $Ty<T, $N2 $(,$N)*> where
                T:$Alloc<$N2 $(,$N)*>,
                N1:IsLessOrEqual<N2,Output=True>
            {
                $Ty::from_inner_unchecked(self.into_inner().cast_dim())
            }

        }
    }
}

impl_dim_cast!(UnitBlade<T:AllocBlade,N1,G> -> N2);
impl_dim_cast!(Rotor<T:AllocEven,N1> -> N2);
impl_dim_cast!(Reflector<T:AllocOdd,N1> -> N2);

//
//Interpretation casting
//


impl<T:AllocBlade<N,U1>, N:Dim> VecN<T,N> {

    #[inline(always)]
    pub fn into_simple_vec(self) -> SimpleVecN<T,N> { self.into_simple_unchecked() }

}

impl<T:AllocBlade<N,G>, N:Dim, G:Dim> Blade<T,N,G> {

    #[inline(always)]
    pub fn into_simple(self) -> SimpleBlade<T,N,G> where T:AllocSimpleBlade<N,G> {
        SimpleBlade::from_inner_unchecked(self)
    }

    #[inline(always)]
    pub fn into_simple_unchecked(self) -> SimpleBlade<T,N,G> {
        SimpleBlade::from_inner_unchecked(self)
    }

    #[inline(always)]
    pub fn into_unit_unchecked(self) -> UnitBlade<T,N,G> {
        UnitBlade::from_inner_unchecked(self)
    }

}

impl<T:AllocBlade<N,G>, N:Dim, G:Dim> SimpleBlade<T,N,G> {

    #[inline(always)]
    pub fn into_blade(self) -> Blade<T,N,G> {
        self.into_inner()
    }

    #[inline(always)]
    pub fn into_unit_unchecked(self) -> UnitBlade<T,N,G> {
        self.into_blade().into_unit_unchecked()
    }

}

impl<T:AllocBlade<N,G>, N:Dim, G:Dim> UnitBlade<T,N,G> {

    #[inline(always)]
    pub fn into_blade(self) -> Blade<T,N,G> {
        self.into_inner()
    }

    #[inline(always)]
    pub fn into_simple(self) -> SimpleBlade<T,N,G> {
        self.into_blade().into_simple_unchecked()
    }

}

impl<T:AllocEven<N>, N:Dim> Even<T,N> {

    #[inline(always)]
    pub fn into_rotor_unchecked(self) -> Rotor<T,N> {
        Rotor::from_inner_unchecked(self)
    }

    #[inline(always)]
    pub fn into_versor_unchecked(self) -> Versor<T,N> where T:AllocVersor<N> {
        Versor::Even(self.into_rotor_unchecked())
    }

}

impl<T:AllocEven<N>, N:Dim> Rotor<T,N> {
    #[inline(always)] pub fn into_even(self) -> Even<T,N> { self.into_inner() }

    #[inline(always)]
    pub fn into_versor(self) -> Versor<T,N> where T:AllocVersor<N> {
        Versor::Even(self)
    }
}


impl<T:AllocOdd<N>, N:Dim> Odd<T,N> {

    #[inline(always)]
    pub fn into_reflector_unchecked(self) -> Reflector<T,N> {
        Reflector::from_inner_unchecked(self)
    }

    #[inline(always)]
    pub fn into_versor_unchecked(self) -> Versor<T,N> where T:AllocVersor<N> {
        self.into_reflector_unchecked().into_versor()
    }

}

impl<T:AllocOdd<N>, N:Dim> Reflector<T,N> {
    #[inline(always)] pub fn into_odd(self) -> Odd<T,N> { self.into_inner() }

    #[inline(always)]
    pub fn into_versor(self) -> Versor<T,N> where T:AllocVersor<N> {
        Versor::Odd(self)
    }
}

impl<T:AllocVersor<N>, N:Dim> Versor<T,N> {

    /// Returns `true` if `self` is an even versor
    pub fn even(&self) -> bool {
        match self {
            Versor::Even(_) => true,
            Versor::Odd(_) => false,
        }
    }

    /// Converts `self` into a `Rotor` if even and returns `None` otherwise
    pub fn try_into_even(self) -> Option<Rotor<T,N>> {
        match self {
            Versor::Even(x) => Some(x),
            Versor::Odd(_) => None
        }
    }

    /// Converts `self` into a `Rotor` if even and panics otherwise
    pub fn unwrap_even(self) -> Rotor<T,N> {
        match self {
            Versor::Even(x) => x,
            Versor::Odd(_) => panic!("Attempted to unwrap an odd versor into a Rotor")
        }
    }

    /// Returns `true` if `self` is an odd versor
    pub fn odd(&self) -> bool {
        match self {
            Versor::Even(_) => false,
            Versor::Odd(_) => true,
        }
    }


    /// Converts `self` into a `Reflector` if odd and returns `None` otherwise
    pub fn try_into_odd(self) -> Option<Reflector<T,N>> {
        match self {
            Versor::Even(_) => None,
            Versor::Odd(x) => Some(x),
        }
    }

    /// Converts `self` into a `Reflector` if odd and panics otherwise
    pub fn unwrap_odd(self) -> Reflector<T,N> {
        match self {
            Versor::Even(_) => panic!("Attempted to unwrap an even versor into a Reflector"),
            Versor::Odd(x) => x,
        }
    }

}

impl<T:AllocBlade<N,G>, N:Dim, G:Dim> From<UnitBlade<T,N,G>> for SimpleBlade<T,N,G> {
    fn from(b: UnitBlade<T,N,G>) -> SimpleBlade<T,N,G> { b.into_simple() }
}

impl<T:AllocVersor<N>, N:Dim> From<Rotor<T,N>> for Versor<T,N> {
    fn from(b: Rotor<T,N>) -> Versor<T,N> { b.into_versor() }
}

impl<T:AllocVersor<N>, N:Dim> From<Reflector<T,N>> for Versor<T,N> {
    fn from(b: Reflector<T,N>) -> Versor<T,N> { b.into_versor() }
}

//
//Finding the dual
//

impl<T:AllocBlade<N,G>, N:Dim, G:Dim> SimpleBlade<T,N,G> where
    N:DimSub<G>,
    T:AllocBlade<N,DimDiff<N,G>> + Neg<Output=T>
{

    /// Finds the dual of this simple blade. See [`Blade::dual()`] for more information
    pub fn dual(self) -> SimpleDualBlade<T,N,G> {
        self.into_inner().dual().into_simple_unchecked()
    }

    /// Finds the inverse dual of this simple blade. See [`Blade::undual()`] for more information
    pub fn undual(self) -> SimpleDualBlade<T,N,G> {
        self.into_inner().undual().into_simple_unchecked()
    }

}

impl<T:AllocBlade<N,G>, N:Dim, G:Dim> UnitBlade<T,N,G> where
    N:DimSub<G>,
    T:AllocBlade<N,DimDiff<N,G>> + Neg<Output=T>
{

    /// Finds the dual of this unit blade. See [`Blade::dual()`] for more information
    pub fn dual(self) -> UnitDualBlade<T,N,G> {
        self.into_inner().dual().into_unit_unchecked()
    }

    /// Finds the inverse dual of this unit blade. See [`Blade::undual()`] for more information
    pub fn undual(self) -> UnitDualBlade<T,N,G> {
        self.into_inner().undual().into_unit_unchecked()
    }

}