1use core::ops::{Neg, Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign};
7use crate::constant::{N1, P1, B0, B1, Integer, NonZero};
8pub trait Numeric:
18 Neg<Output = Self> +
19 Add<Output = Self> +
20 Sub<Output = Self> +
21 Mul<Output = Self> +
22 Div<Output = Self> +
23 AddAssign +
24 SubAssign +
25 From<i32> +
26 Copy +
27 Clone +
28 Default +
29 Sized +
30 'static
31{}
32
33impl Numeric for i64 {} impl Numeric for f64 {} pub trait Scalar:
40 Neg<Output = Self> +
41 Add<Output = Self> +
42 Sub<Output = Self> +
43 Mul<Output = Self> +
44 Div<Output = Self> +
45 AddAssign +
46 SubAssign +
47 MulAssign +
48 From<i32> +
49 Copy +
50 Clone +
51 Default +
52 Sized +
53 'static
54{}
55
56impl Scalar for Var<i64> {} impl Scalar for Var<f64> {} #[derive(Debug, Clone, Copy, PartialEq, Default)]
63pub struct Var<T: Numeric>(pub T);
64
65impl<T: Numeric> Neg for Var<T> {
71 type Output = Self;
72
73 fn neg(self) -> Self::Output {
74 Var(-self.0) }
76}
77
78impl<T: Numeric> Add for Var<T> {
81 type Output = Self;
82
83 fn add(self, b: Self) -> Self::Output {
84 Var(self.0 + b.0) }
86}
87
88impl<T: Numeric> Sub for Var<T> {
91 type Output = Self;
92
93 fn sub(self, b: Self) -> Self::Output {
94 Var(self.0 - b.0) }
96}
97
98impl<T: Numeric> Mul<Var<T>> for Var<T> {
101 type Output = Self;
102
103 fn mul(self, b: Self) -> Self::Output {
104 Var(self.0 * b.0) }
106}
107
108impl<T: Numeric> Div<Var<T>> for Var<T> {
111 type Output = Self;
112
113 fn div(self, b: Self) -> Self::Output {
114 Var(self.0 / b.0) }
116}
117
118impl<T: Numeric> AddAssign for Var<T> {
121 fn add_assign(&mut self, rhs: Self) {
122 self.0 += rhs.0; }
124}
125
126impl<T: Numeric> SubAssign for Var<T> {
129 fn sub_assign(&mut self, rhs: Self) {
130 self.0 -= rhs.0; }
132}
133
134impl<T: Numeric, C: Integer + Add<Var<T>>> Add<C> for Var<T> {
140 type Output = <C as Add<Var<T>>>::Output;
141
142 fn add(self, c:C) -> Self::Output {
143 c + self }
145}
146
147impl<T: Numeric, C: Integer + Neg> Sub<C> for Var<T>
150where
151 <C as Neg>::Output: Add<Var<T>>,
152{
153 type Output = < C::Output as Add<Var<T>> >::Output;
154
155 fn sub(self, c: C) -> Self::Output {
156 -c+self }
158}
159
160impl<T: Numeric, C:Integer + Mul<Var<T>>> Mul<C> for Var<T> {
163 type Output = <C as Mul<Var<T>>>::Output;
164
165 fn mul(self, c: C) -> Self::Output {
166 c * self }
168}
169
170impl<T: Numeric> Div<P1> for Var<T> {
176 type Output = Self;
177
178 fn div(self, _rhs: P1) -> Self::Output {
179 self
180 }
181}
182
183impl<T: Numeric> Div<N1> for Var<T> {
185 type Output = Self;
186
187 fn div(self, _rhs: N1) -> Self::Output {
188 -self
189 }
190}
191
192impl<H: NonZero, T:Numeric> Div<B0<H>> for Var<T>
194where
195 B0<H>: Integer,
196 Var<T>: Div<Var<T>,Output = Var<T>>,
197{
198 type Output = Var<T>;
199 #[inline(always)]
200 fn div(self, _rhs: B0<H>) -> Self::Output {
201 Var(self.0 / T::from(B0::<H>::to_i32()))
202 }
203}
204
205impl<H: NonZero, T:Numeric> Div<B1<H>> for Var<T>
207where
208 B1<H>: Integer,
209 Var<T>: Div<Var<T>,Output = Var<T>>,
210{
211 type Output = Var<T>;
212 #[inline(always)]
213 fn div(self, _rhs: B1<H>) -> Self::Output {
214 Var(self.0 / T::from(B1::<H>::to_i32()))
215 }
216}
217
218impl From<i32> for Var<i64> {
223 fn from(value: i32) -> Self {
224 Var(value as i64) }
226}
227
228impl From<i32> for Var<f64> {
230 fn from(value: i32) -> Self {
231 Var(value as f64) }
233}
234
235impl From<i64> for Var<i64> {
237 fn from(value: i64) -> Self {
238 Var(value) }
240}
241
242impl From<f64> for Var<f64> {
244 fn from(value: f64) -> Self {
245 Var(value) }
247}
248
249impl<T: Numeric + MulAssign> MulAssign for Var<T> {
252 fn mul_assign(&mut self, rhs: Self) {
253 self.0 *= rhs.0; }
255}
256
257impl<T: Numeric + MulAssign> MulAssign<T> for Var<T> {
260 fn mul_assign(&mut self, rhs: T) {
261 self.0 *= rhs; }
263}