concision_core/traits/arr/
create.rs

1/*
2   Appellation: create <module>
3   Contrib: FL03 <jo3mccain@icloud.com>
4*/
5use nd::{ArrayBase, DataOwned, Dimension, Ix2, ShapeBuilder};
6use num::traits::Num;
7
8pub trait NdLike<T, O = Self>
9where
10    Self: DefaultLike<Output = O>
11        + FillLike<T, Output = O>
12        + OnesLike<Output = O>
13        + ZerosLike<Output = O>,
14{
15}
16
17pub trait ArrayLike<A = f64, D = Ix2>
18where
19    D: Dimension,
20{
21    type Output;
22
23    fn array_like<Sh>(&self, shape: Sh, elem: A) -> Self::Output
24    where
25        Sh: ShapeBuilder<Dim = D>;
26}
27
28macro_rules! ndlike {
29    ($($name:ident::$(<$($T:ident),*>::)?$method:ident $(($($field:ident:$ft:ty),*))?),* $(,)?) => {
30        $(ndlike!(@impl $name::$(<$($T),*>::)?$method$(($($field:$ft),*))?);)*
31    };
32    (@impl $name:ident::$(<$($T:ident),*>::)?$method:ident$(($($field:ident: $ft:ty),*))?) => {
33        pub trait $name$(<$($T),*>)? {
34            type Output;
35
36            fn $method(&self $(, $($field:$ft),*)?) -> Self::Output;
37        }
38    };
39
40}
41
42ndlike!(DefaultLike::default_like, OnesLike::ones_like, ZerosLike::zeros_like, FillLike::<T>::fill_like(elem: T));
43
44/*
45 ******** implementations ********
46*/
47
48impl<A, S, D> NdLike<A, ArrayBase<S, D>> for ArrayBase<S, D>
49where
50    A: Clone + Default + Num,
51    D: Dimension,
52    S: DataOwned<Elem = A>,
53{
54}
55
56impl<A, S, D> ArrayLike<A, D> for ArrayBase<S, D>
57where
58    A: Clone,
59    D: Dimension,
60    S: nd::DataOwned<Elem = A>,
61{
62    type Output = ArrayBase<S, D>;
63
64    fn array_like<Sh>(&self, shape: Sh, elem: A) -> Self::Output
65    where
66        Sh: ShapeBuilder<Dim = D>,
67    {
68        if self.is_standard_layout() {
69            ArrayBase::from_elem(shape, elem)
70        } else {
71            ArrayBase::from_elem(shape.f(), elem)
72        }
73    }
74}
75
76impl<A, S, D> FillLike<A> for ArrayBase<S, D>
77where
78    A: Clone,
79    D: Dimension,
80    S: DataOwned<Elem = A>,
81{
82    type Output = ArrayBase<S, D>;
83
84    fn fill_like(&self, elem: A) -> Self::Output {
85        ArrayBase::from_elem(self.dim(), elem)
86    }
87}
88
89macro_rules! impl_ndlike {
90
91    ($name:ident::$method:ident.$call:ident: $($p:tt)*) => {
92        impl<A, S, D> $name for ArrayBase<S, D>
93        where
94            A: $($p)*,
95            D: Dimension,
96            S: DataOwned<Elem = A>,
97        {
98            type Output = ArrayBase<S, D>;
99
100            fn $method(&self) -> Self::Output {
101                ArrayBase::$call(self.dim())
102            }
103        }
104    };
105}
106
107impl_ndlike!(DefaultLike::default_like.default: Default);
108impl_ndlike!(OnesLike::ones_like.ones: Clone + num::One);
109impl_ndlike!(ZerosLike::zeros_like.zeros: Clone + num::Zero);