1extern crate alloc;
2
3use crate::{
4 fields::{ConstantField, FunctionField, IdentityField, ScalarFieldWrapper},
5 MapField, ScalarField, TransformField,
6};
7use alloc::boxed::Box;
8use core::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Not, Rem, Shl, Shr, Sub};
9
10macro_rules! binary_ops {
11 {$dollar:tt $($name:ident $func:ident $wrapper:ident $macro:ident;)*} => {
12 $(
13 #[derive(Copy, Clone, Debug)]
14 pub struct $wrapper<L, R> {
15 lhs: L,
16 rhs: R,
17 }
18
19 impl<L, R> ScalarField for $wrapper<L, R>
20 where
21 L: ScalarField,
22 R: ScalarField<Point = L::Point>,
23 L::Scalar: $name<R::Scalar>,
24 L::Point: Clone,
25 {
26 type Point = L::Point;
27 type Scalar = <L::Scalar as $name<R::Scalar>>::Output;
28
29 fn value(&self, point: Self::Point) -> Self::Scalar {
30 self.lhs.value(point.clone()).$func(self.rhs.value(point))
31 }
32 }
33
34 macro_rules! $macro {
35 {impl <$dollar($g:tt),*> Op for $t:ty where $dollar($bounds:tt)*} => {
36 impl<Rhs $dollar(,$g)* > $name<Rhs> for $t
37 where
38 Rhs: ScalarField<Point = <$t as ScalarField>::Point>,
39 <$t as ScalarField>::Scalar: $name<Rhs::Scalar>,
40 $dollar($bounds)*
41 {
42 type Output = $wrapper<$t, Rhs>;
43
44 fn $func(self, rhs: Rhs) -> Self::Output {
45 Self::Output { lhs: self, rhs }
46 }
47 }
48 }
49 }
50 )*
51 }
52}
53
54macro_rules! unary_ops {
55 {$dollar:tt $($name:ident $func:ident $wrapper:ident $macro:ident;)*} => {
56 $(
57 #[derive(Copy, Clone, Debug)]
58 pub struct $wrapper<T> {
59 inner: T,
60 }
61
62 impl<T> ScalarField for $wrapper<T>
63 where
64 T: ScalarField,
65 T::Scalar: $name,
66 {
67 type Point = T::Point;
68 type Scalar = <T::Scalar as $name>::Output;
69
70 fn value(&self, point: Self::Point) -> Self::Scalar {
71 self.inner.value(point).$func()
72 }
73 }
74
75 macro_rules! $macro {
76 {impl <$dollar($g:tt),*> Op for $t:ty where $dollar($bounds:tt)*} => {
77 impl<$dollar($g),*> $name for $t
78 where
79 <$t as ScalarField>::Scalar: $name,
80 $dollar($bounds)*
81 {
82 type Output = $wrapper<$t>;
83
84 fn $func(self) -> Self::Output {
85 Self::Output { inner: self }
86 }
87 }
88 }
89 }
90 )*
91 }
92}
93
94binary_ops! {$
95 Add add AddField impl_add;
96 BitAnd bitand BitAndField impl_bitand;
97 BitOr bitor BitOrField impl_bitor;
98 BitXor bitxor BitXorField impl_bitxor;
99 Div div DivField impl_div;
100 Mul mul MulField impl_mul;
101 Rem rem RemField impl_rem;
102 Shl shl ShlField impl_shl;
103 Shr shr ShrField impl_shr;
104 Sub sub SubField impl_sub;
105}
106
107unary_ops! {$
108 Neg neg NegField impl_neg;
109 Not not NotField impl_not;
110}
111
112macro_rules! impl_ops {
113 {$($token:tt)*} => {
114 impl_add!{$($token)*}
115 impl_bitand!{$($token)*}
116 impl_bitor!{$($token)*}
117 impl_bitxor!{$($token)*}
118 impl_div!{$($token)*}
119 impl_mul!{$($token)*}
120 impl_rem!{$($token)*}
121 impl_shl!{$($token)*}
122 impl_shr!{$($token)*}
123 impl_sub!{$($token)*}
124
125 impl_neg!{$($token)*}
126 impl_not!{$($token)*}
127 }
128}
129
130impl_ops! {
131 impl<L, R> Op for AddField<L, R>
132 where
133 L: ScalarField,
134 R: ScalarField<Point = L::Point>,
135 L::Scalar: Add<R::Scalar>,
136 L::Point: Clone,
137}
138impl_ops! {
139 impl<L, R> Op for SubField<L, R>
140 where
141 L: ScalarField,
142 R: ScalarField<Point = L::Point>,
143 L::Scalar: Sub<R::Scalar>,
144 L::Point: Clone,
145}
146impl_ops! {
147 impl<L, R> Op for MulField<L, R>
148 where
149 L: ScalarField,
150 R: ScalarField<Point = L::Point>,
151 L::Scalar: Mul<R::Scalar>,
152 L::Point: Clone,
153}
154impl_ops! {
155 impl<L, R> Op for DivField<L, R>
156 where
157 L: ScalarField,
158 R: ScalarField<Point = L::Point>,
159 L::Scalar: Div<R::Scalar>,
160 L::Point: Clone,
161}
162impl_ops! {
163 impl<T> Op for NegField<T>
164 where
165 T: ScalarField,
166 T::Scalar: Neg,
167}
168
169impl_ops! {
170 impl<P, S> Op for Box<dyn ScalarField<Point = P, Scalar = S>>
171 where
172}
173impl_ops! {
174 impl<I, S, F> Op for MapField<I, F>
175 where
176 I: ScalarField,
177 F: Fn(I::Scalar) -> S,
178}
179impl_ops! {
180 impl<I, P, F> Op for TransformField<I, P, F>
181 where
182 I: ScalarField,
183 F: Fn(P) -> I::Point,
184}
185
186impl_ops! {
187 impl<Lhs> Op for ScalarFieldWrapper<Lhs>
188 where
189 Lhs: ScalarField,
190}
191impl_ops! {
192 impl<P, S> Op for ConstantField<P, S>
193 where
194 S: Clone,
195}
196impl_ops! {
197 impl<P, S, F> Op for FunctionField<P, F>
198 where
199 F: Fn(P) -> S,
200}
201impl_ops! {
202 impl<T> Op for IdentityField<T>
203 where
204}