1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
//! This module provides useful **type operators** that are not defined in `core`. //! //! /// A **type operator** that ensures that `Rhs` is the same as `Self`, it is mainly useful /// for writing macros that can take arbitrary binary or unary operators. /// /// `Same` is implemented generically for all types; it should never need to be implemented /// for anything else. /// /// Note that Rust lazily evaluates types, so this will only fail for two different types if /// the `Output` is used. /// /// # Example /// ```rust /// use typenum::{Same, U4, U5, Unsigned}; /// /// assert_eq!(<U5 as Same<U5>>::Output::to_u32(), 5); /// /// // Only an error if we use it: /// type Undefined = <U5 as Same<U4>>::Output; /// // Compiler error: /// // Undefined::to_u32(); /// ``` pub trait Same<Rhs = Self> { /// Should always be `Self` type Output; } impl<T> Same<T> for T { type Output = T; } /// A **type operator** that provides exponentiation by repeated squaring. /// /// # Example /// ```rust /// use typenum::{Pow, N3, P3, Integer}; /// /// assert_eq!(<N3 as Pow<P3>>::Output::to_i32(), -27); /// ``` pub trait Pow<Exp> { /// The result of the exponentiation. type Output; /// This function isn't used in this crate, but may be useful for others. /// It is implemented for primitives. /// /// # Example /// ```rust /// use typenum::{Pow, U3}; /// /// let a = 7u32.powi(U3::new()); /// let b = 7u32.pow(3); /// assert_eq!(a, b); /// /// let x = 3.0.powi(U3::new()); /// let y = 27.0; /// assert_eq!(x, y); /// ``` fn powi(self, exp: Exp) -> Self::Output; } use Unsigned; macro_rules! impl_pow_f { ($t: ty) => ( impl<Exp: Unsigned> Pow<Exp> for $t { type Output = $t; // powi is unstable in core, so we have to write this function ourselves. // copied from num::pow::pow #[inline] fn powi(self, _: Exp) -> Self::Output { let mut exp = Exp::to_u32(); let mut base = self; if exp == 0 { return 1.0 } while exp & 1 == 0 { base *= base; exp >>= 1; } if exp == 1 { return base } let mut acc = base.clone(); while exp > 1 { exp >>= 1; base *= base; if exp & 1 == 1 { acc *= base.clone(); } } acc } } ); } impl_pow_f!(f32); impl_pow_f!(f64); macro_rules! impl_pow_i { () => (); ($t: ty $(, $tail:tt)*) => ( impl<Exp: Unsigned> Pow<Exp> for $t { type Output = $t; #[inline] fn powi(self, _: Exp) -> Self::Output { self.pow(Exp::to_u32()) } } impl_pow_i!($($tail),*); ); } impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); /// A **type operator** for comparing `Self` and `Rhs`. It provides a similar functionality to /// the function /// [`core::cmp::Ord::cmp`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html#tymethod.cmp) /// but for types. /// /// # Example /// ```rust /// use typenum::{Cmp, Ord, Greater, Less, Equal, N3, P2, P5}; /// use std::cmp::Ordering; /// /// assert_eq!(<P2 as Cmp<N3>>::Output::to_ordering(), Ordering::Greater); /// assert_eq!(<P2 as Cmp<P2>>::Output::to_ordering(), Ordering::Equal); /// assert_eq!(<P2 as Cmp<P5>>::Output::to_ordering(), Ordering::Less); pub trait Cmp<Rhs = Self> { /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`. type Output; } /// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`. pub trait Len { /// The length as a type-level unsigned integer. type Output: ::Unsigned; /// This function isn't used in this crate, but may be useful for others. fn len(&self) -> Self::Output; }