1 //! Useful **type operators** that are not defined in `core::ops`.
2 //!
3 
4 use {Bit, NInt, NonZero, PInt, UInt, UTerm, Unsigned, Z0};
5 
6 /// A **type operator** that ensures that `Rhs` is the same as `Self`, it is mainly useful
7 /// for writing macros that can take arbitrary binary or unary operators.
8 ///
9 /// `Same` is implemented generically for all types; it should never need to be implemented
10 /// for anything else.
11 ///
12 /// Note that Rust lazily evaluates types, so this will only fail for two different types if
13 /// the `Output` is used.
14 ///
15 /// # Example
16 /// ```rust
17 /// use typenum::{Same, U4, U5, Unsigned};
18 ///
19 /// assert_eq!(<U5 as Same<U5>>::Output::to_u32(), 5);
20 ///
21 /// // Only an error if we use it:
22 /// # #[allow(dead_code)]
23 /// type Undefined = <U5 as Same<U4>>::Output;
24 /// // Compiler error:
25 /// // Undefined::to_u32();
26 /// ```
27 pub trait Same<Rhs = Self> {
28     /// Should always be `Self`
29     type Output;
30 }
31 
32 impl<T> Same<T> for T {
33     type Output = T;
34 }
35 
36 /// A **type operator** that returns the absolute value.
37 ///
38 /// # Example
39 /// ```rust
40 /// use typenum::{Abs, N5, Integer};
41 ///
42 /// assert_eq!(<N5 as Abs>::Output::to_i32(), 5);
43 /// ```
44 pub trait Abs {
45     /// The absolute value.
46     type Output;
47 }
48 
49 impl Abs for Z0 {
50     type Output = Z0;
51 }
52 
53 impl<U: Unsigned + NonZero> Abs for PInt<U> {
54     type Output = Self;
55 }
56 
57 impl<U: Unsigned + NonZero> Abs for NInt<U> {
58     type Output = PInt<U>;
59 }
60 
61 /// A **type operator** that provides exponentiation by repeated squaring.
62 ///
63 /// # Example
64 /// ```rust
65 /// use typenum::{Pow, N3, P3, Integer};
66 ///
67 /// assert_eq!(<N3 as Pow<P3>>::Output::to_i32(), -27);
68 /// ```
69 pub trait Pow<Exp> {
70     /// The result of the exponentiation.
71     type Output;
72     /// This function isn't used in this crate, but may be useful for others.
73     /// It is implemented for primitives.
74     ///
75     /// # Example
76     /// ```rust
77     /// use typenum::{Pow, U3};
78     ///
79     /// let a = 7u32.powi(U3::new());
80     /// let b = 7u32.pow(3);
81     /// assert_eq!(a, b);
82     ///
83     /// let x = 3.0.powi(U3::new());
84     /// let y = 27.0;
85     /// assert_eq!(x, y);
86     /// ```
powi(self, exp: Exp) -> Self::Output87     fn powi(self, exp: Exp) -> Self::Output;
88 }
89 
90 macro_rules! impl_pow_f {
91     ($t:ty) => {
92         impl Pow<UTerm> for $t {
93             type Output = $t;
94             #[inline]
95             fn powi(self, _: UTerm) -> Self::Output {
96                 1.0
97             }
98         }
99 
100         impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
101             type Output = $t;
102             // powi is unstable in core, so we have to write this function ourselves.
103             // copied from num::pow::pow
104             #[inline]
105             fn powi(self, _: UInt<U, B>) -> Self::Output {
106                 let mut exp = <UInt<U, B> as Unsigned>::to_u32();
107                 let mut base = self;
108 
109                 if exp == 0 {
110                     return 1.0;
111                 }
112 
113                 while exp & 1 == 0 {
114                     base *= base;
115                     exp >>= 1;
116                 }
117                 if exp == 1 {
118                     return base;
119                 }
120 
121                 let mut acc = base.clone();
122                 while exp > 1 {
123                     exp >>= 1;
124                     base *= base;
125                     if exp & 1 == 1 {
126                         acc *= base.clone();
127                     }
128                 }
129                 acc
130             }
131         }
132 
133         impl Pow<Z0> for $t {
134             type Output = $t;
135             #[inline]
136             fn powi(self, _: Z0) -> Self::Output {
137                 1.0
138             }
139         }
140 
141         impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
142             type Output = $t;
143             // powi is unstable in core, so we have to write this function ourselves.
144             // copied from num::pow::pow
145             #[inline]
146             fn powi(self, _: PInt<U>) -> Self::Output {
147                 let mut exp = U::to_u32();
148                 let mut base = self;
149 
150                 if exp == 0 {
151                     return 1.0;
152                 }
153 
154                 while exp & 1 == 0 {
155                     base *= base;
156                     exp >>= 1;
157                 }
158                 if exp == 1 {
159                     return base;
160                 }
161 
162                 let mut acc = base.clone();
163                 while exp > 1 {
164                     exp >>= 1;
165                     base *= base;
166                     if exp & 1 == 1 {
167                         acc *= base.clone();
168                     }
169                 }
170                 acc
171             }
172         }
173     };
174 }
175 
176 impl_pow_f!(f32);
177 impl_pow_f!(f64);
178 
179 macro_rules! impl_pow_i {
180     () => ();
181     ($t: ty $(, $tail:tt)*) => (
182         impl Pow<UTerm> for $t {
183             type Output = $t;
184             #[inline]
185             fn powi(self, _: UTerm) -> Self::Output {
186                 1
187             }
188         }
189 
190         impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
191             type Output = $t;
192             #[inline]
193             fn powi(self, _: UInt<U, B>) -> Self::Output {
194                 self.pow(<UInt<U, B> as Unsigned>::to_u32())
195             }
196         }
197 
198         impl Pow<Z0> for $t {
199             type Output = $t;
200             #[inline]
201             fn powi(self, _: Z0) -> Self::Output {
202                 1
203             }
204         }
205 
206         impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
207             type Output = $t;
208             #[inline]
209             fn powi(self, _: PInt<U>) -> Self::Output {
210                 self.pow(U::to_u32())
211             }
212         }
213 
214         impl_pow_i!($($tail),*);
215     );
216 }
217 
218 impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
219 #[cfg(feature = "i128")]
220 impl_pow_i!(u128, i128);
221 
222 #[test]
pow_test()223 fn pow_test() {
224     use consts::*;
225     let z0 = Z0::new();
226     let p3 = P3::new();
227 
228     let u0 = U0::new();
229     let u3 = U3::new();
230 
231     macro_rules! check {
232         ($x:ident) => {
233             assert_eq!($x.powi(z0), 1);
234             assert_eq!($x.powi(u0), 1);
235 
236             assert_eq!($x.powi(p3), $x * $x * $x);
237             assert_eq!($x.powi(u3), $x * $x * $x);
238         };
239         ($x:ident, $f:ident) => {
240             assert!((<$f as Pow<Z0>>::powi(*$x, z0) - 1.0).abs() < ::core::$f::EPSILON);
241             assert!((<$f as Pow<U0>>::powi(*$x, u0) - 1.0).abs() < ::core::$f::EPSILON);
242 
243             assert!((<$f as Pow<P3>>::powi(*$x, p3) - $x * $x * $x).abs() < ::core::$f::EPSILON);
244             assert!((<$f as Pow<U3>>::powi(*$x, u3) - $x * $x * $x).abs() < ::core::$f::EPSILON);
245         };
246     }
247 
248     for x in &[0i8, -3, 2] {
249         check!(x);
250     }
251     for x in &[0u8, 1, 5] {
252         check!(x);
253     }
254     for x in &[0usize, 1, 5, 40] {
255         check!(x);
256     }
257     for x in &[0isize, 1, 2, -30, -22, 48] {
258         check!(x);
259     }
260     for x in &[0.0f32, 2.2, -3.5, 378.223] {
261         check!(x, f32);
262     }
263     for x in &[0.0f64, 2.2, -3.5, -2387.2, 234.22] {
264         check!(x, f64);
265     }
266 }
267 
268 /// A **type operator** for comparing `Self` and `Rhs`. It provides a similar functionality to
269 /// the function
270 /// [`core::cmp::Ord::cmp`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html#tymethod.cmp)
271 /// but for types.
272 ///
273 /// # Example
274 /// ```rust
275 /// use typenum::{Cmp, Ord, N3, P2, P5};
276 /// use std::cmp::Ordering;
277 ///
278 /// assert_eq!(<P2 as Cmp<N3>>::Output::to_ordering(), Ordering::Greater);
279 /// assert_eq!(<P2 as Cmp<P2>>::Output::to_ordering(), Ordering::Equal);
280 /// assert_eq!(<P2 as Cmp<P5>>::Output::to_ordering(), Ordering::Less);
281 pub trait Cmp<Rhs = Self> {
282     /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`.
283     type Output;
284 }
285 
286 /// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`.
287 pub trait Len {
288     /// The length as a type-level unsigned integer.
289     type Output: ::Unsigned;
290     /// This function isn't used in this crate, but may be useful for others.
len(&self) -> Self::Output291     fn len(&self) -> Self::Output;
292 }
293 
294 /// Division as a partial function. This **type operator** performs division just as `Div`, but is
295 /// only defined when the result is an integer (i.e. there is no remainder).
296 pub trait PartialDiv<Rhs = Self> {
297     /// The type of the result of the division
298     type Output;
299     /// Method for performing the division
partial_div(self, _: Rhs) -> Self::Output300     fn partial_div(self, _: Rhs) -> Self::Output;
301 }
302 
303 /// A **type operator** that returns the minimum of `Self` and `Rhs`.
304 pub trait Min<Rhs = Self> {
305     /// The type of the minimum of `Self` and `Rhs`
306     type Output;
307     /// Method returning the minimum
min(self, rhs: Rhs) -> Self::Output308     fn min(self, rhs: Rhs) -> Self::Output;
309 }
310 
311 /// A **type operator** that returns the maximum of `Self` and `Rhs`.
312 pub trait Max<Rhs = Self> {
313     /// The type of the maximum of `Self` and `Rhs`
314     type Output;
315     /// Method returning the maximum
max(self, rhs: Rhs) -> Self::Output316     fn max(self, rhs: Rhs) -> Self::Output;
317 }
318 
319 use Compare;
320 
321 /// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`.
322 pub trait IsLess<Rhs = Self> {
323     /// The type representing either `True` or `False`
324     type Output: Bit;
325     /// Method returning `True` or `False`.
is_less(self, rhs: Rhs) -> Self::Output326     fn is_less(self, rhs: Rhs) -> Self::Output;
327 }
328 
329 use private::IsLessPrivate;
330 impl<A, B> IsLess<B> for A
331 where
332     A: Cmp<B> + IsLessPrivate<B, Compare<A, B>>,
333 {
334     type Output = <A as IsLessPrivate<B, Compare<A, B>>>::Output;
335 
is_less(self, _: B) -> Self::Output336     fn is_less(self, _: B) -> Self::Output {
337         unsafe { ::core::mem::uninitialized() }
338     }
339 }
340 
341 /// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`.
342 pub trait IsEqual<Rhs = Self> {
343     /// The type representing either `True` or `False`
344     type Output: Bit;
345     /// Method returning `True` or `False`.
is_equal(self, rhs: Rhs) -> Self::Output346     fn is_equal(self, rhs: Rhs) -> Self::Output;
347 }
348 
349 use private::IsEqualPrivate;
350 impl<A, B> IsEqual<B> for A
351 where
352     A: Cmp<B> + IsEqualPrivate<B, Compare<A, B>>,
353 {
354     type Output = <A as IsEqualPrivate<B, Compare<A, B>>>::Output;
355 
is_equal(self, _: B) -> Self::Output356     fn is_equal(self, _: B) -> Self::Output {
357         unsafe { ::core::mem::uninitialized() }
358     }
359 }
360 
361 /// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`.
362 pub trait IsGreater<Rhs = Self> {
363     /// The type representing either `True` or `False`
364     type Output: Bit;
365     /// Method returning `True` or `False`.
is_greater(self, rhs: Rhs) -> Self::Output366     fn is_greater(self, rhs: Rhs) -> Self::Output;
367 }
368 
369 use private::IsGreaterPrivate;
370 impl<A, B> IsGreater<B> for A
371 where
372     A: Cmp<B> + IsGreaterPrivate<B, Compare<A, B>>,
373 {
374     type Output = <A as IsGreaterPrivate<B, Compare<A, B>>>::Output;
375 
is_greater(self, _: B) -> Self::Output376     fn is_greater(self, _: B) -> Self::Output {
377         unsafe { ::core::mem::uninitialized() }
378     }
379 }
380 
381 /// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`.
382 pub trait IsLessOrEqual<Rhs = Self> {
383     /// The type representing either `True` or `False`
384     type Output: Bit;
385     /// Method returning `True` or `False`.
is_less_or_equal(self, rhs: Rhs) -> Self::Output386     fn is_less_or_equal(self, rhs: Rhs) -> Self::Output;
387 }
388 
389 use private::IsLessOrEqualPrivate;
390 impl<A, B> IsLessOrEqual<B> for A
391 where
392     A: Cmp<B> + IsLessOrEqualPrivate<B, Compare<A, B>>,
393 {
394     type Output = <A as IsLessOrEqualPrivate<B, Compare<A, B>>>::Output;
395 
is_less_or_equal(self, _: B) -> Self::Output396     fn is_less_or_equal(self, _: B) -> Self::Output {
397         unsafe { ::core::mem::uninitialized() }
398     }
399 }
400 
401 /// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`.
402 pub trait IsNotEqual<Rhs = Self> {
403     /// The type representing either `True` or `False`
404     type Output: Bit;
405     /// Method returning `True` or `False`.
is_not_equal(self, rhs: Rhs) -> Self::Output406     fn is_not_equal(self, rhs: Rhs) -> Self::Output;
407 }
408 
409 use private::IsNotEqualPrivate;
410 impl<A, B> IsNotEqual<B> for A
411 where
412     A: Cmp<B> + IsNotEqualPrivate<B, Compare<A, B>>,
413 {
414     type Output = <A as IsNotEqualPrivate<B, Compare<A, B>>>::Output;
415 
is_not_equal(self, _: B) -> Self::Output416     fn is_not_equal(self, _: B) -> Self::Output {
417         unsafe { ::core::mem::uninitialized() }
418     }
419 }
420 
421 /// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`.
422 pub trait IsGreaterOrEqual<Rhs = Self> {
423     /// The type representing either `True` or `False`
424     type Output: Bit;
425     /// Method returning `True` or `False`.
is_greater_or_equal(self, rhs: Rhs) -> Self::Output426     fn is_greater_or_equal(self, rhs: Rhs) -> Self::Output;
427 }
428 
429 use private::IsGreaterOrEqualPrivate;
430 impl<A, B> IsGreaterOrEqual<B> for A
431 where
432     A: Cmp<B> + IsGreaterOrEqualPrivate<B, Compare<A, B>>,
433 {
434     type Output = <A as IsGreaterOrEqualPrivate<B, Compare<A, B>>>::Output;
435 
is_greater_or_equal(self, _: B) -> Self::Output436     fn is_greater_or_equal(self, _: B) -> Self::Output {
437         unsafe { ::core::mem::uninitialized() }
438     }
439 }
440 
441 /**
442 A convenience macro for comparing type numbers. Use `op!` instead.
443 
444 Due to the intricacies of the macro system, if the left-hand operand is more complex than a simple
445 `ident`, you must place a comma between it and the comparison sign.
446 
447 For example, you can do `cmp!(P5 > P3)` or `cmp!(typenum::P5, > typenum::P3)` but not
448 `cmp!(typenum::P5 > typenum::P3)`.
449 
450 The result of this comparison will always be one of `True` (aka `B1`) or `False` (aka `B0`).
451 
452 # Example
453 ```rust
454 #[macro_use] extern crate typenum;
455 use typenum::consts::*;
456 use typenum::Bit;
457 
458 fn main() {
459 type Result = cmp!(P9 == op!(P1 + P2 * (P2 - N2)));
460 assert_eq!(Result::to_bool(), true);
461 }
462 ```
463  */
464 #[deprecated(since = "1.9.0", note = "use the `op!` macro instead")]
465 #[macro_export]
466 macro_rules! cmp {
467     ($a:ident < $b:ty) => {
468         <$a as $crate::IsLess<$b>>::Output
469     };
470     ($a:ty, < $b:ty) => {
471         <$a as $crate::IsLess<$b>>::Output
472     };
473 
474     ($a:ident == $b:ty) => {
475         <$a as $crate::IsEqual<$b>>::Output
476     };
477     ($a:ty, == $b:ty) => {
478         <$a as $crate::IsEqual<$b>>::Output
479     };
480 
481     ($a:ident > $b:ty) => {
482         <$a as $crate::IsGreater<$b>>::Output
483     };
484     ($a:ty, > $b:ty) => {
485         <$a as $crate::IsGreater<$b>>::Output
486     };
487 
488     ($a:ident <= $b:ty) => {
489         <$a as $crate::IsLessOrEqual<$b>>::Output
490     };
491     ($a:ty, <= $b:ty) => {
492         <$a as $crate::IsLessOrEqual<$b>>::Output
493     };
494 
495     ($a:ident != $b:ty) => {
496         <$a as $crate::IsNotEqual<$b>>::Output
497     };
498     ($a:ty, != $b:ty) => {
499         <$a as $crate::IsNotEqual<$b>>::Output
500     };
501 
502     ($a:ident >= $b:ty) => {
503         <$a as $crate::IsGreaterOrEqual<$b>>::Output
504     };
505     ($a:ty, >= $b:ty) => {
506         <$a as $crate::IsGreaterOrEqual<$b>>::Output
507     };
508 }
509 
510 /// A **type operator** for taking the integer square root of `Self`.
511 ///
512 /// The integer square root of `n` is the largest integer `m` such
513 /// that `n >= m*m`. This definition is equivalent to truncating the
514 /// real-valued square root: `floor(real_sqrt(n))`.
515 pub trait SquareRoot {
516     /// The result of the integer square root.
517     type Output;
518 }
519 
520 /// A **type operator** for taking the integer binary logarithm of `Self`.
521 ///
522 /// The integer binary logarighm of `n` is the largest integer `m` such
523 /// that `n >= 2^m`. This definition is equivalent to truncating the
524 /// real-valued binary logarithm: `floor(log2(n))`.
525 pub trait Logarithm2 {
526     /// The result of the integer binary logarithm.
527     type Output;
528 }
529