Skip to content

Commit

Permalink
More traits...
Browse files Browse the repository at this point in the history
  • Loading branch information
recmo committed Aug 27, 2023
1 parent b409b6e commit 3e1a234
Showing 1 changed file with 113 additions and 23 deletions.
136 changes: 113 additions & 23 deletions src/support/num_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
// to call functions on the `Uint::` type.
#![deny(unconditional_recursion)]
use crate::Uint;
use core::ops::{Shl, Shr};
use num_traits::{
bounds::*,
ops::{bytes::*, checked::*, overflowing::*, saturating::*, wrapping::*, *},
*,
};

// TODO: PrimInt, Unsigned
// TODO: cast::* PrimInt

// Note. We can not implement `NumBytes` as it requires T to be `AsMut<[u8]>`.
// This is not safe for `Uint` when `BITS % 8 != 0`.

impl<const BITS: usize, const LIMBS: usize> Zero for Uint<BITS, LIMBS> {
#[inline(always)]
Expand Down Expand Up @@ -107,17 +111,37 @@ impl<const BITS: usize, const LIMBS: usize> CheckedRem for Uint<BITS, LIMBS> {
}

Check warning on line 111 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L109-L111

Added lines #L109 - L111 were not covered by tests
}

// impl<const BITS: usize, const LIMBS: usize> CheckedShl for Uint<BITS, LIMBS>
// { fn checked_shl(&self, other: u32) -> Option<Self> {
// Uint::checked_shl(self, other as usize)
// }
// }
// TODO: Move out of support.
impl<const BITS: usize, const LIMBS: usize> Shl<u32> for Uint<BITS, LIMBS> {
type Output = Self;

#[inline(always)]
fn shl(self, rhs: u32) -> Self::Output {
<Self>::shl(self, rhs as usize)
}

Check warning on line 121 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L119-L121

Added lines #L119 - L121 were not covered by tests
}

// impl<const BITS: usize, const LIMBS: usize> CheckedShr for Uint<BITS, LIMBS>
// { fn checked_shr(&self, other: u32) -> Option<Self> {
// Uint::checked_shr(self, other as usize)
// }
// }
// TODO: Move out of support lib into.
impl<const BITS: usize, const LIMBS: usize> Shr<u32> for Uint<BITS, LIMBS> {
type Output = Self;

#[inline(always)]
fn shr(self, rhs: u32) -> Self::Output {
<Self>::shr(self, rhs as usize)
}

Check warning on line 131 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L129-L131

Added lines #L129 - L131 were not covered by tests
}

impl<const BITS: usize, const LIMBS: usize> CheckedShl for Uint<BITS, LIMBS> {
fn checked_shl(&self, other: u32) -> Option<Self> {
Uint::checked_shl(*self, other as usize)
}

Check warning on line 137 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L135-L137

Added lines #L135 - L137 were not covered by tests
}

impl<const BITS: usize, const LIMBS: usize> CheckedShr for Uint<BITS, LIMBS> {
fn checked_shr(&self, other: u32) -> Option<Self> {
Uint::checked_shr(*self, other as usize)
}

Check warning on line 143 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L141-L143

Added lines #L141 - L143 were not covered by tests
}

impl<const BITS: usize, const LIMBS: usize> CheckedSub for Uint<BITS, LIMBS> {
#[inline(always)]
Expand Down Expand Up @@ -189,24 +213,44 @@ impl<const BITS: usize, const LIMBS: usize> Saturating for Uint<BITS, LIMBS> {
}

Check warning on line 213 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L211-L213

Added lines #L211 - L213 were not covered by tests
}

