matreex 0.42.3

A simple matrix implementation.
Documentation
use super::super::Matrix;
use super::super::layout::{Order, OrderKind};
use crate::convert::IntoRows;
use crate::index::Index;
use alloc::boxed::Box;
use alloc::vec::Vec;

impl<T, O> IntoRows<Box<[Box<[T]>]>> for Matrix<T, O>
where
    O: Order,
{
    fn into_rows(self) -> Box<[Box<[T]>]> {
        IntoRows::<Box<[Vec<T>]>>::into_rows(self)
            .into_iter()
            .map(|row| row.into_boxed_slice())
            .collect()
    }
}

impl<T, O> IntoRows<Vec<Box<[T]>>> for Matrix<T, O>
where
    O: Order,
{
    fn into_rows(self) -> Vec<Box<[T]>> {
        IntoRows::<Box<[Box<[T]>]>>::into_rows(self).into_vec()
    }
}

impl<T, O> IntoRows<Box<[Vec<T>]>> for Matrix<T, O>
where
    O: Order,
{
    fn into_rows(self) -> Box<[Vec<T>]> {
        let shape = self.shape();
        let stride = self.stride();

        match O::KIND {
            OrderKind::RowMajor => {
                let mut iter = self.data.into_iter();
                (0..shape.nrows)
                    .map(|_| iter.by_ref().take(shape.ncols).collect())
                    .collect()
            }

            OrderKind::ColMajor => {
                let mut output: Box<_> = (0..shape.nrows)
                    .map(|_| Vec::with_capacity(shape.ncols))
                    .collect();
                self.data
                    .into_iter()
                    .enumerate()
                    .for_each(|(index, element)| unsafe {
                        let index = Index::from_flattened::<O>(index, stride);
                        output.get_unchecked_mut(index.row).push(element)
                    });
                output
            }
        }
    }
}

impl<T, O> IntoRows<Vec<Vec<T>>> for Matrix<T, O>
where
    O: Order,
{
    fn into_rows(self) -> Vec<Vec<T>> {
        IntoRows::<Box<[Vec<T>]>>::into_rows(self).into_vec()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::convert::TryFromRows;
    use crate::dispatch_unary;
    use alloc::vec;

    #[test]
    fn test_into_rows() {
        dispatch_unary! {{
            let matrix = Matrix::<i32, O>::try_from_rows([[1, 2, 3], [4, 5, 6]]).unwrap();
            let output: Box<[Box<[i32]>]> = matrix.into_rows();
            let expected: Box<[Box<[i32]>]> = Box::new([Box::new([1, 2, 3]), Box::new([4, 5, 6])]);
            assert_eq!(output, expected);

            let matrix = Matrix::<i32, O>::try_from_rows([[1, 2, 3], [4, 5, 6]]).unwrap();
            let output: Vec<Box<[i32]>> = matrix.into_rows();
            let expected: Vec<Box<[i32]>> = vec![Box::new([1, 2, 3]), Box::new([4, 5, 6])];
            assert_eq!(output, expected);

            let matrix = Matrix::<i32, O>::try_from_rows([[1, 2, 3], [4, 5, 6]]).unwrap();
            let output: Box<[Vec<i32>]> = matrix.into_rows();
            let expected: Box<[Vec<i32>]> = Box::new([vec![1, 2, 3], vec![4, 5, 6]]);
            assert_eq!(output, expected);

            let matrix = Matrix::<i32, O>::try_from_rows([[1, 2, 3], [4, 5, 6]]).unwrap();
            let output: Vec<Vec<i32>> = matrix.into_rows();
            let expected: Vec<Vec<i32>> = vec![vec![1, 2, 3], vec![4, 5, 6]];
            assert_eq!(output, expected);
        }}
    }
}