Merge #74
74: Run cargo fmt r=cuviper a=cuviper Co-authored-by: Josh Stone <cuviper@gmail.com>
This commit is contained in:
commit
a415e2a751
|
@ -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,12 +18,16 @@ 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);
|
||||||
|
@ -43,8 +47,12 @@ bounded_impl!(i64, i64::MIN, i64::MAX);
|
||||||
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 {
|
||||||
|
|
129
src/cast.rs
129
src/cast.rs
|
@ -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> {
|
||||||
#[inline]
|
Some(*self as f32)
|
||||||
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
|
|
||||||
}
|
}
|
||||||
)
|
#[inline]
|
||||||
|
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> {
|
||||||
#[inline]
|
Some(*self as f32)
|
||||||
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
|
|
||||||
}
|
}
|
||||||
)
|
#[inline]
|
||||||
|
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,29 +471,71 @@ 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() }
|
|
||||||
#[cfg(has_i128)]
|
|
||||||
#[inline] fn from_i128(n: i128) -> Option<$T> { n.$to_ty() }
|
|
||||||
|
|
||||||
#[inline] fn from_usize(n: usize) -> 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)]
|
|
||||||
#[inline] fn from_u128(n: u128) -> Option<$T> { n.$to_ty() }
|
|
||||||
|
|
||||||
#[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
|
|
||||||
#[inline] fn from_f64(n: f64) -> 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)]
|
||||||
|
#[inline]
|
||||||
|
fn from_i128(n: i128) -> Option<$T> {
|
||||||
|
n.$to_ty()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_usize(n: usize) -> 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)]
|
||||||
|
#[inline]
|
||||||
|
fn from_u128(n: u128) -> Option<$T> {
|
||||||
|
n.$to_ty()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
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);
|
||||||
|
@ -505,7 +555,6 @@ 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 ; )*) => {$(
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -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,7 +654,7 @@ macro_rules! impl_num_cast {
|
||||||
n.$conv()
|
n.$conv()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_num_cast!(u8, to_u8);
|
impl_num_cast!(u8, to_u8);
|
||||||
|
@ -669,7 +717,7 @@ impl<T: NumCast> NumCast for Wrapping<T> {
|
||||||
///
|
///
|
||||||
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 => {});
|
||||||
|
|
||||||
|
|
44
src/float.rs
44
src/float.rs
|
@ -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
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,11 +29,15 @@ 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);
|
||||||
|
@ -55,7 +59,10 @@ 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,9 +108,11 @@ 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);
|
||||||
|
@ -123,7 +134,10 @@ 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() {
|
||||||
|
|
39
src/int.rs
39
src/int.rs
|
@ -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,7 +363,7 @@ 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);
|
||||||
|
|
117
src/lib.rs
117
src/lib.rs
|
@ -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
|
||||||
|
T: 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>,
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
28
src/pow.rs
28
src/pow.rs
|
@ -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 {
|
||||||
|
|
10
src/real.rs
10
src/real.rs
|
@ -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.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
|
|
41
src/sign.rs
41
src/sign.rs
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue