1#![doc(hidden)]
22
23use crate::{
24 bit::{Bit, B0, B1},
25 uint::{UInt, UTerm, Unsigned},
26};
27
28pub(crate) enum Internal {}
30
31pub trait InternalMarker {}
32
33impl InternalMarker for Internal {}
34
35pub trait Trim {
37 type Output;
38
39 fn trim(self) -> Self::Output;
40}
41pub type TrimOut<A> = <A as Trim>::Output;
42
43pub trait TrimTrailingZeros {
46 type Output;
47
48 fn trim_trailing_zeros(self) -> Self::Output;
49}
50pub type TrimTrailingZerosOut<A> = <A as TrimTrailingZeros>::Output;
51
52pub trait Invert {
55 type Output;
56
57 fn invert(self) -> Self::Output;
58}
59pub type InvertOut<A> = <A as Invert>::Output;
60
61pub trait PrivateInvert<Rhs> {
64 type Output;
65
66 fn private_invert(self, rhs: Rhs) -> Self::Output;
67}
68pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output;
69
70pub struct InvertedUTerm;
72
73pub struct InvertedUInt<IU: InvertedUnsigned, B: Bit> {
75 msb: IU,
76 lsb: B,
77}
78
79pub trait PrivateAnd<Rhs = Self> {
81 type Output;
82
83 fn private_and(self, rhs: Rhs) -> Self::Output;
84}
85pub type PrivateAndOut<A, Rhs> = <A as PrivateAnd<Rhs>>::Output;
86
87pub trait PrivateXor<Rhs = Self> {
89 type Output;
90
91 fn private_xor(self, rhs: Rhs) -> Self::Output;
92}
93pub type PrivateXorOut<A, Rhs> = <A as PrivateXor<Rhs>>::Output;
94
95pub trait PrivateSub<Rhs = Self> {
97 type Output;
98
99 fn private_sub(self, rhs: Rhs) -> Self::Output;
100}
101pub type PrivateSubOut<A, Rhs> = <A as PrivateSub<Rhs>>::Output;
102
103pub trait PrivateIntegerAdd<C, N> {
107 type Output;
108
109 fn private_integer_add(self, _: C, _: N) -> Self::Output;
110}
111pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output;
112
113pub trait PrivatePow<Y, N> {
114 type Output;
115
116 fn private_pow(self, _: Y, _: N) -> Self::Output;
117}
118pub type PrivatePowOut<A, Y, N> = <A as PrivatePow<Y, N>>::Output;
119
120pub trait ShiftDiff<Rhs> {
123 type Output;
124}
125pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output;
126
127pub trait BitDiff<Rhs> {
129 type Output;
130}
131pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output;
132
133pub trait InvertedUnsigned {
135 fn to_u64() -> u64;
136}
137
138impl InvertedUnsigned for InvertedUTerm {
139 #[inline]
140 fn to_u64() -> u64 {
141 0
142 }
143}
144
145impl<IU: InvertedUnsigned, B: Bit> InvertedUnsigned for InvertedUInt<IU, B> {
146 #[inline]
147 fn to_u64() -> u64 {
148 u64::from(B::to_u8()) | IU::to_u64() << 1
149 }
150}
151
152impl Invert for UTerm {
153 type Output = InvertedUTerm;
154
155 #[inline]
156 fn invert(self) -> Self::Output {
157 InvertedUTerm
158 }
159}
160
161impl<U: Unsigned, B: Bit> Invert for UInt<U, B>
162where
163 U: PrivateInvert<InvertedUInt<InvertedUTerm, B>>,
164{
165 type Output = PrivateInvertOut<U, InvertedUInt<InvertedUTerm, B>>;
166
167 #[inline]
168 fn invert(self) -> Self::Output {
169 self.msb.private_invert(InvertedUInt {
170 msb: InvertedUTerm,
171 lsb: self.lsb,
172 })
173 }
174}
175
176impl<IU: InvertedUnsigned> PrivateInvert<IU> for UTerm {
177 type Output = IU;
178
179 #[inline]
180 fn private_invert(self, rhs: IU) -> Self::Output {
181 rhs
182 }
183}
184
185impl<IU: InvertedUnsigned, U: Unsigned, B: Bit> PrivateInvert<IU> for UInt<U, B>
186where
187 U: PrivateInvert<InvertedUInt<IU, B>>,
188{
189 type Output = PrivateInvertOut<U, InvertedUInt<IU, B>>;
190
191 #[inline]
192 fn private_invert(self, rhs: IU) -> Self::Output {
193 self.msb.private_invert(InvertedUInt {
194 msb: rhs,
195 lsb: self.lsb,
196 })
197 }
198}
199
200#[test]
201fn test_inversion() {
202 type Test4 = <crate::consts::U4 as Invert>::Output;
203 type Test5 = <crate::consts::U5 as Invert>::Output;
204 type Test12 = <crate::consts::U12 as Invert>::Output;
205 type Test16 = <crate::consts::U16 as Invert>::Output;
206
207 assert_eq!(1, <Test4 as InvertedUnsigned>::to_u64());
208 assert_eq!(5, <Test5 as InvertedUnsigned>::to_u64());
209 assert_eq!(3, <Test12 as InvertedUnsigned>::to_u64());
210 assert_eq!(1, <Test16 as InvertedUnsigned>::to_u64());
211}
212
213impl Invert for InvertedUTerm {
214 type Output = UTerm;
215
216 #[inline]
217 fn invert(self) -> Self::Output {
218 UTerm
219 }
220}
221
222impl<IU: InvertedUnsigned, B: Bit> Invert for InvertedUInt<IU, B>
223where
224 IU: PrivateInvert<UInt<UTerm, B>>,
225{
226 type Output = <IU as PrivateInvert<UInt<UTerm, B>>>::Output;
227
228 #[inline]
229 fn invert(self) -> Self::Output {
230 self.msb.private_invert(UInt {
231 msb: UTerm,
232 lsb: self.lsb,
233 })
234 }
235}
236
237impl<U: Unsigned> PrivateInvert<U> for InvertedUTerm {
238 type Output = U;
239
240 #[inline]
241 fn private_invert(self, rhs: U) -> Self::Output {
242 rhs
243 }
244}
245
246impl<U: Unsigned, IU: InvertedUnsigned, B: Bit> PrivateInvert<U> for InvertedUInt<IU, B>
247where
248 IU: PrivateInvert<UInt<U, B>>,
249{
250 type Output = <IU as PrivateInvert<UInt<U, B>>>::Output;
251
252 #[inline]
253 fn private_invert(self, rhs: U) -> Self::Output {
254 self.msb.private_invert(UInt {
255 msb: rhs,
256 lsb: self.lsb,
257 })
258 }
259}
260
261#[test]
262fn test_double_inversion() {
263 type Test4 = <<crate::consts::U4 as Invert>::Output as Invert>::Output;
264 type Test5 = <<crate::consts::U5 as Invert>::Output as Invert>::Output;
265 type Test12 = <<crate::consts::U12 as Invert>::Output as Invert>::Output;
266 type Test16 = <<crate::consts::U16 as Invert>::Output as Invert>::Output;
267
268 assert_eq!(4, <Test4 as Unsigned>::to_u64());
269 assert_eq!(5, <Test5 as Unsigned>::to_u64());
270 assert_eq!(12, <Test12 as Unsigned>::to_u64());
271 assert_eq!(16, <Test16 as Unsigned>::to_u64());
272}
273
274impl TrimTrailingZeros for InvertedUTerm {
275 type Output = InvertedUTerm;
276
277 #[inline]
278 fn trim_trailing_zeros(self) -> Self::Output {
279 InvertedUTerm
280 }
281}
282
283impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {
284 type Output = Self;
285
286 #[inline]
287 fn trim_trailing_zeros(self) -> Self::Output {
288 self
289 }
290}
291
292impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
293where
294 IU: TrimTrailingZeros,
295{
296 type Output = <IU as TrimTrailingZeros>::Output;
297
298 #[inline]
299 fn trim_trailing_zeros(self) -> Self::Output {
300 self.msb.trim_trailing_zeros()
301 }
302}
303
304impl<U: Unsigned> Trim for U
305where
306 U: Invert,
307 <U as Invert>::Output: TrimTrailingZeros,
308 <<U as Invert>::Output as TrimTrailingZeros>::Output: Invert,
309{
310 type Output = <<<U as Invert>::Output as TrimTrailingZeros>::Output as Invert>::Output;
311
312 #[inline]
313 fn trim(self) -> Self::Output {
314 self.invert().trim_trailing_zeros().invert()
315 }
316}
317
318pub trait PrivateCmp<Rhs, SoFar> {
321 type Output;
322
323 fn private_cmp(&self, _: &Rhs, _: SoFar) -> Self::Output;
324}
325pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output;
326
327pub trait PrivateSetBit<I, B> {
329 type Output;
330
331 fn private_set_bit(self, _: I, _: B) -> Self::Output;
332}
333pub type PrivateSetBitOut<N, I, B> = <N as PrivateSetBit<I, B>>::Output;
334
335pub trait PrivateDiv<N, D, Q, R, I> {
337 type Quotient;
338 type Remainder;
339
340 fn private_div_quotient(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Quotient;
341
342 fn private_div_remainder(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Remainder;
343}
344
345pub type PrivateDivQuot<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Quotient;
346pub type PrivateDivRem<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Remainder;
347
348pub trait PrivateDivIf<N, D, Q, R, I, RcmpD> {
349 type Quotient;
350 type Remainder;
351
352 fn private_div_if_quotient(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Quotient;
353
354 fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Remainder;
355}
356
357pub type PrivateDivIfQuot<N, D, Q, R, I, RcmpD> =
358 <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Quotient;
359pub type PrivateDivIfRem<N, D, Q, R, I, RcmpD> =
360 <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Remainder;
361
362pub trait PrivateDivInt<C, Divisor> {
364 type Output;
365
366 fn private_div_int(self, _: C, _: Divisor) -> Self::Output;
367}
368pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output;
369
370pub trait PrivateRem<URem, Divisor> {
371 type Output;
372
373 fn private_rem(self, _: URem, _: Divisor) -> Self::Output;
374}
375pub type PrivateRemOut<A, URem, Divisor> = <A as PrivateRem<URem, Divisor>>::Output;
376
377pub trait PrivateMin<Rhs, CmpResult> {
379 type Output;
380 fn private_min(self, rhs: Rhs) -> Self::Output;
381}
382pub type PrivateMinOut<A, B, CmpResult> = <A as PrivateMin<B, CmpResult>>::Output;
383
384pub trait PrivateMax<Rhs, CmpResult> {
385 type Output;
386 fn private_max(self, rhs: Rhs) -> Self::Output;
387}
388pub type PrivateMaxOut<A, B, CmpResult> = <A as PrivateMax<B, CmpResult>>::Output;
389
390use crate::{Equal, False, Greater, Less, True};
393
394pub trait IsLessPrivate<Rhs, Cmp> {
395 type Output: Bit;
396
397 #[allow(clippy::wrong_self_convention)]
398 fn is_less_private(self, _: Rhs, _: Cmp) -> Self::Output;
399}
400
401impl<A, B> IsLessPrivate<B, Less> for A {
402 type Output = True;
403
404 #[inline]
405 fn is_less_private(self, _: B, _: Less) -> Self::Output {
406 B1
407 }
408}
409impl<A, B> IsLessPrivate<B, Equal> for A {
410 type Output = False;
411
412 #[inline]
413 fn is_less_private(self, _: B, _: Equal) -> Self::Output {
414 B0
415 }
416}
417impl<A, B> IsLessPrivate<B, Greater> for A {
418 type Output = False;
419
420 #[inline]
421 fn is_less_private(self, _: B, _: Greater) -> Self::Output {
422 B0
423 }
424}
425
426pub trait IsEqualPrivate<Rhs, Cmp> {
427 type Output: Bit;
428
429 #[allow(clippy::wrong_self_convention)]
430 fn is_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
431}
432
433impl<A, B> IsEqualPrivate<B, Less> for A {
434 type Output = False;
435
436 #[inline]
437 fn is_equal_private(self, _: B, _: Less) -> Self::Output {
438 B0
439 }
440}
441impl<A, B> IsEqualPrivate<B, Equal> for A {
442 type Output = True;
443
444 #[inline]
445 fn is_equal_private(self, _: B, _: Equal) -> Self::Output {
446 B1
447 }
448}
449impl<A, B> IsEqualPrivate<B, Greater> for A {
450 type Output = False;
451
452 #[inline]
453 fn is_equal_private(self, _: B, _: Greater) -> Self::Output {
454 B0
455 }
456}
457
458pub trait IsGreaterPrivate<Rhs, Cmp> {
459 type Output: Bit;
460
461 #[allow(clippy::wrong_self_convention)]
462 fn is_greater_private(self, _: Rhs, _: Cmp) -> Self::Output;
463}
464
465impl<A, B> IsGreaterPrivate<B, Less> for A {
466 type Output = False;
467
468 #[inline]
469 fn is_greater_private(self, _: B, _: Less) -> Self::Output {
470 B0
471 }
472}
473impl<A, B> IsGreaterPrivate<B, Equal> for A {
474 type Output = False;
475
476 #[inline]
477 fn is_greater_private(self, _: B, _: Equal) -> Self::Output {
478 B0
479 }
480}
481impl<A, B> IsGreaterPrivate<B, Greater> for A {
482 type Output = True;
483
484 #[inline]
485 fn is_greater_private(self, _: B, _: Greater) -> Self::Output {
486 B1
487 }
488}
489
490pub trait IsLessOrEqualPrivate<Rhs, Cmp> {
491 type Output: Bit;
492
493 #[allow(clippy::wrong_self_convention)]
494 fn is_less_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
495}
496
497impl<A, B> IsLessOrEqualPrivate<B, Less> for A {
498 type Output = True;
499
500 #[inline]
501 fn is_less_or_equal_private(self, _: B, _: Less) -> Self::Output {
502 B1
503 }
504}
505impl<A, B> IsLessOrEqualPrivate<B, Equal> for A {
506 type Output = True;
507
508 #[inline]
509 fn is_less_or_equal_private(self, _: B, _: Equal) -> Self::Output {
510 B1
511 }
512}
513impl<A, B> IsLessOrEqualPrivate<B, Greater> for A {
514 type Output = False;
515
516 #[inline]
517 fn is_less_or_equal_private(self, _: B, _: Greater) -> Self::Output {
518 B0
519 }
520}
521
522pub trait IsNotEqualPrivate<Rhs, Cmp> {
523 type Output: Bit;
524
525 #[allow(clippy::wrong_self_convention)]
526 fn is_not_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
527}
528
529impl<A, B> IsNotEqualPrivate<B, Less> for A {
530 type Output = True;
531
532 #[inline]
533 fn is_not_equal_private(self, _: B, _: Less) -> Self::Output {
534 B1
535 }
536}
537impl<A, B> IsNotEqualPrivate<B, Equal> for A {
538 type Output = False;
539
540 #[inline]
541 fn is_not_equal_private(self, _: B, _: Equal) -> Self::Output {
542 B0
543 }
544}
545impl<A, B> IsNotEqualPrivate<B, Greater> for A {
546 type Output = True;
547
548 #[inline]
549 fn is_not_equal_private(self, _: B, _: Greater) -> Self::Output {
550 B1
551 }
552}
553
554pub trait IsGreaterOrEqualPrivate<Rhs, Cmp> {
555 type Output: Bit;
556
557 #[allow(clippy::wrong_self_convention)]
558 fn is_greater_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
559}
560
561impl<A, B> IsGreaterOrEqualPrivate<B, Less> for A {
562 type Output = False;
563
564 #[inline]
565 fn is_greater_or_equal_private(self, _: B, _: Less) -> Self::Output {
566 B0
567 }
568}
569impl<A, B> IsGreaterOrEqualPrivate<B, Equal> for A {
570 type Output = True;
571
572 #[inline]
573 fn is_greater_or_equal_private(self, _: B, _: Equal) -> Self::Output {
574 B1
575 }
576}
577impl<A, B> IsGreaterOrEqualPrivate<B, Greater> for A {
578 type Output = True;
579
580 #[inline]
581 fn is_greater_or_equal_private(self, _: B, _: Greater) -> Self::Output {
582 B1
583 }
584}
585
586pub trait PrivateSquareRoot {
587 type Output;
588}
589
590pub trait PrivateLogarithm2 {
591 type Output;
592}