mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 15:47:58 +00:00
Attempt to remove the where bounds in arithmetic. (#7933)
* Attempt to remove the where bounds. * Fix further and further. * Format better. * Update primitives/npos-elections/src/lib.rs * fix build * remove unused
This commit is contained in:
@@ -22,6 +22,7 @@ use sp_std::{ops, fmt, prelude::*, convert::TryInto};
|
||||
use codec::{Encode, CompactAs};
|
||||
use crate::traits::{
|
||||
SaturatedConversion, UniqueSaturatedInto, Saturating, BaseArithmetic, Bounded, Zero, Unsigned,
|
||||
One,
|
||||
};
|
||||
use sp_debug_derive::RuntimeDebug;
|
||||
|
||||
@@ -37,13 +38,17 @@ pub trait PerThing:
|
||||
Sized + Saturating + Copy + Default + Eq + PartialEq + Ord + PartialOrd + Bounded + fmt::Debug
|
||||
{
|
||||
/// The data type used to build this per-thingy.
|
||||
type Inner: BaseArithmetic + Unsigned + Copy + fmt::Debug;
|
||||
type Inner: BaseArithmetic + Unsigned + Copy + Into<u128> + fmt::Debug;
|
||||
|
||||
/// A data type larger than `Self::Inner`, used to avoid overflow in some computations.
|
||||
/// It must be able to compute `ACCURACY^2`.
|
||||
type Upper:
|
||||
BaseArithmetic + Copy + From<Self::Inner> + TryInto<Self::Inner> +
|
||||
UniqueSaturatedInto<Self::Inner> + Unsigned + fmt::Debug;
|
||||
type Upper: BaseArithmetic
|
||||
+ Copy
|
||||
+ From<Self::Inner>
|
||||
+ TryInto<Self::Inner>
|
||||
+ UniqueSaturatedInto<Self::Inner>
|
||||
+ Unsigned
|
||||
+ fmt::Debug;
|
||||
|
||||
/// The accuracy of this type.
|
||||
const ACCURACY: Self::Inner;
|
||||
@@ -65,14 +70,14 @@ pub trait PerThing:
|
||||
fn from_percent(x: Self::Inner) -> Self {
|
||||
let a: Self::Inner = x.min(100.into());
|
||||
let b: Self::Inner = 100.into();
|
||||
Self::from_rational_approximation(a, b)
|
||||
Self::from_rational_approximation::<Self::Inner>(a, b)
|
||||
}
|
||||
|
||||
/// Return the product of multiplication of this value by itself.
|
||||
fn square(self) -> Self {
|
||||
let p = Self::Upper::from(self.deconstruct());
|
||||
let q = Self::Upper::from(Self::ACCURACY);
|
||||
Self::from_rational_approximation(p * p, q * q)
|
||||
Self::from_rational_approximation::<Self::Upper>(p * p, q * q)
|
||||
}
|
||||
|
||||
/// Multiplication that always rounds down to a whole number. The standard `Mul` rounds to the
|
||||
@@ -91,8 +96,10 @@ pub trait PerThing:
|
||||
/// # }
|
||||
/// ```
|
||||
fn mul_floor<N>(self, b: N) -> N
|
||||
where N: Clone + From<Self::Inner> + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Unsigned,
|
||||
Self::Inner: Into<N>,
|
||||
{
|
||||
overflow_prune_mul::<N, Self>(b, self.deconstruct(), Rounding::Down)
|
||||
}
|
||||
@@ -113,8 +120,10 @@ pub trait PerThing:
|
||||
/// # }
|
||||
/// ```
|
||||
fn mul_ceil<N>(self, b: N) -> N
|
||||
where N: Clone + From<Self::Inner> + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Unsigned,
|
||||
Self::Inner: Into<N>
|
||||
{
|
||||
overflow_prune_mul::<N, Self>(b, self.deconstruct(), Rounding::Up)
|
||||
}
|
||||
@@ -129,9 +138,11 @@ pub trait PerThing:
|
||||
/// # }
|
||||
/// ```
|
||||
fn saturating_reciprocal_mul<N>(self, b: N) -> N
|
||||
where N: Clone + From<Self::Inner> + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Saturating +
|
||||
Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Saturating +
|
||||
Unsigned,
|
||||
Self::Inner: Into<N>,
|
||||
{
|
||||
saturating_reciprocal_mul::<N, Self>(b, self.deconstruct(), Rounding::Nearest)
|
||||
}
|
||||
@@ -149,9 +160,11 @@ pub trait PerThing:
|
||||
/// # }
|
||||
/// ```
|
||||
fn saturating_reciprocal_mul_floor<N>(self, b: N) -> N
|
||||
where N: Clone + From<Self::Inner> + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Saturating +
|
||||
Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Saturating +
|
||||
Unsigned,
|
||||
Self::Inner: Into<N>,
|
||||
{
|
||||
saturating_reciprocal_mul::<N, Self>(b, self.deconstruct(), Rounding::Down)
|
||||
}
|
||||
@@ -169,9 +182,11 @@ pub trait PerThing:
|
||||
/// # }
|
||||
/// ```
|
||||
fn saturating_reciprocal_mul_ceil<N>(self, b: N) -> N
|
||||
where N: Clone + From<Self::Inner> + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Saturating +
|
||||
Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<Self::Inner> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Saturating +
|
||||
Unsigned,
|
||||
Self::Inner: Into<N>,
|
||||
{
|
||||
saturating_reciprocal_mul::<N, Self>(b, self.deconstruct(), Rounding::Up)
|
||||
}
|
||||
@@ -199,14 +214,16 @@ pub trait PerThing:
|
||||
/// # fn main () {
|
||||
/// // 989/100 is technically closer to 99%.
|
||||
/// assert_eq!(
|
||||
/// Percent::from_rational_approximation(989u64, 1000),
|
||||
/// Percent::from_parts(98),
|
||||
/// );
|
||||
/// Percent::from_rational_approximation(989u64, 1000),
|
||||
/// Percent::from_parts(98),
|
||||
/// );
|
||||
/// # }
|
||||
/// ```
|
||||
fn from_rational_approximation<N>(p: N, q: N) -> Self
|
||||
where N: Clone + Ord + From<Self::Inner> + TryInto<Self::Inner> + TryInto<Self::Upper> +
|
||||
ops::Div<N, Output=N> + ops::Rem<N, Output=N> + ops::Add<N, Output=N> + Unsigned;
|
||||
where
|
||||
N: Clone + Ord + TryInto<Self::Inner> + TryInto<Self::Upper> +
|
||||
ops::Div<N, Output=N> + ops::Rem<N, Output=N> + ops::Add<N, Output=N> + Unsigned,
|
||||
Self::Inner: Into<N>;
|
||||
}
|
||||
|
||||
/// The rounding method to use.
|
||||
@@ -221,15 +238,12 @@ enum Rounding {
|
||||
|
||||
/// Saturating reciprocal multiplication. Compute `x / self`, saturating at the numeric
|
||||
/// bounds instead of overflowing.
|
||||
fn saturating_reciprocal_mul<N, P>(
|
||||
x: N,
|
||||
part: P::Inner,
|
||||
rounding: Rounding,
|
||||
) -> N
|
||||
fn saturating_reciprocal_mul<N, P>(x: N, part: P::Inner, rounding: Rounding) -> N
|
||||
where
|
||||
N: Clone + From<P::Inner> + UniqueSaturatedInto<P::Inner> + ops::Div<N, Output=N> + ops::Mul<N,
|
||||
N: Clone + UniqueSaturatedInto<P::Inner> + ops::Div<N, Output=N> + ops::Mul<N,
|
||||
Output=N> + ops::Add<N, Output=N> + ops::Rem<N, Output=N> + Saturating + Unsigned,
|
||||
P: PerThing,
|
||||
P::Inner: Into<N>,
|
||||
{
|
||||
let maximum: N = P::ACCURACY.into();
|
||||
let c = rational_mul_correction::<N, P>(
|
||||
@@ -242,15 +256,12 @@ where
|
||||
}
|
||||
|
||||
/// Overflow-prune multiplication. Accurately multiply a value by `self` without overflowing.
|
||||
fn overflow_prune_mul<N, P>(
|
||||
x: N,
|
||||
part: P::Inner,
|
||||
rounding: Rounding,
|
||||
) -> N
|
||||
fn overflow_prune_mul<N, P>(x: N, part: P::Inner, rounding: Rounding) -> N
|
||||
where
|
||||
N: Clone + From<P::Inner> + UniqueSaturatedInto<P::Inner> + ops::Div<N, Output=N> + ops::Mul<N,
|
||||
N: Clone + UniqueSaturatedInto<P::Inner> + ops::Div<N, Output=N> + ops::Mul<N,
|
||||
Output=N> + ops::Add<N, Output=N> + ops::Rem<N, Output=N> + Unsigned,
|
||||
P: PerThing,
|
||||
P::Inner: Into<N>,
|
||||
{
|
||||
let maximum: N = P::ACCURACY.into();
|
||||
let part_n: N = part.into();
|
||||
@@ -267,19 +278,15 @@ where
|
||||
///
|
||||
/// Take the remainder of `x / denom` and multiply by `numer / denom`. The result can be added
|
||||
/// to `x / denom * numer` for an accurate result.
|
||||
fn rational_mul_correction<N, P>(
|
||||
x: N,
|
||||
numer: P::Inner,
|
||||
denom: P::Inner,
|
||||
rounding: Rounding,
|
||||
) -> N
|
||||
fn rational_mul_correction<N, P>(x: N, numer: P::Inner, denom: P::Inner, rounding: Rounding) -> N
|
||||
where
|
||||
N: From<P::Inner> + UniqueSaturatedInto<P::Inner> + ops::Div<N, Output=N> + ops::Mul<N,
|
||||
N: UniqueSaturatedInto<P::Inner> + ops::Div<N, Output=N> + ops::Mul<N,
|
||||
Output=N> + ops::Add<N, Output=N> + ops::Rem<N, Output=N> + Unsigned,
|
||||
P: PerThing,
|
||||
P::Inner: Into<N>
|
||||
{
|
||||
let numer_upper = P::Upper::from(numer);
|
||||
let denom_n = N::from(denom);
|
||||
let denom_n: N = denom.into();
|
||||
let denom_upper = P::Upper::from(denom);
|
||||
let rem = x.rem(denom_n);
|
||||
// `rem` is less than `denom`, which fits in `P::Inner`.
|
||||
@@ -362,14 +369,17 @@ macro_rules! implement_per_thing {
|
||||
}
|
||||
|
||||
fn from_rational_approximation<N>(p: N, q: N) -> Self
|
||||
where N: Clone + Ord + From<Self::Inner> + TryInto<Self::Inner> + TryInto<Self::Upper>
|
||||
+ ops::Div<N, Output=N> + ops::Rem<N, Output=N> + ops::Add<N, Output=N> + Unsigned
|
||||
where
|
||||
N: Clone + Ord + TryInto<Self::Inner> + TryInto<Self::Upper>
|
||||
+ ops::Div<N, Output=N> + ops::Rem<N, Output=N> + ops::Add<N, Output=N> + Unsigned
|
||||
+ Zero + One,
|
||||
Self::Inner: Into<N>,
|
||||
{
|
||||
let div_ceil = |x: N, f: N| -> N {
|
||||
let mut o = x.clone() / f.clone();
|
||||
let r = x.rem(f.clone());
|
||||
if r > N::from(0) {
|
||||
o = o + N::from(1);
|
||||
if r > N::zero() {
|
||||
o = o + N::one();
|
||||
}
|
||||
o
|
||||
};
|
||||
@@ -464,54 +474,66 @@ macro_rules! implement_per_thing {
|
||||
|
||||
/// See [`PerThing::from_rational_approximation`].
|
||||
pub fn from_rational_approximation<N>(p: N, q: N) -> Self
|
||||
where N: Clone + Ord + From<$type> + TryInto<$type> +
|
||||
where N: Clone + Ord + TryInto<$type> +
|
||||
TryInto<$upper_type> + ops::Div<N, Output=N> + ops::Rem<N, Output=N> +
|
||||
ops::Add<N, Output=N> + Unsigned
|
||||
ops::Add<N, Output=N> + Unsigned,
|
||||
$type: Into<N>,
|
||||
{
|
||||
<Self as PerThing>::from_rational_approximation(p, q)
|
||||
}
|
||||
|
||||
/// See [`PerThing::mul_floor`].
|
||||
pub fn mul_floor<N>(self, b: N) -> N
|
||||
where N: Clone + From<$type> + UniqueSaturatedInto<$type> +
|
||||
ops::Rem<N, Output=N> + ops::Div<N, Output=N> + ops::Mul<N, Output=N> +
|
||||
ops::Add<N, Output=N> + Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<$type> +
|
||||
ops::Rem<N, Output=N> + ops::Div<N, Output=N> + ops::Mul<N, Output=N> +
|
||||
ops::Add<N, Output=N> + Unsigned,
|
||||
$type: Into<N>,
|
||||
|
||||
{
|
||||
PerThing::mul_floor(self, b)
|
||||
}
|
||||
|
||||
/// See [`PerThing::mul_ceil`].
|
||||
pub fn mul_ceil<N>(self, b: N) -> N
|
||||
where N: Clone + From<$type> + UniqueSaturatedInto<$type> +
|
||||
ops::Rem<N, Output=N> + ops::Div<N, Output=N> + ops::Mul<N, Output=N> +
|
||||
ops::Add<N, Output=N> + Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<$type> +
|
||||
ops::Rem<N, Output=N> + ops::Div<N, Output=N> + ops::Mul<N, Output=N> +
|
||||
ops::Add<N, Output=N> + Unsigned,
|
||||
$type: Into<N>,
|
||||
{
|
||||
PerThing::mul_ceil(self, b)
|
||||
}
|
||||
|
||||
/// See [`PerThing::saturating_reciprocal_mul`].
|
||||
pub fn saturating_reciprocal_mul<N>(self, b: N) -> N
|
||||
where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> +
|
||||
Saturating + Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> +
|
||||
Saturating + Unsigned,
|
||||
$type: Into<N>,
|
||||
{
|
||||
PerThing::saturating_reciprocal_mul(self, b)
|
||||
}
|
||||
|
||||
/// See [`PerThing::saturating_reciprocal_mul_floor`].
|
||||
pub fn saturating_reciprocal_mul_floor<N>(self, b: N) -> N
|
||||
where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> +
|
||||
Saturating + Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> +
|
||||
Saturating + Unsigned,
|
||||
$type: Into<N>,
|
||||
{
|
||||
PerThing::saturating_reciprocal_mul_floor(self, b)
|
||||
}
|
||||
|
||||
/// See [`PerThing::saturating_reciprocal_mul_ceil`].
|
||||
pub fn saturating_reciprocal_mul_ceil<N>(self, b: N) -> N
|
||||
where N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> +
|
||||
Saturating + Unsigned
|
||||
where
|
||||
N: Clone + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N> +
|
||||
ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> +
|
||||
Saturating + Unsigned,
|
||||
$type: Into<N>,
|
||||
{
|
||||
PerThing::saturating_reciprocal_mul_ceil(self, b)
|
||||
}
|
||||
@@ -611,8 +633,9 @@ macro_rules! implement_per_thing {
|
||||
/// This is tailored to be used with a balance type.
|
||||
impl<N> ops::Mul<N> for $name
|
||||
where
|
||||
N: Clone + From<$type> + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N>
|
||||
N: Clone + UniqueSaturatedInto<$type> + ops::Rem<N, Output=N>
|
||||
+ ops::Div<N, Output=N> + ops::Mul<N, Output=N> + ops::Add<N, Output=N> + Unsigned,
|
||||
$type: Into<N>,
|
||||
{
|
||||
type Output = N;
|
||||
fn mul(self, b: N) -> Self::Output {
|
||||
|
||||
Reference in New Issue
Block a user