haar_lib/macros/
impl_ops.rs

1//! `impl_ops!`
2
3/// [`Add`](std::ops::Add), [`Sub`](std::ops::Sub), [`Mul`](std::ops::Mul), [`Div`](std::ops::Div), [`Rem`](std::ops::Rem), [`AddAssign`](std::ops::AddAssign), [`SubAssign`](std::ops::SubAssign), [`MulAssign`](std::ops::MulAssign), [`DivAssign`](std::ops::DivAssign), [`RemAssign`](std::ops::RemAssign), [`Neg`](std::ops::Neg)を実装する。
4#[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}