diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index ddfdbca196c66..51ba01a68aae9 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -10,28 +10,10 @@ //! Operations on boolean values (`bool` type) //! -//! A quick summary: -//! -//! Implementations of the following traits: -//! -//! * `Not` -//! * `BitAnd` -//! * `BitOr` -//! * `BitXor` -//! * `Ord` -//! * `TotalOrd` -//! * `Eq` -//! * `TotalEq` -//! * `Default` -//! //! A `to_bit` conversion function. use num::{Int, one, zero}; -#[cfg(not(test))] use cmp::{Eq, Ord, TotalOrd, Ordering, TotalEq}; -#[cfg(not(test))] use ops::{Not, BitAnd, BitOr, BitXor}; -#[cfg(not(test))] use default::Default; - ///////////////////////////////////////////////////////////////////////////// // Freestanding functions ///////////////////////////////////////////////////////////////////////////// @@ -51,131 +33,6 @@ pub fn to_bit(p: bool) -> N { if p { one() } else { zero() } } -///////////////////////////////////////////////////////////////////////////// -// Trait impls on `bool` -///////////////////////////////////////////////////////////////////////////// - -#[cfg(not(test))] -impl Not for bool { - /// The logical complement of a boolean value. - /// - /// # Examples - /// - /// ```rust - /// assert_eq!(!true, false); - /// assert_eq!(!false, true); - /// ``` - #[inline] - fn not(&self) -> bool { !*self } -} - -#[cfg(not(test))] -impl BitAnd for bool { - /// Conjunction of two boolean values. - /// - /// # Examples - /// - /// ```rust - /// assert_eq!(false.bitand(&false), false); - /// assert_eq!(true.bitand(&false), false); - /// assert_eq!(false.bitand(&true), false); - /// assert_eq!(true.bitand(&true), true); - /// - /// assert_eq!(false & false, false); - /// assert_eq!(true & false, false); - /// assert_eq!(false & true, false); - /// assert_eq!(true & true, true); - /// ``` - #[inline] - fn bitand(&self, b: &bool) -> bool { *self & *b } -} - -#[cfg(not(test))] -impl BitOr for bool { - /// Disjunction of two boolean values. - /// - /// # Examples - /// - /// ```rust - /// assert_eq!(false.bitor(&false), false); - /// assert_eq!(true.bitor(&false), true); - /// assert_eq!(false.bitor(&true), true); - /// assert_eq!(true.bitor(&true), true); - /// - /// assert_eq!(false | false, false); - /// assert_eq!(true | false, true); - /// assert_eq!(false | true, true); - /// assert_eq!(true | true, true); - /// ``` - #[inline] - fn bitor(&self, b: &bool) -> bool { *self | *b } -} - -#[cfg(not(test))] -impl BitXor for bool { - /// An 'exclusive or' of two boolean values. - /// - /// 'exclusive or' is identical to `or(and(a, not(b)), and(not(a), b))`. - /// - /// # Examples - /// - /// ```rust - /// assert_eq!(false.bitxor(&false), false); - /// assert_eq!(true.bitxor(&false), true); - /// assert_eq!(false.bitxor(&true), true); - /// assert_eq!(true.bitxor(&true), false); - /// - /// assert_eq!(false ^ false, false); - /// assert_eq!(true ^ false, true); - /// assert_eq!(false ^ true, true); - /// assert_eq!(true ^ true, false); - /// ``` - #[inline] - fn bitxor(&self, b: &bool) -> bool { *self ^ *b } -} - -#[cfg(not(test))] -impl Ord for bool { - #[inline] - fn lt(&self, other: &bool) -> bool { - to_bit::(*self) < to_bit(*other) - } -} - -#[cfg(not(test))] -impl TotalOrd for bool { - #[inline] - fn cmp(&self, other: &bool) -> Ordering { - to_bit::(*self).cmp(&to_bit(*other)) - } -} - -/// Equality between two boolean values. -/// -/// Two booleans are equal if they have the same value. -/// -/// # Examples -/// -/// ```rust -/// assert_eq!(false.eq(&true), false); -/// assert_eq!(false == false, true); -/// assert_eq!(false != true, true); -/// assert_eq!(false.ne(&false), false); -/// ``` -#[cfg(not(test))] -impl Eq for bool { - #[inline] - fn eq(&self, other: &bool) -> bool { (*self) == (*other) } -} - -#[cfg(not(test))] -impl TotalEq for bool {} - -#[cfg(not(test))] -impl Default for bool { - fn default() -> bool { false } -} - #[cfg(test)] mod tests { use realstd::prelude::*; diff --git a/src/libcore/char.rs b/src/libcore/char.rs index 224f4ce199462..0c5d3151af0f5 100644 --- a/src/libcore/char.rs +++ b/src/libcore/char.rs @@ -34,9 +34,6 @@ pub use unicode::normalization::decompose_canonical; /// Returns the compatibility decomposition of a character. pub use unicode::normalization::decompose_compatible; -#[cfg(not(test))] use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering}; -#[cfg(not(test))] use default::Default; - // UTF-8 ranges and tags for encoding characters static TAG_CONT: u8 = 0b1000_0000u8; static TAG_TWO_B: u8 = 0b1100_0000u8; @@ -601,33 +598,6 @@ impl Char for char { } } -#[cfg(not(test))] -impl Eq for char { - #[inline] - fn eq(&self, other: &char) -> bool { (*self) == (*other) } -} - -#[cfg(not(test))] -impl TotalEq for char {} - -#[cfg(not(test))] -impl Ord for char { - #[inline] - fn lt(&self, other: &char) -> bool { *self < *other } -} - -#[cfg(not(test))] -impl TotalOrd for char { - fn cmp(&self, other: &char) -> Ordering { - (*self as u32).cmp(&(*other as u32)) - } -} - -#[cfg(not(test))] -impl Default for char { - #[inline] - fn default() -> char { '\x00' } -} #[cfg(test)] mod test { diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 269dfa496eb0a..1c621f7f4ce15 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -189,10 +189,21 @@ pub fn max(v1: T, v2: T) -> T { if v1 > v2 { v1 } else { v2 } } -// Implementation of Eq/TotalEq for some primitive types +// Implementation of Eq, TotalEq, Ord and TotalOrd for primitive types #[cfg(not(test))] mod impls { - use cmp::{Ord, TotalOrd, Eq, TotalEq, Ordering, Equal}; + use cmp::{Ord, TotalOrd, Eq, TotalEq, Ordering, Less, Greater, Equal}; + + macro_rules! eq_impl( + ($($t:ty)*) => ($( + impl Eq for $t { + #[inline] + fn eq(&self, other: &$t) -> bool { (*self) == (*other) } + #[inline] + fn ne(&self, other: &$t) -> bool { (*self) != (*other) } + } + )*) + ) impl Eq for () { #[inline] @@ -200,16 +211,73 @@ mod impls { #[inline] fn ne(&self, _other: &()) -> bool { false } } - impl TotalEq for () {} + + eq_impl!(bool char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + + macro_rules! totaleq_impl( + ($($t:ty)*) => ($( + impl TotalEq for $t {} + )*) + ) + + totaleq_impl!(() bool char uint u8 u16 u32 u64 int i8 i16 i32 i64) + + macro_rules! ord_impl( + ($($t:ty)*) => ($( + impl Ord for $t { + #[inline] + fn lt(&self, other: &$t) -> bool { (*self) < (*other) } + #[inline] + fn le(&self, other: &$t) -> bool { (*self) <= (*other) } + #[inline] + fn ge(&self, other: &$t) -> bool { (*self) >= (*other) } + #[inline] + fn gt(&self, other: &$t) -> bool { (*self) > (*other) } + } + )*) + ) + impl Ord for () { #[inline] fn lt(&self, _other: &()) -> bool { false } } + + impl Ord for bool { + #[inline] + fn lt(&self, other: &bool) -> bool { + (*self as u8) < (*other as u8) + } + } + + ord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + + macro_rules! totalord_impl( + ($($t:ty)*) => ($( + impl TotalOrd for $t { + #[inline] + fn cmp(&self, other: &$t) -> Ordering { + if *self < *other { Less } + else if *self > *other { Greater } + else { Equal } + } + } + )*) + ) + impl TotalOrd for () { #[inline] fn cmp(&self, _other: &()) -> Ordering { Equal } } + impl TotalOrd for bool { + #[inline] + fn cmp(&self, other: &bool) -> Ordering { + (*self as u8).cmp(&(*other as u8)) + } + } + + totalord_impl!(char uint u8 u16 u32 u64 int i8 i16 i32 i64) + // & pointers impl<'a, T: Eq> Eq for &'a T { #[inline] diff --git a/src/libcore/default.rs b/src/libcore/default.rs index 50ddfcc52f7be..809706b4fd73b 100644 --- a/src/libcore/default.rs +++ b/src/libcore/default.rs @@ -16,10 +16,33 @@ pub trait Default { fn default() -> Self; } -impl Default for () { - #[inline] - fn default() -> () { () } -} +macro_rules! default_impl( + ($t:ty, $v:expr) => { + impl Default for $t { + #[inline] + fn default() -> $t { $v } + } + } +) + +default_impl!((), ()) +default_impl!(bool, false) +default_impl!(char, '\x00') + +default_impl!(uint, 0u) +default_impl!(u8, 0u8) +default_impl!(u16, 0u16) +default_impl!(u32, 0u32) +default_impl!(u64, 0u64) + +default_impl!(int, 0i) +default_impl!(i8, 0i8) +default_impl!(i16, 0i16) +default_impl!(i32, 0i32) +default_impl!(i64, 0i64) + +default_impl!(f32, 0.0f32) +default_impl!(f64, 0.0f64) impl Default for @T { fn default() -> @T { @Default::default() } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 694f3e9fbd1f9..75d3db596ba5d 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -10,16 +10,12 @@ //! Operations and constants for 32-bits floats (`f32` type) -use default::Default; use intrinsics; use mem; use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN}; -use num::{Zero, One, Bounded, Signed, Num, Primitive, Float}; +use num::Float; use option::Option; -#[cfg(not(test))] use cmp::{Eq, Ord}; -#[cfg(not(test))] use ops::{Add, Sub, Mul, Div, Rem, Neg}; - pub static RADIX: uint = 2u; pub static MANTISSA_DIGITS: uint = 24u; @@ -104,131 +100,6 @@ pub mod consts { pub static LN_10: f32 = 2.30258509299404568401799145468436421_f32; } -#[cfg(not(test))] -impl Ord for f32 { - #[inline] - fn lt(&self, other: &f32) -> bool { (*self) < (*other) } - #[inline] - fn le(&self, other: &f32) -> bool { (*self) <= (*other) } - #[inline] - fn ge(&self, other: &f32) -> bool { (*self) >= (*other) } - #[inline] - fn gt(&self, other: &f32) -> bool { (*self) > (*other) } -} -#[cfg(not(test))] -impl Eq for f32 { - #[inline] - fn eq(&self, other: &f32) -> bool { (*self) == (*other) } -} - -impl Num for f32 {} - -impl Default for f32 { - #[inline] - fn default() -> f32 { 0.0 } -} - -impl Primitive for f32 {} - -impl Zero for f32 { - #[inline] - fn zero() -> f32 { 0.0 } - - /// Returns true if the number is equal to either `0.0` or `-0.0` - #[inline] - fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } -} - -impl One for f32 { - #[inline] - fn one() -> f32 { 1.0 } -} - -#[cfg(not(test))] -impl Add for f32 { - #[inline] - fn add(&self, other: &f32) -> f32 { *self + *other } -} - -#[cfg(not(test))] -impl Sub for f32 { - #[inline] - fn sub(&self, other: &f32) -> f32 { *self - *other } -} - -#[cfg(not(test))] -impl Mul for f32 { - #[inline] - fn mul(&self, other: &f32) -> f32 { *self * *other } -} - -#[cfg(not(test))] -impl Div for f32 { - #[inline] - fn div(&self, other: &f32) -> f32 { *self / *other } -} - -#[cfg(not(test))] -impl Rem for f32 { - #[inline] - fn rem(&self, other: &f32) -> f32 { - extern { fn fmodf(a: f32, b: f32) -> f32; } - unsafe { fmodf(*self, *other) } - } -} - -#[cfg(not(test))] -impl Neg for f32 { - #[inline] - fn neg(&self) -> f32 { -*self } -} - -impl Signed for f32 { - /// Computes the absolute value. Returns `NAN` if the number is `NAN`. - #[inline] - fn abs(&self) -> f32 { - unsafe { intrinsics::fabsf32(*self) } - } - - /// The positive difference of two numbers. Returns `0.0` if the number is - /// less than or equal to `other`, otherwise the difference between`self` - /// and `other` is returned. - #[inline] - fn abs_sub(&self, other: &f32) -> f32 { - extern { fn fdimf(a: f32, b: f32) -> f32; } - unsafe { fdimf(*self, *other) } - } - - /// # Returns - /// - /// - `1.0` if the number is positive, `+0.0` or `INFINITY` - /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - `NAN` if the number is NaN - #[inline] - fn signum(&self) -> f32 { - if self != self { NAN } else { - unsafe { intrinsics::copysignf32(1.0, *self) } - } - } - - /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` - #[inline] - fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == INFINITY } - - /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` - #[inline] - fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY } -} - -impl Bounded for f32 { - // NOTE: this is the smallest non-infinite f32 value, *not* MIN_VALUE - #[inline] - fn min_value() -> f32 { -MAX_VALUE } - - #[inline] - fn max_value() -> f32 { MAX_VALUE } -} - impl Float for f32 { #[inline] fn nan() -> f32 { NAN } diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index 2c802f5d059f1..d59aad077ccb4 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -10,16 +10,12 @@ //! Operations and constants for 64-bits floats (`f64` type) -use default::Default; use intrinsics; use mem; use num::{FPNormal, FPCategory, FPZero, FPSubnormal, FPInfinite, FPNaN}; -use num::{Zero, One, Bounded, Signed, Num, Primitive, Float}; +use num::Float; use option::Option; -#[cfg(not(test))] use cmp::{Eq, Ord}; -#[cfg(not(test))] use ops::{Add, Sub, Mul, Div, Rem, Neg}; - // FIXME(#5527): These constants should be deprecated once associated // constants are implemented in favour of referencing the respective // members of `Bounded` and `Float`. @@ -110,125 +106,6 @@ pub mod consts { pub static LN_10: f64 = 2.30258509299404568401799145468436421_f64; } -#[cfg(not(test))] -impl Ord for f64 { - #[inline] - fn lt(&self, other: &f64) -> bool { (*self) < (*other) } - #[inline] - fn le(&self, other: &f64) -> bool { (*self) <= (*other) } - #[inline] - fn ge(&self, other: &f64) -> bool { (*self) >= (*other) } - #[inline] - fn gt(&self, other: &f64) -> bool { (*self) > (*other) } -} -#[cfg(not(test))] -impl Eq for f64 { - #[inline] - fn eq(&self, other: &f64) -> bool { (*self) == (*other) } -} - -impl Default for f64 { - #[inline] - fn default() -> f64 { 0.0 } -} - -impl Primitive for f64 {} - -impl Num for f64 {} - -impl Zero for f64 { - #[inline] - fn zero() -> f64 { 0.0 } - - /// Returns true if the number is equal to either `0.0` or `-0.0` - #[inline] - fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 } -} - -impl One for f64 { - #[inline] - fn one() -> f64 { 1.0 } -} - -#[cfg(not(test))] -impl Add for f64 { - #[inline] - fn add(&self, other: &f64) -> f64 { *self + *other } -} -#[cfg(not(test))] -impl Sub for f64 { - #[inline] - fn sub(&self, other: &f64) -> f64 { *self - *other } -} -#[cfg(not(test))] -impl Mul for f64 { - #[inline] - fn mul(&self, other: &f64) -> f64 { *self * *other } -} -#[cfg(not(test))] -impl Div for f64 { - #[inline] - fn div(&self, other: &f64) -> f64 { *self / *other } -} -#[cfg(not(test))] -impl Rem for f64 { - #[inline] - fn rem(&self, other: &f64) -> f64 { - extern { fn fmod(a: f64, b: f64) -> f64; } - unsafe { fmod(*self, *other) } - } -} -#[cfg(not(test))] -impl Neg for f64 { - #[inline] - fn neg(&self) -> f64 { -*self } -} - -impl Signed for f64 { - /// Computes the absolute value. Returns `NAN` if the number is `NAN`. - #[inline] - fn abs(&self) -> f64 { - unsafe { intrinsics::fabsf64(*self) } - } - - /// The positive difference of two numbers. Returns `0.0` if the number is less than or - /// equal to `other`, otherwise the difference between`self` and `other` is returned. - #[inline] - fn abs_sub(&self, other: &f64) -> f64 { - extern { fn fdim(a: f64, b: f64) -> f64; } - unsafe { fdim(*self, *other) } - } - - /// # Returns - /// - /// - `1.0` if the number is positive, `+0.0` or `INFINITY` - /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - `NAN` if the number is NaN - #[inline] - fn signum(&self) -> f64 { - if self != self { NAN } else { - unsafe { intrinsics::copysignf64(1.0, *self) } - } - } - - /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` - #[inline] - fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == INFINITY } - - /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` - #[inline] - fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == NEG_INFINITY } -} - -impl Bounded for f64 { - // NOTE: this is the smallest non-infinite f32 value, *not* MIN_VALUE - #[inline] - fn min_value() -> f64 { -MAX_VALUE } - - #[inline] - fn max_value() -> f64 { MAX_VALUE } -} - impl Float for f64 { #[inline] fn nan() -> f64 { NAN } diff --git a/src/libcore/num/i16.rs b/src/libcore/num/i16.rs index 361f75b9e8831..957e585e71cdf 100644 --- a/src/libcore/num/i16.rs +++ b/src/libcore/num/i16.rs @@ -10,63 +10,5 @@ //! Operations and constants for signed 16-bits integers (`i16` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; -use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; -use option::{Option, Some, None}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - int_module!(i16, 16) -impl Bitwise for i16 { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> i16 { unsafe { intrinsics::ctpop16(*self as u16) as i16 } } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> i16 { unsafe { intrinsics::ctlz16(*self as u16) as i16 } } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self as u16) as i16 } } -} - -impl CheckedAdd for i16 { - #[inline] - fn checked_add(&self, v: &i16) -> Option { - unsafe { - let (x, y) = intrinsics::i16_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedSub for i16 { - #[inline] - fn checked_sub(&self, v: &i16) -> Option { - unsafe { - let (x, y) = intrinsics::i16_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedMul for i16 { - #[inline] - fn checked_mul(&self, v: &i16) -> Option { - unsafe { - let (x, y) = intrinsics::i16_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} diff --git a/src/libcore/num/i32.rs b/src/libcore/num/i32.rs index 9071f150292d2..cfeb1020f446a 100644 --- a/src/libcore/num/i32.rs +++ b/src/libcore/num/i32.rs @@ -10,63 +10,5 @@ //! Operations and constants for signed 32-bits integers (`i32` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; -use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; -use option::{Option, Some, None}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - int_module!(i32, 32) -impl Bitwise for i32 { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> i32 { unsafe { intrinsics::ctpop32(*self as u32) as i32 } } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> i32 { unsafe { intrinsics::ctlz32(*self as u32) as i32 } } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self as u32) as i32 } } -} - -impl CheckedAdd for i32 { - #[inline] - fn checked_add(&self, v: &i32) -> Option { - unsafe { - let (x, y) = intrinsics::i32_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedSub for i32 { - #[inline] - fn checked_sub(&self, v: &i32) -> Option { - unsafe { - let (x, y) = intrinsics::i32_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedMul for i32 { - #[inline] - fn checked_mul(&self, v: &i32) -> Option { - unsafe { - let (x, y) = intrinsics::i32_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} diff --git a/src/libcore/num/i64.rs b/src/libcore/num/i64.rs index ba7b715f13d6a..21ae162d4aac6 100644 --- a/src/libcore/num/i64.rs +++ b/src/libcore/num/i64.rs @@ -10,62 +10,5 @@ //! Operations and constants for signed 64-bits integers (`i64` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; -use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; -use option::{Option, Some, None}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - int_module!(i64, 64) -impl Bitwise for i64 { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> i64 { unsafe { intrinsics::ctpop64(*self as u64) as i64 } } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> i64 { unsafe { intrinsics::ctlz64(*self as u64) as i64 } } - - /// Counts the number of trailing zeros. - #[inline] - fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self as u64) as i64 } } -} - -impl CheckedAdd for i64 { - #[inline] - fn checked_add(&self, v: &i64) -> Option { - unsafe { - let (x, y) = intrinsics::i64_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedSub for i64 { - #[inline] - fn checked_sub(&self, v: &i64) -> Option { - unsafe { - let (x, y) = intrinsics::i64_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedMul for i64 { - #[inline] - fn checked_mul(&self, v: &i64) -> Option { - unsafe { - let (x, y) = intrinsics::i64_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} diff --git a/src/libcore/num/i8.rs b/src/libcore/num/i8.rs index 6ec05eb50ee61..b9ae13da07588 100644 --- a/src/libcore/num/i8.rs +++ b/src/libcore/num/i8.rs @@ -10,63 +10,5 @@ //! Operations and constants for signed 8-bits integers (`i8` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; -use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; -use option::{Option, Some, None}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - int_module!(i8, 8) -impl Bitwise for i8 { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> i8 { unsafe { intrinsics::ctpop8(*self as u8) as i8 } } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> i8 { unsafe { intrinsics::ctlz8(*self as u8) as i8 } } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self as u8) as i8 } } -} - -impl CheckedAdd for i8 { - #[inline] - fn checked_add(&self, v: &i8) -> Option { - unsafe { - let (x, y) = intrinsics::i8_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedSub for i8 { - #[inline] - fn checked_sub(&self, v: &i8) -> Option { - unsafe { - let (x, y) = intrinsics::i8_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedMul for i8 { - #[inline] - fn checked_mul(&self, v: &i8) -> Option { - unsafe { - let (x, y) = intrinsics::i8_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} diff --git a/src/libcore/num/int.rs b/src/libcore/num/int.rs index 8273fa2b39f27..4979e9e01d3bf 100644 --- a/src/libcore/num/int.rs +++ b/src/libcore/num/int.rs @@ -10,118 +10,6 @@ //! Operations and constants for architecture-sized signed integers (`int` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Signed, Num, Primitive, Int}; -use num::{CheckedDiv, CheckedAdd, CheckedSub, CheckedMul}; -use option::{Option, Some, None}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitOr, BitAnd, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - #[cfg(target_word_size = "32")] int_module!(int, 32) #[cfg(target_word_size = "64")] int_module!(int, 64) -#[cfg(target_word_size = "32")] -impl Bitwise for int { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> int { (*self as i32).count_ones() as int } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> int { (*self as i32).leading_zeros() as int } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> int { (*self as i32).trailing_zeros() as int } -} - -#[cfg(target_word_size = "64")] -impl Bitwise for int { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> int { (*self as i64).count_ones() as int } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> int { (*self as i64).leading_zeros() as int } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int } -} - -#[cfg(target_word_size = "32")] -impl CheckedAdd for int { - #[inline] - fn checked_add(&self, v: &int) -> Option { - unsafe { - let (x, y) = intrinsics::i32_add_with_overflow(*self as i32, *v as i32); - if y { None } else { Some(x as int) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedAdd for int { - #[inline] - fn checked_add(&self, v: &int) -> Option { - unsafe { - let (x, y) = intrinsics::i64_add_with_overflow(*self as i64, *v as i64); - if y { None } else { Some(x as int) } - } - } -} - -#[cfg(target_word_size = "32")] -impl CheckedSub for int { - #[inline] - fn checked_sub(&self, v: &int) -> Option { - unsafe { - let (x, y) = intrinsics::i32_sub_with_overflow(*self as i32, *v as i32); - if y { None } else { Some(x as int) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedSub for int { - #[inline] - fn checked_sub(&self, v: &int) -> Option { - unsafe { - let (x, y) = intrinsics::i64_sub_with_overflow(*self as i64, *v as i64); - if y { None } else { Some(x as int) } - } - } -} - -#[cfg(target_word_size = "32")] -impl CheckedMul for int { - #[inline] - fn checked_mul(&self, v: &int) -> Option { - unsafe { - let (x, y) = intrinsics::i32_mul_with_overflow(*self as i32, *v as i32); - if y { None } else { Some(x as int) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedMul for int { - #[inline] - fn checked_mul(&self, v: &int) -> Option { - unsafe { - let (x, y) = intrinsics::i64_mul_with_overflow(*self as i64, *v as i64); - if y { None } else { Some(x as int) } - } - } -} diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs index 7d21764eb70d3..445ac248cd67f 100644 --- a/src/libcore/num/int_macros.rs +++ b/src/libcore/num/int_macros.rs @@ -28,220 +28,6 @@ pub static MIN: $T = (-1 as $T) << (BITS - 1); // calling the `Bounded::max_value` function. pub static MAX: $T = !MIN; -#[cfg(not(test))] -impl Ord for $T { - #[inline] - fn lt(&self, other: &$T) -> bool { *self < *other } -} -#[cfg(not(test))] -impl TotalEq for $T {} -#[cfg(not(test))] -impl Eq for $T { - #[inline] - fn eq(&self, other: &$T) -> bool { *self == *other } -} -#[cfg(not(test))] -impl TotalOrd for $T { - #[inline] - fn cmp(&self, other: &$T) -> Ordering { - if *self < *other { Less } - else if *self > *other { Greater } - else { Equal } - } -} - -impl Num for $T {} - -impl Zero for $T { - #[inline] - fn zero() -> $T { 0 } - - #[inline] - fn is_zero(&self) -> bool { *self == 0 } -} - -impl One for $T { - #[inline] - fn one() -> $T { 1 } -} - -#[cfg(not(test))] -impl Add<$T,$T> for $T { - #[inline] - fn add(&self, other: &$T) -> $T { *self + *other } -} - -#[cfg(not(test))] -impl Sub<$T,$T> for $T { - #[inline] - fn sub(&self, other: &$T) -> $T { *self - *other } -} - -#[cfg(not(test))] -impl Mul<$T,$T> for $T { - #[inline] - fn mul(&self, other: &$T) -> $T { *self * *other } -} - -#[cfg(not(test))] -impl Div<$T,$T> for $T { - /// Integer division, truncated towards 0. - /// - /// # Examples - /// - /// ~~~ - /// assert!( 8 / 3 == 2); - /// assert!( 8 / -3 == -2); - /// assert!(-8 / 3 == -2); - /// assert!(-8 / -3 == 2); - /// - /// assert!( 1 / 2 == 0); - /// assert!( 1 / -2 == 0); - /// assert!(-1 / 2 == 0); - /// assert!(-1 / -2 == 0); - /// ~~~ - #[inline] - fn div(&self, other: &$T) -> $T { *self / *other } -} - -#[cfg(not(test))] -impl Rem<$T,$T> for $T { - /// Returns the integer remainder after division, satisfying: - /// - /// ~~~ - /// # let n = 1; - /// # let d = 2; - /// assert!((n / d) * d + (n % d) == n) - /// ~~~ - /// - /// # Examples - /// - /// ~~~ - /// assert!( 8 % 3 == 2); - /// assert!( 8 % -3 == 2); - /// assert!(-8 % 3 == -2); - /// assert!(-8 % -3 == -2); - /// - /// assert!( 1 % 2 == 1); - /// assert!( 1 % -2 == 1); - /// assert!(-1 % 2 == -1); - /// assert!(-1 % -2 == -1); - /// ~~~ - #[inline] - fn rem(&self, other: &$T) -> $T { *self % *other } -} - -#[cfg(not(test))] -impl Neg<$T> for $T { - #[inline] - fn neg(&self) -> $T { -*self } -} - -impl Signed for $T { - /// Computes the absolute value - #[inline] - fn abs(&self) -> $T { - if self.is_negative() { -*self } else { *self } - } - - /// - /// The positive difference of two numbers. Returns `0` if the number is less than or - /// equal to `other`, otherwise the difference between`self` and `other` is returned. - /// - #[inline] - fn abs_sub(&self, other: &$T) -> $T { - if *self <= *other { 0 } else { *self - *other } - } - - /// - /// # Returns - /// - /// - `0` if the number is zero - /// - `1` if the number is positive - /// - `-1` if the number is negative - /// - #[inline] - fn signum(&self) -> $T { - match *self { - n if n > 0 => 1, - 0 => 0, - _ => -1, - } - } - - /// Returns true if the number is positive - #[inline] - fn is_positive(&self) -> bool { *self > 0 } - - /// Returns true if the number is negative - #[inline] - fn is_negative(&self) -> bool { *self < 0 } -} - -#[cfg(not(test))] -impl BitOr<$T,$T> for $T { - #[inline] - fn bitor(&self, other: &$T) -> $T { *self | *other } -} - -#[cfg(not(test))] -impl BitAnd<$T,$T> for $T { - #[inline] - fn bitand(&self, other: &$T) -> $T { *self & *other } -} - -#[cfg(not(test))] -impl BitXor<$T,$T> for $T { - #[inline] - fn bitxor(&self, other: &$T) -> $T { *self ^ *other } -} - -#[cfg(not(test))] -impl Shl<$T,$T> for $T { - #[inline] - fn shl(&self, other: &$T) -> $T { *self << *other } -} - -#[cfg(not(test))] -impl Shr<$T,$T> for $T { - #[inline] - fn shr(&self, other: &$T) -> $T { *self >> *other } -} - -#[cfg(not(test))] -impl Not<$T> for $T { - #[inline] - fn not(&self) -> $T { !*self } -} - -impl Bounded for $T { - #[inline] - fn min_value() -> $T { MIN } - - #[inline] - fn max_value() -> $T { MAX } -} - -impl CheckedDiv for $T { - #[inline] - fn checked_div(&self, v: &$T) -> Option<$T> { - if *v == 0 || (*self == MIN && *v == -1) { - None - } else { - Some(self / *v) - } - } -} - -impl Default for $T { - #[inline] - fn default() -> $T { 0 } -} - -impl Int for $T {} - -impl Primitive for $T {} - #[cfg(test)] mod tests { use prelude::*; diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 03eca8b12b825..fe3f07c6024e0 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -9,12 +9,13 @@ // except according to those terms. //! Numeric traits and functions for generic mathematics -//! -//! These are implemented for the primitive numeric types in `std::{u8, u16, -//! u32, u64, uint, i8, i16, i32, i64, int, f32, f64}`. #![allow(missing_doc)] +use intrinsics; +use {int, i8, i16, i32, i64}; +use {uint, u8, u16, u32, u64}; +use {f32, f64}; use clone::Clone; use cmp::{Eq, Ord}; use kinds::Copy; @@ -32,6 +33,14 @@ pub trait Num: Eq + Zero + One + Div + Rem {} +macro_rules! trait_impl( + ($name:ident for $($t:ty)*) => ($( + impl $name for $t {} + )*) +) + +trait_impl!(Num for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + /// Simultaneous division and remainder #[inline] pub fn div_rem + Rem>(x: T, y: T) -> (T, T) { @@ -67,6 +76,44 @@ pub trait Zero: Add { fn is_zero(&self) -> bool; } +macro_rules! zero_impl( + ($t:ty, $v:expr) => { + impl Zero for $t { + #[inline] + fn zero() -> $t { $v } + #[inline] + fn is_zero(&self) -> bool { *self == $v } + } + } +) + +macro_rules! zero_float_impl( + ($t:ty, $v:expr) => { + impl Zero for $t { + #[inline] + fn zero() -> $t { $v } + + #[inline] + fn is_zero(&self) -> bool { *self == $v || *self == -$v } + } + } +) + +zero_impl!(uint, 0u) +zero_impl!(u8, 0u8) +zero_impl!(u16, 0u16) +zero_impl!(u32, 0u32) +zero_impl!(u64, 0u64) + +zero_impl!(int, 0i) +zero_impl!(i8, 0i8) +zero_impl!(i16, 0i16) +zero_impl!(i32, 0i32) +zero_impl!(i64, 0i64) + +zero_float_impl!(f32, 0.0f32) +zero_float_impl!(f64, 0.0f64) + /// Returns the additive identity, `0`. #[inline(always)] pub fn zero() -> T { Zero::zero() } @@ -90,6 +137,30 @@ pub trait One: Mul { fn one() -> Self; } +macro_rules! one_impl( + ($t:ty, $v:expr) => { + impl One for $t { + #[inline] + fn one() -> $t { $v } + } + } +) + +one_impl!(uint, 1u) +one_impl!(u8, 1u8) +one_impl!(u16, 1u16) +one_impl!(u32, 1u32) +one_impl!(u64, 1u64) + +one_impl!(int, 1i) +one_impl!(i8, 1i8) +one_impl!(i16, 1i16) +one_impl!(i32, 1i32) +one_impl!(i64, 1i64) + +one_impl!(f32, 1.0f32) +one_impl!(f64, 1.0f64) + /// Returns the multiplicative identity, `1`. #[inline(always)] pub fn one() -> T { One::one() } @@ -128,6 +199,85 @@ pub trait Signed: Num + Neg { fn is_negative(&self) -> bool; } +macro_rules! signed_impl( + ($($t:ty)*) => ($( + impl Signed for $t { + #[inline] + fn abs(&self) -> $t { + if self.is_negative() { -*self } else { *self } + } + + #[inline] + fn abs_sub(&self, other: &$t) -> $t { + if *self <= *other { 0 } else { *self - *other } + } + + #[inline] + fn signum(&self) -> $t { + match *self { + n if n > 0 => 1, + 0 => 0, + _ => -1, + } + } + + #[inline] + fn is_positive(&self) -> bool { *self > 0 } + + #[inline] + fn is_negative(&self) -> bool { *self < 0 } + } + )*) +) + +signed_impl!(int i8 i16 i32 i64) + +macro_rules! signed_float_impl( + ($t:ty, $nan:expr, $inf:expr, $neg_inf:expr, $fabs:path, $fcopysign:path, $fdim:ident) => { + impl Signed for $t { + /// Computes the absolute value. Returns `NAN` if the number is `NAN`. + #[inline] + fn abs(&self) -> $t { + unsafe { $fabs(*self) } + } + + /// The positive difference of two numbers. Returns `0.0` if the number is + /// less than or equal to `other`, otherwise the difference between`self` + /// and `other` is returned. + #[inline] + fn abs_sub(&self, other: &$t) -> $t { + extern { fn $fdim(a: $t, b: $t) -> $t; } + unsafe { $fdim(*self, *other) } + } + + /// # Returns + /// + /// - `1.0` if the number is positive, `+0.0` or `INFINITY` + /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` + /// - `NAN` if the number is NaN + #[inline] + fn signum(&self) -> $t { + if self != self { $nan } else { + unsafe { $fcopysign(1.0, *self) } + } + } + + /// Returns `true` if the number is positive, including `+0.0` and `INFINITY` + #[inline] + fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == $inf } + + /// Returns `true` if the number is negative, including `-0.0` and `NEG_INFINITY` + #[inline] + fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == $neg_inf } + } + } +) + +signed_float_impl!(f32, f32::NAN, f32::INFINITY, f32::NEG_INFINITY, + intrinsics::fabsf32, intrinsics::copysignf32, fdimf) +signed_float_impl!(f64, f64::NAN, f64::INFINITY, f64::NEG_INFINITY, + intrinsics::fabsf64, intrinsics::copysignf64, fdim) + /// Computes the absolute value. /// /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN` @@ -163,6 +313,8 @@ pub fn abs_sub(x: T, y: T) -> T { /// A trait for values which cannot be negative pub trait Unsigned: Num {} +trait_impl!(Unsigned for uint u8 u16 u32 u64) + /// Raises a value to the power of exp, using exponentiation by squaring. /// /// # Example @@ -197,6 +349,33 @@ pub trait Bounded { fn max_value() -> Self; } +macro_rules! bounded_impl( + ($t:ty, $min:expr, $max:expr) => { + impl Bounded for $t { + #[inline] + fn min_value() -> $t { $min } + + #[inline] + fn max_value() -> $t { $max } + } + } +) + +bounded_impl!(uint, uint::MIN, uint::MAX) +bounded_impl!(u8, u8::MIN, u8::MAX) +bounded_impl!(u16, u16::MIN, u16::MAX) +bounded_impl!(u32, u32::MIN, u32::MAX) +bounded_impl!(u64, u64::MIN, u64::MAX) + +bounded_impl!(int, int::MIN, int::MAX) +bounded_impl!(i8, i8::MIN, i8::MAX) +bounded_impl!(i16, i16::MIN, i16::MAX) +bounded_impl!(i32, i32::MIN, i32::MAX) +bounded_impl!(i64, i64::MIN, i64::MAX) + +bounded_impl!(f32, f32::MIN_VALUE, f32::MAX_VALUE) +bounded_impl!(f64, f64::MIN_VALUE, f64::MAX_VALUE) + /// Numbers with a fixed binary representation. pub trait Bitwise: Bounded + Not @@ -259,6 +438,56 @@ pub trait Bitwise: Bounded fn trailing_zeros(&self) -> Self; } +macro_rules! bitwise_impl( + ($t:ty, $co:path, $lz:path, $tz:path) => { + impl Bitwise for $t { + #[inline] + fn count_ones(&self) -> $t { unsafe { $co(*self) } } + + #[inline] + fn leading_zeros(&self) -> $t { unsafe { $lz(*self) } } + + #[inline] + fn trailing_zeros(&self) -> $t { unsafe { $tz(*self) } } + } + } +) + +macro_rules! bitwise_cast_impl( + ($t:ty, $t_cast:ty, $co:path, $lz:path, $tz:path) => { + impl Bitwise for $t { + #[inline] + fn count_ones(&self) -> $t { unsafe { $co(*self as $t_cast) as $t } } + + #[inline] + fn leading_zeros(&self) -> $t { unsafe { $lz(*self as $t_cast) as $t } } + + #[inline] + fn trailing_zeros(&self) -> $t { unsafe { $tz(*self as $t_cast) as $t } } + } + } +) + +#[cfg(target_word_size = "32")] +bitwise_cast_impl!(uint, u32, intrinsics::ctpop32, intrinsics::ctlz32, intrinsics::cttz32) +#[cfg(target_word_size = "64")] +bitwise_cast_impl!(uint, u64, intrinsics::ctpop64, intrinsics::ctlz64, intrinsics::cttz64) + +bitwise_impl!(u8, intrinsics::ctpop8, intrinsics::ctlz8, intrinsics::cttz8) +bitwise_impl!(u16, intrinsics::ctpop16, intrinsics::ctlz16, intrinsics::cttz16) +bitwise_impl!(u32, intrinsics::ctpop32, intrinsics::ctlz32, intrinsics::cttz32) +bitwise_impl!(u64, intrinsics::ctpop64, intrinsics::ctlz64, intrinsics::cttz64) + +#[cfg(target_word_size = "32")] +bitwise_cast_impl!(int, u32, intrinsics::ctpop32, intrinsics::ctlz32, intrinsics::cttz32) +#[cfg(target_word_size = "64")] +bitwise_cast_impl!(int, u64, intrinsics::ctpop64, intrinsics::ctlz64, intrinsics::cttz64) + +bitwise_cast_impl!(i8, u8, intrinsics::ctpop8, intrinsics::ctlz8, intrinsics::cttz8) +bitwise_cast_impl!(i16, u16, intrinsics::ctpop16, intrinsics::ctlz16, intrinsics::cttz16) +bitwise_cast_impl!(i32, u32, intrinsics::ctpop32, intrinsics::ctlz32, intrinsics::cttz32) +bitwise_cast_impl!(i64, u64, intrinsics::ctpop64, intrinsics::ctlz64, intrinsics::cttz64) + /// Specifies the available operations common to all of Rust's core numeric primitives. /// These may not always make sense from a purely mathematical point of view, but /// may be useful for systems programming. @@ -269,6 +498,8 @@ pub trait Primitive: Copy + Ord + Bounded {} +trait_impl!(Primitive for uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + /// A collection of traits relevant to primitive signed and unsigned integers pub trait Int: Primitive + Bitwise @@ -277,6 +508,8 @@ pub trait Int: Primitive + CheckedMul + CheckedDiv {} +trait_impl!(Int for uint u8 u16 u32 u64 int i8 i16 i32 i64) + /// Returns the smallest power of 2 greater than or equal to `n`. #[inline] pub fn next_power_of_two(n: T) -> T { @@ -842,12 +1075,79 @@ pub trait CheckedAdd: Add { fn checked_add(&self, v: &Self) -> Option; } +macro_rules! checked_impl( + ($trait_name:ident, $method:ident, $t:ty, $op:path) => { + impl $trait_name for $t { + #[inline] + fn $method(&self, v: &$t) -> Option<$t> { + unsafe { + let (x, y) = $op(*self, *v); + if y { None } else { Some(x) } + } + } + } + } +) +macro_rules! checked_cast_impl( + ($trait_name:ident, $method:ident, $t:ty, $cast:ty, $op:path) => { + impl $trait_name for $t { + #[inline] + fn $method(&self, v: &$t) -> Option<$t> { + unsafe { + let (x, y) = $op(*self as $cast, *v as $cast); + if y { None } else { Some(x as $t) } + } + } + } + } +) + +#[cfg(target_word_size = "32")] +checked_cast_impl!(CheckedAdd, checked_add, uint, u32, intrinsics::u32_add_with_overflow) +#[cfg(target_word_size = "64")] +checked_cast_impl!(CheckedAdd, checked_add, uint, u64, intrinsics::u64_add_with_overflow) + +checked_impl!(CheckedAdd, checked_add, u8, intrinsics::u8_add_with_overflow) +checked_impl!(CheckedAdd, checked_add, u16, intrinsics::u16_add_with_overflow) +checked_impl!(CheckedAdd, checked_add, u32, intrinsics::u32_add_with_overflow) +checked_impl!(CheckedAdd, checked_add, u64, intrinsics::u64_add_with_overflow) + +#[cfg(target_word_size = "32")] +checked_cast_impl!(CheckedAdd, checked_add, int, i32, intrinsics::i32_add_with_overflow) +#[cfg(target_word_size = "64")] +checked_cast_impl!(CheckedAdd, checked_add, int, i64, intrinsics::i64_add_with_overflow) + +checked_impl!(CheckedAdd, checked_add, i8, intrinsics::i8_add_with_overflow) +checked_impl!(CheckedAdd, checked_add, i16, intrinsics::i16_add_with_overflow) +checked_impl!(CheckedAdd, checked_add, i32, intrinsics::i32_add_with_overflow) +checked_impl!(CheckedAdd, checked_add, i64, intrinsics::i64_add_with_overflow) + /// Performs subtraction that returns `None` instead of wrapping around on underflow. pub trait CheckedSub: Sub { /// Subtracts two numbers, checking for underflow. If underflow happens, `None` is returned. fn checked_sub(&self, v: &Self) -> Option; } +#[cfg(target_word_size = "32")] +checked_cast_impl!(CheckedSub, checked_sub, uint, u32, intrinsics::u32_sub_with_overflow) +#[cfg(target_word_size = "64")] +checked_cast_impl!(CheckedSub, checked_sub, uint, u64, intrinsics::u64_sub_with_overflow) + +checked_impl!(CheckedSub, checked_sub, u8, intrinsics::u8_sub_with_overflow) +checked_impl!(CheckedSub, checked_sub, u16, intrinsics::u16_sub_with_overflow) +checked_impl!(CheckedSub, checked_sub, u32, intrinsics::u32_sub_with_overflow) +checked_impl!(CheckedSub, checked_sub, u64, intrinsics::u64_sub_with_overflow) + +#[cfg(target_word_size = "32")] +checked_cast_impl!(CheckedSub, checked_sub, int, i32, intrinsics::i32_sub_with_overflow) +#[cfg(target_word_size = "64")] +checked_cast_impl!(CheckedSub, checked_sub, int, i64, intrinsics::i64_sub_with_overflow) + +checked_impl!(CheckedSub, checked_sub, i8, intrinsics::i8_sub_with_overflow) +checked_impl!(CheckedSub, checked_sub, i16, intrinsics::i16_sub_with_overflow) +checked_impl!(CheckedSub, checked_sub, i32, intrinsics::i32_sub_with_overflow) +checked_impl!(CheckedSub, checked_sub, i64, intrinsics::i64_sub_with_overflow) + /// Performs multiplication that returns `None` instead of wrapping around on underflow or /// overflow. pub trait CheckedMul: Mul { @@ -856,6 +1156,26 @@ pub trait CheckedMul: Mul { fn checked_mul(&self, v: &Self) -> Option; } +#[cfg(target_word_size = "32")] +checked_cast_impl!(CheckedMul, checked_mul, uint, u32, intrinsics::u32_mul_with_overflow) +#[cfg(target_word_size = "64")] +checked_cast_impl!(CheckedMul, checked_mul, uint, u64, intrinsics::u64_mul_with_overflow) + +checked_impl!(CheckedMul, checked_mul, u8, intrinsics::u8_mul_with_overflow) +checked_impl!(CheckedMul, checked_mul, u16, intrinsics::u16_mul_with_overflow) +checked_impl!(CheckedMul, checked_mul, u32, intrinsics::u32_mul_with_overflow) +checked_impl!(CheckedMul, checked_mul, u64, intrinsics::u64_mul_with_overflow) + +#[cfg(target_word_size = "32")] +checked_cast_impl!(CheckedMul, checked_mul, int, i32, intrinsics::i32_mul_with_overflow) +#[cfg(target_word_size = "64")] +checked_cast_impl!(CheckedMul, checked_mul, int, i64, intrinsics::i64_mul_with_overflow) + +checked_impl!(CheckedMul, checked_mul, i8, intrinsics::i8_mul_with_overflow) +checked_impl!(CheckedMul, checked_mul, i16, intrinsics::i16_mul_with_overflow) +checked_impl!(CheckedMul, checked_mul, i32, intrinsics::i32_mul_with_overflow) +checked_impl!(CheckedMul, checked_mul, i64, intrinsics::i64_mul_with_overflow) + /// Performs division that returns `None` instead of wrapping around on underflow or overflow. pub trait CheckedDiv: Div { /// Divides two numbers, checking for underflow or overflow. If underflow or overflow happens, @@ -863,6 +1183,44 @@ pub trait CheckedDiv: Div { fn checked_div(&self, v: &Self) -> Option; } +macro_rules! checkeddiv_int_impl( + ($t:ty, $min:expr) => { + impl CheckedDiv for $t { + #[inline] + fn checked_div(&self, v: &$t) -> Option<$t> { + if *v == 0 || (*self == $min && *v == -1) { + None + } else { + Some(self / *v) + } + } + } + } +) + +checkeddiv_int_impl!(int, int::MIN) +checkeddiv_int_impl!(i8, i8::MIN) +checkeddiv_int_impl!(i16, i16::MIN) +checkeddiv_int_impl!(i32, i32::MIN) +checkeddiv_int_impl!(i64, i64::MIN) + +macro_rules! checkeddiv_uint_impl( + ($($t:ty)*) => ($( + impl CheckedDiv for $t { + #[inline] + fn checked_div(&self, v: &$t) -> Option<$t> { + if *v == 0 { + None + } else { + Some(self / *v) + } + } + } + )*) +) + +checkeddiv_uint_impl!(uint u8 u16 u32 u64) + /// Helper function for testing numeric operations #[cfg(test)] pub fn test_num(ten: T, two: T) { diff --git a/src/libcore/num/u16.rs b/src/libcore/num/u16.rs index 96db898e3b069..b3c701115c54f 100644 --- a/src/libcore/num/u16.rs +++ b/src/libcore/num/u16.rs @@ -10,47 +10,4 @@ //! Operations and constants for unsigned 16-bits integers (`u16` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; -use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; -use option::{Some, None, Option}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - uint_module!(u16, i16, 16) - -impl CheckedAdd for u16 { - #[inline] - fn checked_add(&self, v: &u16) -> Option { - unsafe { - let (x, y) = intrinsics::u16_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedSub for u16 { - #[inline] - fn checked_sub(&self, v: &u16) -> Option { - unsafe { - let (x, y) = intrinsics::u16_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedMul for u16 { - #[inline] - fn checked_mul(&self, v: &u16) -> Option { - unsafe { - let (x, y) = intrinsics::u16_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} diff --git a/src/libcore/num/u32.rs b/src/libcore/num/u32.rs index 2748b001bb8ed..46f90dca83333 100644 --- a/src/libcore/num/u32.rs +++ b/src/libcore/num/u32.rs @@ -10,47 +10,5 @@ //! Operations and constants for unsigned 32-bits integers (`u32` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; -use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; -use option::{Some, None, Option}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - uint_module!(u32, i32, 32) -impl CheckedAdd for u32 { - #[inline] - fn checked_add(&self, v: &u32) -> Option { - unsafe { - let (x, y) = intrinsics::u32_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedSub for u32 { - #[inline] - fn checked_sub(&self, v: &u32) -> Option { - unsafe { - let (x, y) = intrinsics::u32_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedMul for u32 { - #[inline] - fn checked_mul(&self, v: &u32) -> Option { - unsafe { - let (x, y) = intrinsics::u32_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} diff --git a/src/libcore/num/u64.rs b/src/libcore/num/u64.rs index c047df095327f..bd4333ab5899a 100644 --- a/src/libcore/num/u64.rs +++ b/src/libcore/num/u64.rs @@ -10,47 +10,5 @@ //! Operations and constants for unsigned 64-bits integer (`u64` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; -use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; -use option::{Some, None, Option}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - uint_module!(u64, i64, 64) -impl CheckedAdd for u64 { - #[inline] - fn checked_add(&self, v: &u64) -> Option { - unsafe { - let (x, y) = intrinsics::u64_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedSub for u64 { - #[inline] - fn checked_sub(&self, v: &u64) -> Option { - unsafe { - let (x, y) = intrinsics::u64_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedMul for u64 { - #[inline] - fn checked_mul(&self, v: &u64) -> Option { - unsafe { - let (x, y) = intrinsics::u64_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} diff --git a/src/libcore/num/u8.rs b/src/libcore/num/u8.rs index a6df17956a143..00871a1c8fad1 100644 --- a/src/libcore/num/u8.rs +++ b/src/libcore/num/u8.rs @@ -10,47 +10,5 @@ //! Operations and constants for unsigned 8-bits integers (`u8` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; -use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; -use option::{Some, None, Option}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - uint_module!(u8, i8, 8) -impl CheckedAdd for u8 { - #[inline] - fn checked_add(&self, v: &u8) -> Option { - unsafe { - let (x, y) = intrinsics::u8_add_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedSub for u8 { - #[inline] - fn checked_sub(&self, v: &u8) -> Option { - unsafe { - let (x, y) = intrinsics::u8_sub_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} - -impl CheckedMul for u8 { - #[inline] - fn checked_mul(&self, v: &u8) -> Option { - unsafe { - let (x, y) = intrinsics::u8_mul_with_overflow(*self, *v); - if y { None } else { Some(x) } - } - } -} diff --git a/src/libcore/num/uint.rs b/src/libcore/num/uint.rs index f988650cc01d4..99ed7e10bf9e3 100644 --- a/src/libcore/num/uint.rs +++ b/src/libcore/num/uint.rs @@ -10,83 +10,5 @@ //! Operations and constants for architecture-sized unsigned integers (`uint` type) -use default::Default; -use intrinsics; -use num::{Bitwise, Bounded, Zero, One, Unsigned, Num, Int, Primitive}; -use num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; -use option::{Some, None, Option}; - -#[cfg(not(test))] -use cmp::{Eq, Ord, TotalEq, TotalOrd, Less, Greater, Equal, Ordering}; -#[cfg(not(test))] -use ops::{Add, Sub, Mul, Div, Rem, Neg, BitAnd, BitOr, BitXor}; -#[cfg(not(test))] -use ops::{Shl, Shr, Not}; - uint_module!(uint, int, ::int::BITS) -#[cfg(target_word_size = "32")] -impl CheckedAdd for uint { - #[inline] - fn checked_add(&self, v: &uint) -> Option { - unsafe { - let (x, y) = intrinsics::u32_add_with_overflow(*self as u32, *v as u32); - if y { None } else { Some(x as uint) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedAdd for uint { - #[inline] - fn checked_add(&self, v: &uint) -> Option { - unsafe { - let (x, y) = intrinsics::u64_add_with_overflow(*self as u64, *v as u64); - if y { None } else { Some(x as uint) } - } - } -} - -#[cfg(target_word_size = "32")] -impl CheckedSub for uint { - #[inline] - fn checked_sub(&self, v: &uint) -> Option { - unsafe { - let (x, y) = intrinsics::u32_sub_with_overflow(*self as u32, *v as u32); - if y { None } else { Some(x as uint) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedSub for uint { - #[inline] - fn checked_sub(&self, v: &uint) -> Option { - unsafe { - let (x, y) = intrinsics::u64_sub_with_overflow(*self as u64, *v as u64); - if y { None } else { Some(x as uint) } - } - } -} - -#[cfg(target_word_size = "32")] -impl CheckedMul for uint { - #[inline] - fn checked_mul(&self, v: &uint) -> Option { - unsafe { - let (x, y) = intrinsics::u32_mul_with_overflow(*self as u32, *v as u32); - if y { None } else { Some(x as uint) } - } - } -} - -#[cfg(target_word_size = "64")] -impl CheckedMul for uint { - #[inline] - fn checked_mul(&self, v: &uint) -> Option { - unsafe { - let (x, y) = intrinsics::u64_mul_with_overflow(*self as u64, *v as u64); - if y { None } else { Some(x as uint) } - } - } -} diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs index 092f7d81d220c..0e094b9ec3143 100644 --- a/src/libcore/num/uint_macros.rs +++ b/src/libcore/num/uint_macros.rs @@ -19,167 +19,6 @@ pub static BYTES : uint = ($bits / 8); pub static MIN: $T = 0 as $T; pub static MAX: $T = 0 as $T - 1 as $T; -#[cfg(not(test))] -impl Ord for $T { - #[inline] - fn lt(&self, other: &$T) -> bool { *self < *other } -} -#[cfg(not(test))] -impl TotalEq for $T {} -#[cfg(not(test))] -impl Eq for $T { - #[inline] - fn eq(&self, other: &$T) -> bool { *self == *other } -} -#[cfg(not(test))] -impl TotalOrd for $T { - #[inline] - fn cmp(&self, other: &$T) -> Ordering { - if *self < *other { Less } - else if *self > *other { Greater } - else { Equal } - } -} - -impl Num for $T {} - -impl Zero for $T { - #[inline] - fn zero() -> $T { 0 } - - #[inline] - fn is_zero(&self) -> bool { *self == 0 } -} - -impl One for $T { - #[inline] - fn one() -> $T { 1 } -} - -#[cfg(not(test))] -impl Add<$T,$T> for $T { - #[inline] - fn add(&self, other: &$T) -> $T { *self + *other } -} - -#[cfg(not(test))] -impl Sub<$T,$T> for $T { - #[inline] - fn sub(&self, other: &$T) -> $T { *self - *other } -} - -#[cfg(not(test))] -impl Mul<$T,$T> for $T { - #[inline] - fn mul(&self, other: &$T) -> $T { *self * *other } -} - -#[cfg(not(test))] -impl Div<$T,$T> for $T { - #[inline] - fn div(&self, other: &$T) -> $T { *self / *other } -} - -#[cfg(not(test))] -impl Rem<$T,$T> for $T { - #[inline] - fn rem(&self, other: &$T) -> $T { *self % *other } -} - -#[cfg(not(test))] -impl Neg<$T> for $T { - #[inline] - fn neg(&self) -> $T { -(*self as $T_SIGNED) as $T } -} - -impl Unsigned for $T {} - -#[cfg(not(test))] -impl BitOr<$T,$T> for $T { - #[inline] - fn bitor(&self, other: &$T) -> $T { *self | *other } -} - -#[cfg(not(test))] -impl BitAnd<$T,$T> for $T { - #[inline] - fn bitand(&self, other: &$T) -> $T { *self & *other } -} - -#[cfg(not(test))] -impl BitXor<$T,$T> for $T { - #[inline] - fn bitxor(&self, other: &$T) -> $T { *self ^ *other } -} - -#[cfg(not(test))] -impl Shl<$T,$T> for $T { - #[inline] - fn shl(&self, other: &$T) -> $T { *self << *other } -} - -#[cfg(not(test))] -impl Shr<$T,$T> for $T { - #[inline] - fn shr(&self, other: &$T) -> $T { *self >> *other } -} - -#[cfg(not(test))] -impl Not<$T> for $T { - #[inline] - fn not(&self) -> $T { !*self } -} - -impl Bounded for $T { - #[inline] - fn min_value() -> $T { MIN } - - #[inline] - fn max_value() -> $T { MAX } -} - -impl Bitwise for $T { - /// Returns the number of ones in the binary representation of the number. - #[inline] - fn count_ones(&self) -> $T { - (*self as $T_SIGNED).count_ones() as $T - } - - /// Returns the number of leading zeros in the in the binary representation - /// of the number. - #[inline] - fn leading_zeros(&self) -> $T { - (*self as $T_SIGNED).leading_zeros() as $T - } - - /// Returns the number of trailing zeros in the in the binary representation - /// of the number. - #[inline] - fn trailing_zeros(&self) -> $T { - (*self as $T_SIGNED).trailing_zeros() as $T - } -} - -impl CheckedDiv for $T { - #[inline] - fn checked_div(&self, v: &$T) -> Option<$T> { - if *v == 0 { - None - } else { - Some(self / *v) - } - } -} - -impl Int for $T {} - -impl Primitive for $T {} - -impl Default for $T { - #[inline] - fn default() -> $T { 0 } -} - #[cfg(test)] mod tests { use prelude::*; diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index a3cb18a283ed4..08e033f961f45 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -115,6 +115,18 @@ pub trait Add { fn add(&self, rhs: &RHS) -> Result; } +macro_rules! add_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Add<$t, $t> for $t { + #[inline] + fn add(&self, other: &$t) -> $t { (*self) + (*other) } + } + )*) +) + +add_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + /** * * The `Sub` trait is used to specify the functionality of `-`. @@ -145,6 +157,18 @@ pub trait Sub { fn sub(&self, rhs: &RHS) -> Result; } +macro_rules! sub_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Sub<$t, $t> for $t { + #[inline] + fn sub(&self, other: &$t) -> $t { (*self) - (*other) } + } + )*) +) + +sub_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + /** * * The `Mul` trait is used to specify the functionality of `*`. @@ -175,6 +199,18 @@ pub trait Mul { fn mul(&self, rhs: &RHS) -> Result; } +macro_rules! mul_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Mul<$t, $t> for $t { + #[inline] + fn mul(&self, other: &$t) -> $t { (*self) * (*other) } + } + )*) +) + +mul_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + /** * * The `Div` trait is used to specify the functionality of `/`. @@ -205,6 +241,18 @@ pub trait Div { fn div(&self, rhs: &RHS) -> Result; } +macro_rules! div_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Div<$t, $t> for $t { + #[inline] + fn div(&self, other: &$t) -> $t { (*self) / (*other) } + } + )*) +) + +div_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64) + /** * * The `Rem` trait is used to specify the functionality of `%`. @@ -235,6 +283,33 @@ pub trait Rem { fn rem(&self, rhs: &RHS) -> Result; } +macro_rules! rem_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Rem<$t, $t> for $t { + #[inline] + fn rem(&self, other: &$t) -> $t { (*self) % (*other) } + } + )*) +) + +macro_rules! rem_float_impl( + ($t:ty, $fmod:ident) => { + #[cfg(not(test))] + impl Rem<$t, $t> for $t { + #[inline] + fn rem(&self, other: &$t) -> $t { + extern { fn $fmod(a: $t, b: $t) -> $t; } + unsafe { $fmod(*self, *other) } + } + } + } +) + +rem_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64) +rem_float_impl!(f32, fmodf) +rem_float_impl!(f64, fmod) + /** * * The `Neg` trait is used to specify the functionality of unary `-`. @@ -265,6 +340,35 @@ pub trait Neg { fn neg(&self) -> Result; } +macro_rules! neg_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Neg<$t> for $t { + #[inline] + fn neg(&self) -> $t { -*self } + } + )*) +) + +macro_rules! neg_uint_impl( + ($t:ty, $t_signed:ty) => { + #[cfg(not(test))] + impl Neg<$t> for $t { + #[inline] + fn neg(&self) -> $t { -(*self as $t_signed) as $t } + } + } +) + +neg_impl!(int i8 i16 i32 i64 f32 f64) + +neg_uint_impl!(uint, int) +neg_uint_impl!(u8, i8) +neg_uint_impl!(u16, i16) +neg_uint_impl!(u32, i32) +neg_uint_impl!(u64, i64) + + /** * * The `Not` trait is used to specify the functionality of unary `!`. @@ -295,6 +399,19 @@ pub trait Not { fn not(&self) -> Result; } + +macro_rules! not_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Not<$t> for $t { + #[inline] + fn not(&self) -> $t { !*self } + } + )*) +) + +not_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64) + /** * * The `BitAnd` trait is used to specify the functionality of `&`. @@ -325,6 +442,18 @@ pub trait BitAnd { fn bitand(&self, rhs: &RHS) -> Result; } +macro_rules! bitand_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl BitAnd<$t, $t> for $t { + #[inline] + fn bitand(&self, rhs: &$t) -> $t { (*self) & (*rhs) } + } + )*) +) + +bitand_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64) + /** * * The `BitOr` trait is used to specify the functionality of `|`. @@ -355,6 +484,18 @@ pub trait BitOr { fn bitor(&self, rhs: &RHS) -> Result; } +macro_rules! bitor_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl BitOr<$t,$t> for $t { + #[inline] + fn bitor(&self, rhs: &$t) -> $t { (*self) | (*rhs) } + } + )*) +) + +bitor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64) + /** * * The `BitXor` trait is used to specify the functionality of `^`. @@ -385,6 +526,18 @@ pub trait BitXor { fn bitxor(&self, rhs: &RHS) -> Result; } +macro_rules! bitxor_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl BitXor<$t, $t> for $t { + #[inline] + fn bitxor(&self, other: &$t) -> $t { (*self) ^ (*other) } + } + )*) +) + +bitxor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64) + /** * * The `Shl` trait is used to specify the functionality of `<<`. @@ -415,6 +568,18 @@ pub trait Shl { fn shl(&self, rhs: &RHS) -> Result; } +macro_rules! shl_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Shl<$t, $t> for $t { + #[inline] + fn shl(&self, other: &$t) -> $t { (*self) << (*other) } + } + )*) +) + +shl_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64) + /** * * The `Shr` trait is used to specify the functionality of `>>`. @@ -445,6 +610,18 @@ pub trait Shr { fn shr(&self, rhs: &RHS) -> Result; } +macro_rules! shr_impl( + ($($t:ty)*) => ($( + #[cfg(not(test))] + impl Shr<$t, $t> for $t { + #[inline] + fn shr(&self, other: &$t) -> $t { (*self) >> (*other) } + } + )*) +) + +shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64) + /** * * The `Index` trait is used to specify the functionality of indexing operations