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
22 #![doc(hidden)]
23
24 // use ::{Sub};
25 use bit::{Bit, B0, B1};
26 use uint::{UInt, UTerm, Unsigned};
27
28 /// Convenience trait. Calls `Invert` -> `TrimTrailingZeros` -> `Invert`
29 pub trait Trim {
30 type Output;
31 }
32 pub type TrimOut<A> = <A as Trim>::Output;
33
34 /// Gets rid of all zeros until it hits a one.
35
36 // ONLY IMPLEMENT FOR INVERTED NUMBERS!
37 pub trait TrimTrailingZeros {
38 type Output;
39 }
40 pub type TrimTrailingZerosOut<A> = <A as TrimTrailingZeros>::Output;
41
42 /// Converts between standard numbers and inverted ones that have the most significant
43 /// digit on the outside.
44 pub trait Invert {
45 type Output;
46 }
47 pub type InvertOut<A> = <A as Invert>::Output;
48
49 /// Doubly private! Called by invert to make the magic happen once its done the first step.
50 /// The Rhs is what we've got so far.
51 pub trait PrivateInvert<Rhs> {
52 type Output;
53 }
54 pub type PrivateInvertOut<A, Rhs> = <A as PrivateInvert<Rhs>>::Output;
55
56 /// Terminating character for `InvertedUInt`s
57 pub enum InvertedUTerm {}
58
59 /// Inverted `UInt` (has most significant digit on the outside)
60 pub struct InvertedUInt<IU: InvertedUnsigned, B: Bit> {
61 _marker: (IU, B),
62 }
63
64 /// Does the real anding for `UInt`s; `And` just calls this and then `Trim`.
65 pub trait PrivateAnd<Rhs = Self> {
66 type Output;
67 }
68 pub type PrivateAndOut<A, Rhs> = <A as PrivateAnd<Rhs>>::Output;
69
70 /// Does the real xoring for `UInt`s; `Xor` just calls this and then `Trim`.
71 pub trait PrivateXor<Rhs = Self> {
72 type Output;
73 }
74 pub type PrivateXorOut<A, Rhs> = <A as PrivateXor<Rhs>>::Output;
75
76 /// Does the real subtraction for `UInt`s; `Sub` just calls this and then `Trim`.
77 pub trait PrivateSub<Rhs = Self> {
78 type Output;
79 }
80 pub type PrivateSubOut<A, Rhs> = <A as PrivateSub<Rhs>>::Output;
81
82 /// Used for addition of signed integers; `C = P.cmp(N)`
83 /// Assumes `P = Self` is positive and `N` is negative
84 /// where `P` and `N` are both passed as unsigned integers
85 pub trait PrivateIntegerAdd<C, N> {
86 type Output;
87 }
88 pub type PrivateIntegerAddOut<P, C, N> = <P as PrivateIntegerAdd<C, N>>::Output;
89
90 pub trait PrivatePow<Y, N> {
91 type Output;
92 }
93 pub type PrivatePowOut<A, Y, N> = <A as PrivatePow<Y, N>>::Output;
94
95 /// Performs `Shl` on `Lhs` so that `SizeOf(Lhs) = SizeOf(Rhs)`
96 /// Fails if `SizeOf(Lhs) > SizeOf(Rhs)`
97 pub trait ShiftDiff<Rhs> {
98 type Output;
99 }
100 pub type ShiftDiffOut<A, Rhs> = <A as ShiftDiff<Rhs>>::Output;
101
102 /// Gives `SizeOf(Lhs) - SizeOf(Rhs)`
103 pub trait BitDiff<Rhs> {
104 type Output;
105 }
106 pub type BitDiffOut<A, Rhs> = <A as BitDiff<Rhs>>::Output;
107
108 /// Inverted unsigned numbers
109 pub trait InvertedUnsigned {
to_u64() -> u64110 fn to_u64() -> u64;
111 }
112
113 impl InvertedUnsigned for InvertedUTerm {
to_u64() -> u64114 fn to_u64() -> u64 {
115 0
116 }
117 }
118
119 impl<IU: InvertedUnsigned, B: Bit> InvertedUnsigned for InvertedUInt<IU, B> {
to_u64() -> u64120 fn to_u64() -> u64 {
121 u64::from(B::to_u8()) | IU::to_u64() << 1
122 }
123 }
124
125 impl Invert for UTerm {
126 type Output = InvertedUTerm;
127 }
128
129 impl<U: Unsigned, B: Bit> Invert for UInt<U, B>
130 where
131 U: PrivateInvert<InvertedUInt<InvertedUTerm, B>>,
132 {
133 type Output = PrivateInvertOut<U, InvertedUInt<InvertedUTerm, B>>;
134 }
135
136 impl<IU: InvertedUnsigned> PrivateInvert<IU> for UTerm {
137 type Output = IU;
138 }
139
140 impl<IU: InvertedUnsigned, U: Unsigned, B: Bit> PrivateInvert<IU> for UInt<U, B>
141 where
142 U: PrivateInvert<InvertedUInt<IU, B>>,
143 {
144 type Output = PrivateInvertOut<U, InvertedUInt<IU, B>>;
145 }
146
147 #[test]
test_inversion()148 fn test_inversion() {
149 type Test4 = <::consts::U4 as Invert>::Output;
150 type Test5 = <::consts::U5 as Invert>::Output;
151 type Test12 = <::consts::U12 as Invert>::Output;
152 type Test16 = <::consts::U16 as Invert>::Output;
153
154 assert_eq!(1, <Test4 as InvertedUnsigned>::to_u64());
155 assert_eq!(5, <Test5 as InvertedUnsigned>::to_u64());
156 assert_eq!(3, <Test12 as InvertedUnsigned>::to_u64());
157 assert_eq!(1, <Test16 as InvertedUnsigned>::to_u64());
158 }
159
160 impl Invert for InvertedUTerm {
161 type Output = UTerm;
162 }
163
164 impl<IU: InvertedUnsigned, B: Bit> Invert for InvertedUInt<IU, B>
165 where
166 IU: PrivateInvert<UInt<UTerm, B>>,
167 {
168 type Output = <IU as PrivateInvert<UInt<UTerm, B>>>::Output;
169 }
170
171 impl<U: Unsigned> PrivateInvert<U> for InvertedUTerm {
172 type Output = U;
173 }
174
175 impl<U: Unsigned, IU: InvertedUnsigned, B: Bit> PrivateInvert<U> for InvertedUInt<IU, B>
176 where
177 IU: PrivateInvert<UInt<U, B>>,
178 {
179 type Output = <IU as PrivateInvert<UInt<U, B>>>::Output;
180 }
181
182 #[test]
test_double_inversion()183 fn test_double_inversion() {
184 type Test4 = <<::consts::U4 as Invert>::Output as Invert>::Output;
185 type Test5 = <<::consts::U5 as Invert>::Output as Invert>::Output;
186 type Test12 = <<::consts::U12 as Invert>::Output as Invert>::Output;
187 type Test16 = <<::consts::U16 as Invert>::Output as Invert>::Output;
188
189 assert_eq!(4, <Test4 as Unsigned>::to_u64());
190 assert_eq!(5, <Test5 as Unsigned>::to_u64());
191 assert_eq!(12, <Test12 as Unsigned>::to_u64());
192 assert_eq!(16, <Test16 as Unsigned>::to_u64());
193 }
194
195 impl TrimTrailingZeros for InvertedUTerm {
196 type Output = InvertedUTerm;
197 }
198
199 impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B1> {
200 type Output = Self;
201 }
202
203 impl<IU: InvertedUnsigned> TrimTrailingZeros for InvertedUInt<IU, B0>
204 where
205 IU: TrimTrailingZeros,
206 {
207 type Output = <IU as TrimTrailingZeros>::Output;
208 }
209
210 impl<U: Unsigned> Trim for U
211 where
212 U: Invert,
213 <U as Invert>::Output: TrimTrailingZeros,
214 <<U as Invert>::Output as TrimTrailingZeros>::Output: Invert,
215 {
216 type Output = <<<U as Invert>::Output as TrimTrailingZeros>::Output as Invert>::Output;
217 }
218
219 // Note: Trimming is tested when we do subtraction.
220
221 pub trait PrivateCmp<Rhs, SoFar> {
222 type Output;
223 }
224 pub type PrivateCmpOut<A, Rhs, SoFar> = <A as PrivateCmp<Rhs, SoFar>>::Output;
225
226 // Set Bit
227 pub trait PrivateSetBit<I, B> {
228 type Output;
229 }
230 pub type PrivateSetBitOut<N, I, B> = <N as PrivateSetBit<I, B>>::Output;
231
232 // Div
233 pub trait PrivateDiv<N, D, Q, R, I> {
234 type Quotient;
235 type Remainder;
236 }
237
238 pub type PrivateDivQuot<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Quotient;
239 pub type PrivateDivRem<N, D, Q, R, I> = <() as PrivateDiv<N, D, Q, R, I>>::Remainder;
240
241 pub trait PrivateDivIf<N, D, Q, R, I, RcmpD> {
242 type Quotient;
243 type Remainder;
244 }
245
246 pub type PrivateDivIfQuot<N, D, Q, R, I, RcmpD> =
247 <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Quotient;
248 pub type PrivateDivIfRem<N, D, Q, R, I, RcmpD> =
249 <() as PrivateDivIf<N, D, Q, R, I, RcmpD>>::Remainder;
250
251 // Div for signed ints
252 pub trait PrivateDivInt<C, Divisor> {
253 type Output;
254 }
255 pub type PrivateDivIntOut<A, C, Divisor> = <A as PrivateDivInt<C, Divisor>>::Output;
256
257 pub trait PrivateRem<URem, Divisor> {
258 type Output;
259 }
260 pub type PrivateRemOut<A, URem, Divisor> = <A as PrivateRem<URem, Divisor>>::Output;
261
262 // min max
263 pub trait PrivateMin<Rhs, CmpResult> {
264 type Output;
private_min(self, rhs: Rhs) -> Self::Output265 fn private_min(self, rhs: Rhs) -> Self::Output;
266 }
267 pub type PrivateMinOut<A, B, CmpResult> = <A as PrivateMin<B, CmpResult>>::Output;
268
269 pub trait PrivateMax<Rhs, CmpResult> {
270 type Output;
private_max(self, rhs: Rhs) -> Self::Output271 fn private_max(self, rhs: Rhs) -> Self::Output;
272 }
273 pub type PrivateMaxOut<A, B, CmpResult> = <A as PrivateMax<B, CmpResult>>::Output;
274
275 // Comparisons
276
277 use {Equal, False, Greater, Less, True};
278
279 pub trait IsLessPrivate<Rhs, Cmp> {
280 type Output: Bit;
281 }
282
283 impl<A, B> IsLessPrivate<B, Less> for A {
284 type Output = True;
285 }
286 impl<A, B> IsLessPrivate<B, Equal> for A {
287 type Output = False;
288 }
289 impl<A, B> IsLessPrivate<B, Greater> for A {
290 type Output = False;
291 }
292
293 pub trait IsEqualPrivate<Rhs, Cmp> {
294 type Output: Bit;
295 }
296
297 impl<A, B> IsEqualPrivate<B, Less> for A {
298 type Output = False;
299 }
300 impl<A, B> IsEqualPrivate<B, Equal> for A {
301 type Output = True;
302 }
303 impl<A, B> IsEqualPrivate<B, Greater> for A {
304 type Output = False;
305 }
306
307 pub trait IsGreaterPrivate<Rhs, Cmp> {
308 type Output: Bit;
309 }
310
311 impl<A, B> IsGreaterPrivate<B, Less> for A {
312 type Output = False;
313 }
314 impl<A, B> IsGreaterPrivate<B, Equal> for A {
315 type Output = False;
316 }
317 impl<A, B> IsGreaterPrivate<B, Greater> for A {
318 type Output = True;
319 }
320
321 pub trait IsLessOrEqualPrivate<Rhs, Cmp> {
322 type Output: Bit;
323 }
324
325 impl<A, B> IsLessOrEqualPrivate<B, Less> for A {
326 type Output = True;
327 }
328 impl<A, B> IsLessOrEqualPrivate<B, Equal> for A {
329 type Output = True;
330 }
331 impl<A, B> IsLessOrEqualPrivate<B, Greater> for A {
332 type Output = False;
333 }
334
335 pub trait IsNotEqualPrivate<Rhs, Cmp> {
336 type Output: Bit;
337 }
338
339 impl<A, B> IsNotEqualPrivate<B, Less> for A {
340 type Output = True;
341 }
342 impl<A, B> IsNotEqualPrivate<B, Equal> for A {
343 type Output = False;
344 }
345 impl<A, B> IsNotEqualPrivate<B, Greater> for A {
346 type Output = True;
347 }
348
349 pub trait IsGreaterOrEqualPrivate<Rhs, Cmp> {
350 type Output: Bit;
351 }
352
353 impl<A, B> IsGreaterOrEqualPrivate<B, Less> for A {
354 type Output = False;
355 }
356 impl<A, B> IsGreaterOrEqualPrivate<B, Equal> for A {
357 type Output = True;
358 }
359 impl<A, B> IsGreaterOrEqualPrivate<B, Greater> for A {
360 type Output = True;
361 }
362
363 pub trait PrivateSquareRoot {
364 type Output;
365 }
366
367 pub trait PrivateLogarithm2 {
368 type Output;
369 }
370