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// ONLY IMPLEMENT FOR INVERTED NUMBERS!
45pub trait TrimTrailingZeros {
46    type Output;
47
48    fn trim_trailing_zeros(self) -> Self::Output;
49}
50pub type TrimTrailingZerosOut<A> = <A as TrimTrailingZeros>::Output;
51
52/// Converts between standard numbers and inverted ones that have the most significant
53/// digit on the outside.
54pub trait Invert {
55    type Output;
56
57    fn invert(self) -> Self::Output;
58}
59pub type InvertOut<A> = <A as Invert>::Output;
60
61/// Doubly private! Called by invert to make the magic happen once its done the first step.
62/// The Rhs is what we've got so far.
63pub 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
70/// Terminating character for `InvertedUInt`s
71pub struct InvertedUTerm;
72
73/// Inverted `UInt` (has most significant digit on the outside)
74pub struct InvertedUInt<IU: InvertedUnsigned, B: Bit> {
75    msb: IU,
76    lsb: B,
77}
78
79/// Does the real anding for `UInt`s; `And` just calls this and then `Trim`.
80pub 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
87/// Does the real xoring for `UInt`s; `Xor` just calls this and then `Trim`.
88pub 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
95/// Does the real subtraction for `UInt`s; `Sub` just calls this and then `Trim`.
96pub 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
103/// Used for addition of signed integers; `C = P.cmp(N)`
104/// Assumes `P = Self` is positive and `N` is negative
105/// where `P` and `N` are both passed as unsigned integers
106pub 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
120/// Performs `Shl` on `Lhs` so that `SizeOf(Lhs) = SizeOf(Rhs)`
121/// Fails if `SizeOf(Lhs) > SizeOf(Rhs)`
122pub trait ShiftDiff<Rhs> {
123    type Output;
124}
125pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output;
126
127/// Gives `SizeOf(Lhs) - SizeOf(Rhs)`
128pub trait BitDiff<Rhs> {
129    type Output;
130}
131pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output;
132
133/// Inverted unsigned numbers
134pub 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
318// Note: Trimming is tested when we do subtraction.
319
320pub 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
327// Set Bit
328pub 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
335// Div
336pub 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
362// Div for signed ints
363pub 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
377// min max
378pub 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
390// Comparisons
391
392use 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}