impl<const BITS: usize, const LIMBS: usize> SaturatingAdd for Uint<BITS, LIMBS> {
macro_rules! binary_op {
($($trait:ident $fn:ident)*) => {$(
impl<const BITS: usize, const LIMBS: usize> $trait for Uint<BITS, LIMBS> {
#[inline(always)]
fn $fn(&self, v: &Self) -> Self {
<Self>::$fn(*self, *v)
}

Check warning on line 222 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L220-L222

Added lines #L220 - L222 were not covered by tests
}
)*};
}

binary_op! {
SaturatingAdd saturating_add
SaturatingSub saturating_sub
SaturatingMul saturating_mul
WrappingAdd wrapping_add
WrappingSub wrapping_sub
WrappingMul wrapping_mul
}

impl<const BITS: usize, const LIMBS: usize> WrappingNeg for Uint<BITS, LIMBS> {
#[inline(always)]
fn saturating_add(&self, v: &Self) -> Self {
<Self>::saturating_add(*self, *v)
fn wrapping_neg(&self) -> Self {
<Self>::wrapping_neg(*self)
}

Check warning on line 240 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L238-L240

Added lines #L238 - L240 were not covered by tests
}

impl<const BITS: usize, const LIMBS: usize> SaturatingSub for Uint<BITS, LIMBS> {
impl<const BITS: usize, const LIMBS: usize> WrappingShl for Uint<BITS, LIMBS> {
#[inline(always)]
fn saturating_sub(&self, v: &Self) -> Self {
<Self>::saturating_sub(*self, *v)
fn wrapping_shl(&self, rhs: u32) -> Self {
<Self>::wrapping_shl(*self, rhs as usize)
}

Check warning on line 247 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L245-L247

Added lines #L245 - L247 were not covered by tests
}

impl<const BITS: usize, const LIMBS: usize> SaturatingMul for Uint<BITS, LIMBS> {
impl<const BITS: usize, const LIMBS: usize> WrappingShr for Uint<BITS, LIMBS> {
#[inline(always)]
fn saturating_mul(&self, v: &Self) -> Self {
<Self>::saturating_mul(*self, *v)
fn wrapping_shr(&self, rhs: u32) -> Self {
<Self>::wrapping_shr(*self, rhs as usize)
}

Check warning on line 254 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L252-L254

Added lines #L252 - L254 were not covered by tests
}

Expand All @@ -218,17 +262,63 @@ impl<const BITS: usize, const LIMBS: usize> Num for Uint<BITS, LIMBS> {
}

Check warning on line 262 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L260-L262

Added lines #L260 - L262 were not covered by tests
}

impl<const BITS: usize, const LIMBS: usize> Pow<Self> for Uint<BITS, LIMBS> {
type Output = Self;

fn pow(self, rhs: Self) -> Self::Output {
<Self>::pow(self, rhs)
}

Check warning on line 270 in src/support/num_traits.rs

View check run for this annotation

Codecov / codecov/patch

src/support/num_traits.rs#L268-L270

Added lines #L268 - L270 were not covered by tests
}

impl<const BITS: usize, const LIMBS: usize> Unsigned for Uint<BITS, LIMBS> {}

#[cfg(test)]
mod tests {
use super::*;
use crate::aliases::U256;

macro_rules! assert_impl{
($type:ident, $($trait:tt),*) => {
$({
fn assert_impl<T: $trait>() {}
assert_impl::<$type>();
})*
}
}

#[test]
fn test_assert_impl() {
fn assert_impl<T: Num + NumOps + NumAssign + NumAssignOps + NumAssignRef + NumRef>() {}

assert_impl::<U256>();
// All applicable traits from num-traits
assert_impl!(U256, Bounded, LowerBounded, UpperBounded);
// assert_impl!(U256, AsPrimitive, FromPrimitive, NumCast, ToPrimitive);
assert_impl!(U256, One, Zero);
// assert_impl!(U256, PrimInt);
assert_impl!(U256, FromBytes, ToBytes);
assert_impl!(
U256, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedSub,
CheckedShl, CheckedShr, CheckedSub
);
assert_impl!(U256, CheckedEuclid, Euclid);
assert_impl!(U256, Inv);
assert_impl!(U256, MulAdd, MulAddAssign);
// assert_impl!(U256, OverflowingAdd, OverflowingMul, OverflowingSub);
assert_impl!(
U256,
Saturating,
SaturatingAdd,
SaturatingMul,
SaturatingSub
);
assert_impl!(
U256,
WrappingAdd,
WrappingMul,
WrappingNeg,
WrappingShl,
WrappingShr,
WrappingSub
);
assert_impl!(U256, (Pow<U256>));
assert_impl!(U256, Unsigned);
}
}

0 comments on commit 3e1a234

Please sign in to comment.