typenum/
private.rs

1//! **Ignore me!** This module is for things that are conceptually private but that must
2//! be made public for typenum to work correctly.
3//!
4//! Unless you are working on typenum itself, **there is no need to view anything here**.
5//!
6//! Certainly don't implement any of the traits here for anything.
7//!
8//!
9//! Just look away.
10//!
11//!
12//! Loooooooooooooooooooooooooooooooooook awaaaaaaaaaaaayyyyyyyyyyyyyyyyyyyyyyyyyyyyy...
13//!
14//!
15//! If you do manage to find something of use in here, please let me know. If you can make a
16//! compelling case, it may be moved out of __private.
17//!
18//! Note: Aliases for private type operators will all be named simply that operator followed
19//! by an abbreviated name of its associated type.
20
21#![doc(hidden)]
22
23use crate::{
24    bit::{Bit, B0, B1},
25    uint::{UInt, UTerm, Unsigned},
26};
27
28/// A marker for restricting a method on a public trait to internal use only.
29pub(crate) enum Internal {}
30
31pub trait InternalMarker {}
32
33impl InternalMarker for Internal {}
34
35/// Convenience trait. Calls `Invert` -> `TrimTrailingZeros` -> `Invert`
36pub trait Trim {
37    type Output;
38
39    fn trim(self) -> Self::Output;
40}
41pub type TrimOut<A> = <A as Trim>::Output;
42
43/// Gets rid of all zeros until it hits a one.
44
45// ONLY IMPLEMENT FOR INVERTED NUMBERS!
46pub trait TrimTrailingZeros {
47    type Output;
48
49    fn trim_trailing_zeros(self) -> Self::Output;
50}
51pub type TrimTrailingZerosOut<A> = <A as TrimTrailingZeros>::Output;
52
53/// Converts between standard numbers and inverted ones that have the most significant
54/// digit on the outside.
55pub trait Invert {
56    type Output;
57
58    fn invert(self) -> Self::Output;
59}
60pub type InvertOut<A> = <A as Invert>::Output;
61
62/// Doubly private! Called by invert to make the magic happen once its done the first step.
63/// The Rhs is what we've got so far.
64pub trait PrivateInvert<Rhs> {
65    type Output;
66
67    fn private_invert(self, rhs: Rhs) -> Self::Output;
68}
69pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output;
70
71/// Terminating character for `InvertedUInt`s
72pub struct InvertedUTerm;
73
74/// Inverted `UInt` (has most significant digit on the outside)
75pub struct InvertedUInt<IU: InvertedUnsigned, B: Bit> {
76    msb: IU,
77    lsb: B,
78}
79
80/// Does the real anding for `UInt`s; `And` just calls this and then `Trim`.
81pub trait PrivateAnd<Rhs = Self> {
82    type Output;
83
84    fn private_and(self, rhs: Rhs) -> Self::Output;
85}
86pub type PrivateAndOut<A, Rhs> = <A as PrivateAnd<Rhs>>::Output;
87
88/// Does the real xoring for `UInt`s; `Xor` just calls this and then `Trim`.
89pub trait PrivateXor<Rhs = Self> {
90    type Output;
91
92    fn private_xor(self, rhs: Rhs) -> Self::Output;
93}
94pub type PrivateXorOut<A, Rhs> = <A as PrivateXor<Rhs>>::Output;
95
96/// Does the real subtraction for `UInt`s; `Sub` just calls this and then `Trim`.
97pub trait PrivateSub<Rhs = Self> {
98    type Output;
99
100    fn private_sub(self, rhs: Rhs) -> Self::Output;
101}
102pub type PrivateSubOut<A, Rhs> = <A as PrivateSub<Rhs>>::Output;
103
104/// Used for addition of signed integers; `C = P.cmp(N)`
105/// Assumes `P = Self` is positive and `N` is negative
106/// where `P` and `N` are both passed as unsigned integers
107pub trait PrivateIntegerAdd<C, N> {
108    type Output;
109
110    fn private_integer_add(self, _: C, _: N) -> Self::Output;
111}
112pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output;
113
114pub trait PrivatePow<Y, N> {
115    type Output;
116
117    fn private_pow(self, _: Y, _: N) -> Self::Output;
118}
119pub type PrivatePowOut<A, Y, N> = <A as PrivatePow<Y, N>>::Output;
120
121/// Performs `Shl` on `Lhs` so that `SizeOf(Lhs) = SizeOf(Rhs)`
122/// Fails if `SizeOf(Lhs) > SizeOf(Rhs)`
123pub trait ShiftDiff<Rhs> {
124    type Output;
125}
126pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output;
127
128/// Gives `SizeOf(Lhs) - SizeOf(Rhs)`
129pub trait BitDiff<Rhs> {
130    type Output;
131}
132pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output;
133
134/// Inverted unsigned numbers
135pub trait InvertedUnsigned {
136    fn to_u64() -> u64;
137}
138
139impl InvertedUnsigned for InvertedUTerm {
140    #[inline]
141    fn to_u64() -> u64 {
142        0
143    }
144}
145
146impl<IU: InvertedUnsigned, B: Bit> InvertedUnsigned for InvertedUInt<IU, B> {
147    #[inline]
148    fn to_u64() -> u64 {
149        u64::from(B::to_u8()) | IU::to_u64() << 1
150    }
151}
152
153impl Invert for UTerm {
154    type Output = InvertedUTerm;
155
156    #[inline]
157    fn invert(self) -> Self::Output {
158        InvertedUTerm
159    }
160}
161
162impl<U: Unsigned, B: Bit> Invert for UInt<U, B>
163where
164    U: PrivateInvert<InvertedUInt<InvertedUTerm, B>>,
165{
166    type Output = PrivateInvertOut<U, InvertedUInt<InvertedUTerm, B>>;
167
168    #[inline]
169    fn invert(self) -> Self::Output {
170        self.msb.private_invert(InvertedUInt {
171            msb: InvertedUTerm,
172            lsb: self.lsb,
173        })
174    }
175}
176
177impl<IU: InvertedUnsigned> PrivateInvert<IU> for UTerm {
178    type Output = IU;
179
180    #[inline]
181    fn private_invert(self, rhs: IU) -> Self::Output {
182        rhs
183    }
184}
185
186impl<IU: InvertedUnsigned, U: Unsigned, B: Bit> PrivateInvert<IU> for UInt<U, B>
187where
188    U: PrivateInvert<InvertedUInt<IU, B>>,
189{
190    type Output = PrivateInvertOut<U, InvertedUInt<IU, B>>;
191
192    #[inline]
193    fn private_invert(self, rhs: IU) -> Self::Output {
194        self.msb.private_invert(InvertedUInt {
195            msb: rhs,
196            lsb: self.lsb,
197        })
198    }
199}
200
201#[test]
202fn test_inversion() {
203    type Test4 = <crate::consts::U4 as Invert>::Output;
204    type Test5 = <crate::consts::U5 as Invert>::Output;
205    type Test12 = <crate::consts::U12 as Invert>::Output;
206    type Test16 = <crate::consts::U16 as Invert>::Output;
207
208    assert_eq!(1, <Test4 as InvertedUnsigned>::to_u64());
209    assert_eq!(5, <Test5 as InvertedUnsigned>::to_u64());
210    assert_eq!(3, <Test12 as InvertedUnsigned>::to_u64());
211    assert_eq!(1, <Test16 as InvertedUnsigned>::to_u64());
212}
213
214impl Invert for InvertedUTerm {
215    type Output = UTerm;
216
217    #[inline]
218    fn invert(self) -> Self::Output {
219        UTerm
220    }
221}
222
223impl<IU: InvertedUnsigned, B: Bit> Invert for InvertedUInt<IU, B>
224where
225    IU: PrivateInvert<UInt<UTerm, B>>,
226{
227    type Output = <IU as PrivateInvert<UInt<UTerm, B>>>::Output;
228
229    #[inline]
230    fn invert(self) -> Self::Output {
231        self.msb.private_invert(UInt {
232            msb: UTerm,
233            lsb: self.lsb,
234        })
235    }
236}
237
238impl<U: Unsigned> PrivateInvert<U> for InvertedUTerm {
239    type Output = U;
240
241    #[inline]
242    fn private_invert(self, rhs: U) -> Self::Output {
243        rhs
244    }
245}
246
247impl<U: Unsigned, IU: InvertedUnsigned, B: Bit> PrivateInvert<U> for InvertedUInt<IU, B>
248where
249    IU: PrivateInvert<UInt<U, B>>,
250{
251    type Output = <IU as PrivateInvert<UInt<U, B>>>::Output;
252
253    #[inline]
254    fn private_invert(self, rhs: U) -> Self::Output {
255        self.msb.private_invert(UInt {
256            msb: rhs,
257            lsb: self.lsb,
258        })
259    }
260}
261
262#[test]
263fn test_double_inversion() {
264    type Test4 = <<crate::consts::U4 as Invert>::Output as Invert>::Output;
265    type Test5 = <<crate::consts::U5 as Invert>::Output as Invert>::Output;
266    type Test12 = <<crate::consts::U12 as Invert>::Output as Invert>::Output;
267    type Test16 = <<crate::consts::U16 as Invert>::Output as Invert>::Output;
268
269    assert_eq!(4, <Test4 as Unsigned>::to_u64());
270    assert_eq!(5, <Test5 as Unsigned>::to_u64());
271    assert_eq!(12, <Test12 as Unsigned>::to_u64());
272    assert_eq!(16, <Test16 as Unsigned>::to_u64());
273}
274
275impl TrimTrailingZeros for InvertedUTerm {
276    type Output = InvertedUTerm;
277
278    #[inline]
279    fn trim_trailing_zeros(self) -> Self::Output {
280        InvertedUTerm
281    }
282}
283
284impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {
285    type Output = Self;
286
287    #[inline]
288    fn trim_trailing_zeros(self) -> Self::Output {
289        self
290    }
291}
292
293impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
294where
295    IU: TrimTrailingZeros,
296{
297    type Output = <IU as TrimTrailingZeros>::Output;
298
299    #[inline]
300    fn trim_trailing_zeros(self) -> Self::Output {
301        self.msb.trim_trailing_zeros()
302    }
303}
304
305impl<U: Unsigned> Trim for U
306where
307    U: Invert,
308    <U as Invert>::Output: TrimTrailingZeros,
309    <<U as Invert>::Output as TrimTrailingZeros>::Output: Invert,
310{
311    type Output = <<<U as Invert>::Output as TrimTrailingZeros>::Output as Invert>::Output;
312
313    #[inline]
314    fn trim(self) -> Self::Output {
315        self.invert().trim_trailing_zeros().invert()
316    }
317}
318
319// Note: Trimming is tested when we do subtraction.
320
321pub trait PrivateCmp<Rhs, SoFar> {
322    type Output;
323
324    fn private_cmp(&self, _: &Rhs, _: SoFar) -> Self::Output;
325}
326pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output;
327
328// Set Bit
329pub trait PrivateSetBit<I, B> {
330    type Output;
331
332    fn private_set_bit(self, _: I, _: B) -> Self::Output;
333}
334pub type PrivateSetBitOut<N, I, B> = <N as PrivateSetBit<I, B>>::Output;
335
336// Div
337pub trait PrivateDiv<N, D, Q, R, I> {
338    type Quotient;
339    type Remainder;
340
341    fn private_div_quotient(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Quotient;
342
343    fn private_div_remainder(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Remainder;
344}
345
346pub type PrivateDivQuot<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Quotient;
347pub type PrivateDivRem<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Remainder;
348
349pub trait PrivateDivIf<N, D, Q, R, I, RcmpD> {
350    type Quotient;
351    type Remainder;
352
353    fn private_div_if_quotient(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Quotient;
354
355    fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Remainder;
356}
357
358pub type PrivateDivIfQuot<N, D, Q, R, I, RcmpD> =
359    <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Quotient;
360pub type PrivateDivIfRem<N, D, Q, R, I, RcmpD> =
361    <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Remainder;
362
363// Div for signed ints
364pub trait PrivateDivInt<C, Divisor> {
365    type Output;
366
367    fn private_div_int(self, _: C, _: Divisor) -> Self::Output;
368}
369pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output;
370
371pub trait PrivateRem<URem, Divisor> {
372    type Output;
373
374    fn private_rem(self, _: URem, _: Divisor) -> Self::Output;
375}
376pub type PrivateRemOut<A, URem, Divisor> = <A as PrivateRem<URem, Divisor>>::Output;
377
378// min max
379pub trait PrivateMin<Rhs, CmpResult> {
380    type Output;
381    fn private_min(self, rhs: Rhs) -> Self::Output;
382}
383pub type PrivateMinOut<A, B, CmpResult> = <A as PrivateMin<B, CmpResult>>::Output;
384
385pub trait PrivateMax<Rhs, CmpResult> {
386    type Output;
387    fn private_max(self, rhs: Rhs) -> Self::Output;
388}
389pub type PrivateMaxOut<A, B, CmpResult> = <A as PrivateMax<B, CmpResult>>::Output;
390
391// Comparisons
392
393use crate::{Equal, False, Greater, Less, True};
394
395pub trait IsLessPrivate<Rhs, Cmp> {
396    type Output: Bit;
397
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    fn is_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
430}
431
432impl<A, B> IsEqualPrivate<B, Less> for A {
433    type Output = False;
434
435    #[inline]
436    fn is_equal_private(self, _: B, _: Less) -> Self::Output {
437        B0
438    }
439}
440impl<A, B> IsEqualPrivate<B, Equal> for A {
441    type Output = True;
442
443    #[inline]
444    fn is_equal_private(self, _: B, _: Equal) -> Self::Output {
445        B1
446    }
447}
448impl<A, B> IsEqualPrivate<B, Greater> for A {
449    type Output = False;
450
451    #[inline]
452    fn is_equal_private(self, _: B, _: Greater) -> Self::Output {
453        B0
454    }
455}
456
457pub trait IsGreaterPrivate<Rhs, Cmp> {
458    type Output: Bit;
459
460    fn is_greater_private(self, _: Rhs, _: Cmp) -> Self::Output;
461}
462
463impl<A, B> IsGreaterPrivate<B, Less> for A {
464    type Output = False;
465
466    #[inline]
467    fn is_greater_private(self, _: B, _: Less) -> Self::Output {
468        B0
469    }
470}
471impl<A, B> IsGreaterPrivate<B, Equal> for A {
472    type Output = False;
473
474    #[inline]
475    fn is_greater_private(self, _: B, _: Equal) -> Self::Output {
476        B0
477    }
478}
479impl<A, B> IsGreaterPrivate<B, Greater> for A {
480    type Output = True;
481
482    #[inline]
483    fn is_greater_private(self, _: B, _: Greater) -> Self::Output {
484        B1
485    }
486}
487
488pub trait IsLessOrEqualPrivate<Rhs, Cmp> {
489    type Output: Bit;
490
491    fn is_less_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
492}
493
494impl<A, B> IsLessOrEqualPrivate<B, Less> for A {
495    type Output = True;
496
497    #[inline]
498    fn is_less_or_equal_private(self, _: B, _: Less) -> Self::Output {
499        B1
500    }
501}
502impl<A, B> IsLessOrEqualPrivate<B, Equal> for A {
503    type Output = True;
504
505    #[inline]
506    fn is_less_or_equal_private(self, _: B, _: Equal) -> Self::Output {
507        B1
508    }
509}
510impl<A, B> IsLessOrEqualPrivate<B, Greater> for A {
511    type Output = False;
512
513    #[inline]
514    fn is_less_or_equal_private(self, _: B, _: Greater) -> Self::Output {
515        B0
516    }
517}
518
519pub trait IsNotEqualPrivate<Rhs, Cmp> {
520    type Output: Bit;
521
522    fn is_not_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
523}
524
525impl<A, B> IsNotEqualPrivate<B, Less> for A {
526    type Output = True;
527
528    #[inline]
529    fn is_not_equal_private(self, _: B, _: Less) -> Self::Output {
530        B1
531    }
532}
533impl<A, B> IsNotEqualPrivate<B, Equal> for A {
534    type Output = False;
535
536    #[inline]
537    fn is_not_equal_private(self, _: B, _: Equal) -> Self::Output {
538        B0
539    }
540}
541impl<A, B> IsNotEqualPrivate<B, Greater> for A {
542    type Output = True;
543
544    #[inline]
545    fn is_not_equal_private(self, _: B, _: Greater) -> Self::Output {
546        B1
547    }
548}
549
550pub trait IsGreaterOrEqualPrivate<Rhs, Cmp> {
551    type Output: Bit;
552
553    fn is_greater_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
554}
555
556impl<A, B> IsGreaterOrEqualPrivate<B, Less> for A {
557    type Output = False;
558
559    #[inline]
560    fn is_greater_or_equal_private(self, _: B, _: Less) -> Self::Output {
561        B0
562    }
563}
564impl<A, B> IsGreaterOrEqualPrivate<B, Equal> for A {
565    type Output = True;
566
567    #[inline]
568    fn is_greater_or_equal_private(self, _: B, _: Equal) -> Self::Output {
569        B1
570    }
571}
572impl<A, B> IsGreaterOrEqualPrivate<B, Greater> for A {
573    type Output = True;
574
575    #[inline]
576    fn is_greater_or_equal_private(self, _: B, _: Greater) -> Self::Output {
577        B1
578    }
579}
580
581pub trait PrivateSquareRoot {
582    type Output;
583}
584
585pub trait PrivateLogarithm2 {
586    type Output;
587}