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