1use core::ops::{Add, Div, Mul, Sub};
6
7use super::*;
8
9#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
11#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
12pub struct ATerm;
13
14impl TypeArray for ATerm {}
15
16#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Hash, Debug)]
23#[cfg_attr(feature = "scale_info", derive(scale_info::TypeInfo))]
24pub struct TArr<V, A> {
25 first: V,
26 rest: A,
27}
28
29impl<V, A> TypeArray for TArr<V, A> {}
30
31#[macro_export]
44macro_rules! tarr {
45 () => ( $crate::ATerm );
46 ($n:ty) => ( $crate::TArr<$n, $crate::ATerm> );
47 ($n:ty,) => ( $crate::TArr<$n, $crate::ATerm> );
48 ($n:ty, $($tail:ty),+) => ( $crate::TArr<$n, tarr![$($tail),+]> );
49 ($n:ty, $($tail:ty),+,) => ( $crate::TArr<$n, tarr![$($tail),+]> );
50 ($n:ty | $rest:ty) => ( $crate::TArr<$n, $rest> );
51 ($n:ty, $($tail:ty),+ | $rest:ty) => ( $crate::TArr<$n, ta![$($tail),+ | $rest]> );
52}
53
54impl Len for ATerm {
59 type Output = U0;
60 #[inline]
61 fn len(&self) -> Self::Output {
62 UTerm
63 }
64}
65
66impl<V, A> Len for TArr<V, A>
68where
69 A: Len,
70 Length<A>: Add<B1>,
71 Sum<Length<A>, B1>: Unsigned,
72{
73 type Output = Add1<Length<A>>;
74 #[inline]
75 fn len(&self) -> Self::Output {
76 self.rest.len() + B1
77 }
78}
79
80const _: () = {
85 pub struct Null;
87 impl<T> Add<T> for Null {
88 type Output = T;
89 fn add(self, rhs: T) -> Self::Output {
90 rhs
91 }
92 }
93
94 impl FoldAdd for ATerm {
95 type Output = Null;
96 }
97};
98
99impl<V, A> FoldAdd for TArr<V, A>
100where
101 A: FoldAdd,
102 FoldSum<A>: Add<V>,
103{
104 type Output = Sum<FoldSum<A>, V>;
105}
106
107const _: () = {
112 pub struct Null;
114 impl<T> Mul<T> for Null {
115 type Output = T;
116 fn mul(self, rhs: T) -> Self::Output {
117 rhs
118 }
119 }
120
121 impl FoldMul for ATerm {
122 type Output = Null;
123 }
124};
125
126impl<V, A> FoldMul for TArr<V, A>
127where
128 A: FoldMul,
129 FoldProd<A>: Mul<V>,
130{
131 type Output = Prod<FoldProd<A>, V>;
132}
133
134impl Add<ATerm> for ATerm {
139 type Output = ATerm;
140 #[inline]
141 fn add(self, _: ATerm) -> Self::Output {
142 ATerm
143 }
144}
145
146impl<Al, Vl, Ar, Vr> Add<TArr<Vr, Ar>> for TArr<Vl, Al>
147where
148 Al: Add<Ar>,
149 Vl: Add<Vr>,
150{
151 type Output = TArr<Sum<Vl, Vr>, Sum<Al, Ar>>;
152 #[inline]
153 fn add(self, rhs: TArr<Vr, Ar>) -> Self::Output {
154 TArr {
155 first: self.first + rhs.first,
156 rest: self.rest + rhs.rest,
157 }
158 }
159}
160
161impl Sub<ATerm> for ATerm {
166 type Output = ATerm;
167 #[inline]
168 fn sub(self, _: ATerm) -> Self::Output {
169 ATerm
170 }
171}
172
173impl<Vl, Al, Vr, Ar> Sub<TArr<Vr, Ar>> for TArr<Vl, Al>
174where
175 Vl: Sub<Vr>,
176 Al: Sub<Ar>,
177{
178 type Output = TArr<Diff<Vl, Vr>, Diff<Al, Ar>>;
179 #[inline]
180 fn sub(self, rhs: TArr<Vr, Ar>) -> Self::Output {
181 TArr {
182 first: self.first - rhs.first,
183 rest: self.rest - rhs.rest,
184 }
185 }
186}
187
188impl<Rhs> Mul<Rhs> for ATerm {
192 type Output = ATerm;
193 #[inline]
194 fn mul(self, _: Rhs) -> Self::Output {
195 ATerm
196 }
197}
198
199impl<V, A, Rhs> Mul<Rhs> for TArr<V, A>
200where
201 V: Mul<Rhs>,
202 A: Mul<Rhs>,
203 Rhs: Copy,
204{
205 type Output = TArr<Prod<V, Rhs>, Prod<A, Rhs>>;
206 #[inline]
207 fn mul(self, rhs: Rhs) -> Self::Output {
208 TArr {
209 first: self.first * rhs,
210 rest: self.rest * rhs,
211 }
212 }
213}
214
215impl Mul<ATerm> for Z0 {
216 type Output = ATerm;
217 #[inline]
218 fn mul(self, _: ATerm) -> Self::Output {
219 ATerm
220 }
221}
222
223impl<U> Mul<ATerm> for PInt<U>
224where
225 U: Unsigned + NonZero,
226{
227 type Output = ATerm;
228 #[inline]
229 fn mul(self, _: ATerm) -> Self::Output {
230 ATerm
231 }
232}
233
234impl<U> Mul<ATerm> for NInt<U>
235where
236 U: Unsigned + NonZero,
237{
238 type Output = ATerm;
239 #[inline]
240 fn mul(self, _: ATerm) -> Self::Output {
241 ATerm
242 }
243}
244
245impl<V, A> Mul<TArr<V, A>> for Z0
246where
247 Z0: Mul<A>,
248{
249 type Output = TArr<Z0, Prod<Z0, A>>;
250 #[inline]
251 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
252 TArr {
253 first: Z0,
254 rest: self * rhs.rest,
255 }
256 }
257}
258
259impl<V, A, U> Mul<TArr<V, A>> for PInt<U>
260where
261 U: Unsigned + NonZero,
262 PInt<U>: Mul<A> + Mul<V>,
263{
264 type Output = TArr<Prod<PInt<U>, V>, Prod<PInt<U>, A>>;
265 #[inline]
266 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
267 TArr {
268 first: self * rhs.first,
269 rest: self * rhs.rest,
270 }
271 }
272}
273
274impl<V, A, U> Mul<TArr<V, A>> for NInt<U>
275where
276 U: Unsigned + NonZero,
277 NInt<U>: Mul<A> + Mul<V>,
278{
279 type Output = TArr<Prod<NInt<U>, V>, Prod<NInt<U>, A>>;
280 #[inline]
281 fn mul(self, rhs: TArr<V, A>) -> Self::Output {
282 TArr {
283 first: self * rhs.first,
284 rest: self * rhs.rest,
285 }
286 }
287}
288
289impl<Rhs> Div<Rhs> for ATerm {
293 type Output = ATerm;
294 #[inline]
295 fn div(self, _: Rhs) -> Self::Output {
296 ATerm
297 }
298}
299
300impl<V, A, Rhs> Div<Rhs> for TArr<V, A>
301where
302 V: Div<Rhs>,
303 A: Div<Rhs>,
304 Rhs: Copy,
305{
306 type Output = TArr<Quot<V, Rhs>, Quot<A, Rhs>>;
307 #[inline]
308 fn div(self, rhs: Rhs) -> Self::Output {
309 TArr {
310 first: self.first / rhs,
311 rest: self.rest / rhs,
312 }
313 }
314}
315
316impl<Rhs> PartialDiv<Rhs> for ATerm {
320 type Output = ATerm;
321 #[inline]
322 fn partial_div(self, _: Rhs) -> Self::Output {
323 ATerm
324 }
325}
326
327impl<V, A, Rhs> PartialDiv<Rhs> for TArr<V, A>
328where
329 V: PartialDiv<Rhs>,
330 A: PartialDiv<Rhs>,
331 Rhs: Copy,
332{
333 type Output = TArr<PartialQuot<V, Rhs>, PartialQuot<A, Rhs>>;
334 #[inline]
335 fn partial_div(self, rhs: Rhs) -> Self::Output {
336 TArr {
337 first: self.first.partial_div(rhs),
338 rest: self.rest.partial_div(rhs),
339 }
340 }
341}
342
343use core::ops::Rem;
346
347impl<Rhs> Rem<Rhs> for ATerm {
348 type Output = ATerm;
349 #[inline]
350 fn rem(self, _: Rhs) -> Self::Output {
351 ATerm
352 }
353}
354
355impl<V, A, Rhs> Rem<Rhs> for TArr<V, A>
356where
357 V: Rem<Rhs>,
358 A: Rem<Rhs>,
359 Rhs: Copy,
360{
361 type Output = TArr<Mod<V, Rhs>, Mod<A, Rhs>>;
362 #[inline]
363 fn rem(self, rhs: Rhs) -> Self::Output {
364 TArr {
365 first: self.first % rhs,
366 rest: self.rest % rhs,
367 }
368 }
369}
370
371use core::ops::Neg;
374
375impl Neg for ATerm {
376 type Output = ATerm;
377 #[inline]
378 fn neg(self) -> Self::Output {
379 ATerm
380 }
381}
382
383impl<V, A> Neg for TArr<V, A>
384where
385 V: Neg,
386 A: Neg,
387{
388 type Output = TArr<Negate<V>, Negate<A>>;
389 #[inline]
390 fn neg(self) -> Self::Output {
391 TArr {
392 first: -self.first,
393 rest: -self.rest,
394 }
395 }
396}