1#[cfg(feature = "integer")]
18use crate::Integer;
19#[cfg(feature = "rational")]
20use crate::Rational;
21use crate::complex::MiniComplex;
22#[allow(deprecated)]
23use crate::complex::SmallComplex;
24use crate::float::Special;
25use crate::{Complex, Float};
26
27impl PartialEq for Complex {
28 #[inline]
29 fn eq(&self, other: &Complex) -> bool {
30 self.real().eq(other.real()) && self.imag().eq(other.imag())
31 }
32}
33
34impl PartialEq<MiniComplex> for Complex {
35 #[inline]
36 fn eq(&self, other: &MiniComplex) -> bool {
37 self.eq(&*other.borrow())
38 }
39}
40
41impl PartialEq<Complex> for MiniComplex {
42 #[inline]
43 fn eq(&self, other: &Complex) -> bool {
44 (*self.borrow()).eq(other)
45 }
46}
47
48#[allow(deprecated)]
49impl PartialEq<SmallComplex> for Complex {
50 #[inline]
51 fn eq(&self, other: &SmallComplex) -> bool {
52 self.eq(&**other)
53 }
54}
55
56#[allow(deprecated)]
57impl PartialEq<Complex> for SmallComplex {
58 #[inline]
59 fn eq(&self, other: &Complex) -> bool {
60 (**self).eq(other)
61 }
62}
63
64macro_rules! eq_re_im {
65 ($Re:ty; $($Im:ty)*) => { $(
66 impl PartialEq<($Re, $Im)> for Complex {
67 #[inline]
68 fn eq(&self, other: &($Re, $Im)) -> bool {
69 self.real().eq(&other.0) && self.imag().eq(&other.1)
70 }
71 }
72
73 impl PartialEq<Complex> for ($Re, $Im) {
74 #[inline]
75 fn eq(&self, other: &Complex) -> bool {
76 other.real().eq(&self.0) && other.imag().eq(&self.1)
77 }
78 }
79 )* };
80}
81
82macro_rules! eq_re {
83 ($($Re:ty)*) => { $(
84 impl PartialEq<$Re> for Complex {
85 #[inline]
86 fn eq(&self, other: &$Re) -> bool {
87 self.imag().is_zero() && self.real().eq(other)
88 }
89 }
90
91 impl PartialEq<Complex> for $Re {
92 #[inline]
93 fn eq(&self, other: &Complex) -> bool {
94 other.imag().is_zero() && other.real().eq(self)
95 }
96 }
97
98 #[cfg(feature = "integer")]
99 eq_re_im! { $Re; Integer }
100 #[cfg(feature = "rational")]
101 eq_re_im! { $Re; Rational }
102 eq_re_im! { $Re; Float Special }
103 eq_re_im! { $Re; i8 i16 i32 i64 i128 isize }
104 eq_re_im! { $Re; u8 u16 u32 u64 u128 usize }
105 eq_re_im! { $Re; f32 f64 }
106 #[cfg(feature = "nightly-float")]
107 eq_re_im! { $Re; f16 f128 }
108 )* };
109}
110
111#[cfg(feature = "integer")]
112eq_re! { Integer }
113#[cfg(feature = "rational")]
114eq_re! { Rational }
115eq_re! { Float Special }
116eq_re! { i8 i16 i32 i64 i128 isize }
117eq_re! { u8 u16 u32 u64 u128 usize }
118eq_re! { f32 f64 }
119#[cfg(feature = "nightly-float")]
120eq_re! { f16 f128 }
121
122#[cfg(test)]
123mod tests {
124 #[cfg(feature = "integer")]
125 use crate::Integer;
126 #[cfg(feature = "rational")]
127 use crate::Rational;
128 use crate::float;
129 use crate::float::{FreeCache, Special};
130 use crate::{Assign, Complex, Float};
131 #[cfg(feature = "integer")]
132 use core::str::FromStr;
133
134 fn check_eq_prim<T>(s: &[T], against: &[Complex])
135 where
136 Complex: Assign<T> + Assign<(T, T)> + PartialEq<T> + PartialEq<(T, T)>,
137 T: Copy + PartialEq<Complex>,
138 (T, T): Copy + PartialEq<Complex>,
139 {
140 for op in s {
141 let fop = Complex::with_val(150, *op);
142 for b in against {
143 assert_eq!(b.eq(op), b.eq(&fop));
144 assert_eq!(op.eq(b), fop.eq(b));
145 assert_eq!(b.eq(op), op.eq(b));
146 }
147 }
148 for op in combinations(s) {
149 let fop = Complex::with_val(150, op);
150 for b in against {
151 assert_eq!(b.eq(&op), b.eq(&fop));
152 assert_eq!(op.eq(b), fop.eq(b));
153 assert_eq!(b.eq(&op), op.eq(b));
154 }
155 }
156 }
157
158 fn check_eq_big<'a, T>(s: &'a [T], against: &[Complex])
159 where
160 Complex:
161 for<'b> Assign<&'b T> + for<'b> Assign<&'b (T, T)> + PartialEq<T> + PartialEq<(T, T)>,
162 T: Clone + PartialEq<Complex>,
163 (T, T): Clone + PartialEq<Complex>,
164 {
165 for op in s {
166 let fop = Complex::with_val(150, op);
167 for b in against {
168 assert_eq!(b.eq(op), b.eq(&fop));
169 assert_eq!(op.eq(b), fop.eq(b));
170 assert_eq!(b.eq(op), op.eq(b));
171 }
172 }
173 for op in combinations(s) {
174 let fop = Complex::with_val(150, &op);
175 for b in against {
176 assert_eq!(b.eq(&op), b.eq(&fop));
177 assert_eq!(op.eq(b), fop.eq(b));
178 assert_eq!(b.eq(&op), op.eq(b));
179 }
180 }
181 }
182
183 fn combinations<T: Clone>(t: &[T]) -> Vec<(T, T)> {
184 let mut ret = Vec::with_capacity(t.len() * t.len());
185 for re in t {
186 for im in t {
187 ret.push((re.clone(), im.clone()));
188 }
189 }
190 ret
191 }
192
193 fn to_complex<T>(t: T) -> Complex
194 where
195 Complex: Assign<T>,
196 {
197 Complex::with_val(20, t)
198 }
199
200 #[test]
201 fn check_eq_others() {
202 use crate::tests::{F32, F64, I32, I64, I128, U32, U64, U128};
203 #[cfg(feature = "integer")]
204 let z = [
205 Integer::from(0),
206 Integer::from(1),
207 Integer::from(-1),
208 Integer::from_str("-1000000000000").unwrap(),
209 Integer::from_str("1000000000000").unwrap(),
210 ];
211 #[cfg(feature = "rational")]
212 let q = [
213 Rational::from(0),
214 Rational::from(1),
215 Rational::from(-1),
216 Rational::from_str("-1000000000000/33333333333").unwrap(),
217 Rational::from_str("1000000000000/33333333333").unwrap(),
218 ];
219 let f = [
220 Float::with_val(20, Special::Zero),
221 Float::with_val(20, Special::NegZero),
222 Float::with_val(20, Special::Infinity),
223 Float::with_val(20, Special::NegInfinity),
224 Float::with_val(20, Special::Nan),
225 Float::with_val(20, 1),
226 Float::with_val(20, -1),
227 Float::with_val(20, 999_999e100),
228 Float::with_val(20, 999_999e-100),
229 Float::with_val(20, -999_999e100),
230 Float::with_val(20, -999_999e-100),
231 ];
232
233 let against = combinations(&f)
234 .iter()
235 .map(to_complex)
236 .chain(combinations(U32).iter().map(to_complex))
237 .chain(combinations(I32).iter().map(to_complex))
238 .chain(combinations(U64).iter().map(to_complex))
239 .chain(combinations(I64).iter().map(to_complex))
240 .chain(combinations(U128).iter().map(to_complex))
241 .chain(combinations(I128).iter().map(to_complex))
242 .chain(combinations(F32).iter().map(to_complex))
243 .chain(combinations(F64).iter().map(to_complex))
244 .collect::<Vec<Complex>>();
245 #[cfg(feature = "integer")]
246 let mut against = against;
247 #[cfg(feature = "integer")]
248 against.extend(combinations(&z).iter().map(to_complex));
249 #[cfg(feature = "rational")]
250 against.extend(combinations(&q).iter().map(to_complex));
251 check_eq_prim(U32, &against);
252 check_eq_prim(I32, &against);
253 check_eq_prim(U64, &against);
254 check_eq_prim(I64, &against);
255 check_eq_prim(U128, &against);
256 check_eq_prim(I128, &against);
257 check_eq_prim(F32, &against);
258 check_eq_prim(F64, &against);
259 #[cfg(feature = "integer")]
260 check_eq_big(&z, &against);
261 #[cfg(feature = "rational")]
262 check_eq_big(&q, &against);
263 check_eq_big(&f, &against);
264
265 float::free_cache(FreeCache::All);
266 }
267}