1use crate::Matrix;
6use num_traits::Num;
7
8#[doc(hidden)]
10macro_rules! impl_matrix_op {
11 (neg) => {
12 _impl_op_unary_ex!(Neg::neg);
13 };
14 (!) => {
15 _impl_op_unary_ex!(Not::not);
16 };
17 (+) => {
18 _impl_op_binary_ex!(Add::add, AddAssign::add_assign);
19 };
20 (-) => {
21 _impl_op_binary_ex!(Sub::sub, SubAssign::sub_assign);
22 };
23 (*) => {
24 _impl_op_binary_ex!(Mul::mul, MulAssign::mul_assign);
25 };
26 (/) => {
27 _impl_op_binary_ex!(Div::div, DivAssign::div_assign);
28 };
29 (%) => {
30 _impl_op_binary_ex!(Rem::rem, RemAssign::rem_assign);
31 };
32 (&) => {
33 _impl_op_binary_ex!(BitAnd::bitand, BitAndAssign::bitand_assign);
34 };
35 (|) => {
36 _impl_op_binary_ex!(BitOr::bitor, BitOrAssign::bitor_assign);
37 };
38 (^) => {
39 _impl_op_binary_ex!(BitXor::bitxor, BitXorAssign::bitxor_assign);
40 };
41 (<<) => {
42 _impl_op_binary_ex!(Shl::shl, ShlAssign::shl_assign);
43 };
44 (>>) => {
45 _impl_op_binary_ex!(Shr::shr, ShrAssign::shr_assign);
46 };
47}
48
49#[doc(hidden)]
50macro_rules! _impl_op_unary_ex {
51 ($op_trait:ident::$op_fn:ident) => {
52 _impl_op_m_internal!($op_trait, $op_fn, Matrix<L,M,N>, Matrix<L,M,N>);
53 _impl_op_m_internal!($op_trait, $op_fn, &Matrix<L,M,N>, Matrix<L,M,N>);
54 }
55}
56
57#[doc(hidden)]
58macro_rules! _impl_op_binary_ex {
59 ($op_trait:ident::$op_fn:ident, $op_assign_trait:ident::$op_assign_fn:ident) => {
60 _impl_op_mm_internal!($op_trait, $op_fn, Matrix<L,M,N>, Matrix<R,M,N>, Matrix<L,M,N>);
61 _impl_op_mm_internal!($op_trait, $op_fn, &Matrix<L,M,N>, Matrix<R,M,N>, Matrix<L,M,N>);
62 _impl_op_mm_internal!($op_trait, $op_fn, Matrix<L,M,N>, &Matrix<R,M,N>, Matrix<L,M,N>);
63 _impl_op_mm_internal!($op_trait, $op_fn, &Matrix<L,M,N>, &Matrix<R,M,N>, Matrix<L,M,N>);
64
65 _impl_op_ms_internal!($op_trait, $op_fn, Matrix<L,M,N>, R, Matrix<L,M,N>);
66 _impl_op_ms_internal!($op_trait, $op_fn, &Matrix<L,M,N>, R, Matrix<L,M,N>);
67
68 _impl_opassign_mm_internal!($op_assign_trait, $op_assign_fn, Matrix<L,M,N>, Matrix<R,M,N>, Matrix<L,M,N>);
69 _impl_opassign_mm_internal!($op_assign_trait, $op_assign_fn, Matrix<L,M,N>, &Matrix<R,M,N>, Matrix<L,M,N>);
70
71 _impl_opassign_ms_internal!($op_assign_trait, $op_assign_fn, Matrix<L,M,N>, R, Matrix<L,M,N>);
72
73 }
74}
75
76#[doc(hidden)]
77macro_rules! _impl_op_m_internal {
78 ($op_trait:ident, $op_fn:ident, $lhs:ty, $out:ty) => {
79 impl<L, const M: usize, const N: usize> ::std::ops::$op_trait for $lhs
80 where
81 L: ::std::ops::$op_trait<Output = L> + Copy,
82 {
83 type Output = $out;
84
85 #[inline(always)]
86 fn $op_fn(self) -> Self::Output {
87 let mut result = self.clone();
88 for m in 0..M {
90 for n in 0..N {
91 result.data[m][n] = self.data[m][n].$op_fn();
92 }
93 }
94 result
95 }
96 }
97 };
98}
99
100#[doc(hidden)]
101macro_rules! _impl_op_mm_internal {
102 ($op_trait:ident, $op_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
103 impl<L, R, const M: usize, const N: usize> ::std::ops::$op_trait<$rhs> for $lhs
104 where
105 L: ::std::ops::$op_trait<R, Output = L> + Copy,
106 R: Copy,
107 {
108 type Output = $out;
109
110 #[inline(always)]
111 fn $op_fn(self, other: $rhs) -> Self::Output {
112 let mut result = self.clone();
113 for m in 0..M {
114 for n in 0..N {
115 result.data[m][n] = self.data[m][n].$op_fn(other.data[m][n]);
116 }
117 }
118 result
119 }
120 }
121 };
122}
123
124#[doc(hidden)]
125macro_rules! _impl_opassign_mm_internal {
126 ($op_trait:ident, $op_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
127 impl<L, R, const M: usize, const N: usize> ::std::ops::$op_trait<$rhs> for $lhs
128 where
129 L: ::std::ops::$op_trait<R> + Copy,
130 R: Copy,
131 {
132 #[inline(always)]
133 fn $op_fn(&mut self, other: $rhs) {
134 for m in 0..M {
135 for n in 0..N {
136 self.data[m][n].$op_fn(other.data[m][n]);
137 }
138 }
139 }
140 }
141 };
142}
143
144#[doc(hidden)]
145macro_rules! _impl_op_ms_internal {
146 ($op_trait:ident, $op_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
147 impl<L, R, const M: usize, const N: usize> ::std::ops::$op_trait<$rhs> for $lhs
148 where
149 L: ::std::ops::$op_trait<R, Output = L> + Copy,
150 R: Copy + Num,
151 {
152 type Output = $out;
153
154 #[inline(always)]
155 fn $op_fn(self, other: $rhs) -> Self::Output {
156 let mut result = self.clone();
157 for m in 0..M {
158 for n in 0..N {
159 result.data[m][n] = self.data[m][n].$op_fn(other);
160 }
161 }
162 result
163 }
164 }
165 };
166}
167
168#[doc(hidden)]
169macro_rules! _impl_opassign_ms_internal {
170 ($op_trait:ident, $op_fn:ident, $lhs:ty, $rhs:ty, $out:ty) => {
171 impl<L, R, const M: usize, const N: usize> ::std::ops::$op_trait<$rhs> for $lhs
172 where
173 L: ::std::ops::$op_trait<R> + Copy,
174 R: Copy + Num,
175 {
176 #[inline(always)]
177 fn $op_fn(&mut self, r: $rhs) {
178 for m in 0..M {
179 for n in 0..N {
180 self.data[m][n].$op_fn(r);
181 }
182 }
183 }
184 }
185 };
186}
187
188impl_matrix_op!(neg);
189impl_matrix_op!(!);
190impl_matrix_op!(+);
191impl_matrix_op!(-);
192impl_matrix_op!(*);
193impl_matrix_op!(/);
194impl_matrix_op!(%);
195impl_matrix_op!(&);
196impl_matrix_op!(|);
197impl_matrix_op!(^);
198impl_matrix_op!(<<);
199impl_matrix_op!(>>);