Run cargo fmt

This commit is contained in:
Josh Stone 2018-07-12 17:09:22 -07:00
parent 83841d15f8
commit d2bf4e04e4
14 changed files with 419 additions and 283 deletions

View File

@ -1,9 +1,9 @@
use core::{usize, u8, u16, u32, u64};
use core::{isize, i8, i16, i32, i64};
use core::{f32, f64};
use core::num::Wrapping; use core::num::Wrapping;
use core::{f32, f64};
#[cfg(has_i128)] #[cfg(has_i128)]
use core::{i128, u128}; use core::{i128, u128};
use core::{i16, i32, i64, i8, isize};
use core::{u16, u32, u64, u8, usize};
/// Numbers which have upper and lower bounds /// Numbers which have upper and lower bounds
pub trait Bounded { pub trait Bounded {
@ -18,33 +18,41 @@ macro_rules! bounded_impl {
($t:ty, $min:expr, $max:expr) => { ($t:ty, $min:expr, $max:expr) => {
impl Bounded for $t { impl Bounded for $t {
#[inline] #[inline]
fn min_value() -> $t { $min } fn min_value() -> $t {
$min
}
#[inline] #[inline]
fn max_value() -> $t { $max } fn max_value() -> $t {
$max
}
} }
} };
} }
bounded_impl!(usize, usize::MIN, usize::MAX); bounded_impl!(usize, usize::MIN, usize::MAX);
bounded_impl!(u8, u8::MIN, u8::MAX); bounded_impl!(u8, u8::MIN, u8::MAX);
bounded_impl!(u16, u16::MIN, u16::MAX); bounded_impl!(u16, u16::MIN, u16::MAX);
bounded_impl!(u32, u32::MIN, u32::MAX); bounded_impl!(u32, u32::MIN, u32::MAX);
bounded_impl!(u64, u64::MIN, u64::MAX); bounded_impl!(u64, u64::MIN, u64::MAX);
#[cfg(has_i128)] #[cfg(has_i128)]
bounded_impl!(u128, u128::MIN, u128::MAX); bounded_impl!(u128, u128::MIN, u128::MAX);
bounded_impl!(isize, isize::MIN, isize::MAX); bounded_impl!(isize, isize::MIN, isize::MAX);
bounded_impl!(i8, i8::MIN, i8::MAX); bounded_impl!(i8, i8::MIN, i8::MAX);
bounded_impl!(i16, i16::MIN, i16::MAX); bounded_impl!(i16, i16::MIN, i16::MAX);
bounded_impl!(i32, i32::MIN, i32::MAX); bounded_impl!(i32, i32::MIN, i32::MAX);
bounded_impl!(i64, i64::MIN, i64::MAX); bounded_impl!(i64, i64::MIN, i64::MAX);
#[cfg(has_i128)] #[cfg(has_i128)]
bounded_impl!(i128, i128::MIN, i128::MAX); bounded_impl!(i128, i128::MIN, i128::MAX);
impl<T: Bounded> Bounded for Wrapping<T> { impl<T: Bounded> Bounded for Wrapping<T> {
fn min_value() -> Self { Wrapping(T::min_value()) } fn min_value() -> Self {
fn max_value() -> Self { Wrapping(T::max_value()) } Wrapping(T::min_value())
}
fn max_value() -> Self {
Wrapping(T::max_value())
}
} }
bounded_impl!(f32, f32::MIN, f32::MAX); bounded_impl!(f32, f32::MIN, f32::MAX);
@ -59,9 +67,9 @@ macro_rules! for_each_tuple_ {
); );
} }
macro_rules! for_each_tuple { macro_rules! for_each_tuple {
( $m:ident ) => ( ($m:ident) => {
for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, } for_each_tuple_! { $m !! A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, }
); };
} }
macro_rules! bounded_tuple { macro_rules! bounded_tuple {
@ -82,7 +90,6 @@ macro_rules! bounded_tuple {
for_each_tuple!(bounded_tuple); for_each_tuple!(bounded_tuple);
bounded_impl!(f64, f64::MIN, f64::MAX); bounded_impl!(f64, f64::MIN, f64::MAX);
#[test] #[test]
fn wrapping_bounded() { fn wrapping_bounded() {
macro_rules! test_wrapping_bounded { macro_rules! test_wrapping_bounded {

View File

@ -1,10 +1,10 @@
use core::{i8, i16, i32, i64, isize};
use core::{u8, u16, u32, u64, usize};
use core::{f32, f64};
use core::mem::size_of; use core::mem::size_of;
use core::num::Wrapping; use core::num::Wrapping;
use core::{f32, f64};
#[cfg(has_i128)] #[cfg(has_i128)]
use core::{i128, u128}; use core::{i128, u128};
use core::{i16, i32, i64, i8, isize};
use core::{u16, u32, u64, u8, usize};
use float::FloatCore; use float::FloatCore;
@ -137,7 +137,7 @@ macro_rules! impl_to_primitive_int_to_uint {
} }
macro_rules! impl_to_primitive_int { macro_rules! impl_to_primitive_int {
($T:ident) => ( ($T:ident) => {
impl ToPrimitive for $T { impl ToPrimitive for $T {
impl_to_primitive_int_to_int! { $T: impl_to_primitive_int_to_int! { $T:
fn to_isize -> isize; fn to_isize -> isize;
@ -160,11 +160,15 @@ macro_rules! impl_to_primitive_int {
} }
#[inline] #[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) } fn to_f32(&self) -> Option<f32> {
Some(*self as f32)
}
#[inline] #[inline]
fn to_f64(&self) -> Option<f64> { Some(*self as f64) } fn to_f64(&self) -> Option<f64> {
Some(*self as f64)
}
} }
) };
} }
impl_to_primitive_int!(isize); impl_to_primitive_int!(isize);
@ -206,7 +210,7 @@ macro_rules! impl_to_primitive_uint_to_uint {
} }
macro_rules! impl_to_primitive_uint { macro_rules! impl_to_primitive_uint {
($T:ident) => ( ($T:ident) => {
impl ToPrimitive for $T { impl ToPrimitive for $T {
impl_to_primitive_uint_to_int! { $T: impl_to_primitive_uint_to_int! { $T:
fn to_isize -> isize; fn to_isize -> isize;
@ -229,11 +233,15 @@ macro_rules! impl_to_primitive_uint {
} }
#[inline] #[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) } fn to_f32(&self) -> Option<f32> {
Some(*self as f32)
}
#[inline] #[inline]
fn to_f64(&self) -> Option<f64> { Some(*self as f64) } fn to_f64(&self) -> Option<f64> {
Some(*self as f64)
}
} }
) };
} }
impl_to_primitive_uint!(usize); impl_to_primitive_uint!(usize);
@ -319,7 +327,7 @@ macro_rules! impl_to_primitive_float_to_unsigned_int {
} }
macro_rules! impl_to_primitive_float { macro_rules! impl_to_primitive_float {
($T:ident) => ( ($T:ident) => {
impl ToPrimitive for $T { impl ToPrimitive for $T {
impl_to_primitive_float_to_signed_int! { $T: impl_to_primitive_float_to_signed_int! { $T:
fn to_isize -> isize; fn to_isize -> isize;
@ -346,7 +354,7 @@ macro_rules! impl_to_primitive_float {
fn to_f64 -> f64; fn to_f64 -> f64;
} }
} }
) };
} }
impl_to_primitive_float!(f32); impl_to_primitive_float!(f32);
@ -463,48 +471,89 @@ pub trait FromPrimitive: Sized {
} }
macro_rules! impl_from_primitive { macro_rules! impl_from_primitive {
($T:ty, $to_ty:ident) => ( ($T:ty, $to_ty:ident) => {
#[allow(deprecated)] #[allow(deprecated)]
impl FromPrimitive for $T { impl FromPrimitive for $T {
#[inline] fn from_isize(n: isize) -> Option<$T> { n.$to_ty() } #[inline]
#[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() } fn from_isize(n: isize) -> Option<$T> {
#[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() } n.$to_ty()
#[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() } }
#[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() } #[inline]
fn from_i8(n: i8) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_i16(n: i16) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_i32(n: i32) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_i64(n: i64) -> Option<$T> {
n.$to_ty()
}
#[cfg(has_i128)] #[cfg(has_i128)]
#[inline] fn from_i128(n: i128) -> Option<$T> { n.$to_ty() } #[inline]
fn from_i128(n: i128) -> Option<$T> {
n.$to_ty()
}
#[inline] fn from_usize(n: usize) -> Option<$T> { n.$to_ty() } #[inline]
#[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() } fn from_usize(n: usize) -> Option<$T> {
#[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() } n.$to_ty()
#[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() } }
#[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() } #[inline]
fn from_u8(n: u8) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_u16(n: u16) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_u32(n: u32) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_u64(n: u64) -> Option<$T> {
n.$to_ty()
}
#[cfg(has_i128)] #[cfg(has_i128)]
#[inline] fn from_u128(n: u128) -> Option<$T> { n.$to_ty() } #[inline]
fn from_u128(n: u128) -> Option<$T> {
n.$to_ty()
}
#[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() } #[inline]
#[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() } fn from_f32(n: f32) -> Option<$T> {
n.$to_ty()
}
#[inline]
fn from_f64(n: f64) -> Option<$T> {
n.$to_ty()
}
} }
) };
} }
impl_from_primitive!(isize, to_isize); impl_from_primitive!(isize, to_isize);
impl_from_primitive!(i8, to_i8); impl_from_primitive!(i8, to_i8);
impl_from_primitive!(i16, to_i16); impl_from_primitive!(i16, to_i16);
impl_from_primitive!(i32, to_i32); impl_from_primitive!(i32, to_i32);
impl_from_primitive!(i64, to_i64); impl_from_primitive!(i64, to_i64);
#[cfg(has_i128)] #[cfg(has_i128)]
impl_from_primitive!(i128, to_i128); impl_from_primitive!(i128, to_i128);
impl_from_primitive!(usize, to_usize); impl_from_primitive!(usize, to_usize);
impl_from_primitive!(u8, to_u8); impl_from_primitive!(u8, to_u8);
impl_from_primitive!(u16, to_u16); impl_from_primitive!(u16, to_u16);
impl_from_primitive!(u32, to_u32); impl_from_primitive!(u32, to_u32);
impl_from_primitive!(u64, to_u64); impl_from_primitive!(u64, to_u64);
#[cfg(has_i128)] #[cfg(has_i128)]
impl_from_primitive!(u128, to_u128); impl_from_primitive!(u128, to_u128);
impl_from_primitive!(f32, to_f32); impl_from_primitive!(f32, to_f32);
impl_from_primitive!(f64, to_f64); impl_from_primitive!(f64, to_f64);
macro_rules! impl_to_primitive_wrapping { macro_rules! impl_to_primitive_wrapping {
($( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$( ($( $(#[$cfg:meta])* fn $method:ident -> $i:ident ; )*) => {$(
@ -572,7 +621,6 @@ impl<T: FromPrimitive> FromPrimitive for Wrapping<T> {
} }
} }
/// Cast from one machine scalar to another. /// Cast from one machine scalar to another.
/// ///
/// # Examples /// # Examples
@ -596,7 +644,7 @@ pub trait NumCast: Sized + ToPrimitive {
} }
macro_rules! impl_num_cast { macro_rules! impl_num_cast {
($T:ty, $conv:ident) => ( ($T:ty, $conv:ident) => {
impl NumCast for $T { impl NumCast for $T {
#[inline] #[inline]
#[allow(deprecated)] #[allow(deprecated)]
@ -606,25 +654,25 @@ macro_rules! impl_num_cast {
n.$conv() n.$conv()
} }
} }
) };
} }
impl_num_cast!(u8, to_u8); impl_num_cast!(u8, to_u8);
impl_num_cast!(u16, to_u16); impl_num_cast!(u16, to_u16);
impl_num_cast!(u32, to_u32); impl_num_cast!(u32, to_u32);
impl_num_cast!(u64, to_u64); impl_num_cast!(u64, to_u64);
#[cfg(has_i128)] #[cfg(has_i128)]
impl_num_cast!(u128, to_u128); impl_num_cast!(u128, to_u128);
impl_num_cast!(usize, to_usize); impl_num_cast!(usize, to_usize);
impl_num_cast!(i8, to_i8); impl_num_cast!(i8, to_i8);
impl_num_cast!(i16, to_i16); impl_num_cast!(i16, to_i16);
impl_num_cast!(i32, to_i32); impl_num_cast!(i32, to_i32);
impl_num_cast!(i64, to_i64); impl_num_cast!(i64, to_i64);
#[cfg(has_i128)] #[cfg(has_i128)]
impl_num_cast!(i128, to_i128); impl_num_cast!(i128, to_i128);
impl_num_cast!(isize, to_isize); impl_num_cast!(isize, to_isize);
impl_num_cast!(f32, to_f32); impl_num_cast!(f32, to_f32);
impl_num_cast!(f64, to_f64); impl_num_cast!(f64, to_f64);
impl<T: NumCast> NumCast for Wrapping<T> { impl<T: NumCast> NumCast for Wrapping<T> {
fn from<U: ToPrimitive>(n: U) -> Option<Self> { fn from<U: ToPrimitive>(n: U) -> Option<Self> {
@ -645,20 +693,20 @@ impl<T: NumCast> NumCast for Wrapping<T> {
/// let three: i32 = (3.14159265f32).as_(); /// let three: i32 = (3.14159265f32).as_();
/// assert_eq!(three, 3); /// assert_eq!(three, 3);
/// ``` /// ```
/// ///
/// # Safety /// # Safety
/// ///
/// Currently, some uses of the `as` operator are not entirely safe. /// Currently, some uses of the `as` operator are not entirely safe.
/// In particular, it is undefined behavior if: /// In particular, it is undefined behavior if:
/// ///
/// - A truncated floating point value cannot fit in the target integer /// - A truncated floating point value cannot fit in the target integer
/// type ([#10184](https://github.com/rust-lang/rust/issues/10184)); /// type ([#10184](https://github.com/rust-lang/rust/issues/10184));
/// ///
/// ```ignore /// ```ignore
/// # use num_traits::AsPrimitive; /// # use num_traits::AsPrimitive;
/// let x: u8 = (1.04E+17).as_(); // UB /// let x: u8 = (1.04E+17).as_(); // UB
/// ``` /// ```
/// ///
/// - Or a floating point value does not fit in another floating /// - Or a floating point value does not fit in another floating
/// point type ([#15536](https://github.com/rust-lang/rust/issues/15536)). /// point type ([#15536](https://github.com/rust-lang/rust/issues/15536)).
/// ///
@ -666,10 +714,10 @@ impl<T: NumCast> NumCast for Wrapping<T> {
/// # use num_traits::AsPrimitive; /// # use num_traits::AsPrimitive;
/// let x: f32 = (1e300f64).as_(); // UB /// let x: f32 = (1e300f64).as_(); // UB
/// ``` /// ```
/// ///
pub trait AsPrimitive<T>: 'static + Copy pub trait AsPrimitive<T>: 'static + Copy
where where
T: 'static + Copy T: 'static + Copy,
{ {
/// Convert a value to another, using the `as` operator. /// Convert a value to another, using the `as` operator.
fn as_(self) -> T; fn as_(self) -> T;
@ -712,4 +760,3 @@ impl_as_primitive!(f32 => { f32, f64 });
impl_as_primitive!(f64 => { f32, f64 }); impl_as_primitive!(f64 => { f32, f64 });
impl_as_primitive!(char => { char }); impl_as_primitive!(char => { char });
impl_as_primitive!(bool => {}); impl_as_primitive!(bool => {});

View File

@ -1,6 +1,6 @@
use core::mem; use core::mem;
use core::ops::Neg;
use core::num::FpCategory; use core::num::FpCategory;
use core::ops::Neg;
use core::f32; use core::f32;
use core::f64; use core::f64;
@ -586,7 +586,11 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
if other.is_nan() { if other.is_nan() {
return self; return self;
} }
if self < other { self } else { other } if self < other {
self
} else {
other
}
} }
/// Returns the maximum of the two numbers. /// Returns the maximum of the two numbers.
@ -616,7 +620,11 @@ pub trait FloatCore: Num + NumCast + Neg<Output = Self> + PartialOrd + Copy {
if other.is_nan() { if other.is_nan() {
return self; return self;
} }
if self > other { self } else { other } if self > other {
self
} else {
other
}
} }
/// Returns the reciprocal (multiplicative inverse) of the number. /// Returns the reciprocal (multiplicative inverse) of the number.
@ -887,13 +895,7 @@ impl FloatCore for f64 {
/// ///
/// This trait is only available with the `std` feature. /// This trait is only available with the `std` feature.
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub trait Float pub trait Float: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
: Num
+ Copy
+ NumCast
+ PartialOrd
+ Neg<Output = Self>
{
/// Returns the `NaN` value. /// Returns the `NaN` value.
/// ///
/// ``` /// ```
@ -1777,7 +1779,6 @@ pub trait Float
/// ``` /// ```
fn atanh(self) -> Self; fn atanh(self) -> Self;
/// Returns the mantissa, base 2 exponent, and sign as integers, respectively. /// Returns the mantissa, base 2 exponent, and sign as integers, respectively.
/// The original number can be recovered by `sign * mantissa * 2 ^ exponent`. /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`.
/// ///
@ -1802,7 +1803,7 @@ pub trait Float
#[cfg(feature = "std")] #[cfg(feature = "std")]
macro_rules! float_impl { macro_rules! float_impl {
($T:ident $decode:ident) => ( ($T:ident $decode:ident) => {
impl Float for $T { impl Float for $T {
constant! { constant! {
nan() -> $T::NAN; nan() -> $T::NAN;
@ -1876,16 +1877,12 @@ macro_rules! float_impl {
Self::atanh(self) -> Self; Self::atanh(self) -> Self;
} }
} }
) };
} }
fn integer_decode_f32(f: f32) -> (u64, i16, i8) { fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
let bits: u32 = unsafe { mem::transmute(f) }; let bits: u32 = unsafe { mem::transmute(f) };
let sign: i8 = if bits >> 31 == 0 { let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
1
} else {
-1
};
let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
let mantissa = if exponent == 0 { let mantissa = if exponent == 0 {
(bits & 0x7fffff) << 1 (bits & 0x7fffff) << 1
@ -1899,11 +1896,7 @@ fn integer_decode_f32(f: f32) -> (u64, i16, i8) {
fn integer_decode_f64(f: f64) -> (u64, i16, i8) { fn integer_decode_f64(f: f64) -> (u64, i16, i8) {
let bits: u64 = unsafe { mem::transmute(f) }; let bits: u64 = unsafe { mem::transmute(f) };
let sign: i8 = if bits >> 63 == 0 { let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
1
} else {
-1
};
let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
let mantissa = if exponent == 0 { let mantissa = if exponent == 0 {
(bits & 0xfffffffffffff) << 1 (bits & 0xfffffffffffff) << 1
@ -2023,6 +2016,9 @@ mod tests {
fn to_degrees_rounding() { fn to_degrees_rounding() {
use float::FloatCore; use float::FloatCore;
assert_eq!(FloatCore::to_degrees(1_f32), 57.2957795130823208767981548141051703); assert_eq!(
FloatCore::to_degrees(1_f32),
57.2957795130823208767981548141051703
);
} }
} }

View File

@ -1,5 +1,5 @@
use core::ops::{Add, Mul};
use core::num::Wrapping; use core::num::Wrapping;
use core::ops::{Add, Mul};
/// 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> {
@ -29,33 +29,40 @@ macro_rules! zero_impl {
($t:ty, $v:expr) => { ($t:ty, $v:expr) => {
impl Zero for $t { impl Zero for $t {
#[inline] #[inline]
fn zero() -> $t { $v } fn zero() -> $t {
$v
}
#[inline] #[inline]
fn is_zero(&self) -> bool { *self == $v } fn is_zero(&self) -> bool {
*self == $v
}
} }
} };
} }
zero_impl!(usize, 0); zero_impl!(usize, 0);
zero_impl!(u8, 0); zero_impl!(u8, 0);
zero_impl!(u16, 0); zero_impl!(u16, 0);
zero_impl!(u32, 0); zero_impl!(u32, 0);
zero_impl!(u64, 0); zero_impl!(u64, 0);
#[cfg(has_i128)] #[cfg(has_i128)]
zero_impl!(u128, 0); zero_impl!(u128, 0);
zero_impl!(isize, 0); zero_impl!(isize, 0);
zero_impl!(i8, 0); zero_impl!(i8, 0);
zero_impl!(i16, 0); zero_impl!(i16, 0);
zero_impl!(i32, 0); zero_impl!(i32, 0);
zero_impl!(i64, 0); zero_impl!(i64, 0);
#[cfg(has_i128)] #[cfg(has_i128)]
zero_impl!(i128, 0); zero_impl!(i128, 0);
zero_impl!(f32, 0.0); zero_impl!(f32, 0.0);
zero_impl!(f64, 0.0); zero_impl!(f64, 0.0);
impl<T: Zero> Zero for Wrapping<T> where Wrapping<T>: Add<Output=Wrapping<T>> { impl<T: Zero> Zero for Wrapping<T>
where
Wrapping<T>: Add<Output = Wrapping<T>>,
{
fn is_zero(&self) -> bool { fn is_zero(&self) -> bool {
self.0.is_zero() self.0.is_zero()
} }
@ -64,7 +71,6 @@ impl<T: Zero> Zero for Wrapping<T> where Wrapping<T>: Add<Output=Wrapping<T>> {
} }
} }
/// 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`.
@ -90,7 +96,10 @@ pub trait One: Sized + Mul<Self, Output = Self> {
/// After a semver bump, this method will be required, and the /// After a semver bump, this method will be required, and the
/// `where Self: PartialEq` bound will be removed. /// `where Self: PartialEq` bound will be removed.
#[inline] #[inline]
fn is_one(&self) -> bool where Self: PartialEq { fn is_one(&self) -> bool
where
Self: PartialEq,
{
*self == Self::one() *self == Self::one()
} }
} }
@ -99,31 +108,36 @@ macro_rules! one_impl {
($t:ty, $v:expr) => { ($t:ty, $v:expr) => {
impl One for $t { impl One for $t {
#[inline] #[inline]
fn one() -> $t { $v } fn one() -> $t {
$v
}
} }
} };
} }
one_impl!(usize, 1); one_impl!(usize, 1);
one_impl!(u8, 1); one_impl!(u8, 1);
one_impl!(u16, 1); one_impl!(u16, 1);
one_impl!(u32, 1); one_impl!(u32, 1);
one_impl!(u64, 1); one_impl!(u64, 1);
#[cfg(has_i128)] #[cfg(has_i128)]
one_impl!(u128, 1); one_impl!(u128, 1);
one_impl!(isize, 1); one_impl!(isize, 1);
one_impl!(i8, 1); one_impl!(i8, 1);
one_impl!(i16, 1); one_impl!(i16, 1);
one_impl!(i32, 1); one_impl!(i32, 1);
one_impl!(i64, 1); one_impl!(i64, 1);
#[cfg(has_i128)] #[cfg(has_i128)]
one_impl!(i128, 1); one_impl!(i128, 1);
one_impl!(f32, 1.0); one_impl!(f32, 1.0);
one_impl!(f64, 1.0); one_impl!(f64, 1.0);
impl<T: One> One for Wrapping<T> where Wrapping<T>: Mul<Output=Wrapping<T>> { impl<T: One> One for Wrapping<T>
where
Wrapping<T>: Mul<Output = Wrapping<T>>,
{
fn one() -> Self { fn one() -> Self {
Wrapping(T::one()) Wrapping(T::one())
} }
@ -132,11 +146,16 @@ impl<T: One> One for Wrapping<T> where Wrapping<T>: Mul<Output=Wrapping<T>> {
// Some helper functions provided for backwards compatibility. // Some helper functions provided for backwards compatibility.
/// Returns the additive identity, `0`. /// Returns the additive identity, `0`.
#[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() } #[inline(always)]
pub fn zero<T: Zero>() -> T {
Zero::zero()
}
/// Returns the multiplicative identity, `1`. /// Returns the multiplicative identity, `1`.
#[inline(always)] pub fn one<T: One>() -> T { One::one() } #[inline(always)]
pub fn one<T: One>() -> T {
One::one()
}
#[test] #[test]
fn wrapping_identities() { fn wrapping_identities() {

View File

@ -1,26 +1,29 @@
use core::ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr}; use core::ops::{BitAnd, BitOr, BitXor, Not, Shl, Shr};
use {Num, NumCast};
use bounds::Bounded; use bounds::Bounded;
use ops::checked::*; use ops::checked::*;
use ops::saturating::Saturating; use ops::saturating::Saturating;
use {Num, NumCast};
pub trait PrimInt pub trait PrimInt:
: Sized Sized
+ Copy + Copy
+ Num + NumCast + Num
+ NumCast
+ Bounded + Bounded
+ PartialOrd + Ord + Eq + PartialOrd
+ Not<Output=Self> + Ord
+ BitAnd<Output=Self> + Eq
+ BitOr<Output=Self> + Not<Output = Self>
+ BitXor<Output=Self> + BitAnd<Output = Self>
+ Shl<usize, Output=Self> + BitOr<Output = Self>
+ Shr<usize, Output=Self> + BitXor<Output = Self>
+ CheckedAdd<Output=Self> + Shl<usize, Output = Self>
+ CheckedSub<Output=Self> + Shr<usize, Output = Self>
+ CheckedMul<Output=Self> + CheckedAdd<Output = Self>
+ CheckedDiv<Output=Self> + CheckedSub<Output = Self>
+ CheckedMul<Output = Self>
+ CheckedDiv<Output = Self>
+ Saturating + Saturating
{ {
/// Returns the number of ones in the binary representation of `self`. /// Returns the number of ones in the binary representation of `self`.
@ -278,7 +281,7 @@ pub trait PrimInt
} }
macro_rules! prim_int_impl { macro_rules! prim_int_impl {
($T:ty, $S:ty, $U:ty) => ( ($T:ty, $S:ty, $U:ty) => {
impl PrimInt for $T { impl PrimInt for $T {
#[inline] #[inline]
fn count_ones(self) -> u32 { fn count_ones(self) -> u32 {
@ -360,21 +363,21 @@ macro_rules! prim_int_impl {
<$T>::pow(self, exp) <$T>::pow(self, exp)
} }
} }
) };
} }
// prim_int_impl!(type, signed, unsigned); // prim_int_impl!(type, signed, unsigned);
prim_int_impl!(u8, i8, u8); prim_int_impl!(u8, i8, u8);
prim_int_impl!(u16, i16, u16); prim_int_impl!(u16, i16, u16);
prim_int_impl!(u32, i32, u32); prim_int_impl!(u32, i32, u32);
prim_int_impl!(u64, i64, u64); prim_int_impl!(u64, i64, u64);
#[cfg(has_i128)] #[cfg(has_i128)]
prim_int_impl!(u128, i128, u128); prim_int_impl!(u128, i128, u128);
prim_int_impl!(usize, isize, usize); prim_int_impl!(usize, isize, usize);
prim_int_impl!(i8, i8, u8); prim_int_impl!(i8, i8, u8);
prim_int_impl!(i16, i16, u16); prim_int_impl!(i16, i16, u16);
prim_int_impl!(i32, i32, u32); prim_int_impl!(i32, i32, u32);
prim_int_impl!(i64, i64, u64); prim_int_impl!(i64, i64, u64);
#[cfg(has_i128)] #[cfg(has_i128)]
prim_int_impl!(i128, i128, u128); prim_int_impl!(i128, i128, u128);
prim_int_impl!(isize, isize, usize); prim_int_impl!(isize, isize, usize);

View File

@ -15,53 +15,51 @@
//! The `num-traits` crate is tested for rustc 1.8 and greater. //! The `num-traits` crate is tested for rustc 1.8 and greater.
#![doc(html_root_url = "https://docs.rs/num-traits/0.2")] #![doc(html_root_url = "https://docs.rs/num-traits/0.2")]
#![deny(unconditional_recursion)] #![deny(unconditional_recursion)]
#![no_std] #![no_std]
#[cfg(feature = "std")] #[cfg(feature = "std")]
extern crate std; extern crate std;
use core::ops::{Add, Sub, Mul, Div, Rem};
use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
use core::num::Wrapping;
use core::fmt; use core::fmt;
use core::num::Wrapping;
use core::ops::{Add, Div, Mul, Rem, Sub};
use core::ops::{AddAssign, DivAssign, MulAssign, RemAssign, SubAssign};
pub use bounds::Bounded; pub use bounds::Bounded;
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use float::Float; pub use float::Float;
pub use float::FloatConst; pub use float::FloatConst;
// pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`. // pub use real::{FloatCore, Real}; // NOTE: Don't do this, it breaks `use num_traits::*;`.
pub use identities::{Zero, One, zero, one}; pub use cast::{cast, AsPrimitive, FromPrimitive, NumCast, ToPrimitive};
pub use identities::{one, zero, One, Zero};
pub use int::PrimInt;
pub use ops::checked::{
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr, CheckedSub,
};
pub use ops::inv::Inv; pub use ops::inv::Inv;
pub use ops::checked::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
CheckedRem, CheckedNeg, CheckedShl, CheckedShr};
pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingSub};
pub use ops::mul_add::{MulAdd, MulAddAssign}; pub use ops::mul_add::{MulAdd, MulAddAssign};
pub use ops::saturating::Saturating; pub use ops::saturating::Saturating;
pub use sign::{Signed, Unsigned, abs, abs_sub, signum}; pub use ops::wrapping::{WrappingAdd, WrappingMul, WrappingSub};
pub use cast::{AsPrimitive, FromPrimitive, ToPrimitive, NumCast, cast}; pub use pow::{checked_pow, pow, Pow};
pub use int::PrimInt; pub use sign::{abs, abs_sub, signum, Signed, Unsigned};
pub use pow::{Pow, pow, checked_pow};
#[macro_use] #[macro_use]
mod macros; mod macros;
pub mod identities;
pub mod sign;
pub mod ops;
pub mod bounds; pub mod bounds;
pub mod cast;
pub mod float; pub mod float;
pub mod identities;
pub mod int;
pub mod ops;
pub mod pow;
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub mod real; pub mod real;
pub mod cast; pub mod sign;
pub mod int;
pub mod pow;
/// The base trait for numeric types, covering `0` and `1` values, /// The base trait for numeric types, covering `0` and `1` values,
/// comparisons, basic numeric operations, and string conversion. /// comparisons, basic numeric operations, and string conversion.
pub trait Num: PartialEq + Zero + One + NumOps pub trait Num: PartialEq + Zero + One + NumOps {
{
type FromStrRadixErr; type FromStrRadixErr;
/// Convert from a string and radix <= 36. /// Convert from a string and radix <= 36.
@ -83,68 +81,81 @@ pub trait Num: PartialEq + Zero + One + NumOps
/// The trait for types implementing basic numeric operations /// The trait for types implementing basic numeric operations
/// ///
/// This is automatically implemented for types which implement the operators. /// This is automatically implemented for types which implement the operators.
pub trait NumOps<Rhs = Self, Output = Self> pub trait NumOps<Rhs = Self, Output = Self>:
: Add<Rhs, Output = Output> Add<Rhs, Output = Output>
+ Sub<Rhs, Output = Output> + Sub<Rhs, Output = Output>
+ Mul<Rhs, Output = Output> + Mul<Rhs, Output = Output>
+ Div<Rhs, Output = Output> + Div<Rhs, Output = Output>
+ Rem<Rhs, Output = Output> + Rem<Rhs, Output = Output>
{} {
}
impl<T, Rhs, Output> NumOps<Rhs, Output> for T impl<T, Rhs, Output> NumOps<Rhs, Output> for T
where T: Add<Rhs, Output = Output> where
+ Sub<Rhs, Output = Output> T: Add<Rhs, Output = Output>
+ Mul<Rhs, Output = Output> + Sub<Rhs, Output = Output>
+ Div<Rhs, Output = Output> + Mul<Rhs, Output = Output>
+ Rem<Rhs, Output = Output> + Div<Rhs, Output = Output>
{} + Rem<Rhs, Output = Output>,
{
}
/// The trait for `Num` types which also implement numeric operations taking /// The trait for `Num` types which also implement numeric operations taking
/// the second operand by reference. /// the second operand by reference.
/// ///
/// This is automatically implemented for types which implement the operators. /// This is automatically implemented for types which implement the operators.
pub trait NumRef: Num + for<'r> NumOps<&'r Self> {} pub trait NumRef: Num + for<'r> NumOps<&'r Self> {}
impl<T> NumRef for T where T: Num + for<'r> NumOps<&'r T> {} impl<T> NumRef for T
where
T: Num + for<'r> NumOps<&'r T>,
{
}
/// The trait for references which implement numeric operations, taking the /// The trait for references which implement numeric operations, taking the
/// second operand either by value or by reference. /// second operand either by value or by reference.
/// ///
/// This is automatically implemented for types which implement the operators. /// This is automatically implemented for types which implement the operators.
pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {} pub trait RefNum<Base>: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {}
impl<T, Base> RefNum<Base> for T where T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base> {} impl<T, Base> RefNum<Base> for T
where
T: NumOps<Base, Base> + for<'r> NumOps<&'r Base, Base>,
{
}
/// The trait for types implementing numeric assignment operators (like `+=`). /// The trait for types implementing numeric assignment operators (like `+=`).
/// ///
/// This is automatically implemented for types which implement the operators. /// This is automatically implemented for types which implement the operators.
pub trait NumAssignOps<Rhs = Self> pub trait NumAssignOps<Rhs = Self>:
: AddAssign<Rhs> AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>
+ SubAssign<Rhs> {
+ MulAssign<Rhs> }
+ DivAssign<Rhs>
+ RemAssign<Rhs>
{}
impl<T, Rhs> NumAssignOps<Rhs> for T impl<T, Rhs> NumAssignOps<Rhs> for T
where T: AddAssign<Rhs> where
+ SubAssign<Rhs> T: AddAssign<Rhs> + SubAssign<Rhs> + MulAssign<Rhs> + DivAssign<Rhs> + RemAssign<Rhs>,
+ MulAssign<Rhs> {
+ DivAssign<Rhs> }
+ RemAssign<Rhs>
{}
/// The trait for `Num` types which also implement assignment operators. /// The trait for `Num` types which also implement assignment operators.
/// ///
/// This is automatically implemented for types which implement the operators. /// This is automatically implemented for types which implement the operators.
pub trait NumAssign: Num + NumAssignOps {} pub trait NumAssign: Num + NumAssignOps {}
impl<T> NumAssign for T where T: Num + NumAssignOps {} impl<T> NumAssign for T
where
T: Num + NumAssignOps,
{
}
/// The trait for `NumAssign` types which also implement assignment operations /// The trait for `NumAssign` types which also implement assignment operations
/// taking the second operand by reference. /// taking the second operand by reference.
/// ///
/// This is automatically implemented for types which implement the operators. /// This is automatically implemented for types which implement the operators.
pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {} pub trait NumAssignRef: NumAssign + for<'r> NumAssignOps<&'r Self> {}
impl<T> NumAssignRef for T where T: NumAssign + for<'r> NumAssignOps<&'r T> {} impl<T> NumAssignRef for T
where
T: NumAssign + for<'r> NumAssignOps<&'r T>,
{
}
macro_rules! int_trait_impl { macro_rules! int_trait_impl {
($name:ident for $($t:ty)*) => ($( ($name:ident for $($t:ty)*) => ($(
@ -164,9 +175,12 @@ int_trait_impl!(Num for usize u8 u16 u32 u64 isize i8 i16 i32 i64);
int_trait_impl!(Num for u128 i128); int_trait_impl!(Num for u128 i128);
impl<T: Num> Num for Wrapping<T> impl<T: Num> Num for Wrapping<T>
where Wrapping<T>: where
Add<Output = Wrapping<T>> + Sub<Output = Wrapping<T>> Wrapping<T>: Add<Output = Wrapping<T>>
+ Mul<Output = Wrapping<T>> + Div<Output = Wrapping<T>> + Rem<Output = Wrapping<T>> + Sub<Output = Wrapping<T>>
+ Mul<Output = Wrapping<T>>
+ Div<Output = Wrapping<T>>
+ Rem<Output = Wrapping<T>>,
{ {
type FromStrRadixErr = T::FromStrRadixErr; type FromStrRadixErr = T::FromStrRadixErr;
fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> { fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> {
@ -174,7 +188,6 @@ impl<T: Num> Num for Wrapping<T>
} }
} }
#[derive(Debug)] #[derive(Debug)]
pub enum FloatErrorKind { pub enum FloatErrorKind {
Empty, Empty,
@ -442,7 +455,8 @@ fn check_numref_ops() {
#[test] #[test]
fn check_refnum_ops() { fn check_refnum_ops() {
fn compute<T: Copy>(x: &T, y: T) -> T fn compute<T: Copy>(x: &T, y: T) -> T
where for<'a> &'a T: RefNum<T> where
for<'a> &'a T: RefNum<T>,
{ {
&(&(&(&(x * y) / y) % y) + y) - y &(&(&(&(x * y) / y) % y) + y) - y
} }
@ -452,7 +466,8 @@ fn check_refnum_ops() {
#[test] #[test]
fn check_refref_ops() { fn check_refref_ops() {
fn compute<T>(x: &T, y: &T) -> T fn compute<T>(x: &T, y: &T) -> T
where for<'a> &'a T: RefNum<T> where
for<'a> &'a T: RefNum<T>,
{ {
&(&(&(&(x * y) / y) % y) + y) - y &(&(&(&(x * y) / y) % y) + y) - y
} }

View File

@ -1,8 +1,8 @@
use core::ops::{Add, Sub, Mul, Div, Rem, Shl, Shr}; use core::ops::{Add, Div, Mul, Rem, Shl, Shr, Sub};
/// Performs addition that returns `None` instead of wrapping around on /// Performs addition that returns `None` instead of wrapping around on
/// overflow. /// overflow.
pub trait CheckedAdd: Sized + Add<Self, Output=Self> { pub trait CheckedAdd: Sized + Add<Self, Output = Self> {
/// Adds two numbers, checking for overflow. If overflow happens, `None` is /// Adds two numbers, checking for overflow. If overflow happens, `None` is
/// returned. /// returned.
fn checked_add(&self, v: &Self) -> Option<Self>; fn checked_add(&self, v: &Self) -> Option<Self>;
@ -16,7 +16,7 @@ macro_rules! checked_impl {
<$t>::$method(*self, *v) <$t>::$method(*self, *v)
} }
} }
} };
} }
checked_impl!(CheckedAdd, checked_add, u8); checked_impl!(CheckedAdd, checked_add, u8);
@ -36,7 +36,7 @@ checked_impl!(CheckedAdd, checked_add, isize);
checked_impl!(CheckedAdd, checked_add, i128); checked_impl!(CheckedAdd, checked_add, i128);
/// Performs subtraction that returns `None` instead of wrapping around on underflow. /// Performs subtraction that returns `None` instead of wrapping around on underflow.
pub trait CheckedSub: Sized + Sub<Self, Output=Self> { pub trait CheckedSub: Sized + Sub<Self, Output = Self> {
/// Subtracts two numbers, checking for underflow. If underflow happens, /// Subtracts two numbers, checking for underflow. If underflow happens,
/// `None` is returned. /// `None` is returned.
fn checked_sub(&self, v: &Self) -> Option<Self>; fn checked_sub(&self, v: &Self) -> Option<Self>;
@ -60,7 +60,7 @@ checked_impl!(CheckedSub, checked_sub, i128);
/// Performs multiplication that returns `None` instead of wrapping around on underflow or /// Performs multiplication that returns `None` instead of wrapping around on underflow or
/// overflow. /// overflow.
pub trait CheckedMul: Sized + Mul<Self, Output=Self> { pub trait CheckedMul: Sized + Mul<Self, Output = Self> {
/// Multiplies two numbers, checking for underflow or overflow. If underflow /// Multiplies two numbers, checking for underflow or overflow. If underflow
/// or overflow happens, `None` is returned. /// or overflow happens, `None` is returned.
fn checked_mul(&self, v: &Self) -> Option<Self>; fn checked_mul(&self, v: &Self) -> Option<Self>;
@ -84,7 +84,7 @@ checked_impl!(CheckedMul, checked_mul, i128);
/// Performs division that returns `None` instead of panicking on division by zero and instead of /// Performs division that returns `None` instead of panicking on division by zero and instead of
/// wrapping around on underflow and overflow. /// wrapping around on underflow and overflow.
pub trait CheckedDiv: Sized + Div<Self, Output=Self> { pub trait CheckedDiv: Sized + Div<Self, Output = Self> {
/// Divides two numbers, checking for underflow, overflow and division by /// Divides two numbers, checking for underflow, overflow and division by
/// zero. If any of that happens, `None` is returned. /// zero. If any of that happens, `None` is returned.
fn checked_div(&self, v: &Self) -> Option<Self>; fn checked_div(&self, v: &Self) -> Option<Self>;
@ -155,7 +155,7 @@ macro_rules! checked_impl_unary {
<$t>::$method(*self) <$t>::$method(*self)
} }
} }
} };
} }
/// Performs negation that returns `None` if the result can't be represented. /// Performs negation that returns `None` if the result can't be represented.
@ -196,7 +196,7 @@ checked_impl_unary!(CheckedNeg, checked_neg, isize);
checked_impl_unary!(CheckedNeg, checked_neg, i128); checked_impl_unary!(CheckedNeg, checked_neg, i128);
/// Performs a left shift that returns `None` on overflow. /// Performs a left shift that returns `None` on overflow.
pub trait CheckedShl: Sized + Shl<u32, Output=Self> { pub trait CheckedShl: Sized + Shl<u32, Output = Self> {
/// Shifts a number to the left, checking for overflow. If overflow happens, /// Shifts a number to the left, checking for overflow. If overflow happens,
/// `None` is returned. /// `None` is returned.
/// ///
@ -221,7 +221,7 @@ macro_rules! checked_shift_impl {
<$t>::$method(*self, rhs) <$t>::$method(*self, rhs)
} }
} }
} };
} }
checked_shift_impl!(CheckedShl, checked_shl, u8); checked_shift_impl!(CheckedShl, checked_shl, u8);
@ -241,7 +241,7 @@ checked_shift_impl!(CheckedShl, checked_shl, isize);
checked_shift_impl!(CheckedShl, checked_shl, i128); checked_shift_impl!(CheckedShl, checked_shl, i128);
/// Performs a right shift that returns `None` on overflow. /// Performs a right shift that returns `None` on overflow.
pub trait CheckedShr: Sized + Shr<u32, Output=Self> { pub trait CheckedShr: Sized + Shr<u32, Output = Self> {
/// Shifts a number to the left, checking for overflow. If overflow happens, /// Shifts a number to the left, checking for overflow. If overflow happens,
/// `None` is returned. /// `None` is returned.
/// ///

View File

@ -20,20 +20,28 @@ pub trait Inv {
impl Inv for f32 { impl Inv for f32 {
type Output = f32; type Output = f32;
#[inline] #[inline]
fn inv(self) -> f32 { 1.0 / self } fn inv(self) -> f32 {
1.0 / self
}
} }
impl Inv for f64 { impl Inv for f64 {
type Output = f64; type Output = f64;
#[inline] #[inline]
fn inv(self) -> f64 { 1.0 / self } fn inv(self) -> f64 {
1.0 / self
}
} }
impl<'a> Inv for &'a f32 { impl<'a> Inv for &'a f32 {
type Output = f32; type Output = f32;
#[inline] #[inline]
fn inv(self) -> f32 { 1.0 / *self } fn inv(self) -> f32 {
1.0 / *self
}
} }
impl<'a> Inv for &'a f64 { impl<'a> Inv for &'a f64 {
type Output = f64; type Output = f64;
#[inline] #[inline]
fn inv(self) -> f64 { 1.0 / *self } fn inv(self) -> f64 {
1.0 / *self
}
} }

View File

@ -1,5 +1,5 @@
pub mod saturating;
pub mod checked; pub mod checked;
pub mod wrapping;
pub mod inv; pub mod inv;
pub mod mul_add; pub mod mul_add;
pub mod saturating;
pub mod wrapping;

View File

@ -1,5 +1,5 @@
use core::ops::{Add, Sub, Mul};
use core::num::Wrapping; use core::num::Wrapping;
use core::ops::{Add, Mul, Sub};
macro_rules! wrapping_impl { macro_rules! wrapping_impl {
($trait_name:ident, $method:ident, $t:ty) => { ($trait_name:ident, $method:ident, $t:ty) => {
@ -17,11 +17,11 @@ macro_rules! wrapping_impl {
<$t>::$method(*self, *v) <$t>::$method(*self, *v)
} }
} }
} };
} }
/// Performs addition that wraps around on overflow. /// Performs addition that wraps around on overflow.
pub trait WrappingAdd: Sized + Add<Self, Output=Self> { pub trait WrappingAdd: Sized + Add<Self, Output = Self> {
/// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of /// Wrapping (modular) addition. Computes `self + other`, wrapping around at the boundary of
/// the type. /// the type.
fn wrapping_add(&self, v: &Self) -> Self; fn wrapping_add(&self, v: &Self) -> Self;
@ -44,7 +44,7 @@ wrapping_impl!(WrappingAdd, wrapping_add, isize);
wrapping_impl!(WrappingAdd, wrapping_add, i128); wrapping_impl!(WrappingAdd, wrapping_add, i128);
/// Performs subtraction that wraps around on overflow. /// Performs subtraction that wraps around on overflow.
pub trait WrappingSub: Sized + Sub<Self, Output=Self> { pub trait WrappingSub: Sized + Sub<Self, Output = Self> {
/// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary /// Wrapping (modular) subtraction. Computes `self - other`, wrapping around at the boundary
/// of the type. /// of the type.
fn wrapping_sub(&self, v: &Self) -> Self; fn wrapping_sub(&self, v: &Self) -> Self;
@ -67,7 +67,7 @@ wrapping_impl!(WrappingSub, wrapping_sub, isize);
wrapping_impl!(WrappingSub, wrapping_sub, i128); wrapping_impl!(WrappingSub, wrapping_sub, i128);
/// Performs multiplication that wraps around on overflow. /// Performs multiplication that wraps around on overflow.
pub trait WrappingMul: Sized + Mul<Self, Output=Self> { pub trait WrappingMul: Sized + Mul<Self, Output = Self> {
/// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary /// Wrapping (modular) multiplication. Computes `self * other`, wrapping around at the boundary
/// of the type. /// of the type.
fn wrapping_mul(&self, v: &Self) -> Self; fn wrapping_mul(&self, v: &Self) -> Self;
@ -90,28 +90,42 @@ wrapping_impl!(WrappingMul, wrapping_mul, isize);
wrapping_impl!(WrappingMul, wrapping_mul, i128); wrapping_impl!(WrappingMul, wrapping_mul, i128);
// Well this is a bit funny, but all the more appropriate. // Well this is a bit funny, but all the more appropriate.
impl<T: WrappingAdd> WrappingAdd for Wrapping<T> where Wrapping<T>: Add<Output = Wrapping<T>> { impl<T: WrappingAdd> WrappingAdd for Wrapping<T>
where
Wrapping<T>: Add<Output = Wrapping<T>>,
{
fn wrapping_add(&self, v: &Self) -> Self { fn wrapping_add(&self, v: &Self) -> Self {
Wrapping(self.0.wrapping_add(&v.0)) Wrapping(self.0.wrapping_add(&v.0))
} }
} }
impl<T: WrappingSub> WrappingSub for Wrapping<T> where Wrapping<T>: Sub<Output = Wrapping<T>> { impl<T: WrappingSub> WrappingSub for Wrapping<T>
where
Wrapping<T>: Sub<Output = Wrapping<T>>,
{
fn wrapping_sub(&self, v: &Self) -> Self { fn wrapping_sub(&self, v: &Self) -> Self {
Wrapping(self.0.wrapping_sub(&v.0)) Wrapping(self.0.wrapping_sub(&v.0))
} }
} }
impl<T: WrappingMul> WrappingMul for Wrapping<T> where Wrapping<T>: Mul<Output = Wrapping<T>> { impl<T: WrappingMul> WrappingMul for Wrapping<T>
where
Wrapping<T>: Mul<Output = Wrapping<T>>,
{
fn wrapping_mul(&self, v: &Self) -> Self { fn wrapping_mul(&self, v: &Self) -> Self {
Wrapping(self.0.wrapping_mul(&v.0)) Wrapping(self.0.wrapping_mul(&v.0))
} }
} }
#[test] #[test]
fn test_wrapping_traits() { fn test_wrapping_traits() {
fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T { a.wrapping_add(&b) } fn wrapping_add<T: WrappingAdd>(a: T, b: T) -> T {
fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T { a.wrapping_sub(&b) } a.wrapping_add(&b)
fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T { a.wrapping_mul(&b) } }
fn wrapping_sub<T: WrappingSub>(a: T, b: T) -> T {
a.wrapping_sub(&b)
}
fn wrapping_mul<T: WrappingMul>(a: T, b: T) -> T {
a.wrapping_mul(&b)
}
assert_eq!(wrapping_add(255, 1), 0u8); assert_eq!(wrapping_add(255, 1), 0u8);
assert_eq!(wrapping_sub(0, 1), 255u8); assert_eq!(wrapping_sub(0, 1), 255u8);
assert_eq!(wrapping_mul(255, 2), 254u8); assert_eq!(wrapping_mul(255, 2), 254u8);

View File

@ -1,6 +1,6 @@
use core::ops::Mul;
use core::num::Wrapping; use core::num::Wrapping;
use {One, CheckedMul}; use core::ops::Mul;
use {CheckedMul, One};
/// Binary operator for raising a value to a power. /// Binary operator for raising a value to a power.
pub trait Pow<RHS> { pub trait Pow<RHS> {
@ -183,13 +183,17 @@ mod float_impls {
/// ``` /// ```
#[inline] #[inline]
pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T { pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
if exp == 0 { return T::one() } if exp == 0 {
return T::one();
}
while exp & 1 == 0 { while exp & 1 == 0 {
base = base.clone() * base; base = base.clone() * base;
exp >>= 1; exp >>= 1;
} }
if exp == 1 { return base } if exp == 1 {
return base;
}
let mut acc = base.clone(); let mut acc = base.clone();
while exp > 1 { while exp > 1 {
@ -217,19 +221,27 @@ pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) ->
/// ``` /// ```
#[inline] #[inline]
pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> { pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
if exp == 0 { return Some(T::one()) } if exp == 0 {
return Some(T::one());
}
macro_rules! optry { macro_rules! optry {
( $ expr : expr ) => { ($expr:expr) => {
if let Some(val) = $expr { val } else { return None } if let Some(val) = $expr {
} val
} else {
return None;
}
};
} }
while exp & 1 == 0 { while exp & 1 == 0 {
base = optry!(base.checked_mul(&base)); base = optry!(base.checked_mul(&base));
exp >>= 1; exp >>= 1;
} }
if exp == 1 { return Some(base) } if exp == 1 {
return Some(base);
}
let mut acc = base.clone(); let mut acc = base.clone();
while exp > 1 { while exp > 1 {

View File

@ -1,6 +1,6 @@
use std::ops::Neg; use std::ops::Neg;
use {Num, NumCast, Float}; use {Float, Num, NumCast};
// NOTE: These doctests have the same issue as those in src/float.rs. // NOTE: These doctests have the same issue as those in src/float.rs.
// They're testing the inherent methods directly, and not those of `Real`. // They're testing the inherent methods directly, and not those of `Real`.
@ -12,13 +12,7 @@ use {Num, NumCast, Float};
/// for a list of data types that could meaningfully implement this trait. /// for a list of data types that could meaningfully implement this trait.
/// ///
/// This trait is only available with the `std` feature. /// This trait is only available with the `std` feature.
pub trait Real pub trait Real: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> {
: Num
+ Copy
+ NumCast
+ PartialOrd
+ Neg<Output = Self>
{
/// Returns the smallest finite value that this type can represent. /// Returns the smallest finite value that this type can represent.
/// ///
/// ``` /// ```

View File

@ -1,8 +1,8 @@
use core::ops::Neg;
use core::num::Wrapping; use core::num::Wrapping;
use core::ops::Neg;
use Num;
use float::FloatCore; use float::FloatCore;
use Num;
/// Useful functions for signed numbers (i.e. numbers that can be negative). /// Useful functions for signed numbers (i.e. numbers that can be negative).
pub trait Signed: Sized + Num + Neg<Output = Self> { pub trait Signed: Sized + Num + Neg<Output = Self> {
@ -77,7 +77,9 @@ signed_impl!(isize i8 i16 i32 i64);
#[cfg(has_i128)] #[cfg(has_i128)]
signed_impl!(i128); signed_impl!(i128);
impl<T: Signed> Signed for Wrapping<T> where Wrapping<T>: Num + Neg<Output=Wrapping<T>> impl<T: Signed> Signed for Wrapping<T>
where
Wrapping<T>: Num + Neg<Output = Wrapping<T>>,
{ {
#[inline] #[inline]
fn abs(&self) -> Self { fn abs(&self) -> Self {
@ -95,10 +97,14 @@ impl<T: Signed> Signed for Wrapping<T> where Wrapping<T>: Num + Neg<Output=Wrapp
} }
#[inline] #[inline]
fn is_positive(&self) -> bool { self.0.is_positive() } fn is_positive(&self) -> bool {
self.0.is_positive()
}
#[inline] #[inline]
fn is_negative(&self) -> bool { self.0.is_negative() } fn is_negative(&self) -> bool {
self.0.is_negative()
}
} }
macro_rules! signed_float_impl { macro_rules! signed_float_impl {
@ -115,7 +121,11 @@ macro_rules! signed_float_impl {
/// and `other` is returned. /// and `other` is returned.
#[inline] #[inline]
fn abs_sub(&self, other: &$t) -> $t { fn abs_sub(&self, other: &$t) -> $t {
if *self <= *other { 0. } else { *self - *other } if *self <= *other {
0.
} else {
*self - *other
}
} }
/// # Returns /// # Returns
@ -130,13 +140,17 @@ macro_rules! signed_float_impl {
/// Returns `true` if the number is positive, including `+0.0` and `INFINITY` /// Returns `true` if the number is positive, including `+0.0` and `INFINITY`
#[inline] #[inline]
fn is_positive(&self) -> bool { FloatCore::is_sign_positive(*self) } fn is_positive(&self) -> bool {
FloatCore::is_sign_positive(*self)
}
/// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY`
#[inline] #[inline]
fn is_negative(&self) -> bool { FloatCore::is_sign_negative(*self) } fn is_negative(&self) -> bool {
FloatCore::is_sign_negative(*self)
}
} }
} };
} }
signed_float_impl!(f32); signed_float_impl!(f32);
@ -174,7 +188,10 @@ pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
/// * `0` if the number is zero /// * `0` if the number is zero
/// * `1` if the number is positive /// * `1` if the number is positive
/// * `-1` if the number is negative /// * `-1` if the number is negative
#[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() } #[inline(always)]
pub fn signum<T: Signed>(value: T) -> T {
value.signum()
}
/// A trait for values which cannot be negative /// A trait for values which cannot be negative
pub trait Unsigned: Num {} pub trait Unsigned: Num {}
@ -189,7 +206,11 @@ empty_trait_impl!(Unsigned for usize u8 u16 u32 u64);
#[cfg(has_i128)] #[cfg(has_i128)]
empty_trait_impl!(Unsigned for u128); empty_trait_impl!(Unsigned for u128);
impl<T: Unsigned> Unsigned for Wrapping<T> where Wrapping<T>: Num {} impl<T: Unsigned> Unsigned for Wrapping<T>
where
Wrapping<T>: Num,
{
}
#[test] #[test]
fn unsigned_wrapping_is_unsigned() { fn unsigned_wrapping_is_unsigned() {

View File

@ -11,11 +11,11 @@ extern crate num_traits;
use num_traits::cast::*; use num_traits::cast::*;
use num_traits::Bounded; use num_traits::Bounded;
use core::{i8, i16, i32, i64, isize};
use core::{u8, u16, u32, u64, usize};
use core::{f32, f64}; use core::{f32, f64};
#[cfg(has_i128)] #[cfg(has_i128)]
use core::{i128, u128}; use core::{i128, u128};
use core::{i16, i32, i64, i8, isize};
use core::{u16, u32, u64, u8, usize};
use core::fmt::Debug; use core::fmt::Debug;
use core::mem; use core::mem;