atools/
pervasive.rs

1//! pervasive array operations.
2pub mod scalar_and_array {
3    //! traits for scalar $op array
4    macro_rules! op {
5        ($op:ident, $n:ident, $f:ident) => {
6            #[doc = concat!("see [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ")")]
7            pub trait $n<T, const N: usize> {
8                #[doc = concat!("apply the [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ") function to each element of this array.")]
9                fn $f(self, rhs: [T; N]) -> [T; N];
10            }
11
12            impl<T: core::ops::$op<Output = T> + Copy, const N: usize> $n<T, N> for T {
13                fn $f(self, rhs: [T; N]) -> [T; N] {
14                    rhs.map(|x| core::ops::$op::$f(self, x))
15                }
16            }
17        };
18    }
19    op!(Add, SAAAdd, add);
20    op!(BitAnd, SAAAnd, bitand);
21    op!(BitOr, SAAOr, bitor);
22    op!(BitXor, SAAXor, bitxor);
23    op!(Div, SAADiv, div);
24    op!(Mul, SAAMul, mul);
25    op!(Rem, SAARem, rem);
26    op!(Shl, SAAShl, shl);
27    op!(Shr, SAAShr, shr);
28    op!(Sub, SAASub, sub);
29}
30
31pub mod array_and_scalar {
32    //! traits for array $op scalar
33    macro_rules! op {
34        ($op:ident, $n:ident, $f:ident) => {
35            #[doc = concat!("see [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ")")]
36            pub trait $n<T, const N: usize> {
37                #[doc = concat!("apply the [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ") function to each element of this array.")]
38                fn $f(self, rhs: T) -> Self;
39            }
40
41            impl<T: core::ops::$op<Output = T> + Copy, const N: usize> $n<T, N> for [T; N] {
42                fn $f(self, rhs: T) -> Self {
43                    self.map(|x| core::ops::$op::$f(x, rhs))
44                }
45            }
46        };
47    }
48    op!(Add, AASAdd, add);
49    op!(BitAnd, AASAnd, bitand);
50    op!(BitOr, AASOr, bitor);
51    op!(BitXor, AASXor, bitxor);
52    op!(Div, AASDiv, div);
53    op!(Mul, AASMul, mul);
54    op!(Rem, AASRem, rem);
55    op!(Shl, AASShl, shl);
56    op!(Shr, AASShr, shr);
57    op!(Sub, AASSub, sub);
58}
59
60mod array_and_array {
61    //! traits for array $op scalar
62    macro_rules! op {
63            ($op:ident, $n:ident, $f:ident, $name:ident) => {
64                #[doc = concat!("see [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ")")]
65                pub trait $n<T, const N: usize> {
66                    #[doc = concat!("apply the [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ") function to the elements of both of these arrays.")]
67                    fn $name(self, rhs: [T; N]) -> Self;
68                }
69
70                impl<T: core::ops::$op<Output = T> + Copy, const N: usize> $n<T, N> for [T; N] {
71                    fn $name(self, rhs: [T; N]) -> Self {
72                        use crate::Zip;
73                        self.zip(rhs).map(|(a, b)| core::ops::$op::$f(a, b))
74                    }
75                }
76            };
77        }
78    op!(Add, AAAdd, add, aadd);
79    op!(BitAnd, AAAnd, bitand, aand);
80    op!(BitOr, AAOr, bitor, aor);
81    op!(BitXor, AAXor, bitxor, axor);
82    op!(Div, AADiv, div, adiv);
83    op!(Mul, AAMul, mul, amul);
84    op!(Rem, AARem, rem, arem);
85    op!(Shl, AAShl, shl, ashl);
86    op!(Shr, AAShr, shr, ashr);
87    op!(Sub, AASub, sub, asub);
88}
89
90/// see [`not`](core::ops::Not::not)
91pub trait ANot<T, const N: usize> {
92    /// apply the [`not`](core::ops::Not::not) function to each element of this array.
93    fn not(self) -> Self;
94}
95impl<T: core::ops::Not<Output = T>, const N: usize> ANot<T, N> for [T; N] {
96    fn not(self) -> Self {
97        self.map(core::ops::Not::not)
98    }
99}
100
101/// see [`neg`](core::ops::Not::not)
102pub trait ANeg<T, const N: usize> {
103    /// apply the [`not`](core::ops::Not::not) function to each element of this array.
104    fn neg(self) -> Self;
105}
106impl<T: core::ops::Neg<Output = T>, const N: usize> ANeg<T, N> for [T; N] {
107    fn neg(self) -> Self {
108        self.map(core::ops::Neg::neg)
109    }
110}
111
112/// Prelude for pervasive operations.
113pub mod prelude {
114    #[doc(inline)]
115    pub use super::{array_and_array::*, array_and_scalar::*, scalar_and_array::*, ANeg, ANot};
116}
117#[test]
118fn x() {
119    use prelude::*;
120    assert_eq!(2.mul([5, 2].add(5)), [20, 14]);
121    assert_eq!(5.0.sub([2., 6.]), [3., -1.]);
122}