Movatterモバイル変換


[0]ホーム

URL:


Docs.rs

typenum/
type_operators.rs

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
//! 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!(<U5 as Same<U5>>::Output::to_u32(), 5);////// // Only an error if we use it:/// # #[allow(dead_code)]/// type Undefined = <U5 as Same<U4>>::Output;/// // Compiler error:/// // Undefined::to_u32();/// ```pub traitSame<Rhs =Self> {/// Should always be `Self`typeOutput;}impl<T> Same<T>forT {typeOutput = T;}/// A **type operator** that returns the absolute value.////// # Example/// ```rust/// use typenum::{Abs, Integer, N5};////// assert_eq!(<N5 as Abs>::Output::to_i32(), 5);/// ```pub traitAbs {/// The absolute value.typeOutput;}implAbsforZ0 {typeOutput = Z0;}impl<U: Unsigned + NonZero> AbsforPInt<U> {typeOutput =Self;}impl<U: Unsigned + NonZero> AbsforNInt<U> {typeOutput = PInt<U>;}/// A **type operator** that provides exponentiation by repeated squaring.////// # Example/// ```rust/// use typenum::{Integer, Pow, N3, P3};////// assert_eq!(<N3 as Pow<P3>>::Output::to_i32(), -27);/// ```pub traitPow<Exp> {/// The result of the exponentiation.typeOutput;/// 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);    /// ```fnpowi(self, exp: Exp) ->Self::Output;}macro_rules! impl_pow_f {    ($t:ty) => {implPow<UTerm>for$t{typeOutput =$t;#[inline]fnpowi(self,_: UTerm) ->Self::Output {1.0}        }impl<U: Unsigned, B: Bit> Pow<UInt<U, B>>for$t{typeOutput =$t;// powi is unstable in core, so we have to write this function ourselves.            // copied from num::pow::pow#[inline]fnpowi(self,_: UInt<U, B>) ->Self::Output {letmutexp = <UInt<U, B>asUnsigned>::to_u32();letmutbase =self;ifexp ==0{return1.0;                }whileexp &1==0{                    base*= base;                    exp >>=1;                }ifexp ==1{returnbase;                }letmutacc = base.clone();whileexp >1{                    exp >>=1;                    base*= base;ifexp &1==1{                        acc*= base.clone();                    }                }                acc            }        }implPow<Z0>for$t{typeOutput =$t;#[inline]fnpowi(self,_: Z0) ->Self::Output {1.0}        }impl<U: Unsigned + NonZero> Pow<PInt<U>>for$t{typeOutput =$t;// powi is unstable in core, so we have to write this function ourselves.            // copied from num::pow::pow#[inline]fnpowi(self,_: PInt<U>) ->Self::Output {letmutexp = U::to_u32();letmutbase =self;ifexp ==0{return1.0;                }whileexp &1==0{                    base*= base;                    exp >>=1;                }ifexp ==1{returnbase;                }letmutacc = base.clone();whileexp >1{                    exp >>=1;                    base*= base;ifexp &1==1{                        acc*= base.clone();                    }                }                acc            }        }impl<U: Unsigned + NonZero> Pow<NInt<U>>for$t{typeOutput =$t;#[inline]fnpowi(self,_: NInt<U>) ->Self::Output {                <$tasPow<PInt<U>>>::powi(self, PInt::new()).recip()            }        }    };}impl_pow_f!(f32);impl_pow_f!(f64);macro_rules! impl_pow_i {    () => ();    ($(#[$meta:meta])*$t: ty $(,$tail:tt)*) => (        $(#[$meta])*implPow<UTerm>for$t{typeOutput =$t;#[inline]fnpowi(self,_: UTerm) ->Self::Output {1}        }        $(#[$meta])*impl<U: Unsigned, B: Bit> Pow<UInt<U, B>>for$t{typeOutput =$t;#[inline]fnpowi(self,_: UInt<U, B>) ->Self::Output {self.pow(<UInt<U, B>asUnsigned>::to_u32())            }        }        $(#[$meta])*implPow<Z0>for$t{typeOutput =$t;#[inline]fnpowi(self,_: Z0) ->Self::Output {1}        }        $(#[$meta])*impl<U: Unsigned + NonZero> Pow<PInt<U>>for$t{typeOutput =$t;#[inline]fnpowi(self,_: PInt<U>) ->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!(#[cfg_attr(docsrs, doc(cfg(feature ="i128")))]u128,    i128);#[test]fnpow_test() {usecrate::consts::*;letz0 = Z0::new();letp3 = P3::new();letu0 = U0::new();letu3 = U3::new();letn3 = 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!((<$fasPow<Z0>>::powi(*$x, z0) -1.0).abs() < ::core::$f::EPSILON);assert!((<$fasPow<U0>>::powi(*$x, u0) -1.0).abs() < ::core::$f::EPSILON);assert!((<$fasPow<P3>>::powi(*$x, p3) -$x*$x*$x).abs() < ::core::$f::EPSILON);assert!((<$fasPow<U3>>::powi(*$x, u3) -$x*$x*$x).abs() < ::core::$f::EPSILON);if*$x==0.0{assert!(<$fasPow<N3>>::powi(*$x, n3).is_infinite());            }else{assert!(                    (<$fasPow<N3>>::powi(*$x, n3) -1./$x/$x/$x).abs()                        < ::core::$f::EPSILON);            }        };    }forxin&[0i8, -3,2] {check!(x);    }forxin&[0u8,1,5] {check!(x);    }forxin&[0usize,1,5,40] {check!(x);    }forxin&[0isize,1,2, -30, -22,48] {check!(x);    }forxin&[0.0f32,2.2, -3.5,378.223] {check!(x, f32);    }forxin&[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!(<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 traitCmp<Rhs =Self> {/// The result of the comparison. It should only ever be one of `Greater`, `Less`, or `Equal`.typeOutput;#[doc(hidden)]fncompare<IM: InternalMarker>(&self,_:&Rhs) ->Self::Output;}/// A **type operator** that gives the length of an `Array` or the number of bits in a `UInt`.pub traitLen {/// The length as a type-level unsigned integer.typeOutput:crate::Unsigned;/// This function isn't used in this crate, but may be useful for others.fnlen(&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 traitPartialDiv<Rhs =Self> {/// The type of the result of the divisiontypeOutput;/// Method for performing the divisionfnpartial_div(self,_: Rhs) ->Self::Output;}/// A **type operator** that returns the minimum of `Self` and `Rhs`.pub traitMin<Rhs =Self> {/// The type of the minimum of `Self` and `Rhs`typeOutput;/// Method returning the minimumfnmin(self, rhs: Rhs) ->Self::Output;}/// A **type operator** that returns the maximum of `Self` and `Rhs`.pub traitMax<Rhs =Self> {/// The type of the maximum of `Self` and `Rhs`typeOutput;/// Method returning the maximumfnmax(self, rhs: Rhs) ->Self::Output;}usecrate::Compare;/// A **type operator** that returns `True` if `Self < Rhs`, otherwise returns `False`.pub traitIsLess<Rhs =Self> {/// The type representing either `True` or `False`typeOutput: Bit;/// Method returning `True` or `False`.fnis_less(self, rhs: Rhs) ->Self::Output;}usecrate::private::IsLessPrivate;impl<A, B> IsLess<B>forAwhereA: Cmp<B> + IsLessPrivate<B, Compare<A, B>>,{typeOutput = <AasIsLessPrivate<B, Compare<A, B>>>::Output;#[inline]fnis_less(self, rhs: B) ->Self::Output {letlhs_cmp_rhs =self.compare::<Internal>(&rhs);self.is_less_private(rhs, lhs_cmp_rhs)    }}/// A **type operator** that returns `True` if `Self == Rhs`, otherwise returns `False`.pub traitIsEqual<Rhs =Self> {/// The type representing either `True` or `False`typeOutput: Bit;/// Method returning `True` or `False`.fnis_equal(self, rhs: Rhs) ->Self::Output;}usecrate::private::IsEqualPrivate;impl<A, B> IsEqual<B>forAwhereA: Cmp<B> + IsEqualPrivate<B, Compare<A, B>>,{typeOutput = <AasIsEqualPrivate<B, Compare<A, B>>>::Output;#[inline]fnis_equal(self, rhs: B) ->Self::Output {letlhs_cmp_rhs =self.compare::<Internal>(&rhs);self.is_equal_private(rhs, lhs_cmp_rhs)    }}/// A **type operator** that returns `True` if `Self > Rhs`, otherwise returns `False`.pub traitIsGreater<Rhs =Self> {/// The type representing either `True` or `False`typeOutput: Bit;/// Method returning `True` or `False`.fnis_greater(self, rhs: Rhs) ->Self::Output;}usecrate::private::IsGreaterPrivate;impl<A, B> IsGreater<B>forAwhereA: Cmp<B> + IsGreaterPrivate<B, Compare<A, B>>,{typeOutput = <AasIsGreaterPrivate<B, Compare<A, B>>>::Output;#[inline]fnis_greater(self, rhs: B) ->Self::Output {letlhs_cmp_rhs =self.compare::<Internal>(&rhs);self.is_greater_private(rhs, lhs_cmp_rhs)    }}/// A **type operator** that returns `True` if `Self <= Rhs`, otherwise returns `False`.pub traitIsLessOrEqual<Rhs =Self> {/// The type representing either `True` or `False`typeOutput: Bit;/// Method returning `True` or `False`.fnis_less_or_equal(self, rhs: Rhs) ->Self::Output;}usecrate::private::IsLessOrEqualPrivate;impl<A, B> IsLessOrEqual<B>forAwhereA: Cmp<B> + IsLessOrEqualPrivate<B, Compare<A, B>>,{typeOutput = <AasIsLessOrEqualPrivate<B, Compare<A, B>>>::Output;#[inline]fnis_less_or_equal(self, rhs: B) ->Self::Output {letlhs_cmp_rhs =self.compare::<Internal>(&rhs);self.is_less_or_equal_private(rhs, lhs_cmp_rhs)    }}/// A **type operator** that returns `True` if `Self != Rhs`, otherwise returns `False`.pub traitIsNotEqual<Rhs =Self> {/// The type representing either `True` or `False`typeOutput: Bit;/// Method returning `True` or `False`.fnis_not_equal(self, rhs: Rhs) ->Self::Output;}usecrate::private::IsNotEqualPrivate;impl<A, B> IsNotEqual<B>forAwhereA: Cmp<B> + IsNotEqualPrivate<B, Compare<A, B>>,{typeOutput = <AasIsNotEqualPrivate<B, Compare<A, B>>>::Output;#[inline]fnis_not_equal(self, rhs: B) ->Self::Output {letlhs_cmp_rhs =self.compare::<Internal>(&rhs);self.is_not_equal_private(rhs, lhs_cmp_rhs)    }}/// A **type operator** that returns `True` if `Self >= Rhs`, otherwise returns `False`.pub traitIsGreaterOrEqual<Rhs =Self> {/// The type representing either `True` or `False`typeOutput: Bit;/// Method returning `True` or `False`.fnis_greater_or_equal(self, rhs: Rhs) ->Self::Output;}usecrate::private::IsGreaterOrEqualPrivate;impl<A, B> IsGreaterOrEqual<B>forAwhereA: Cmp<B> + IsGreaterOrEqualPrivate<B, Compare<A, B>>,{typeOutput = <AasIsGreaterOrEqualPrivate<B, Compare<A, B>>>::Output;#[inline]fnis_greater_or_equal(self, rhs: B) ->Self::Output {letlhs_cmp_rhs =self.compare::<Internal>(&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) => {        <$aas$crate::IsLess<$b>>::Output    };    ($a:ty, <$b:ty) => {        <$aas$crate::IsLess<$b>>::Output    };    ($a:ident ==$b:ty) => {        <$aas$crate::IsEqual<$b>>::Output    };    ($a:ty, ==$b:ty) => {        <$aas$crate::IsEqual<$b>>::Output    };    ($a:ident >$b:ty) => {        <$aas$crate::IsGreater<$b>>::Output    };    ($a:ty, >$b:ty) => {        <$aas$crate::IsGreater<$b>>::Output    };    ($a:ident <=$b:ty) => {        <$aas$crate::IsLessOrEqual<$b>>::Output    };    ($a:ty, <=$b:ty) => {        <$aas$crate::IsLessOrEqual<$b>>::Output    };    ($a:ident !=$b:ty) => {        <$aas$crate::IsNotEqual<$b>>::Output    };    ($a:ty, !=$b:ty) => {        <$aas$crate::IsNotEqual<$b>>::Output    };    ($a:ident >=$b:ty) => {        <$aas$crate::IsGreaterOrEqual<$b>>::Output    };    ($a:ty, >=$b:ty) => {        <$aas$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 traitSquareRoot {/// The result of the integer square root.typeOutput;}/// 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 traitLogarithm2 {/// The result of the integer binary logarithm.typeOutput;}/// 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!(<U12 as Gcd<U8>>::Output::to_i32(), 4);/// ```pub traitGcd<Rhs> {/// The greatest common divisor.typeOutput;}/// 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 traitToInt<T> {/// Method returning the concrete value for the type.fnto_int() -> T;/// The concrete value for the type. Can be used in `const` contexts.constINT: T;}

[8]ページ先頭

©2009-2025 Movatter.jp