//! pervasive array operations. pub mod scalar_and_array { //! traits for scalar $op array macro_rules! op { ($op:ident, $n:ident, $f:ident) => { #[doc = concat!("see [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ")")] pub trait $n { #[doc = concat!("apply the [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ") function to each element of this array.")] fn $f(self, rhs: [T; N]) -> [T; N]; } impl + Copy, const N: usize> $n for T { fn $f(self, rhs: [T; N]) -> [T; N] { rhs.map(|x| core::ops::$op::$f(self, x)) } } }; } op!(Add, SAAAdd, add); op!(BitAnd, SAAAnd, bitand); op!(BitOr, SAAOr, bitor); op!(BitXor, SAAXor, bitxor); op!(Div, SAADiv, div); op!(Mul, SAAMul, mul); op!(Rem, SAARem, rem); op!(Shl, SAAShl, shl); op!(Shr, SAAShr, shr); op!(Sub, SAASub, sub); } pub mod array_and_scalar { //! traits for array $op scalar macro_rules! op { ($op:ident, $n:ident, $f:ident) => { #[doc = concat!("see [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ")")] pub trait $n { #[doc = concat!("apply the [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ") function to each element of this array.")] fn $f(self, rhs: T) -> Self; } impl + Copy, const N: usize> $n for [T; N] { fn $f(self, rhs: T) -> Self { self.map(|x| core::ops::$op::$f(x, rhs)) } } }; } op!(Add, AASAdd, add); op!(BitAnd, AASAnd, bitand); op!(BitOr, AASOr, bitor); op!(BitXor, AASXor, bitxor); op!(Div, AASDiv, div); op!(Mul, AASMul, mul); op!(Rem, AASRem, rem); op!(Shl, AASShl, shl); op!(Shr, AASShr, shr); op!(Sub, AASSub, sub); } mod array_and_array { //! traits for array $op scalar macro_rules! op { ($op:ident, $n:ident, $f:ident, $name:ident) => { #[doc = concat!("see [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ")")] pub trait $n { #[doc = concat!("apply the [`", stringify!($f), "`](core::ops::", stringify!($op), "::", stringify!($f), ") function to the elements of both of these arrays.")] fn $name(self, rhs: [T; N]) -> Self; } impl + Copy, const N: usize> $n for [T; N] { fn $name(self, rhs: [T; N]) -> Self { use crate::Zip; self.zip(rhs).map(|(a, b)| core::ops::$op::$f(a, b)) } } }; } op!(Add, AAAdd, add, aadd); op!(BitAnd, AAAnd, bitand, aand); op!(BitOr, AAOr, bitor, aor); op!(BitXor, AAXor, bitxor, axor); op!(Div, AADiv, div, adiv); op!(Mul, AAMul, mul, amul); op!(Rem, AARem, rem, arem); op!(Shl, AAShl, shl, ashl); op!(Shr, AAShr, shr, ashr); op!(Sub, AASub, sub, asub); } /// see [`not`](core::ops::Not::not) pub trait ANot { /// apply the [`not`](core::ops::Not::not) function to each element of this array. fn not(self) -> Self; } impl, const N: usize> ANot for [T; N] { fn not(self) -> Self { self.map(core::ops::Not::not) } } /// see [`neg`](core::ops::Not::not) pub trait ANeg { /// apply the [`not`](core::ops::Not::not) function to each element of this array. fn neg(self) -> Self; } impl, const N: usize> ANeg for [T; N] { fn neg(self) -> Self { self.map(core::ops::Neg::neg) } } /// Prelude for pervasive operations. pub mod prelude { #[doc(inline)] pub use super::{array_and_array::*, array_and_scalar::*, scalar_and_array::*, ANeg, ANot}; } #[test] fn x() { use prelude::*; assert_eq!(2.mul([5, 2].add(5)), [20, 14]); assert_eq!(5.0.sub([2., 6.]), [3., -1.]); }