1use core::ops::{Add, Div, Mul, Sub};
6
7use super::*;
8
9#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
11pub struct ATerm;
12
13impl TypeArray for ATerm {}
14
15#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
22pub struct TArr<V, A> {
23 first: V,
24 rest: A,
25}
26
27impl<V, A> TypeArray for TArr<V, A> {}
28
29#[macro_export]
42macro_rules! tarr {
43 () => ( $crate::ATerm );
44 ($n:ty) => ( $crate::TArr<$n, $crate::ATerm> );
45 ($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> );
46 ($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> );
47 ($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> );
48}
49
50impl Len for ATerm {
55 type Output = U0;
56 #[inline]
57 fn len(&self) -> Self::Output {
58 UTerm
59 }
60}
61
62impl<V, A> Len for TArr<V, A>
64where
65 A: Len,
66 Length<A>: Add<B1>,
67 Sum<Length<A>, B1>: Unsigned,
68{
69 type Output = Add1<Length<A>>;
70 #[inline]
71 fn len(&self) -> Self::Output {
72 self.rest.len() + B1
73 }
74}
75
76impl Add<ATerm> for ATerm {
81 type Output = ATerm;
82 #[inline]
83 fn add(self, _: ATerm) -> Self::Output {
84 ATerm
85 }
86}
87
88impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al>
89where
90 Al: Add<Ar>,
91 Vl: Add<Vr>,
92{
93 type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;
94 #[inline]
95 fn add(self, rhs: TArr<Vr, Ar>) -> Self::Output {
96 TArr {
97 first: self.first + rhs.first,
98 rest: self.rest + rhs.rest,
99 }
100 }
101}
102
103impl Sub<ATerm> for ATerm {
108 type Output = ATerm;
109 #[inline]
110 fn sub(self, _: ATerm) -> Self::Output {
111 ATerm
112 }
113}
114
115impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al>
116where
117 Vl: Sub<Vr>,
118 Al: Sub<Ar>,
119{
120 type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;
121 #[inline]
122 fn sub(self, rhs: TArr<Vr, Ar>) -> Self::Output {
123 TArr {
124 first: self.first - rhs.first,
125 rest: self.rest - rhs.rest,
126 }
127 }
128}
129
130impl<Rhs> Mul<Rhs> for ATerm {
134 type Output = ATerm;
135 #[inline]
136 fn mul(self, _: Rhs) -> Self::Output {
137 ATerm
138 }
139}
140
141impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
142where
143 V: Mul<Rhs>,
144 A: Mul<Rhs>,
145 Rhs: Copy,
146{
147 type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
148 #[inline]
149 fn mul(self, rhs: Rhs) -> Self::Output {
150 TArr {
151 first: self.first * rhs,
152 rest: self.rest * rhs,
153 }
154 }
155}
156
157impl Mul<ATerm> for Z0 {
158 type Output = ATerm;
159 #[inline]
160 fn mul(self, _: ATerm) -> Self::Output {
161 ATerm
162 }
163}
164
165impl<U> Mul<ATerm> for PInt<U>
166where
167 U: Unsigned + NonZero,
168{
169 type Output = ATerm;
170 #[inline]
171 fn mul(self, _: ATerm) -> Self::Output {
172 ATerm
173 }
174}
175
176impl<U> Mul<ATerm> for NInt<U>
177where
178 U: Unsigned + NonZero,
179{
180 type Output = ATerm;
181 #[inline]
182 fn mul(self, _: ATerm) -> Self::Output {
183 ATerm
184 }
185}
186
187impl<V, A> Mul<TArr<V, A>> for Z0
188where
189 Z0: Mul<A>,
190{
191 type Output = TArr<Z0, Prod<Z0, A>>;
192 #[inline]
193 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
194 TArr {
195 first: Z0,
196 rest: self * rhs.rest,
197 }
198 }
199}
200
201impl<V, A, U> Mul<TArr<V, A>> for PInt<U>
202where
203 U: Unsigned + NonZero,
204 PInt<U>: Mul<A> + Mul<V>,
205{
206 type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>;
207 #[inline]
208 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
209 TArr {
210 first: self * rhs.first,
211 rest: self * rhs.rest,
212 }
213 }
214}
215
216impl<V, A, U> Mul<TArr<V, A>> for NInt<U>
217where
218 U: Unsigned + NonZero,
219 NInt<U>: Mul<A> + Mul<V>,
220{
221 type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>;
222 #[inline]
223 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
224 TArr {
225 first: self * rhs.first,
226 rest: self * rhs.rest,
227 }
228 }
229}
230
231impl<Rhs> Div<Rhs> for ATerm {
235 type Output = ATerm;
236 #[inline]
237 fn div(self, _: Rhs) -> Self::Output {
238 ATerm
239 }
240}
241
242impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
243where
244 V: Div<Rhs>,
245 A: Div<Rhs>,
246 Rhs: Copy,
247{
248 type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
249 #[inline]
250 fn div(self, rhs: Rhs) -> Self::Output {
251 TArr {
252 first: self.first / rhs,
253 rest: self.rest / rhs,
254 }
255 }
256}
257
258impl<Rhs> PartialDiv<Rhs> for ATerm {
262 type Output = ATerm;
263 #[inline]
264 fn partial_div(self, _: Rhs) -> Self::Output {
265 ATerm
266 }
267}
268
269impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A>
270where
271 V: PartialDiv<Rhs>,
272 A: PartialDiv<Rhs>,
273 Rhs: Copy,
274{
275 type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;
276 #[inline]
277 fn partial_div(self, rhs: Rhs) -> Self::Output {
278 TArr {
279 first: self.first.partial_div(rhs),
280 rest: self.rest.partial_div(rhs),
281 }
282 }
283}
284
285use core::ops::Rem;
288
289impl<Rhs> Rem<Rhs> for ATerm {
290 type Output = ATerm;
291 #[inline]
292 fn rem(self, _: Rhs) -> Self::Output {
293 ATerm
294 }
295}
296
297impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
298where
299 V: Rem<Rhs>,
300 A: Rem<Rhs>,
301 Rhs: Copy,
302{
303 type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
304 #[inline]
305 fn rem(self, rhs: Rhs) -> Self::Output {
306 TArr {
307 first: self.first % rhs,
308 rest: self.rest % rhs,
309 }
310 }
311}
312
313use core::ops::Neg;
316
317impl Neg for ATerm {
318 type Output = ATerm;
319 #[inline]
320 fn neg(self) -> Self::Output {
321 ATerm
322 }
323}
324
325impl<V, A> Neg for TArr<V, A>
326where
327 V: Neg,
328 A: Neg,
329{
330 type Output = TArr<Negate<V>, Negate<A>>;
331 #[inline]
332 fn neg(self) -> Self::Output {
333 TArr {
334 first: -self.first,
335 rest: -self.rest,
336 }
337 }
338}