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