scalar_field/
ops.rs

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}