typenum/
type_operators.rs

1//! Useful **type operators** that are not defined in `core::ops`.
2
3use 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/// ```
29pub trait Same<Rhs = Self> {
30    /// Should always be `Self`
31    type Output;
32}
33
34impl<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/// ```
46pub trait Abs {
47    /// The absolute value.
48    type Output;
49}
50
51impl Abs for Z0 {
52    type Output = Z0;
53}
54
55impl<U: Unsigned + NonZero> Abs for PInt<U> {
56    type Output = Self;
57}
58
59impl<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/// ```
71pub 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    /// ```
89    fn powi(self, exp: Exp) -> Self::Output;
90}
91
92macro_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
187impl_pow_f!(f32);
188impl_pow_f!(f64);
189
190macro_rules! impl_pow_i {
191    () => ();
192    ($(#[$meta:meta])*  $t: ty $(, $tail:tt)*) => (
193        $(#[$meta])*
194        impl Pow<UTerm> for $t {
195            type Output = $t;
196            #[inline]
197            fn powi(self, _: UTerm) -> Self::Output {
198                1
199            }
200        }
201
202        $(#[$meta])*
203        impl<U: Unsigned, B: Bit> Pow<UInt<U, B>> for $t {
204            type Output = $t;
205            #[inline]
206            fn powi(self, _: UInt<U, B>) -> Self::Output {
207                self.pow(<UInt<U, B> as Unsigned>::to_u32())
208            }
209        }
210
211        $(#[$meta])*
212        impl Pow<Z0> for $t {
213            type Output = $t;
214            #[inline]
215            fn powi(self, _: Z0) -> Self::Output {
216                1
217            }
218        }
219
220        $(#[$meta])*
221        impl<U: Unsigned + NonZero> Pow<PInt<U>> for $t {
222            type Output = $t;
223            #[inline]
224            fn powi(self, _: PInt<U>) -> Self::Output {
225                self.pow(U::to_u32())
226            }
227        }
228
229        impl_pow_i!($($tail),*);
230    );
231}
232
233impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize);
234#[cfg(feature = "i128")]
235impl_pow_i!(
236    #[cfg_attr(docsrs, doc(cfg(feature = "i128")))]
237    u128,
238    i128
239);
240
241#[test]
242fn pow_test() {
243    use crate::consts::*;
244    let z0 = Z0::new();
245    let p3 = P3::new();
246
247    let u0 = U0::new();
248    let u3 = U3::new();
249    let n3 = N3::new();
250
251    macro_rules! check {
252        ($x:ident) => {
253            assert_eq!($x.powi(z0), 1);
254            assert_eq!($x.powi(u0), 1);
255
256            assert_eq!($x.powi(p3), $x * $x * $x);
257            assert_eq!($x.powi(u3), $x * $x * $x);
258        };
259        ($x:ident, $f:ident) => {
260            assert!((<$f as Pow<Z0>>::powi(*$x, z0) - 1.0).abs() < ::core::$f::EPSILON);
261            assert!((<$f as Pow<U0>>::powi(*$x, u0) - 1.0).abs() < ::core::$f::EPSILON);
262
263            assert!((<$f as Pow<P3>>::powi(*$x, p3) - $x * $x * $x).abs() < ::core::$f::EPSILON);
264            assert!((<$f as Pow<U3>>::powi(*$x, u3) - $x * $x * $x).abs() < ::core::$f::EPSILON);
265
266            if *$x == 0.0 {
267                assert!(<$f as Pow<N3>>::powi(*$x, n3).is_infinite());
268            } else {
269                assert!(
270                    (<$f as Pow<N3>>::powi(*$x, n3) - 1. / $x / $x / $x).abs()
271                        < ::core::$f::EPSILON
272                );
273            }
274        };
275    }
276
277    for x in &[0i8, -3, 2] {
278        check!(x);
279    }
280    for x in &[0u8, 1, 5] {
281        check!(x);
282    }
283    for x in &[0usize, 1, 5, 40] {
284        check!(x);
285    }
286    for x in &[0isize, 1, 2, -30, -22, 48] {
287        check!(x);
288    }
289    for x in &[0.0f32, 2.2, -3.5, 378.223] {
290        check!(x, f32);
291    }
292    for x in &[0.0f64, 2.2, -3.5, -2387.2, 234.22] {
293        check!(x, f64);
294    }
295}
296
297/// A **type operator** for comparing `Self` and `Rhs`. It provides a similar functionality to
298/// the function
299/// [`core::cmp::Ord::cmp`](https://doc.rust-lang.org/nightly/core/cmp/trait.Ord.html#tymethod.cmp)
300/// but for types.
301///
302/// # Example
303/// ```rust
304/// use typenum::{Cmp, Ord, N3, P2, P5};
305/// use std::cmp::Ordering;
306///
307/// assert_eq!(<P2 as Cmp<N3>>::Output::to_ordering(), Ordering::Greater);
308/// assert_eq!(<P2 as Cmp<P2>>::Output::to_ordering(), Ordering::Equal);
309/// assert_eq!(<P2 as Cmp<P5>>::Output::to_ordering(), Ordering::Less);
310pub trait Cmp<Rhs = Self> {
311    /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`.
312    type Output;
313
314    #[doc(hidden)]
315    fn compare<IM: InternalMarker>(&self, _: &Rhs) -> Self::Output;
316}
317
318/// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`.
319pub trait Len {
320    /// The length as a type-level unsigned integer.
321    type Output: crate::Unsigned;
322    /// This function isn't used in this crate, but may be useful for others.
323    fn len(&self) -> Self::Output;
324}
325
326/// Division as a partial function. This **type operator** performs division just as `Div`, but is
327/// only defined when the result is an integer (i.e. there is no remainder).
328pub trait PartialDiv<Rhs = Self> {
329    /// The type of the result of the division
330    type Output;
331    /// Method for performing the division
332    fn partial_div(self, _: Rhs) -> Self::Output;
333}
334
335/// A **type operator** that returns the minimum of `Self` and `Rhs`.
336pub trait Min<Rhs = Self> {
337    /// The type of the minimum of `Self` and `Rhs`
338    type Output;
339    /// Method returning the minimum
340    fn min(self, rhs: Rhs) -> Self::Output;
341}
342
343/// A **type operator** that returns the maximum of `Self` and `Rhs`.
344pub trait Max<Rhs = Self> {
345    /// The type of the maximum of `Self` and `Rhs`
346    type Output;
347    /// Method returning the maximum
348    fn max(self, rhs: Rhs) -> Self::Output;
349}
350
351use crate::Compare;
352
353/// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`.
354pub trait IsLess<Rhs = Self> {
355    /// The type representing either `True` or `False`
356    type Output: Bit;
357    /// Method returning `True` or `False`.
358    fn is_less(self, rhs: Rhs) -> Self::Output;
359}
360
361use crate::private::IsLessPrivate;
362impl<A, B> IsLess<B> for A
363where
364    A: Cmp<B> + IsLessPrivate<B, Compare<A, B>>,
365{
366    type Output = <A as IsLessPrivate<B, Compare<A, B>>>::Output;
367
368    #[inline]
369    fn is_less(self, rhs: B) -> Self::Output {
370        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
371        self.is_less_private(rhs, lhs_cmp_rhs)
372    }
373}
374
375/// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`.
376pub trait IsEqual<Rhs = Self> {
377    /// The type representing either `True` or `False`
378    type Output: Bit;
379    /// Method returning `True` or `False`.
380    fn is_equal(self, rhs: Rhs) -> Self::Output;
381}
382
383use crate::private::IsEqualPrivate;
384impl<A, B> IsEqual<B> for A
385where
386    A: Cmp<B> + IsEqualPrivate<B, Compare<A, B>>,
387{
388    type Output = <A as IsEqualPrivate<B, Compare<A, B>>>::Output;
389
390    #[inline]
391    fn is_equal(self, rhs: B) -> Self::Output {
392        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
393        self.is_equal_private(rhs, lhs_cmp_rhs)
394    }
395}
396
397/// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`.
398pub trait IsGreater<Rhs = Self> {
399    /// The type representing either `True` or `False`
400    type Output: Bit;
401    /// Method returning `True` or `False`.
402    fn is_greater(self, rhs: Rhs) -> Self::Output;
403}
404
405use crate::private::IsGreaterPrivate;
406impl<A, B> IsGreater<B> for A
407where
408    A: Cmp<B> + IsGreaterPrivate<B, Compare<A, B>>,
409{
410    type Output = <A as IsGreaterPrivate<B, Compare<A, B>>>::Output;
411
412    #[inline]
413    fn is_greater(self, rhs: B) -> Self::Output {
414        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
415        self.is_greater_private(rhs, lhs_cmp_rhs)
416    }
417}
418
419/// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`.
420pub trait IsLessOrEqual<Rhs = Self> {
421    /// The type representing either `True` or `False`
422    type Output: Bit;
423    /// Method returning `True` or `False`.
424    fn is_less_or_equal(self, rhs: Rhs) -> Self::Output;
425}
426
427use crate::private::IsLessOrEqualPrivate;
428impl<A, B> IsLessOrEqual<B> for A
429where
430    A: Cmp<B> + IsLessOrEqualPrivate<B, Compare<A, B>>,
431{
432    type Output = <A as IsLessOrEqualPrivate<B, Compare<A, B>>>::Output;
433
434    #[inline]
435    fn is_less_or_equal(self, rhs: B) -> Self::Output {
436        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
437        self.is_less_or_equal_private(rhs, lhs_cmp_rhs)
438    }
439}
440
441/// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`.
442pub trait IsNotEqual<Rhs = Self> {
443    /// The type representing either `True` or `False`
444    type Output: Bit;
445    /// Method returning `True` or `False`.
446    fn is_not_equal(self, rhs: Rhs) -> Self::Output;
447}
448
449use crate::private::IsNotEqualPrivate;
450impl<A, B> IsNotEqual<B> for A
451where
452    A: Cmp<B> + IsNotEqualPrivate<B, Compare<A, B>>,
453{
454    type Output = <A as IsNotEqualPrivate<B, Compare<A, B>>>::Output;
455
456    #[inline]
457    fn is_not_equal(self, rhs: B) -> Self::Output {
458        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
459        self.is_not_equal_private(rhs, lhs_cmp_rhs)
460    }
461}
462
463/// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`.
464pub trait IsGreaterOrEqual<Rhs = Self> {
465    /// The type representing either `True` or `False`
466    type Output: Bit;
467    /// Method returning `True` or `False`.
468    fn is_greater_or_equal(self, rhs: Rhs) -> Self::Output;
469}
470
471use crate::private::IsGreaterOrEqualPrivate;
472impl<A, B> IsGreaterOrEqual<B> for A
473where
474    A: Cmp<B> + IsGreaterOrEqualPrivate<B, Compare<A, B>>,
475{
476    type Output = <A as IsGreaterOrEqualPrivate<B, Compare<A, B>>>::Output;
477
478    #[inline]
479    fn is_greater_or_equal(self, rhs: B) -> Self::Output {
480        let lhs_cmp_rhs = self.compare::<Internal>(&rhs);
481        self.is_greater_or_equal_private(rhs, lhs_cmp_rhs)
482    }
483}
484
485/**
486A convenience macro for comparing type numbers. Use `op!` instead.
487
488Due to the intricacies of the macro system, if the left-hand operand is more complex than a simple
489`ident`, you must place a comma between it and the comparison sign.
490
491For example, you can do `cmp!(P5 > P3)` or `cmp!(typenum::P5, > typenum::P3)` but not
492`cmp!(typenum::P5 > typenum::P3)`.
493
494The result of this comparison will always be one of `True` (aka `B1`) or `False` (aka `B0`).
495
496# Example
497```rust
498#[macro_use] extern crate typenum;
499use typenum::consts::*;
500use typenum::Bit;
501
502fn main() {
503type Result = cmp!(P9 == op!(P1 + P2 * (P2 - N2)));
504assert_eq!(Result::to_bool(), true);
505}
506```
507 */
508#[deprecated(since = "1.9.0", note = "use the `op!` macro instead")]
509#[macro_export]
510macro_rules! cmp {
511    ($a:ident < $b:ty) => {
512        <$a as $crate::IsLess<$b>>::Output
513    };
514    ($a:ty, < $b:ty) => {
515        <$a as $crate::IsLess<$b>>::Output
516    };
517
518    ($a:ident == $b:ty) => {
519        <$a as $crate::IsEqual<$b>>::Output
520    };
521    ($a:ty, == $b:ty) => {
522        <$a as $crate::IsEqual<$b>>::Output
523    };
524
525    ($a:ident > $b:ty) => {
526        <$a as $crate::IsGreater<$b>>::Output
527    };
528    ($a:ty, > $b:ty) => {
529        <$a as $crate::IsGreater<$b>>::Output
530    };
531
532    ($a:ident <= $b:ty) => {
533        <$a as $crate::IsLessOrEqual<$b>>::Output
534    };
535    ($a:ty, <= $b:ty) => {
536        <$a as $crate::IsLessOrEqual<$b>>::Output
537    };
538
539    ($a:ident != $b:ty) => {
540        <$a as $crate::IsNotEqual<$b>>::Output
541    };
542    ($a:ty, != $b:ty) => {
543        <$a as $crate::IsNotEqual<$b>>::Output
544    };
545
546    ($a:ident >= $b:ty) => {
547        <$a as $crate::IsGreaterOrEqual<$b>>::Output
548    };
549    ($a:ty, >= $b:ty) => {
550        <$a as $crate::IsGreaterOrEqual<$b>>::Output
551    };
552}
553
554/// A **type operator** for taking the integer square root of `Self`.
555///
556/// The integer square root of `n` is the largest integer `m` such
557/// that `n >= m*m`. This definition is equivalent to truncating the
558/// real-valued square root: `floor(real_sqrt(n))`.
559pub trait SquareRoot {
560    /// The result of the integer square root.
561    type Output;
562}
563
564/// A **type operator** for taking the integer binary logarithm of `Self`.
565///
566/// The integer binary logarighm of `n` is the largest integer `m` such
567/// that `n >= 2^m`. This definition is equivalent to truncating the
568/// real-valued binary logarithm: `floor(log2(n))`.
569pub trait Logarithm2 {
570    /// The result of the integer binary logarithm.
571    type Output;
572}
573
574/// A **type operator** that computes the [greatest common divisor][gcd] of `Self` and `Rhs`.
575///
576/// [gcd]: https://en.wikipedia.org/wiki/Greatest_common_divisor
577///
578/// # Example
579///
580/// ```rust
581/// use typenum::{Gcd, Unsigned, U12, U8};
582///
583/// assert_eq!(<U12 as Gcd<U8>>::Output::to_i32(), 4);
584/// ```
585pub trait Gcd<Rhs> {
586    /// The greatest common divisor.
587    type Output;
588}
589
590/// A **type operator** for taking a concrete integer value from a type.
591///
592/// It returns arbitrary integer value without explicitly specifying the
593/// type. It is useful when you pass the values to methods that accept
594/// distinct types without runtime casting.
595pub trait ToInt<T> {
596    /// Method returning the concrete value for the type.
597    fn to_int() -> T;
598    /// The concrete value for the type. Can be used in `const` contexts.
599    const INT: T;
600}