concision_core/traits/arr/
create.rs1use 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
44impl<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);