1#[macro_export]
5macro_rules! impl_ops {
6 (@inner, $(#[$meta:meta])* [$($bound:tt)*]; $tr:ty, $rhs:ty, $a:ty, $f:expr, $fn:tt) => {
7 impl <$($bound)*> $tr for $a {
8 type Output = Self;
9 $(#[$meta])*
10 fn $fn(self, rhs: $rhs) -> Self::Output {
11 $f(self, rhs)
12 }
13 }
14 };
15 (@inner_assign, $(#[$meta:meta])* [$($bound:tt)*]; $tr:ty, $rhs:ty, $a:ty, $f:expr, $fn:tt) => {
16 impl <$($bound)*> $tr for $a {
17 $(#[$meta])*
18 fn $fn(&mut self, rhs: $rhs) {
19 $f(self, rhs)
20 }
21 }
22 };
23
24 ($(#[$meta:meta])* [$($bound:tt)*]; $trait:ident for $a:ty, $f:expr) => {
25 impl_ops!(@when $(#[$meta])* [$($bound)*]; $trait, Self, $a, $f);
26 };
27 ($(#[$meta:meta])* [$($bound:tt)*]; $trait:ident <$rhs:ty> for $a:ty, $f:expr) => {
28 impl_ops!(@when $(#[$meta])* [$($bound)*]; $trait, $rhs, $a, $f);
29 };
30 ($(#[$meta:meta])* $trait:ident for $a:ty, $f:expr) => {
31 impl_ops!(@when $(#[$meta])* []; $trait, Self, $a, $f);
32 };
33 ($(#[$meta:meta])* $trait:ident <$rhs:ty> for $a:ty, $f:expr) => {
34 impl_ops!(@when $(#[$meta])* []; $trait, $rhs, $a, $f);
35 };
36
37 (@when $(#[$meta:meta])* [$($bound:tt)*]; Add, $rhs:ty, $a:ty, $f:expr) => {
38 impl_ops!(@inner, $(#[$meta])* [$($bound)*]; std::ops::Add<$rhs>, $rhs, $a, $f, add);
39 };
40 (@when $(#[$meta:meta])* [$($bound:tt)*]; Sub, $rhs:ty, $a:ty, $f:expr) => {
41 impl_ops!(@inner, $(#[$meta])* [$($bound)*]; std::ops::Sub<$rhs>, $rhs, $a, $f, sub);
42 };
43 (@when $(#[$meta:meta])* [$($bound:tt)*]; Mul, $rhs:ty, $a:ty, $f:expr) => {
44 impl_ops!(@inner, $(#[$meta])* [$($bound)*]; std::ops::Mul<$rhs>, $rhs, $a, $f, mul);
45 };
46 (@when $(#[$meta:meta])* [$($bound:tt)*]; Div, $rhs:ty, $a:ty, $f:expr) => {
47 impl_ops!(@inner, $(#[$meta])* [$($bound)*]; std::ops::Div<$rhs>, $rhs, $a, $f, div);
48 };
49 (@when $(#[$meta:meta])* [$($bound:tt)*]; Rem, $rhs:ty, $a:ty, $f:expr) => {
50 impl_ops!(@inner, $(#[$meta])* [$($bound)*]; std::ops::Rem<$rhs>, $rhs, $a, $f, rem);
51 };
52
53 (@when $(#[$meta:meta])* [$($bound:tt)*]; AddAssign, $rhs:ty, $a:ty, $f:expr) => {
54 impl_ops!(@inner_assign, $(#[$meta])* [$($bound)*]; std::ops::AddAssign<$rhs>, $rhs, $a, $f, add_assign);
55 };
56 (@when $(#[$meta:meta])* [$($bound:tt)*]; SubAssign, $rhs:ty, $a:ty, $f:expr) => {
57 impl_ops!(@inner_assign, $(#[$meta])* [$($bound)*]; std::ops::SubAssign<$rhs>, $rhs, $a, $f, sub_assign);
58 };
59 (@when $(#[$meta:meta])* [$($bound:tt)*]; MulAssign, $rhs:ty, $a:ty, $f:expr) => {
60 impl_ops!(@inner_assign, $(#[$meta])* [$($bound)*]; std::ops::MulAssign<$rhs>, $rhs, $a, $f, mul_assign);
61 };
62 (@when $(#[$meta:meta])* [$($bound:tt)*]; DivAssign, $rhs:ty, $a:ty, $f:expr) => {
63 impl_ops!(@inner_assign, $(#[$meta])* [$($bound)*]; std::ops::DivAssign<$rhs>, $rhs, $a, $f, div_assign);
64 };
65 (@when $(#[$meta:meta])* [$($bound:tt)*]; RemAssign, $rhs:ty, $a:ty, $f:expr) => {
66 impl_ops!(@inner_assign, $(#[$meta])* [$($bound)*]; std::ops::RemAssign<$rhs>, $rhs, $a, $f, rem_assign);
67 };
68
69 (@when $(#[$meta:meta])* [$($bound:tt)*]; Neg, $rhs:ty, $a:ty, $f:expr) => {
70 impl <$($bound)*> std::ops::Neg for $a {
71 type Output = Self;
72 $(#[$meta])*
73 fn neg(self) -> Self::Output {
74 $f(self)
75 }
76 }
77 }
78}