algea 0.2.1

Small fixed-size SIMD-oriented vectors and matrices
Documentation
use crate::{Element, Vector, api::vector, private};

pub enum Dimension<const D: usize> {}

#[expect(private_bounds)]
pub trait AtLeast<const MIN: usize>: private::Sealed {}
#[expect(private_bounds)]
pub trait AtMost<const MAX: usize>: private::Sealed {}

impl<const N: usize> private::Sealed for Dimension<N> {}

impl AtLeast<1> for Dimension<1> {}
impl AtLeast<1> for Dimension<2> {}
impl AtLeast<2> for Dimension<2> {}
impl AtLeast<1> for Dimension<3> {}
impl AtLeast<2> for Dimension<3> {}
impl AtLeast<3> for Dimension<3> {}
impl AtLeast<1> for Dimension<4> {}
impl AtLeast<2> for Dimension<4> {}
impl AtLeast<3> for Dimension<4> {}
impl AtLeast<4> for Dimension<4> {}

impl AtMost<1> for Dimension<1> {}
impl AtMost<2> for Dimension<1> {}
impl AtMost<2> for Dimension<2> {}
impl AtMost<3> for Dimension<1> {}
impl AtMost<3> for Dimension<2> {}
impl AtMost<3> for Dimension<3> {}
impl AtMost<4> for Dimension<1> {}
impl AtMost<4> for Dimension<2> {}
impl AtMost<4> for Dimension<3> {}
impl AtMost<4> for Dimension<4> {}

pub enum __ConcatDispatch {}

impl private::Sealed for __ConcatDispatch {}

#[expect(private_bounds)]
pub trait __IntoVector<T: Element<D>, const D: usize>: private::Sealed {
    fn __into_vector(value: Self) -> Vector<T, D>;
}

impl<T: Element> __IntoVector<T, 1> for T {
    #[inline]
    fn __into_vector(value: Self) -> Vector<T, 1> { Vector::from_array([value]) }
}

impl<T: Element<D>, const D: usize> private::Sealed for Vector<T, D> {}

impl<T: Element<D>, const D: usize> __IntoVector<T, D> for Vector<T, D> {
    #[inline]
    fn __into_vector(value: Self) -> Vector<T, D> { value }
}

#[expect(private_bounds)]
pub trait __Concat4<A, B, C, D>: private::Sealed {
    type __Output;
    fn __concat(a: A, b: B, c: C, d: D) -> Self::__Output;
}

#[expect(private_bounds)]
pub trait __Concat3<A, B, C>: private::Sealed {
    type __Output;
    fn __concat(a: A, b: B, c: C) -> Self::__Output;
}

#[expect(private_bounds)]
pub trait __Concat2<A, B>: private::Sealed {
    type __Output;
    fn __concat(a: A, b: B) -> Self::__Output;
}

impl<T> __Concat4<Vector<T, 1>, Vector<T, 1>, Vector<T, 1>, Vector<T, 1>> for __ConcatDispatch
where
    T: Element<1> + Element<4>,
{
    type __Output = Vector<T, 4>;
    #[inline]
    fn __concat(
        a: Vector<T, 1>,
        b: Vector<T, 1>,
        c: Vector<T, 1>,
        d: Vector<T, 1>,
    ) -> Self::__Output {
        let [a0] = a.to_array();
        let [b0] = b.to_array();
        let [c0] = c.to_array();
        let [d0] = d.to_array();
        Vector::from_array([a0, b0, c0, d0])
    }
}

impl<T> __Concat3<Vector<T, 1>, Vector<T, 1>, Vector<T, 1>> for __ConcatDispatch
where
    T: Element<1> + Element<3>,
{
    type __Output = Vector<T, 3>;
    #[inline]
    fn __concat(a: Vector<T, 1>, b: Vector<T, 1>, c: Vector<T, 1>) -> Self::__Output {
        let [a0] = a.to_array();
        let [b0] = b.to_array();
        let [c0] = c.to_array();
        Vector::from_array([a0, b0, c0])
    }
}

