computation_types/
macros.rs

1pub use paste;
2
3#[macro_export]
4macro_rules! impl_core_ops {
5    ( $ty:ident $( < $( $gen:ident ),* > )? ) => {
6        impl_core_ops!(@impl Add for $ty $( < $( $gen ),* > )?);
7        impl_core_ops!(@impl Sub for $ty $( < $( $gen ),* > )?);
8        impl_core_ops!(@impl Mul for $ty $( < $( $gen ),* > )?);
9        impl_core_ops!(@impl Div for $ty $( < $( $gen ),* > )?);
10
11        impl $( < $( $gen ),* > )? core::ops::Neg for $ty $( < $( $gen ),* > )?
12        where
13            Self: Computation,
14            $crate::math::Neg<Self>: $crate::Computation,
15        {
16            type Output = $crate::math::Neg<Self>;
17
18            fn neg(self) -> Self::Output {
19                <Self as $crate::Computation>::neg(self)
20            }
21        }
22    };
23    ( @impl $op:ident for $ty:ident $( < $( $gen:ident ),* > )? ) => {
24        $crate::macros::paste::paste! {
25            impl<Rhs, $( $( $gen ),* )?> core::ops::$op<Rhs> for $ty $( < $( $gen ),* > )?
26            where
27                Self: Computation,
28                $crate::math::$op<Self, Rhs>: $crate::Computation,
29            {
30                type Output = $crate::math::$op<Self, Rhs>;
31
32                fn [<$op:lower>](self, rhs: Rhs) -> Self::Output {
33                    <Self as $crate::Computation>::[<$op:lower>](self, rhs)
34                }
35            }
36        }
37    };
38}
39
40#[macro_export]
41macro_rules! impl_display_for_inline_binary {
42    ( $op:ident, $inline:literal ) => {
43        impl<A, B> core::fmt::Display for $op<A, B>
44        where
45            Self: $crate::Computation,
46            A: core::fmt::Display,
47            B: core::fmt::Display,
48        {
49            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
50                write!(f, "({} {} {})", self.0, $inline, self.1)
51            }
52        }
53    };
54}
55
56#[macro_export]
57macro_rules! impl_computation_fn_for_unary {
58    ( $op:ident ) => {
59        impl<A> ComputationFn for $op<A>
60        where
61            Self: Computation,
62            A: ComputationFn,
63            $op<A::Filled>: Computation,
64        {
65            type Filled = $op<A::Filled>;
66
67            fn fill(self, named_args: NamedArgs) -> Self::Filled {
68                $op(self.0.fill(named_args))
69            }
70
71            fn arg_names(&self) -> $crate::Names {
72                self.0.arg_names()
73            }
74        }
75    };
76}
77
78#[macro_export]
79macro_rules! impl_computation_fn_for_binary {
80    ( $op:ident ) => {
81        impl<A, B> ComputationFn for $op<A, B>
82        where
83            Self: Computation,
84            A: ComputationFn,
85            B: ComputationFn,
86            $op<A::Filled, B::Filled>: Computation,
87        {
88            type Filled = $op<A::Filled, B::Filled>;
89
90            fn fill(self, named_args: NamedArgs) -> Self::Filled {
91                let (args_0, args_1) = named_args
92                    .partition(&self.0.arg_names(), &self.1.arg_names())
93                    .unwrap_or_else(|e| panic!("{}", e));
94                $op(self.0.fill(args_0), self.1.fill(args_1))
95            }
96
97            fn arg_names(&self) -> $crate::Names {
98                self.0.arg_names().union(self.1.arg_names())
99            }
100        }
101    };
102}