1use super::*;
2use std::ops::*;
3
4macro_rules! complex_add {
6 ($LHS:ty, $RHS:ty, $T:tt) => {
7 impl<$T: Add<Output = $T> + Copy + PartialEq> Add<$RHS> for $LHS {
8 type Output = C<$T>;
9 fn add(self, rhs: $RHS) -> Self::Output {
10 C(self.0 + rhs.0, self.1 + rhs.1)
11 }
12 }
13 };
14}
15macro_rules! complex_real_add {
16 ($LHS:ty, $T:tt ) => {
17 impl<$T: Add<Output = $T> + Copy + PartialEq> Add<$T> for $LHS {
18 type Output = C<$T>;
19 fn add(self, rhs: $T) -> Self::Output {
20 C(self.0 + rhs, self.1)
21 }
22 }
23 };
24}
25
26macro_rules! real_complex_add {
27 ($T:tt) => {
28 impl Add<C<$T>> for $T {
29 type Output = C<$T>;
30 fn add(self, rhs: C<$T>) -> Self::Output {
31 C(self + rhs.0, rhs.1)
32 }
33 }
34 };
35}
36complex_add!(C<T>, C<T>, T);
37complex_add!(&C<T>, &C<T>, T);
38complex_add!(C<T>, &C<T>, T);
39complex_add!(&C<T>, C<T>, T);
40
41complex_real_add!(C<T>, T);
42complex_real_add!(&C<T>, T);
43
44real_complex_add!(u8);
45real_complex_add!(u16);
46real_complex_add!(u32);
47real_complex_add!(u64);
48real_complex_add!(u128);
49real_complex_add!(i8);
50real_complex_add!(i16);
51real_complex_add!(i32);
52real_complex_add!(i64);
53real_complex_add!(i128);
54real_complex_add!(f32);
55real_complex_add!(f64);
56real_complex_add!(usize);
57real_complex_add!(isize);
58
59macro_rules! complex_sub {
61 ($LHS:ty, $RHS:ty, $T:tt) => {
62 impl<$T: Sub<Output = $T> + Copy + PartialEq> Sub<$RHS> for $LHS {
63 type Output = C<$T>;
64 fn sub(self, rhs: $RHS) -> Self::Output {
65 C(self.0 - rhs.0, self.1 - rhs.1)
66 }
67 }
68 };
69}
70macro_rules! complex_real_sub {
71 ($LHS:ty, $T:tt ) => {
72 impl<$T: Sub<Output = $T> + Copy + PartialEq> Sub<$T> for $LHS {
73 type Output = C<$T>;
74 fn sub(self, rhs: $T) -> Self::Output {
75 C(self.0 - rhs, self.1)
76 }
77 }
78 };
79}
80
81macro_rules! real_complex_sub {
82 ($T:tt) => {
83 impl Sub<C<$T>> for $T {
84 type Output = C<$T>;
85 fn sub(self, rhs: C<$T>) -> Self::Output {
86 C(self - rhs.0, -rhs.1)
87 }
88 }
89 };
90}
91
92complex_sub!(C<T>, C<T>, T);
93complex_sub!(&C<T>, &C<T>, T);
94complex_sub!(C<T>, &C<T>, T);
95complex_sub!(&C<T>, C<T>, T);
96
97complex_real_sub!(C<T>, T);
98complex_real_sub!(&C<T>, T);
99
100real_complex_sub!(i8);
101real_complex_sub!(i16);
102real_complex_sub!(i32);
103real_complex_sub!(i64);
104real_complex_sub!(i128);
105real_complex_sub!(f32);
106real_complex_sub!(f64);
107real_complex_sub!(isize);
108
109macro_rules! complex_mul {
112 ($LHS:ty, $RHS:ty, $T:tt ) => {
113 impl<$T: Add<Output = $T> + Mul<Output = $T> + Sub<Output = $T> + Copy + PartialEq>
114 Mul<$RHS> for $LHS
115 {
116 type Output = C<$T>;
117 fn mul(self, rhs: $RHS) -> Self::Output {
118 C(
119 self.0 * rhs.0 - self.1 * rhs.1,
120 self.0 * rhs.1 + self.1 * rhs.0,
121 )
122 }
123 }
124 };
125}
126macro_rules! complex_real_mul {
127 ($LHS:ty, $T:tt ) => {
128 impl<$T: Add<Output = $T> + Mul<Output = $T> + Sub<Output = $T> + Copy + PartialEq> Mul<$T>
129 for $LHS
130 {
131 type Output = C<$T>;
132 fn mul(self, rhs: $T) -> Self::Output {
133 C(self.0 * rhs, self.1 * rhs)
134 }
135 }
136 };
137}
138
139macro_rules! real_complex_mul {
140 ($T:tt) => {
141 impl Mul<C<$T>> for $T {
142 type Output = C<$T>;
143 fn mul(self, rhs: C<$T>) -> Self::Output {
144 C(self * rhs.0, self * rhs.1)
145 }
146 }
147 };
148}
149complex_mul!(C<T>, C<T>, T);
150complex_mul!(&C<T>, &C<T>, T);
151complex_mul!(C<T>, &C<T>, T);
152complex_mul!(&C<T>, C<T>, T);
153
154complex_real_mul!(C<T>, T);
155complex_real_mul!(&C<T>, T);
156
157real_complex_mul!(u8);
158real_complex_mul!(u16);
159real_complex_mul!(u32);
160real_complex_mul!(u64);
161real_complex_mul!(u128);
162real_complex_mul!(i8);
163real_complex_mul!(i16);
164real_complex_mul!(i32);
165real_complex_mul!(i64);
166real_complex_mul!(i128);
167real_complex_mul!(f32);
168real_complex_mul!(f64);
169real_complex_mul!(usize);
170real_complex_mul!(isize);
171
172macro_rules! complex_div {
174 ($LHS:ty, $RHS:ty, $T:tt ) => {
175 impl<
176 $T: Add<Output = $T>
177 + Mul<Output = $T>
178 + Sub<Output = $T>
179 + Div<Output = T>
180 + Copy
181 + PartialEq,
182 > Div<$RHS> for $LHS
183 {
184 type Output = C<$T>;
185 fn div(self, rhs: $RHS) -> Self::Output {
186 let den = rhs.0 * rhs.0 + rhs.1 * rhs.1;
187 C(
188 (self.0 * rhs.0 + self.1 * rhs.1) / den,
189 (self.1 * rhs.0 - self.0 * rhs.1) / den,
190 )
191 }
192 }
193 };
194}
195
196macro_rules! complex_real_div {
197 ($LHS:ty, $T:tt ) => {
198 impl<
199 $T: Add<Output = $T>
200 + Mul<Output = $T>
201 + Sub<Output = $T>
202 + Div<Output = T>
203 + Copy
204 + PartialEq,
205 > Div<$T> for $LHS
206 {
207 type Output = C<$T>;
208 fn div(self, rhs: $T) -> Self::Output {
209 C(self.0 / rhs, self.1 / rhs)
210 }
211 }
212 };
213}
214
215macro_rules! real_complex_div {
216 ($T:tt ) => {
217 impl Div<C<$T>> for $T {
218 type Output = C<$T>;
219 fn div(self, rhs: C<$T>) -> Self::Output {
220 let den = self * self + rhs.1 * rhs.1;
221 C((self * rhs.0) / den, (-self * rhs.1) / den)
222 }
223 }
224 };
225}
226complex_real_div!(C<T>, T);
227complex_real_div!(&C<T>, T);
228
229complex_div!(C<T>, C<T>, T);
230complex_div!(&C<T>, &C<T>, T);
231complex_div!(C<T>, &C<T>, T);
232complex_div!(&C<T>, C<T>, T);
233
234real_complex_div!(i8);
235real_complex_div!(i16);
236real_complex_div!(i32);
237real_complex_div!(i64);
238real_complex_div!(i128);
239real_complex_div!(f32);
240real_complex_div!(f64);
241real_complex_div!(isize);
242
243macro_rules! complex_neg {
245 ($LHS:ty, $T:tt ) => {
246 impl<$T: Neg<Output = $T> + Copy + PartialEq> Neg for $LHS {
247 type Output = C<$T>;
248 fn neg(self) -> Self::Output {
249 C(-self.0, -self.1)
250 }
251 }
252 };
253}
254complex_neg!(C<T>, T);
255complex_neg!(&C<T>, T);
256
257impl<T: Copy + PartialEq + Add<T, Output = T>> AddAssign<C<T>> for C<T> {
260 fn add_assign(&mut self, rhs: Self) {
261 self.0 = self.0 + rhs.0;
262 self.1 = self.1 + rhs.1;
263 }
264}
265impl<T: Copy + PartialEq + Add<T, Output = T>> AddAssign<T> for C<T> {
266 fn add_assign(&mut self, rhs: T) {
267 self.0 = self.0 + rhs;
268 }
269}
270
271impl<T: Copy + PartialEq + Sub<T, Output = T>> SubAssign<C<T>> for C<T> {
273 fn sub_assign(&mut self, rhs: Self) {
274 self.0 = self.0 - rhs.0;
275 self.1 = self.1 - rhs.1;
276 }
277}
278impl<T: Copy + PartialEq + Sub<T, Output = T>> SubAssign<T> for C<T> {
279 fn sub_assign(&mut self, rhs: T) {
280 self.0 = self.0 - rhs;
281 }
282}
283
284impl<T: Copy + PartialEq + Mul<T, Output = T> + Add<Output = T> + Sub<Output = T>> MulAssign<C<T>>
286 for C<T>
287{
288 fn mul_assign(&mut self, rhs: Self) {
289 let out = self.clone() * rhs;
290 self.0 = out.0;
291 self.1 = out.1;
292 }
293}
294impl<T: Copy + PartialEq + Mul<T, Output = T>> MulAssign<T> for C<T> {
295 fn mul_assign(&mut self, rhs: T) {
296 self.0 = self.0 * rhs;
297 self.1 = self.1 * rhs;
298 }
299}
300
301impl<
303 T: Copy + PartialEq + Div<Output = T> + Mul<T, Output = T> + Add<Output = T> + Sub<Output = T>,
304 > DivAssign<C<T>> for C<T>
305{
306 fn div_assign(&mut self, rhs: Self) {
307 let out = self.clone() / rhs;
308 self.0 = out.0;
309 self.1 = out.1;
310 }
311}
312impl<T: Copy + PartialEq + Div<T, Output = T>> DivAssign<T> for C<T> {
313 fn div_assign(&mut self, rhs: T) {
314 self.0 = self.0 / rhs;
315 self.1 = self.1 / rhs;
316 }
317}