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}
588