From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/typenum/src/type_operators.rs | 590 +++++++++++++++++++++++++++++++++++ 1 file changed, 590 insertions(+) create mode 100644 vendor/typenum/src/type_operators.rs (limited to 'vendor/typenum/src/type_operators.rs') diff --git a/vendor/typenum/src/type_operators.rs b/vendor/typenum/src/type_operators.rs new file mode 100644 index 000000000..50b558b4f --- /dev/null +++ b/vendor/typenum/src/type_operators.rs @@ -0,0 +1,590 @@ +//! Useful **type operators** that are not defined in `core::ops`. + +use crate::{ + private::{Internal, InternalMarker}, + Bit, NInt, NonZero, PInt, UInt, UTerm, Unsigned, Z0, +}; + +/// 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, Unsigned, U4, U5}; +/// +/// assert_eq!(>::Output::to_u32(), 5); +/// +/// // Only an error if we use it: +/// # #[allow(dead_code)] +/// type Undefined = >::Output; +/// // Compiler error: +/// // Undefined::to_u32(); +/// ``` +pub trait Same { + /// Should always be `Self` + type Output; +} + +impl Same for T { + type Output = T; +} + +/// A **type operator** that returns the absolute value. +/// +/// # Example +/// ```rust +/// use typenum::{Abs, Integer, N5}; +/// +/// assert_eq!(::Output::to_i32(), 5); +/// ``` +pub trait Abs { + /// The absolute value. + type Output; +} + +impl Abs for Z0 { + type Output = Z0; +} + +impl Abs for PInt { + type Output = Self; +} + +impl Abs for NInt { + type Output = PInt; +} + +/// A **type operator** that provides exponentiation by repeated squaring. +/// +/// # Example +/// ```rust +/// use typenum::{Integer, Pow, N3, P3}; +/// +/// assert_eq!(>::Output::to_i32(), -27); +/// ``` +pub trait Pow { + /// 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; +} + +macro_rules! impl_pow_f { + ($t:ty) => { + impl Pow for $t { + type Output = $t; + #[inline] + fn powi(self, _: UTerm) -> Self::Output { + 1.0 + } + } + + impl Pow> 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, _: UInt) -> Self::Output { + let mut exp = as Unsigned>::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 for $t { + type Output = $t; + #[inline] + fn powi(self, _: Z0) -> Self::Output { + 1.0 + } + } + + impl Pow> 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, _: PInt) -> Self::Output { + let mut exp = U::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> for $t { + type Output = $t; + + #[inline] + fn powi(self, _: NInt) -> Self::Output { + <$t as Pow>>::powi(self, PInt::new()).recip() + } + } + }; +} + +impl_pow_f!(f32); +impl_pow_f!(f64); + +macro_rules! impl_pow_i { + () => (); + ($t: ty $(, $tail:tt)*) => ( + impl Pow for $t { + type Output = $t; + #[inline] + fn powi(self, _: UTerm) -> Self::Output { + 1 + } + } + + impl Pow> for $t { + type Output = $t; + #[inline] + fn powi(self, _: UInt) -> Self::Output { + self.pow( as Unsigned>::to_u32()) + } + } + + impl Pow for $t { + type Output = $t; + #[inline] + fn powi(self, _: Z0) -> Self::Output { + 1 + } + } + + impl Pow> for $t { + type Output = $t; + #[inline] + fn powi(self, _: PInt) -> Self::Output { + self.pow(U::to_u32()) + } + } + + impl_pow_i!($($tail),*); + ); +} + +impl_pow_i!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); +#[cfg(feature = "i128")] +impl_pow_i!(u128, i128); + +#[test] +fn pow_test() { + use crate::consts::*; + let z0 = Z0::new(); + let p3 = P3::new(); + + let u0 = U0::new(); + let u3 = U3::new(); + let n3 = N3::new(); + + macro_rules! check { + ($x:ident) => { + assert_eq!($x.powi(z0), 1); + assert_eq!($x.powi(u0), 1); + + assert_eq!($x.powi(p3), $x * $x * $x); + assert_eq!($x.powi(u3), $x * $x * $x); + }; + ($x:ident, $f:ident) => { + assert!((<$f as Pow>::powi(*$x, z0) - 1.0).abs() < ::core::$f::EPSILON); + assert!((<$f as Pow>::powi(*$x, u0) - 1.0).abs() < ::core::$f::EPSILON); + + assert!((<$f as Pow>::powi(*$x, p3) - $x * $x * $x).abs() < ::core::$f::EPSILON); + assert!((<$f as Pow>::powi(*$x, u3) - $x * $x * $x).abs() < ::core::$f::EPSILON); + + if *$x == 0.0 { + assert!(<$f as Pow>::powi(*$x, n3).is_infinite()); + } else { + assert!( + (<$f as Pow>::powi(*$x, n3) - 1. / $x / $x / $x).abs() + < ::core::$f::EPSILON + ); + } + }; + } + + for x in &[0i8, -3, 2] { + check!(x); + } + for x in &[0u8, 1, 5] { + check!(x); + } + for x in &[0usize, 1, 5, 40] { + check!(x); + } + for x in &[0isize, 1, 2, -30, -22, 48] { + check!(x); + } + for x in &[0.0f32, 2.2, -3.5, 378.223] { + check!(x, f32); + } + for x in &[0.0f64, 2.2, -3.5, -2387.2, 234.22] { + check!(x, f64); + } +} + +/// 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, N3, P2, P5}; +/// use std::cmp::Ordering; +/// +/// assert_eq!(>::Output::to_ordering(), Ordering::Greater); +/// assert_eq!(>::Output::to_ordering(), Ordering::Equal); +/// assert_eq!(>::Output::to_ordering(), Ordering::Less); +pub trait Cmp { + /// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`. + type Output; + + #[doc(hidden)] + fn compare(&self, _: &Rhs) -> Self::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: crate::Unsigned; + /// This function isn't used in this crate, but may be useful for others. + fn len(&self) -> Self::Output; +} + +/// Division as a partial function. This **type operator** performs division just as `Div`, but is +/// only defined when the result is an integer (i.e. there is no remainder). +pub trait PartialDiv { + /// The type of the result of the division + type Output; + /// Method for performing the division + fn partial_div(self, _: Rhs) -> Self::Output; +} + +/// A **type operator** that returns the minimum of `Self` and `Rhs`. +pub trait Min { + /// The type of the minimum of `Self` and `Rhs` + type Output; + /// Method returning the minimum + fn min(self, rhs: Rhs) -> Self::Output; +} + +/// A **type operator** that returns the maximum of `Self` and `Rhs`. +pub trait Max { + /// The type of the maximum of `Self` and `Rhs` + type Output; + /// Method returning the maximum + fn max(self, rhs: Rhs) -> Self::Output; +} + +use crate::Compare; + +/// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`. +pub trait IsLess { + /// The type representing either `True` or `False` + type Output: Bit; + /// Method returning `True` or `False`. + fn is_less(self, rhs: Rhs) -> Self::Output; +} + +use crate::private::IsLessPrivate; +impl IsLess for A +where + A: Cmp + IsLessPrivate>, +{ + type Output = >>::Output; + + #[inline] + fn is_less(self, rhs: B) -> Self::Output { + let lhs_cmp_rhs = self.compare::(&rhs); + self.is_less_private(rhs, lhs_cmp_rhs) + } +} + +/// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`. +pub trait IsEqual { + /// The type representing either `True` or `False` + type Output: Bit; + /// Method returning `True` or `False`. + fn is_equal(self, rhs: Rhs) -> Self::Output; +} + +use crate::private::IsEqualPrivate; +impl IsEqual for A +where + A: Cmp + IsEqualPrivate>, +{ + type Output = >>::Output; + + #[inline] + fn is_equal(self, rhs: B) -> Self::Output { + let lhs_cmp_rhs = self.compare::(&rhs); + self.is_equal_private(rhs, lhs_cmp_rhs) + } +} + +/// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`. +pub trait IsGreater { + /// The type representing either `True` or `False` + type Output: Bit; + /// Method returning `True` or `False`. + fn is_greater(self, rhs: Rhs) -> Self::Output; +} + +use crate::private::IsGreaterPrivate; +impl IsGreater for A +where + A: Cmp + IsGreaterPrivate>, +{ + type Output = >>::Output; + + #[inline] + fn is_greater(self, rhs: B) -> Self::Output { + let lhs_cmp_rhs = self.compare::(&rhs); + self.is_greater_private(rhs, lhs_cmp_rhs) + } +} + +/// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`. +pub trait IsLessOrEqual { + /// The type representing either `True` or `False` + type Output: Bit; + /// Method returning `True` or `False`. + fn is_less_or_equal(self, rhs: Rhs) -> Self::Output; +} + +use crate::private::IsLessOrEqualPrivate; +impl IsLessOrEqual for A +where + A: Cmp + IsLessOrEqualPrivate>, +{ + type Output = >>::Output; + + #[inline] + fn is_less_or_equal(self, rhs: B) -> Self::Output { + let lhs_cmp_rhs = self.compare::(&rhs); + self.is_less_or_equal_private(rhs, lhs_cmp_rhs) + } +} + +/// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`. +pub trait IsNotEqual { + /// The type representing either `True` or `False` + type Output: Bit; + /// Method returning `True` or `False`. + fn is_not_equal(self, rhs: Rhs) -> Self::Output; +} + +use crate::private::IsNotEqualPrivate; +impl IsNotEqual for A +where + A: Cmp + IsNotEqualPrivate>, +{ + type Output = >>::Output; + + #[inline] + fn is_not_equal(self, rhs: B) -> Self::Output { + let lhs_cmp_rhs = self.compare::(&rhs); + self.is_not_equal_private(rhs, lhs_cmp_rhs) + } +} + +/// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`. +pub trait IsGreaterOrEqual { + /// The type representing either `True` or `False` + type Output: Bit; + /// Method returning `True` or `False`. + fn is_greater_or_equal(self, rhs: Rhs) -> Self::Output; +} + +use crate::private::IsGreaterOrEqualPrivate; +impl IsGreaterOrEqual for A +where + A: Cmp + IsGreaterOrEqualPrivate>, +{ + type Output = >>::Output; + + #[inline] + fn is_greater_or_equal(self, rhs: B) -> Self::Output { + let lhs_cmp_rhs = self.compare::(&rhs); + self.is_greater_or_equal_private(rhs, lhs_cmp_rhs) + } +} + +/** +A convenience macro for comparing type numbers. Use `op!` instead. + +Due to the intricacies of the macro system, if the left-hand operand is more complex than a simple +`ident`, you must place a comma between it and the comparison sign. + +For example, you can do `cmp!(P5 > P3)` or `cmp!(typenum::P5, > typenum::P3)` but not +`cmp!(typenum::P5 > typenum::P3)`. + +The result of this comparison will always be one of `True` (aka `B1`) or `False` (aka `B0`). + +# Example +```rust +#[macro_use] extern crate typenum; +use typenum::consts::*; +use typenum::Bit; + +fn main() { +type Result = cmp!(P9 == op!(P1 + P2 * (P2 - N2))); +assert_eq!(Result::to_bool(), true); +} +``` + */ +#[deprecated(since = "1.9.0", note = "use the `op!` macro instead")] +#[macro_export] +macro_rules! cmp { + ($a:ident < $b:ty) => { + <$a as $crate::IsLess<$b>>::Output + }; + ($a:ty, < $b:ty) => { + <$a as $crate::IsLess<$b>>::Output + }; + + ($a:ident == $b:ty) => { + <$a as $crate::IsEqual<$b>>::Output + }; + ($a:ty, == $b:ty) => { + <$a as $crate::IsEqual<$b>>::Output + }; + + ($a:ident > $b:ty) => { + <$a as $crate::IsGreater<$b>>::Output + }; + ($a:ty, > $b:ty) => { + <$a as $crate::IsGreater<$b>>::Output + }; + + ($a:ident <= $b:ty) => { + <$a as $crate::IsLessOrEqual<$b>>::Output + }; + ($a:ty, <= $b:ty) => { + <$a as $crate::IsLessOrEqual<$b>>::Output + }; + + ($a:ident != $b:ty) => { + <$a as $crate::IsNotEqual<$b>>::Output + }; + ($a:ty, != $b:ty) => { + <$a as $crate::IsNotEqual<$b>>::Output + }; + + ($a:ident >= $b:ty) => { + <$a as $crate::IsGreaterOrEqual<$b>>::Output + }; + ($a:ty, >= $b:ty) => { + <$a as $crate::IsGreaterOrEqual<$b>>::Output + }; +} + +/// A **type operator** for taking the integer square root of `Self`. +/// +/// The integer square root of `n` is the largest integer `m` such +/// that `n >= m*m`. This definition is equivalent to truncating the +/// real-valued square root: `floor(real_sqrt(n))`. +pub trait SquareRoot { + /// The result of the integer square root. + type Output; +} + +/// A **type operator** for taking the integer binary logarithm of `Self`. +/// +/// The integer binary logarighm of `n` is the largest integer `m` such +/// that `n >= 2^m`. This definition is equivalent to truncating the +/// real-valued binary logarithm: `floor(log2(n))`. +pub trait Logarithm2 { + /// The result of the integer binary logarithm. + type Output; +} + +/// A **type operator** that computes the [greatest common divisor][gcd] of `Self` and `Rhs`. +/// +/// [gcd]: https://en.wikipedia.org/wiki/Greatest_common_divisor +/// +/// # Example +/// +/// ```rust +/// use typenum::{Gcd, Unsigned, U12, U8}; +/// +/// assert_eq!(>::Output::to_i32(), 4); +/// ``` +pub trait Gcd { + /// The greatest common divisor. + type Output; +} + +/// A **type operator** for taking a concrete integer value from a type. +/// +/// It returns arbitrary integer value without explicitly specifying the +/// type. It is useful when you pass the values to methods that accept +/// distinct types without runtime casting. +pub trait ToInt { + /// Method returning the concrete value for the type. + fn to_int() -> T; +} -- cgit v1.2.3