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 | |
45 | // ONLY IMPLEMENT FOR INVERTED NUMBERS! |
46 | pub trait TrimTrailingZeros { |
47 | type Output; |
48 | |
49 | 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 | |
58 | 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 | |
67 | 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 | |
84 | 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 | |
92 | 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 | |
100 | 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 | |
110 | 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 | |
117 | 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 { |
136 | fn to_u64() -> u64; |
137 | } |
138 | |
139 | impl InvertedUnsigned for InvertedUTerm { |
140 | #[inline ] |
141 | fn to_u64() -> u64 { |
142 | 0 |
143 | } |
144 | } |
145 | |
146 | impl<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 | |
153 | impl Invert for UTerm { |
154 | type Output = InvertedUTerm; |
155 | |
156 | #[inline ] |
157 | 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 ] |
169 | 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 ] |
181 | 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 ] |
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 ] |
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 ] |
218 | 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 ] |
230 | 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 ] |
242 | 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 ] |
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 ] |
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 ] |
279 | 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 ] |
288 | 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 ] |
300 | 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 ] |
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 | |
321 | pub trait PrivateCmp<Rhs, SoFar> { |
322 | type Output; |
323 | |
324 | 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 | |
332 | 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 | |
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 | |
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 | |
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 | |
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 | |
367 | 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 | |
374 | 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; |
381 | 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; |
387 | 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 | |
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 | 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 ] |
436 | 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 ] |
444 | 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 ] |
452 | 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 | |
460 | 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 ] |
467 | 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 ] |
475 | 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 ] |
483 | 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 | |
491 | 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 ] |
498 | 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 ] |
506 | 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 ] |
514 | 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 | |
522 | 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 ] |
529 | 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 ] |
537 | 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 ] |
545 | 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 | |
553 | 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 ] |
560 | 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 ] |
568 | 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 ] |
576 | 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 | |