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 | |
39 | 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 | // ONLY IMPLEMENT FOR INVERTED NUMBERS! |
45 | pub trait TrimTrailingZeros { |
46 | type Output; |
47 | |
48 | fn trim_trailing_zeros(self) -> Self::Output; |
49 | } |
50 | pub 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. |
54 | pub trait Invert { |
55 | type Output; |
56 | |
57 | fn invert(self) -> Self::Output; |
58 | } |
59 | pub 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. |
63 | pub trait PrivateInvert<Rhs> { |
64 | type Output; |
65 | |
66 | fn private_invert(self, rhs: Rhs) -> Self::Output; |
67 | } |
68 | pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output; |
69 | |
70 | /// Terminating character for `InvertedUInt`s |
71 | pub struct InvertedUTerm; |
72 | |
73 | /// Inverted `UInt` (has most significant digit on the outside) |
74 | pub 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`. |
80 | pub trait PrivateAnd<Rhs = Self> { |
81 | type Output; |
82 | |
83 | fn private_and(self, rhs: Rhs) -> Self::Output; |
84 | } |
85 | pub 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`. |
88 | pub trait PrivateXor<Rhs = Self> { |
89 | type Output; |
90 | |
91 | fn private_xor(self, rhs: Rhs) -> Self::Output; |
92 | } |
93 | pub 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`. |
96 | pub trait PrivateSub<Rhs = Self> { |
97 | type Output; |
98 | |
99 | fn private_sub(self, rhs: Rhs) -> Self::Output; |
100 | } |
101 | pub 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 |
106 | pub trait PrivateIntegerAdd<C, N> { |
107 | type Output; |
108 | |
109 | fn private_integer_add(self, _: C, _: N) -> Self::Output; |
110 | } |
111 | pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output; |
112 | |
113 | pub trait PrivatePow<Y, N> { |
114 | type Output; |
115 | |
116 | fn private_pow(self, _: Y, _: N) -> Self::Output; |
117 | } |
118 | pub 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)` |
122 | pub trait ShiftDiff<Rhs> { |
123 | type Output; |
124 | } |
125 | pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output; |
126 | |
127 | /// Gives `SizeOf(Lhs) - SizeOf(Rhs)` |
128 | pub trait BitDiff<Rhs> { |
129 | type Output; |
130 | } |
131 | pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output; |
132 | |
133 | /// Inverted unsigned numbers |
134 | pub trait InvertedUnsigned { |
135 | fn to_u64() -> u64; |
136 | } |
137 | |
138 | impl InvertedUnsigned for InvertedUTerm { |
139 | #[inline ] |
140 | fn to_u64() -> u64 { |
141 | 0 |
142 | } |
143 | } |
144 | |
145 | impl<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 | |
152 | impl Invert for UTerm { |
153 | type Output = InvertedUTerm; |
154 | |
155 | #[inline ] |
156 | fn invert(self) -> Self::Output { |
157 | InvertedUTerm |
158 | } |
159 | } |
160 | |
161 | impl<U: Unsigned, B: Bit> Invert for UInt<U, B> |
162 | where |
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 | |
176 | impl<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 | |
185 | impl<IU: InvertedUnsigned, U: Unsigned, B: Bit> PrivateInvert<IU> for UInt<U, B> |
186 | where |
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 ] |
201 | fn 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 | |
213 | impl Invert for InvertedUTerm { |
214 | type Output = UTerm; |
215 | |
216 | #[inline ] |
217 | fn invert(self) -> Self::Output { |
218 | UTerm |
219 | } |
220 | } |
221 | |
222 | impl<IU: InvertedUnsigned, B: Bit> Invert for InvertedUInt<IU, B> |
223 | where |
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 | |
237 | impl<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 | |
246 | impl<U: Unsigned, IU: InvertedUnsigned, B: Bit> PrivateInvert<U> for InvertedUInt<IU, B> |
247 | where |
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 ] |
262 | fn 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 | |
274 | impl TrimTrailingZeros for InvertedUTerm { |
275 | type Output = InvertedUTerm; |
276 | |
277 | #[inline ] |
278 | fn trim_trailing_zeros(self) -> Self::Output { |
279 | InvertedUTerm |
280 | } |
281 | } |
282 | |
283 | impl<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 | |
292 | impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0> |
293 | where |
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 | |
304 | impl<U: Unsigned> Trim for U |
305 | where |
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 | |
320 | pub trait PrivateCmp<Rhs, SoFar> { |
321 | type Output; |
322 | |
323 | fn private_cmp(&self, _: &Rhs, _: SoFar) -> Self::Output; |
324 | } |
325 | pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output; |
326 | |
327 | // Set Bit |
328 | pub trait PrivateSetBit<I, B> { |
329 | type Output; |
330 | |
331 | fn private_set_bit(self, _: I, _: B) -> Self::Output; |
332 | } |
333 | pub type PrivateSetBitOut<N, I, B> = <N as PrivateSetBit<I, B>>::Output; |
334 | |
335 | // Div |
336 | pub 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 | |
345 | pub type PrivateDivQuot<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Quotient; |
346 | pub type PrivateDivRem<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Remainder; |
347 | |
348 | pub 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 | |
357 | pub type PrivateDivIfQuot<N, D, Q, R, I, RcmpD> = |
358 | <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Quotient; |
359 | pub type PrivateDivIfRem<N, D, Q, R, I, RcmpD> = |
360 | <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Remainder; |
361 | |
362 | // Div for signed ints |
363 | pub trait PrivateDivInt<C, Divisor> { |
364 | type Output; |
365 | |
366 | fn private_div_int(self, _: C, _: Divisor) -> Self::Output; |
367 | } |
368 | pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output; |
369 | |
370 | pub trait PrivateRem<URem, Divisor> { |
371 | type Output; |
372 | |
373 | fn private_rem(self, _: URem, _: Divisor) -> Self::Output; |
374 | } |
375 | pub type PrivateRemOut<A, URem, Divisor> = <A as PrivateRem<URem, Divisor>>::Output; |
376 | |
377 | // min max |
378 | pub trait PrivateMin<Rhs, CmpResult> { |
379 | type Output; |
380 | fn private_min(self, rhs: Rhs) -> Self::Output; |
381 | } |
382 | pub type PrivateMinOut<A, B, CmpResult> = <A as PrivateMin<B, CmpResult>>::Output; |
383 | |
384 | pub trait PrivateMax<Rhs, CmpResult> { |
385 | type Output; |
386 | fn private_max(self, rhs: Rhs) -> Self::Output; |
387 | } |
388 | pub type PrivateMaxOut<A, B, CmpResult> = <A as PrivateMax<B, CmpResult>>::Output; |
389 | |
390 | // Comparisons |
391 | |
392 | use crate::{Equal, False, Greater, Less, True}; |
393 | |
394 | pub 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 | |
401 | impl<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 | } |
409 | impl<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 | } |
417 | impl<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 | |
426 | pub 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 | |
433 | impl<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 | } |
441 | impl<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 | } |
449 | impl<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 | |
458 | pub 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 | |
465 | impl<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 | } |
473 | impl<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 | } |
481 | impl<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 | |
490 | pub 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 | |
497 | impl<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 | } |
505 | impl<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 | } |
513 | impl<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 | |
522 | pub 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 | |
529 | impl<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 | } |
537 | impl<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 | } |
545 | impl<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 | |
554 | pub 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 | |
561 | impl<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 | } |
569 | impl<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 | } |
577 | impl<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 | |
586 | pub trait PrivateSquareRoot { |
587 | type Output; |
588 | } |
589 | |
590 | pub trait PrivateLogarithm2 { |
591 | type Output; |
592 | } |
593 | |