impl<T> __Concat3<Vector<T, 1>, Vector<T, 1>, Vector<T, 2>> for __ConcatDispatch
where
    T: Element<1> + Element<2> + Element<4>,
{
    type __Output = Vector<T, 4>;
    #[inline]
    fn __concat(a: Vector<T, 1>, b: Vector<T, 1>, c: Vector<T, 2>) -> Self::__Output {
        let [a0] = a.to_array();
        let [b0] = b.to_array();
        let [c0, c1] = c.to_array();
        Vector::from_array([a0, b0, c0, c1])
    }
}

impl<T> __Concat3<Vector<T, 1>, Vector<T, 2>, Vector<T, 1>> for __ConcatDispatch
where
    T: Element<1> + Element<2> + Element<4>,
{
    type __Output = Vector<T, 4>;
    #[inline]
    fn __concat(a: Vector<T, 1>, b: Vector<T, 2>, c: Vector<T, 1>) -> Self::__Output {
        let [a0] = a.to_array();
        let [b0, b1] = b.to_array();
        let [c0] = c.to_array();
        Vector::from_array([a0, b0, b1, c0])
    }
}

impl<T> __Concat3<Vector<T, 2>, Vector<T, 1>, Vector<T, 1>> for __ConcatDispatch
where
    T: Element<1> + Element<2> + Element<4>,
{
    type __Output = Vector<T, 4>;

    #[inline]
    fn __concat(a: Vector<T, 2>, b: Vector<T, 1>, c: Vector<T, 1>) -> Self::__Output {
        let [a0, a1] = a.to_array();
        let [b0] = b.to_array();
        let [c0] = c.to_array();
        Vector::from_array([a0, a1, b0, c0])
    }
}

impl<T> __Concat2<Vector<T, 1>, Vector<T, 1>> for __ConcatDispatch
where
    T: Element<1> + Element<2>,
{
    type __Output = Vector<T, 2>;
    #[inline]
    fn __concat(a: Vector<T, 1>, b: Vector<T, 1>) -> Self::__Output {
        Vector { storage: vector::call!(<T, 1>::vector_concat_1_1(a.storage, b.storage)) }
    }
}

impl<T> __Concat2<Vector<T, 1>, Vector<T, 2>> for __ConcatDispatch
where
    T: Element<1> + Element<2> + Element<3>,
{
    type __Output = Vector<T, 3>;
    #[inline]
    fn __concat(a: Vector<T, 1>, b: Vector<T, 2>) -> Self::__Output {
        Vector { storage: vector::call!(<T, 1>::vector_concat_1_2(a.storage, b.storage)) }
    }
}

impl<T> __Concat2<Vector<T, 1>, Vector<T, 3>> for __ConcatDispatch
where
    T: Element<1> + Element<3> + Element<4>,
{
    type __Output = Vector<T, 4>;
    #[inline]
    fn __concat(a: Vector<T, 1>, b: Vector<T, 3>) -> Self::__Output {
        let [a0] = a.to_array();
        let [b0, b1, b2] = b.to_array();
        Vector::from_array([a0, b0, b1, b2])
    }
}

impl<T> __Concat2<Vector<T, 2>, Vector<T, 1>> for __ConcatDispatch
where
    T: Element<1> + Element<2> + Element<3>,
{
    type __Output = Vector<T, 3>;
    #[inline]
    fn __concat(a: Vector<T, 2>, b: Vector<T, 1>) -> Self::__Output {
        Vector { storage: vector::call!(<T, 1>::vector_concat_2_1(a.storage, b.storage)) }
    }
}

impl<T> __Concat2<Vector<T, 2>, Vector<T, 2>> for __ConcatDispatch
where
    T: Element<2> + Element<4>,
{
    type __Output = Vector<T, 4>;
    #[inline]
    fn __concat(a: Vector<T, 2>, b: Vector<T, 2>) -> Self::__Output {
        let [a0, a1] = a.to_array();
        let [b0, b1] = b.to_array();
        Vector::from_array([a0, a1, b0, b1])
    }
}

impl<T> __Concat2<Vector<T, 3>, Vector<T, 1>> for __ConcatDispatch
where
    T: Element<1> + Element<3> + Element<4>,
{
    type __Output = Vector<T, 4>;
    #[inline]
    fn __concat(a: Vector<T, 3>, b: Vector<T, 1>) -> Self::__Output {
        let [a0, a1, a2] = a.to_array();
        let [b0] = b.to_array();
        Vector::from_array([a0, a1, a2, b0])
    }
}