Implemented Zero, One and Num for Wrapping<T>

This commit is contained in:
Yoan Lecoq 2017-04-21 09:26:53 +02:00
parent 6513a5618b
commit b024e1c326
2 changed files with 32 additions and 3 deletions

View File

@ -1,4 +1,5 @@
use std::ops::{Add, Mul}; use std::ops::{Add, Mul};
use std::num::Wrapping;
/// Defines an additive identity element for `Self`. /// Defines an additive identity element for `Self`.
pub trait Zero: Sized + Add<Self, Output = Self> { pub trait Zero: Sized + Add<Self, Output = Self> {
@ -50,6 +51,16 @@ zero_impl!(i64, 0i64);
zero_impl!(f32, 0.0f32); zero_impl!(f32, 0.0f32);
zero_impl!(f64, 0.0f64); zero_impl!(f64, 0.0f64);
impl<T: Zero + PartialEq> Zero for Wrapping<T> where Self: Add<Output=Self> {
fn is_zero(&self) -> bool {
self.0 == T::zero()
}
fn zero() -> Self {
Wrapping(T::zero())
}
}
/// Defines a multiplicative identity element for `Self`. /// Defines a multiplicative identity element for `Self`.
pub trait One: Sized + Mul<Self, Output = Self> { pub trait One: Sized + Mul<Self, Output = Self> {
/// Returns the multiplicative identity element of `Self`, `1`. /// Returns the multiplicative identity element of `Self`, `1`.
@ -94,6 +105,11 @@ one_impl!(i64, 1i64);
one_impl!(f32, 1.0f32); one_impl!(f32, 1.0f32);
one_impl!(f64, 1.0f64); one_impl!(f64, 1.0f64);
impl<T: One> One for Wrapping<T> where Self: Add<Output=Self> + Mul<Output=Self> {
fn one() -> Self {
Wrapping(T::one())
}
}
// Some helper functions provided for backwards compatibility. // Some helper functions provided for backwards compatibility.

View File

@ -15,6 +15,7 @@
html_playground_url = "http://play.integer32.com/")] html_playground_url = "http://play.integer32.com/")]
use std::ops::{Add, Sub, Mul, Div, Rem}; use std::ops::{Add, Sub, Mul, Div, Rem};
use std::num::Wrapping;
pub use bounds::Bounded; pub use bounds::Bounded;
pub use float::{Float, FloatConst}; pub use float::{Float, FloatConst};
@ -74,6 +75,18 @@ macro_rules! int_trait_impl {
} }
int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64); int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);
impl<T: Num> Num for Wrapping<T>
where Self: Zero + One
+ Add<Output = Self> + Sub<Output = Self>
+ Mul<Output = Self> + Div<Output = Self> + Rem<Output = Self>
{
type FromStrRadixErr = T::FromStrRadixErr;
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
T::from_str_radix(str, radix).map(|x| Wrapping(x))
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum FloatErrorKind { pub enum FloatErrorKind {
Empty, Empty,
@ -243,9 +256,9 @@ float_trait_impl!(Num for f32 f64);
/// A value bounded by a minimum and a maximum /// A value bounded by a minimum and a maximum
/// ///
/// If input is less than min then this returns min. /// If input is less than min then this returns min.
/// If input is greater than max then this returns max. /// If input is greater than max then this returns max.
/// Otherwise this returns input. /// Otherwise this returns input.
#[inline] #[inline]
pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T { pub fn clamp<T: PartialOrd>(input: T, min: T, max: T) -> T {
debug_assert!(min <= max, "min must be less than or equal to max"); debug_assert!(min <= max, "min must be less than or equal to max");