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
23 use 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.
29 pub(crate) enum Internal {}
30
31 pub trait InternalMarker {}
32
33 impl InternalMarker for Internal {}
34
35 /// Convenience trait. Calls `Invert` -> `TrimTrailingZeros` -> `Invert`
36 pub trait Trim {
37 type Output;
38
trim(self) -> Self::Output39 fn trim(self) -> Self::Output;
40 }
41 pub 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!
46 pub trait TrimTrailingZeros {
47 type Output;
48
trim_trailing_zeros(self) -> Self::Output49 fn trim_trailing_zeros(self) -> Self::Output;
50 }
51 pub 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.
55 pub trait Invert {
56 type Output;
57
invert(self) -> Self::Output58 fn invert(self) -> Self::Output;
59 }
60 pub 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.
64 pub trait PrivateInvert<Rhs> {
65 type Output;
66
private_invert(self, rhs: Rhs) -> Self::Output67 fn private_invert(self, rhs: Rhs) -> Self::Output;
68 }
69 pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output;
70
71 /// Terminating character for `InvertedUInt`s
72 pub struct InvertedUTerm;
73
74 /// Inverted `UInt` (has most significant digit on the outside)
75 pub 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`.
81 pub trait PrivateAnd<Rhs = Self> {
82 type Output;
83
private_and(self, rhs: Rhs) -> Self::Output84 fn private_and(self, rhs: Rhs) -> Self::Output;
85 }
86 pub 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`.
89 pub trait PrivateXor<Rhs = Self> {
90 type Output;
91
private_xor(self, rhs: Rhs) -> Self::Output92 fn private_xor(self, rhs: Rhs) -> Self::Output;
93 }
94 pub 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`.
97 pub trait PrivateSub<Rhs = Self> {
98 type Output;
99
private_sub(self, rhs: Rhs) -> Self::Output100 fn private_sub(self, rhs: Rhs) -> Self::Output;
101 }
102 pub 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
107 pub trait PrivateIntegerAdd<C, N> {
108 type Output;
109
private_integer_add(self, _: C, _: N) -> Self::Output110 fn private_integer_add(self, _: C, _: N) -> Self::Output;
111 }
112 pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output;
113
114 pub trait PrivatePow<Y, N> {
115 type Output;
116
private_pow(self, _: Y, _: N) -> Self::Output117 fn private_pow(self, _: Y, _: N) -> Self::Output;
118 }
119 pub 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)`
123 pub trait ShiftDiff<Rhs> {
124 type Output;
125 }
126 pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output;
127
128 /// Gives `SizeOf(Lhs) - SizeOf(Rhs)`
129 pub trait BitDiff<Rhs> {
130 type Output;
131 }
132 pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output;
133
134 /// Inverted unsigned numbers
135 pub trait InvertedUnsigned {
to_u64() -> u64136 fn to_u64() -> u64;
137 }
138
139 impl InvertedUnsigned for InvertedUTerm {
140 #[inline]
to_u64() -> u64141 fn to_u64() -> u64 {
142 0
143 }
144 }
145
146 impl<IU: InvertedUnsigned, B: Bit> InvertedUnsigned for InvertedUInt<IU, B> {
147 #[inline]
to_u64() -> u64148 fn to_u64() -> u64 {
149 u64::from(B::to_u8()) | IU::to_u64() << 1
150 }
151 }
152
153 impl Invert for UTerm {
154 type Output = InvertedUTerm;
155
156 #[inline]
invert(self) -> Self::Output157 fn invert(self) -> Self::Output {
158 InvertedUTerm
159 }
160 }
161
162 impl<U: Unsigned, B: Bit> Invert for UInt<U, B>
163 where
164 U: PrivateInvert<InvertedUInt<InvertedUTerm, B>>,
165 {
166 type Output = PrivateInvertOut<U, InvertedUInt<InvertedUTerm, B>>;
167
168 #[inline]
invert(self) -> Self::Output169 fn invert(self) -> Self::Output {
170 self.msb.private_invert(InvertedUInt {
171 msb: InvertedUTerm,
172 lsb: self.lsb,
173 })
174 }
175 }
176
177 impl<IU: InvertedUnsigned> PrivateInvert<IU> for UTerm {
178 type Output = IU;
179
180 #[inline]
private_invert(self, rhs: IU) -> Self::Output181 fn private_invert(self, rhs: IU) -> Self::Output {
182 rhs
183 }
184 }
185
186 impl<IU: InvertedUnsigned, U: Unsigned, B: Bit> PrivateInvert<IU> for UInt<U, B>
187 where
188 U: PrivateInvert<InvertedUInt<IU, B>>,
189 {
190 type Output = PrivateInvertOut<U, InvertedUInt<IU, B>>;
191
192 #[inline]
private_invert(self, rhs: IU) -> Self::Output193 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]
test_inversion()202 fn 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
214 impl Invert for InvertedUTerm {
215 type Output = UTerm;
216
217 #[inline]
invert(self) -> Self::Output218 fn invert(self) -> Self::Output {
219 UTerm
220 }
221 }
222
223 impl<IU: InvertedUnsigned, B: Bit> Invert for InvertedUInt<IU, B>
224 where
225 IU: PrivateInvert<UInt<UTerm, B>>,
226 {
227 type Output = <IU as PrivateInvert<UInt<UTerm, B>>>::Output;
228
229 #[inline]
invert(self) -> Self::Output230 fn invert(self) -> Self::Output {
231 self.msb.private_invert(UInt {
232 msb: UTerm,
233 lsb: self.lsb,
234 })
235 }
236 }
237
238 impl<U: Unsigned> PrivateInvert<U> for InvertedUTerm {
239 type Output = U;
240
241 #[inline]
private_invert(self, rhs: U) -> Self::Output242 fn private_invert(self, rhs: U) -> Self::Output {
243 rhs
244 }
245 }
246
247 impl<U: Unsigned, IU: InvertedUnsigned, B: Bit> PrivateInvert<U> for InvertedUInt<IU, B>
248 where
249 IU: PrivateInvert<UInt<U, B>>,
250 {
251 type Output = <IU as PrivateInvert<UInt<U, B>>>::Output;
252
253 #[inline]
private_invert(self, rhs: U) -> Self::Output254 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]
test_double_inversion()263 fn 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
275 impl TrimTrailingZeros for InvertedUTerm {
276 type Output = InvertedUTerm;
277
278 #[inline]
trim_trailing_zeros(self) -> Self::Output279 fn trim_trailing_zeros(self) -> Self::Output {
280 InvertedUTerm
281 }
282 }
283
284 impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {
285 type Output = Self;
286
287 #[inline]
trim_trailing_zeros(self) -> Self::Output288 fn trim_trailing_zeros(self) -> Self::Output {
289 self
290 }
291 }
292
293 impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
294 where
295 IU: TrimTrailingZeros,
296 {
297 type Output = <IU as TrimTrailingZeros>::Output;
298
299 #[inline]
trim_trailing_zeros(self) -> Self::Output300 fn trim_trailing_zeros(self) -> Self::Output {
301 self.msb.trim_trailing_zeros()
302 }
303 }
304
305 impl<U: Unsigned> Trim for U
306 where
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]
trim(self) -> Self::Output314 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
321 pub trait PrivateCmp<Rhs, SoFar> {
322 type Output;
323
private_cmp(&self, _: &Rhs, _: SoFar) -> Self::Output324 fn private_cmp(&self, _: &Rhs, _: SoFar) -> Self::Output;
325 }
326 pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output;
327
328 // Set Bit
329 pub trait PrivateSetBit<I, B> {
330 type Output;
331
private_set_bit(self, _: I, _: B) -> Self::Output332 fn private_set_bit(self, _: I, _: B) -> Self::Output;
333 }
334 pub type PrivateSetBitOut<N, I, B> = <N as PrivateSetBit<I, B>>::Output;
335
336 // Div
337 pub trait PrivateDiv<N, D, Q, R, I> {
338 type Quotient;
339 type Remainder;
340
private_div_quotient(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Quotient341 fn private_div_quotient(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Quotient;
342
private_div_remainder(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Remainder343 fn private_div_remainder(self, _: N, _: D, _: Q, _: R, _: I) -> Self::Remainder;
344 }
345
346 pub type PrivateDivQuot<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Quotient;
347 pub type PrivateDivRem<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Remainder;
348
349 pub trait PrivateDivIf<N, D, Q, R, I, RcmpD> {
350 type Quotient;
351 type Remainder;
352
private_div_if_quotient(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Quotient353 fn private_div_if_quotient(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Quotient;
354
private_div_if_remainder(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Remainder355 fn private_div_if_remainder(self, _: N, _: D, _: Q, _: R, _: I, _: RcmpD) -> Self::Remainder;
356 }
357
358 pub type PrivateDivIfQuot<N, D, Q, R, I, RcmpD> =
359 <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Quotient;
360 pub type PrivateDivIfRem<N, D, Q, R, I, RcmpD> =
361 <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Remainder;
362
363 // Div for signed ints
364 pub trait PrivateDivInt<C, Divisor> {
365 type Output;
366
private_div_int(self, _: C, _: Divisor) -> Self::Output367 fn private_div_int(self, _: C, _: Divisor) -> Self::Output;
368 }
369 pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output;
370
371 pub trait PrivateRem<URem, Divisor> {
372 type Output;
373
private_rem(self, _: URem, _: Divisor) -> Self::Output374 fn private_rem(self, _: URem, _: Divisor) -> Self::Output;
375 }
376 pub type PrivateRemOut<A, URem, Divisor> = <A as PrivateRem<URem, Divisor>>::Output;
377
378 // min max
379 pub trait PrivateMin<Rhs, CmpResult> {
380 type Output;
private_min(self, rhs: Rhs) -> Self::Output381 fn private_min(self, rhs: Rhs) -> Self::Output;
382 }
383 pub type PrivateMinOut<A, B, CmpResult> = <A as PrivateMin<B, CmpResult>>::Output;
384
385 pub trait PrivateMax<Rhs, CmpResult> {
386 type Output;
private_max(self, rhs: Rhs) -> Self::Output387 fn private_max(self, rhs: Rhs) -> Self::Output;
388 }
389 pub type PrivateMaxOut<A, B, CmpResult> = <A as PrivateMax<B, CmpResult>>::Output;
390
391 // Comparisons
392
393 use crate::{Equal, False, Greater, Less, True};
394
395 pub trait IsLessPrivate<Rhs, Cmp> {
396 type Output: Bit;
397
is_less_private(self, _: Rhs, _: Cmp) -> Self::Output398 fn is_less_private(self, _: Rhs, _: Cmp) -> Self::Output;
399 }
400
401 impl<A, B> IsLessPrivate<B, Less> for A {
402 type Output = True;
403
404 #[inline]
is_less_private(self, _: B, _: Less) -> Self::Output405 fn is_less_private(self, _: B, _: Less) -> Self::Output {
406 B1
407 }
408 }
409 impl<A, B> IsLessPrivate<B, Equal> for A {
410 type Output = False;
411
412 #[inline]
is_less_private(self, _: B, _: Equal) -> Self::Output413 fn is_less_private(self, _: B, _: Equal) -> Self::Output {
414 B0
415 }
416 }
417 impl<A, B> IsLessPrivate<B, Greater> for A {
418 type Output = False;
419
420 #[inline]
is_less_private(self, _: B, _: Greater) -> Self::Output421 fn is_less_private(self, _: B, _: Greater) -> Self::Output {
422 B0
423 }
424 }
425
426 pub trait IsEqualPrivate<Rhs, Cmp> {
427 type Output: Bit;
428
is_equal_private(self, _: Rhs, _: Cmp) -> Self::Output429 fn is_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
430 }
431
432 impl<A, B> IsEqualPrivate<B, Less> for A {
433 type Output = False;
434
435 #[inline]
is_equal_private(self, _: B, _: Less) -> Self::Output436 fn is_equal_private(self, _: B, _: Less) -> Self::Output {
437 B0
438 }
439 }
440 impl<A, B> IsEqualPrivate<B, Equal> for A {
441 type Output = True;
442
443 #[inline]
is_equal_private(self, _: B, _: Equal) -> Self::Output444 fn is_equal_private(self, _: B, _: Equal) -> Self::Output {
445 B1
446 }
447 }
448 impl<A, B> IsEqualPrivate<B, Greater> for A {
449 type Output = False;
450
451 #[inline]
is_equal_private(self, _: B, _: Greater) -> Self::Output452 fn is_equal_private(self, _: B, _: Greater) -> Self::Output {
453 B0
454 }
455 }
456
457 pub trait IsGreaterPrivate<Rhs, Cmp> {
458 type Output: Bit;
459
is_greater_private(self, _: Rhs, _: Cmp) -> Self::Output460 fn is_greater_private(self, _: Rhs, _: Cmp) -> Self::Output;
461 }
462
463 impl<A, B> IsGreaterPrivate<B, Less> for A {
464 type Output = False;
465
466 #[inline]
is_greater_private(self, _: B, _: Less) -> Self::Output467 fn is_greater_private(self, _: B, _: Less) -> Self::Output {
468 B0
469 }
470 }
471 impl<A, B> IsGreaterPrivate<B, Equal> for A {
472 type Output = False;
473
474 #[inline]
is_greater_private(self, _: B, _: Equal) -> Self::Output475 fn is_greater_private(self, _: B, _: Equal) -> Self::Output {
476 B0
477 }
478 }
479 impl<A, B> IsGreaterPrivate<B, Greater> for A {
480 type Output = True;
481
482 #[inline]
is_greater_private(self, _: B, _: Greater) -> Self::Output483 fn is_greater_private(self, _: B, _: Greater) -> Self::Output {
484 B1
485 }
486 }
487
488 pub trait IsLessOrEqualPrivate<Rhs, Cmp> {
489 type Output: Bit;
490
is_less_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output491 fn is_less_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
492 }
493
494 impl<A, B> IsLessOrEqualPrivate<B, Less> for A {
495 type Output = True;
496
497 #[inline]
is_less_or_equal_private(self, _: B, _: Less) -> Self::Output498 fn is_less_or_equal_private(self, _: B, _: Less) -> Self::Output {
499 B1
500 }
501 }
502 impl<A, B> IsLessOrEqualPrivate<B, Equal> for A {
503 type Output = True;
504
505 #[inline]
is_less_or_equal_private(self, _: B, _: Equal) -> Self::Output506 fn is_less_or_equal_private(self, _: B, _: Equal) -> Self::Output {
507 B1
508 }
509 }
510 impl<A, B> IsLessOrEqualPrivate<B, Greater> for A {
511 type Output = False;
512
513 #[inline]
is_less_or_equal_private(self, _: B, _: Greater) -> Self::Output514 fn is_less_or_equal_private(self, _: B, _: Greater) -> Self::Output {
515 B0
516 }
517 }
518
519 pub trait IsNotEqualPrivate<Rhs, Cmp> {
520 type Output: Bit;
521
is_not_equal_private(self, _: Rhs, _: Cmp) -> Self::Output522 fn is_not_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
523 }
524
525 impl<A, B> IsNotEqualPrivate<B, Less> for A {
526 type Output = True;
527
528 #[inline]
is_not_equal_private(self, _: B, _: Less) -> Self::Output529 fn is_not_equal_private(self, _: B, _: Less) -> Self::Output {
530 B1
531 }
532 }
533 impl<A, B> IsNotEqualPrivate<B, Equal> for A {
534 type Output = False;
535
536 #[inline]
is_not_equal_private(self, _: B, _: Equal) -> Self::Output537 fn is_not_equal_private(self, _: B, _: Equal) -> Self::Output {
538 B0
539 }
540 }
541 impl<A, B> IsNotEqualPrivate<B, Greater> for A {
542 type Output = True;
543
544 #[inline]
is_not_equal_private(self, _: B, _: Greater) -> Self::Output545 fn is_not_equal_private(self, _: B, _: Greater) -> Self::Output {
546 B1
547 }
548 }
549
550 pub trait IsGreaterOrEqualPrivate<Rhs, Cmp> {
551 type Output: Bit;
552
is_greater_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output553 fn is_greater_or_equal_private(self, _: Rhs, _: Cmp) -> Self::Output;
554 }
555
556 impl<A, B> IsGreaterOrEqualPrivate<B, Less> for A {
557 type Output = False;
558
559 #[inline]
is_greater_or_equal_private(self, _: B, _: Less) -> Self::Output560 fn is_greater_or_equal_private(self, _: B, _: Less) -> Self::Output {
561 B0
562 }
563 }
564 impl<A, B> IsGreaterOrEqualPrivate<B, Equal> for A {
565 type Output = True;
566
567 #[inline]
is_greater_or_equal_private(self, _: B, _: Equal) -> Self::Output568 fn is_greater_or_equal_private(self, _: B, _: Equal) -> Self::Output {
569 B1
570 }
571 }
572 impl<A, B> IsGreaterOrEqualPrivate<B, Greater> for A {
573 type Output = True;
574
575 #[inline]
is_greater_or_equal_private(self, _: B, _: Greater) -> Self::Output576 fn is_greater_or_equal_private(self, _: B, _: Greater) -> Self::Output {
577 B1
578 }
579 }
580
581 pub trait PrivateSquareRoot {
582 type Output;
583 }
584
585 pub trait PrivateLogarithm2 {
586 type Output;
587 }
588