// Copyright 2017-2020 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Substrate is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . //! Primitive traits for the runtime arithmetic. use sp_std::{self, convert::{TryFrom, TryInto}}; use codec::HasCompact; pub use integer_sqrt::IntegerSquareRoot; pub use num_traits::{ Zero, One, Bounded, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, CheckedShl, CheckedShr, checked_pow }; use sp_std::ops::{ Add, Sub, Mul, Div, Rem, AddAssign, SubAssign, MulAssign, DivAssign, RemAssign, Shl, Shr }; /// A meta trait for arithmetic type operations, regardless of any limitation on size. pub trait BaseArithmetic: From + Zero + One + IntegerSquareRoot + Add + AddAssign + Sub + SubAssign + Mul + MulAssign + Div + DivAssign + Rem + RemAssign + Shl + Shr + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + Saturating + PartialOrd + Ord + Bounded + HasCompact + Sized + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto {} impl + Zero + One + IntegerSquareRoot + Add + AddAssign + Sub + SubAssign + Mul + MulAssign + Div + DivAssign + Rem + RemAssign + Shl + Shr + CheckedShl + CheckedShr + CheckedAdd + CheckedSub + CheckedMul + CheckedDiv + Saturating + PartialOrd + Ord + Bounded + HasCompact + Sized + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + TryFrom + TryInto + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto + UniqueSaturatedFrom + UniqueSaturatedInto > BaseArithmetic for T {} /// A meta trait for arithmetic. /// /// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to /// be able to represent at least `u32` values without loss, hence the trait implies `From` /// and smaller integers. All other conversions are fallible. pub trait AtLeast32Bit: BaseArithmetic + From + From {} impl + From> AtLeast32Bit for T {} /// Just like `From` except that if the source value is too big to fit into the destination type /// then it'll saturate the destination. pub trait UniqueSaturatedFrom: Sized { /// Convert from a value of `T` into an equivalent instance of `Self`. fn unique_saturated_from(t: T) -> Self; } /// Just like `Into` except that if the source value is too big to fit into the destination type /// then it'll saturate the destination. pub trait UniqueSaturatedInto: Sized { /// Consume self to return an equivalent value of `T`. fn unique_saturated_into(self) -> T; } impl + Bounded + Sized> UniqueSaturatedFrom for S { fn unique_saturated_from(t: T) -> Self { S::try_from(t).unwrap_or_else(|_| Bounded::max_value()) } } impl + Sized> UniqueSaturatedInto for S { fn unique_saturated_into(self) -> T { self.try_into().unwrap_or_else(|_| Bounded::max_value()) } } /// Saturating arithmetic operations, returning maximum or minimum values instead of overflowing. pub trait Saturating { /// Saturating addition. Compute `self + rhs`, saturating at the numeric bounds instead of /// overflowing. fn saturating_add(self, rhs: Self) -> Self; /// Saturating subtraction. Compute `self - rhs`, saturating at the numeric bounds instead of /// overflowing. fn saturating_sub(self, rhs: Self) -> Self; /// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of /// overflowing. fn saturating_mul(self, rhs: Self) -> Self; /// Saturating exponentiation. Compute `self.pow(exp)`, saturating at the numeric bounds /// instead of overflowing. fn saturating_pow(self, exp: usize) -> Self; } impl Saturating for T { fn saturating_add(self, o: Self) -> Self { ::saturating_add(self, o) } fn saturating_sub(self, o: Self) -> Self { ::saturating_sub(self, o) } fn saturating_mul(self, o: Self) -> Self { self.checked_mul(&o).unwrap_or_else(Bounded::max_value) } fn saturating_pow(self, exp: usize) -> Self { checked_pow(self, exp).unwrap_or_else(Bounded::max_value) } } /// Convenience type to work around the highly unergonomic syntax needed /// to invoke the functions of overloaded generic traits, in this case /// `SaturatedFrom` and `SaturatedInto`. pub trait SaturatedConversion { /// Convert from a value of `T` into an equivalent instance of `Self`. /// /// This just uses `UniqueSaturatedFrom` internally but with this /// variant you can provide the destination type using turbofish syntax /// in case Rust happens not to assume the correct type. fn saturated_from(t: T) -> Self where Self: UniqueSaturatedFrom { >::unique_saturated_from(t) } /// Consume self to return an equivalent value of `T`. /// /// This just uses `UniqueSaturatedInto` internally but with this /// variant you can provide the destination type using turbofish syntax /// in case Rust happens not to assume the correct type. fn saturated_into(self) -> T where Self: UniqueSaturatedInto { >::unique_saturated_into(self) } } impl SaturatedConversion for T {}