提交 b6242100 编写于 作者: B Brendan Zabarauskas

Add Bitwise, Bounded, Primitive, and PrimitiveInt traits

上级 f40be999
......@@ -106,6 +106,8 @@ pub use iter::{ExtendedMutableIter};
pub use num::{Num, NumCast};
pub use num::{Signed, Unsigned, Integer};
pub use num::{Round, Fractional, Real, RealExt};
pub use num::{Bitwise, Bounded};
pub use num::{Primitive, PrimitiveInt};
pub use ptr::Ptr;
pub use to_str::ToStr;
pub use clone::Clone;
......
......@@ -509,6 +509,14 @@ fn cosh(&self) -> f32 { cosh(*self) }
fn tanh(&self) -> f32 { tanh(*self) }
}
impl Primitive for f32 {
#[inline(always)]
fn bits() -> uint { 32 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<f32>() / 8 }
}
//
// Section: String Conversions
//
......@@ -873,6 +881,12 @@ pub fn test_signed() {
assert!((1f32/neg_infinity).is_negative());
assert!(!NaN.is_negative());
}
#[test]
fn test_primitive() {
assert_eq!(Primitive::bits::<f32>(), sys::size_of::<f32>() * 8);
assert_eq!(Primitive::bytes::<f32>(), sys::size_of::<f32>());
}
}
//
......
......@@ -549,6 +549,14 @@ fn y1(&self) -> f64 { y1(*self) }
fn yn(&self, n: int) -> f64 { yn(n as c_int, *self) }
}
impl Primitive for f64 {
#[inline(always)]
fn bits() -> uint { 64 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<f64>() / 8 }
}
//
// Section: String Conversions
//
......@@ -914,6 +922,12 @@ pub fn test_signed() {
assert!((1f64/neg_infinity).is_negative());
assert!(!NaN.is_negative());
}
#[test]
fn test_primitive() {
assert_eq!(Primitive::bits::<f64>(), sys::size_of::<f64>() * 8);
assert_eq!(Primitive::bytes::<f64>(), sys::size_of::<f64>());
}
}
//
......
......@@ -689,6 +689,14 @@ fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
}
impl Primitive for float {
#[inline(always)]
fn bits() -> uint { Primitive::bits::<f64>() }
#[inline(always)]
fn bytes() -> uint { Primitive::bytes::<f64>() }
}
#[cfg(test)]
mod tests {
use super::*;
......@@ -836,6 +844,12 @@ fn test_signed() {
assert!(!NaN.is_negative());
}
#[test]
fn test_primitive() {
assert_eq!(Primitive::bits::<float>(), sys::size_of::<float>() * 8);
assert_eq!(Primitive::bytes::<float>(), sys::size_of::<float>());
}
#[test]
pub fn test_to_str_exact_do_decimal() {
let s = to_str_exact(5.0, 4u);
......
......@@ -399,6 +399,8 @@ fn is_even(&self) -> bool { self.divisible_by(&2) }
fn is_odd(&self) -> bool { !self.is_even() }
}
impl Bitwise for T {}
#[cfg(notest)]
impl BitOr<T,T> for T {
#[inline(always)]
......@@ -435,6 +437,16 @@ impl Not<T> for T {
fn not(&self) -> T { !*self }
}
impl Bounded for T {
#[inline(always)]
fn min_value() -> T { min_value }
#[inline(always)]
fn max_value() -> T { max_value }
}
impl PrimitiveInt for T {}
// String conversion functions and impl str -> num
/// Parse a string as a number in base 10.
......@@ -641,6 +653,12 @@ fn test_bitwise_ops() {
assert_eq!(-(0b11 as T) - (1 as T), (0b11 as T).not());
}
#[test]
fn test_primitive() {
assert_eq!(Primitive::bits::<T>(), sys::size_of::<T>() * 8);
assert_eq!(Primitive::bytes::<T>(), sys::size_of::<T>());
}
#[test]
fn test_from_str() {
assert_eq!(from_str(~"0"), Some(0 as T));
......
......@@ -11,6 +11,16 @@
//! Operations and constants for `i16`
mod inst {
use num::Primitive;
pub type T = i16;
pub static bits: uint = ::u16::bits;
impl Primitive for i16 {
#[inline(always)]
fn bits() -> uint { 16 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<i16>() / 8 }
}
}
......@@ -11,6 +11,16 @@
//! Operations and constants for `i32`
mod inst {
use num::Primitive;
pub type T = i32;
pub static bits: uint = ::u32::bits;
impl Primitive for i32 {
#[inline(always)]
fn bits() -> uint { 32 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<i32>() / 8 }
}
}
......@@ -11,6 +11,16 @@
//! Operations and constants for `i64`
mod inst {
use num::Primitive;
pub type T = i64;
pub static bits: uint = ::u64::bits;
impl Primitive for i64 {
#[inline(always)]
fn bits() -> uint { 64 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<i64>() / 8 }
}
}
......@@ -11,6 +11,16 @@
//! Operations and constants for `i8`
mod inst {
use num::Primitive;
pub type T = i8;
pub static bits: uint = ::u8::bits;
impl Primitive for i8 {
#[inline(always)]
fn bits() -> uint { 8 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<i8>() / 8 }
}
}
......@@ -13,9 +13,30 @@
pub use self::inst::pow;
mod inst {
use num::Primitive;
pub type T = int;
pub static bits: uint = ::uint::bits;
impl Primitive for int {
#[cfg(target_word_size = "32")]
#[inline(always)]
fn bits() -> uint { 32 }
#[cfg(target_word_size = "64")]
#[inline(always)]
fn bits() -> uint { 64 }
// fallback if we don't have access to the current word size
#[cfg(not(target_word_size = "32"),
not(target_word_size = "64"))]
#[inline(always)]
fn bits() -> uint { sys::size_of::<int>() * 8 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<int>() / 8 }
}
/// Returns `base` raised to the power of `exponent`
pub fn pow(base: int, exponent: uint) -> int {
if exponent == 0u {
......
......@@ -18,6 +18,7 @@
use Rem = ops::Modulo;
#[cfg(not(stage0))]
use ops::{Add, Sub, Mul, Quot, Rem, Neg};
use ops::{Not, BitAnd, BitOr, BitXor, Shl, Shr};
use option::Option;
use kinds::Copy;
......@@ -173,6 +174,60 @@ pub trait RealExt: Real {
fn yn(&self, n: int) -> Self;
}
///
/// Collects the bitwise operators under one trait.
///
pub trait Bitwise: Not<Self>
+ BitAnd<Self,Self>
+ BitOr<Self,Self>
+ BitXor<Self,Self>
+ Shl<Self,Self>
+ Shr<Self,Self> {}
pub trait Bounded {
// FIXME (#5527): These should be associated constants
fn min_value() -> Self;
fn max_value() -> Self;
}
///
/// 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.
///
pub trait Primitive: Num
+ NumCast
+ Neg<Self>
+ Add<Self,Self>
+ Sub<Self,Self>
+ Mul<Self,Self>
+ Quot<Self,Self>
+ Rem<Self,Self> {
// FIXME (#5527): These should be associated constants
fn bits() -> uint;
fn bytes() -> uint;
}
///
/// A collection of traits relevant to primitive signed and unsigned integers
///
pub trait PrimitiveInt: Integer
+ Primitive
+ Bounded
+ Bitwise {}
///
/// Specialisation of `PrimitiveInt` for unsigned integers
///
pub trait Uint: PrimitiveInt
+ Unsigned {}
///
/// Specialisation of `PrimitiveInt` for signed integers
///
pub trait Int: PrimitiveInt
+ Signed {}
///
/// Cast from one machine scalar to another
///
......
......@@ -231,6 +231,8 @@ fn is_even(&self) -> bool { self.divisible_by(&2) }
fn is_odd(&self) -> bool { !self.is_even() }
}
impl Bitwise for T {}
#[cfg(notest)]
impl BitOr<T,T> for T {
#[inline(always)]
......@@ -267,6 +269,16 @@ impl Not<T> for T {
fn not(&self) -> T { !*self }
}
impl Bounded for T {
#[inline(always)]
fn min_value() -> T { min_value }
#[inline(always)]
fn max_value() -> T { max_value }
}
impl PrimitiveInt for T {}
// String conversion functions and impl str -> num
/// Parse a string as a number in base 10.
......@@ -384,6 +396,12 @@ fn test_bitwise_ops() {
assert_eq!(max_value - (0b1011 as T), (0b1011 as T).not());
}
#[test]
fn test_primitive() {
assert_eq!(Primitive::bits::<T>(), sys::size_of::<T>() * 8);
assert_eq!(Primitive::bytes::<T>(), sys::size_of::<T>());
}
#[test]
pub fn test_to_str() {
assert_eq!(to_str_radix(0 as T, 10u), ~"0");
......
......@@ -11,8 +11,18 @@
//! Operations and constants for `u16`
mod inst {
use num::Primitive;
pub type T = u16;
#[allow(non_camel_case_types)]
pub type T_SIGNED = i16;
pub static bits: uint = 16;
impl Primitive for u16 {
#[inline(always)]
fn bits() -> uint { 16 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<u16>() / 8 }
}
}
......@@ -11,8 +11,18 @@
//! Operations and constants for `u32`
mod inst {
use num::Primitive;
pub type T = u32;
#[allow(non_camel_case_types)]
pub type T_SIGNED = i32;
pub static bits: uint = 32;
impl Primitive for u32 {
#[inline(always)]
fn bits() -> uint { 32 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<u32>() / 8 }
}
}
......@@ -11,8 +11,18 @@
//! Operations and constants for `u64`
mod inst {
use num::Primitive;
pub type T = u64;
#[allow(non_camel_case_types)]
pub type T_SIGNED = i64;
pub static bits: uint = 64;
impl Primitive for u64 {
#[inline(always)]
fn bits() -> uint { 64 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<u64>() / 8 }
}
}
......@@ -11,8 +11,18 @@
//! Operations and constants for `u8`
mod inst {
use num::Primitive;
pub type T = u8;
#[allow(non_camel_case_types)]
pub type T_SIGNED = i8;
pub static bits: uint = 8;
impl Primitive for u8 {
#[inline(always)]
fn bits() -> uint { 8 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<u8>() / 8 }
}
}
......@@ -18,6 +18,7 @@
pub mod inst {
use sys;
use iter;
use num::Primitive;
pub type T = uint;
#[allow(non_camel_case_types)]
......@@ -31,6 +32,25 @@ pub mod inst {
#[cfg(target_arch = "x86_64")]
pub static bits: uint = 64;
impl Primitive for uint {
#[cfg(target_word_size = "32")]
#[inline(always)]
fn bits() -> uint { 32 }
#[cfg(target_word_size = "64")]
#[inline(always)]
fn bits() -> uint { 64 }
// fallback if we don't have access to the current word size
#[cfg(not(target_word_size = "32"),
not(target_word_size = "64"))]
#[inline(always)]
fn bits() -> uint { sys::size_of::<uint>() * 8 }
#[inline(always)]
fn bytes() -> uint { Primitive::bits::<uint>() / 8 }
}
///
/// Divide two numbers, return the result, rounded up.
///
......
......@@ -40,6 +40,8 @@
pub use num::{Num, NumCast};
pub use num::{Signed, Unsigned, Integer};
pub use num::{Round, Fractional, Real, RealExt};
pub use num::{Bitwise, Bounded};
pub use num::{Primitive, PrimitiveInt};
pub use path::GenericPath;
pub use path::Path;
pub use path::PosixPath;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册