1#[macro_export]
2macro_rules! impl_from_f {
3 ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
4 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> From<F> for $struct<T, F$($(, $dim)*)?>
5 where
6 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
7 {
8 #[inline]
9 fn from(float: F) -> Self {
10 Self::from_re(T::from(float))
11 }
12 }
13 };
14}
15
16#[macro_export]
17macro_rules! impl_zero_one {
18 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
19 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Zero for $struct<T, F$($(, $dim)*)?>
20 where
21 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
22 {
23 #[inline]
24 fn zero() -> Self {
25 Self::from_re(T::zero())
26 }
27
28 #[inline]
29 fn is_zero(&self) -> bool {
30 self.re.is_zero()
31 }
32 }
33
34 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> One for $struct<T, F$($(, $dim)*)?>
35 where
36 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
37 {
38 #[inline]
39 fn one() -> Self {
40 Self::from_re(T::one())
41 }
42
43 #[inline]
44 fn is_one(&self) -> bool {
45 self.re.is_one()
46 }
47 }
48 };
49}
50
51#[macro_export]
52macro_rules! impl_add_sub_rem {
53 ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
54 impl<'a, 'b, T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Add<&'a $struct<T, F$($(, $dim)*)?>>
55 for &'b $struct<T, F$($(, $dim)*)?>
56 where
57 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
58 {
59 type Output = $struct<T, F$($(, $dim)*)?>;
60 #[inline]
61 fn add(self, other: &$struct<T, F$($(, $dim)*)?>) -> $struct<T, F$($(, $dim)*)?> {
62 Self::Output::new(self.re.clone() + &other.re, $(self.$im.clone() + &other.$im,)*)
63 }
64 }
65
66 impl<'a, 'b, T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Sub<&'a $struct<T, F$($(, $dim)*)?>>
67 for &'b $struct<T, F$($(, $dim)*)?>
68 where
69 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
70 {
71 type Output = $struct<T, F$($(, $dim)*)?>;
72 #[inline]
73 fn sub(self, other: &$struct<T, F$($(, $dim)*)?>) -> $struct<T, F$($(, $dim)*)?> {
74 Self::Output::new(self.re.clone() - &other.re, $(self.$im.clone() - &other.$im,)*)
75 }
76 }
77
78 impl<'a, 'b, T: DualNum<F>, F$($(, $dim: Dim)*)?> Rem<&'a $struct<T, F$($(, $dim)*)?>> for &'b $struct<T, F$($(, $dim)*)?>
79 where
80 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
81 {
82 type Output = $struct<T, F$($(, $dim)*)?>;
83 #[inline]
84 fn rem(self, _other: &$struct<T, F$($(, $dim)*)?>) -> $struct<T, F$($(, $dim)*)?> {
85 unimplemented!()
86 }
87 }
88 };
89}
90
91#[macro_export]
92macro_rules! forward_binop {
93 ($struct:ident, $trt:ident, $operator:tt, $mth:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
94 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> $trt<$struct<T, F$($(, $dim)*)?>> for &$struct<T, F$($(, $dim)*)?>
95 where
96 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
97 {
98 type Output = $struct<T, F$($(, $dim)*)?>;
99 #[inline]
100 fn $mth(self, rhs: $struct<T, F$($(, $dim)*)?>) -> Self::Output {
101 self $operator &rhs
102 }
103 }
104
105 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> $trt<&$struct<T, F$($(, $dim)*)?>> for $struct<T, F$($(, $dim)*)?>
106 where
107 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
108 {
109 type Output = $struct<T, F$($(, $dim)*)?>;
110 #[inline]
111 fn $mth(self, rhs: &$struct<T, F$($(, $dim)*)?>) -> Self::Output {
112 &self $operator rhs
113 }
114 }
115
116 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> $trt for $struct<T, F$($(, $dim)*)?>
117 where
118 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
119 {
120 type Output = $struct<T, F$($(, $dim)*)?>;
121 #[inline]
122 fn $mth(self, rhs: $struct<T, F$($(, $dim)*)?>) -> Self::Output {
123 &self $operator &rhs
124 }
125 }
126 };
127}
128
129#[macro_export]
130macro_rules! impl_neg {
131 ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
132 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Neg for $struct<T, F$($(, $dim)*)?>
133 where
134 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
135 {
136 type Output = Self;
137 #[inline]
138 fn neg(self) -> Self {
139 -&self
140 }
141 }
142
143 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Neg for &$struct<T, F$($(, $dim)*)?>
144 where
145 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
146 {
147 type Output = $struct<T, F$($(, $dim)*)?>;
148 #[inline]
149 fn neg(self) -> Self::Output {
150 <$struct<T, F$($(, $dim)*)?>>::new(-self.re.clone(), $(-self.$im.clone()),*)
151 }
152 }
153 };
154}
155
156#[macro_export]
157macro_rules! impl_assign_ops {
158 ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
159 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> MulAssign for $struct<T, F$($(, $dim)*)?>
160 where
161 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
162 {
163 #[inline]
164 fn mul_assign(&mut self, other: Self) {
165 *self = self.clone() * other;
166 }
167 }
168
169 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> DivAssign for $struct<T, F$($(, $dim)*)?>
170 where
171 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
172 {
173 #[inline]
174 fn div_assign(&mut self, other: Self) {
175 *self = self.clone() / other;
176 }
177 }
178
179 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> AddAssign for $struct<T, F$($(, $dim)*)?>
180 where
181 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
182 {
183 #[inline]
184 fn add_assign(&mut self, other: Self) {
185 self.re += other.re;
186 $(self.$im += other.$im;)*
187 }
188 }
189
190 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> SubAssign for $struct<T, F$($(, $dim)*)?>
191 where
192 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
193 {
194 #[inline]
195 fn sub_assign(&mut self, other: Self) {
196 self.re -= other.re;
197 $(self.$im -= other.$im;)*
198 }
199 }
200
201 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> RemAssign for $struct<T, F$($(, $dim)*)?>
202 where
203 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
204 {
205 #[inline]
206 fn rem_assign(&mut self, _other: Self) {
207 unimplemented!()
208 }
209 }
210 };
211}
212
213#[macro_export]
214macro_rules! impl_scalar_op {
215 ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
216 impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> Mul<F> for $struct<T, F$($(, $dim)*)?>
217 where
218 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
219 {
220 type Output = Self;
221 #[inline]
222 fn mul(mut self, other: F) -> Self {
223 self *= other;
224 self
225 }
226 }
227
228 impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> MulAssign<F> for $struct<T, F$($(, $dim)*)?>
229 where
230 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
231 {
232 #[inline]
233 fn mul_assign(&mut self, other: F) {
234 self.re *= other;
235 $(self.$im *= T::from(other);)*
236 }
237 }
238
239 impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> Div<F> for $struct<T, F$($(, $dim)*)?>
240 where
241 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
242 {
243 type Output = Self;
244 #[inline]
245 fn div(mut self, other: F) -> Self {
246 self /= other;
247 self
248 }
249 }
250
251 impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> DivAssign<F> for $struct<T, F$($(, $dim)*)?>
252 where
253 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
254 {
255 #[inline]
256 fn div_assign(&mut self, other: F) {
257 self.re /= other;
258 $(self.$im /= T::from(other);)*
259 }
260 }
261
262 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> Add<F> for $struct<T, F$($(, $dim)*)?>
263 where
264 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
265 {
266 type Output = Self;
267 #[inline]
268 fn add(mut self, other: F) -> Self {
269 self.re += other;
270 self
271 }
272 }
273
274 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> AddAssign<F> for $struct<T, F$($(, $dim)*)?>
275 where
276 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
277 {
278 #[inline]
279 fn add_assign(&mut self, other: F) {
280 self.re += other;
281 }
282 }
283
284 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> Sub<F> for $struct<T, F$($(, $dim)*)?>
285 where
286 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
287 {
288 type Output = Self;
289 #[inline]
290 fn sub(mut self, other: F) -> Self {
291 self.re -= other;
292 self
293 }
294 }
295
296 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> SubAssign<F> for $struct<T, F$($(, $dim)*)?>
297 where
298 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
299 {
300 #[inline]
301 fn sub_assign(&mut self, other: F) {
302 self.re -= other;
303 }
304 }
305
306 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> Rem<F> for $struct<T, F$($(, $dim)*)?>
307 where
308 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
309 {
310 type Output = Self;
311 #[inline]
312 fn rem(self, _other: F) -> Self {
313 unimplemented!()
314 }
315 }
316
317 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> RemAssign<F> for $struct<T, F$($(, $dim)*)?>
318 where
319 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
320 {
321 #[inline]
322 fn rem_assign(&mut self, _other: F) {
323 unimplemented!()
324 }
325 }
326 };
327}
328
329#[macro_export]
330macro_rules! impl_inv {
331 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
332 impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> Inv for $struct<T, F$($(, $dim)*)?>
333 where
334 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
335 {
336 type Output = Self;
337 #[inline]
338 fn inv(self) -> Self {
339 self.recip()
340 }
341 }
342 };
343}
344
345#[macro_export]
346macro_rules! impl_iterator {
347 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
348 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Sum for $struct<T, F$($(, $dim)*)?>
349 where
350 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
351 {
352 #[inline]
353 fn sum<I>(iter: I) -> Self
354 where
355 I: Iterator<Item = Self>,
356 {
357 iter.fold(Self::zero(), |acc, c| acc + c)
358 }
359 }
360
361 impl<'a, T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Sum<&'a $struct<T, F$($(, $dim)*)?>>
362 for $struct<T, F$($(, $dim)*)?>
363 where
364 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
365 {
366 #[inline]
367 fn sum<I>(iter: I) -> Self
368 where
369 I: Iterator<Item = &'a $struct<T, F$($(, $dim)*)?>>,
370 {
371 iter.fold(Self::zero(), |acc, c| acc + c)
372 }
373 }
374 impl<T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Product for $struct<T, F$($(, $dim)*)?>
375 where
376 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
377 {
378 #[inline]
379 fn product<I>(iter: I) -> Self
380 where
381 I: Iterator<Item = Self>,
382 {
383 iter.fold(Self::one(), |acc, c| acc * c)
384 }
385 }
386 impl<'a, T: DualNum<F>, F: Float$($(, $dim: Dim)*)?> Product<&'a $struct<T, F$($(, $dim)*)?>>
387 for $struct<T, F$($(, $dim)*)?>
388 where
389 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
390 {
391 #[inline]
392 fn product<I>(iter: I) -> Self
393 where
394 I: Iterator<Item = &'a $struct<T, F$($(, $dim)*)?>>,
395 {
396 iter.fold(Self::one(), |acc, c| acc * c)
397 }
398 }
399 };
400}
401
402#[macro_export]
403macro_rules! impl_from_primitive {
404 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
405 impl<T: DualNum<F>, F: Float + FromPrimitive$($(, $dim: Dim)*)?> FromPrimitive for $struct<T, F$($(, $dim)*)?>
406 where
407 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
408 {
409 #[inline]
410 fn from_isize(n: isize) -> Option<Self> {
411 F::from_isize(n).map(|f| f.into())
412 }
413
414 #[inline]
415 fn from_i8(n: i8) -> Option<Self> {
416 F::from_i8(n).map(|f| f.into())
417 }
418
419 #[inline]
420 fn from_i16(n: i16) -> Option<Self> {
421 F::from_i16(n).map(|f| f.into())
422 }
423
424 #[inline]
425 fn from_i32(n: i32) -> Option<Self> {
426 F::from_i32(n).map(|f| f.into())
427 }
428
429 #[inline]
430 fn from_i64(n: i64) -> Option<Self> {
431 F::from_i64(n).map(|f| f.into())
432 }
433
434 #[inline]
435 fn from_i128(n: i128) -> Option<Self> {
436 F::from_i128(n).map(|f| f.into())
437 }
438
439 #[inline]
440 fn from_usize(n: usize) -> Option<Self> {
441 F::from_usize(n).map(|f| f.into())
442 }
443
444 #[inline]
445 fn from_u8(n: u8) -> Option<Self> {
446 F::from_u8(n).map(|f| f.into())
447 }
448
449 #[inline]
450 fn from_u16(n: u16) -> Option<Self> {
451 F::from_u16(n).map(|f| f.into())
452 }
453
454 #[inline]
455 fn from_u32(n: u32) -> Option<Self> {
456 F::from_u32(n).map(|f| f.into())
457 }
458
459 #[inline]
460 fn from_u64(n: u64) -> Option<Self> {
461 F::from_u64(n).map(|f| f.into())
462 }
463
464 #[inline]
465 fn from_u128(n: u128) -> Option<Self> {
466 F::from_u128(n).map(|f| f.into())
467 }
468
469 #[inline]
470 fn from_f32(n: f32) -> Option<Self> {
471 F::from_f32(n).map(|f| f.into())
472 }
473
474 #[inline]
475 fn from_f64(n: f64) -> Option<Self> {
476 F::from_f64(n).map(|f| f.into())
477 }
478 }
479 };
480}
481
482#[macro_export]
483macro_rules! impl_signed {
484 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
485 impl<T: DualNum<F>, F: DualNumFloat$($(, $dim: Dim)*)?> Signed for $struct<T, F$($(, $dim)*)?>
486 where
487 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
488 {
489 #[inline]
490 fn abs(&self) -> Self {
491 if self.is_positive() {
492 self.clone()
493 } else {
494 -self
495 }
496 }
497
498 #[inline]
499 fn abs_sub(&self, other: &Self) -> Self {
500 if self.re() > other.re() {
501 self - other
502 } else {
503 Self::zero()
504 }
505 }
506
507 #[inline]
508 fn signum(&self) -> Self {
509 if self.is_positive() {
510 Self::one()
511 } else if self.is_zero() {
512 Self::zero()
513 } else {
514 -Self::one()
515 }
516 }
517
518 #[inline]
519 fn is_positive(&self) -> bool {
520 self.re.is_positive()
521 }
522
523 #[inline]
524 fn is_negative(&self) -> bool {
525 self.re.is_negative()
526 }
527 }
528 };
529}
530
531#[macro_export]
532macro_rules! impl_float_const {
533 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
534 impl<T: DualNum<F>, F: Float + FloatConst$($(, $dim: Dim)*)?> FloatConst for $struct<T, F$($(, $dim)*)?>
535 where
536 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
537 {
538 fn E() -> Self {
539 Self::from(F::E())
540 }
541
542 fn FRAC_1_PI() -> Self {
543 Self::from(F::FRAC_1_PI())
544 }
545
546 fn FRAC_1_SQRT_2() -> Self {
547 Self::from(F::FRAC_1_SQRT_2())
548 }
549
550 fn FRAC_2_PI() -> Self {
551 Self::from(F::FRAC_2_PI())
552 }
553
554 fn FRAC_2_SQRT_PI() -> Self {
555 Self::from(F::FRAC_2_SQRT_PI())
556 }
557
558 fn FRAC_PI_2() -> Self {
559 Self::from(F::FRAC_PI_2())
560 }
561
562 fn FRAC_PI_3() -> Self {
563 Self::from(F::FRAC_PI_3())
564 }
565
566 fn FRAC_PI_4() -> Self {
567 Self::from(F::FRAC_PI_4())
568 }
569
570 fn FRAC_PI_6() -> Self {
571 Self::from(F::FRAC_PI_6())
572 }
573
574 fn FRAC_PI_8() -> Self {
575 Self::from(F::FRAC_PI_8())
576 }
577
578 fn LN_10() -> Self {
579 Self::from(F::LN_10())
580 }
581
582 fn LN_2() -> Self {
583 Self::from(F::LN_2())
584 }
585
586 fn LOG10_E() -> Self {
587 Self::from(F::LOG10_E())
588 }
589
590 fn LOG2_E() -> Self {
591 Self::from(F::LOG2_E())
592 }
593
594 fn PI() -> Self {
595 Self::from(F::PI())
596 }
597
598 fn SQRT_2() -> Self {
599 Self::from(F::SQRT_2())
600 }
601 }
602 };
603}
604
605#[macro_export]
606macro_rules! impl_num {
607 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
608 impl<T: DualNum<F> + Signed, F: Float$($(, $dim: Dim)*)?> Num for $struct<T, F$($(, $dim)*)?>
609 where
610 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
611 {
612 type FromStrRadixErr = F::FromStrRadixErr;
613 #[inline]
614 fn from_str_radix(_str: &str, _radix: u32) -> Result<Self, Self::FromStrRadixErr> {
615 unimplemented!()
616 }
617 }
618 };
619}
620
621#[macro_export]
622macro_rules! impl_dual_struct {
623 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
624 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> $crate::DualStruct<Self,F> for $struct<T, F$($(, $dim)*)?>
625 where
626 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
627 {
628 type Real = F;
629 type Inner = T;
630 #[inline]
631 fn re(&self) -> Self::Real {
632 self.re.re()
633 }
634 #[inline]
635 fn from_inner(inner: &Self::Inner) -> Self {
636 Self::from_re(inner.clone())
637 }
638 }
639
640 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> $crate::Mappable<Self> for $struct<T, F$($(, $dim)*)?>
641 where
642 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
643 {
644 type Output<O> = O;
645 #[inline]
646 fn map_dual<G: Fn(Self) -> O, O>(self, g: G) -> O {
647 g(self)
648 }
649 }
650 };
651}
652
653#[macro_export]
654macro_rules! impl_comparisons {
655 ($struct:ident$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
656 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> PartialEq for $struct<T, F$($(, $dim)*)?>
659 where
660 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
661 {
662 #[inline]
663 fn eq(&self, other: &Self) -> bool {
664 self.re.eq(&other.re)
665 }
666 }
667 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> PartialEq<F> for $struct<T, F$($(, $dim)*)?>
668 where
669 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
670 {
671 #[inline]
672 fn eq(&self, other: &F) -> bool {
673 self.re.eq(other)
674 }
675 }
676
677 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> PartialOrd for $struct<T, F$($(, $dim)*)?>
680 where
681 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
682 {
683 #[inline]
684 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
685 self.re.partial_cmp(&other.re)
686 }
687 }
688 impl<T: DualNum<F>, F$($(, $dim: Dim)*)?> PartialOrd<F> for $struct<T, F$($(, $dim)*)?>
689 where
690 $($(DefaultAllocator: Allocator<$($ddim,)*>),*)?
691 {
692 #[inline]
693 fn partial_cmp(&self, other: &F) -> Option<std::cmp::Ordering> {
694 self.re.partial_cmp(other)
695 }
696 }
697 };
698}
699
700#[macro_export]
701macro_rules! impl_dual {
702 ($struct:ident, [$($im:ident),*]$(, [$($dim:tt),*]$(, [$($ddim:tt),*])*)?) => {
703 impl_from_f!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
704 impl_zero_one!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
705 impl_add_sub_rem!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
706 forward_binop!($struct, Add, +, add$(, [$($dim),*]$(, [$($ddim),*])*)?);
707 forward_binop!($struct, Sub, -, sub$(, [$($dim),*]$(, [$($ddim),*])*)?);
708 forward_binop!($struct, Mul, *, mul$(, [$($dim),*]$(, [$($ddim),*])*)?);
709 forward_binop!($struct, Div, /, div$(, [$($dim),*]$(, [$($ddim),*])*)?);
710 forward_binop!($struct, Rem, %, rem$(, [$($dim),*]$(, [$($ddim),*])*)?);
711 impl_neg!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
712 impl_assign_ops!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
713 impl_scalar_op!($struct, [$($im),*]$(, [$($dim),*]$(, [$($ddim),*])*)?);
714 impl_inv!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
715 impl_iterator!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
716 impl_from_primitive!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
717 impl_signed!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
718 impl_num!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
719 impl_float_const!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
720 impl_dual_struct!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
721 impl_comparisons!($struct$(, [$($dim),*]$(, [$($ddim),*])*)?);
722 };
723}