Switch to using numeric-rs for numeric type traits

This commit is contained in:
Brendan Zabarauskas 2012-12-16 15:05:04 +10:00
parent 00e2543b22
commit ff336f0791
20 changed files with 71 additions and 1172 deletions

View file

@ -2,6 +2,14 @@
Lmath is generic linear algebra library for Rust. There is still much to do, unit tests to write, bugs to fix, and performance enhancements to make. Help is much appreciated, so please don't hesitate to send me a pull request.
# Installation
`$ cargo install lmath`
# Dependencies
- [numeric-rs](https://github.com/bjz/numeric-rs/) (can be installed via `$ cargo install numeric`)
## Todo:
- ~~Matrix inversion~~

View file

@ -1,250 +0,0 @@
use core::cmp::{Eq, Ord};
use std::cmp::FuzzyEq;
use funs::triganomic::{cos, sin};
use mat::{Mat3, Mat4};
use num::types::{Float, Number};
use quat::Quat;
use vec::Vec3;
/**
* The base trait for angular units
*/
pub trait Angle<T>: Add<self,self>
Sub<self,self>
Mul<T,self>
Div<T,self>
// Div<self,T> // TODO: not sure how to implement this, or if it is even possible...
Modulo<T,self>
// Modulo<self,T> // TODO: not sure how to implement this, or if it is even possible...
Neg<self>
FuzzyEq
Eq Ord {
static pure fn full_turn() -> self;
static pure fn half_turn() -> self;
static pure fn quadrant() -> self;
static pure fn sextant() -> self;
static pure fn octant() -> self;
static pure fn zero() -> self;
pure fn to_radians(&self) -> Radians<T>;
pure fn to_degrees(&self) -> Degrees<T>;
pure fn wrap(&self) -> self;
pure fn opposite(&self) -> self;
}
// pub struct Radians<T>(T); // error: internal compiler error: deref_cat() invoked on non-derefable type angle::Radians<'a>
pub enum Radians<T> = T;
pub impl<T:Copy Float> Radians<T>: Angle<T> {
#[inline(always)] static pure fn full_turn() -> Radians<T> { Radians(Float::two_pi()) }
#[inline(always)] static pure fn half_turn() -> Radians<T> { Radians(Float::pi()) }
#[inline(always)] static pure fn quadrant() -> Radians<T> { Radians(Float::frac_pi_2()) }
#[inline(always)] static pure fn sextant() -> Radians<T> { Radians(Float::frac_pi_3()) }
#[inline(always)] static pure fn octant() -> Radians<T> { Radians(Float::frac_pi_4()) }
#[inline(always)] static pure fn zero() -> Radians<T> { Radians(Number::zero()) }
#[inline(always)] pure fn to_radians(&self) -> Radians<T> { *self }
#[inline(always)] pure fn to_degrees(&self) -> Degrees<T> { Degrees(**self * Number::from(180.0 / Float::pi())) }
#[inline(always)]
pure fn wrap(&self) -> Radians<T> {
let theta = (*self) % Number::from(2.0 * Float::pi());
// keep in the domain of 0 to 1 rad
if theta >= Angle::zero() {
theta
} else {
theta + Angle::full_turn()
}
}
#[inline(always)]
pure fn opposite(&self) -> Radians<T> {
(self + Angle::half_turn()).wrap()
}
}
pub impl<T:Copy Float> Radians<T>: Add<Radians<T>, Radians<T>> {
#[inline(always)]
pure fn add(&self, rhs: &Radians<T>) -> Radians<T> {
Radians(**self + **rhs)
}
}
pub impl<T:Copy Float> Radians<T>: Sub<Radians<T>, Radians<T>> {
#[inline(always)]
pure fn sub(&self, rhs: &Radians<T>) -> Radians<T> {
Radians(**self - **rhs)
}
}
pub impl<T:Copy Float> Radians<T>: Mul<T, Radians<T>> {
#[inline(always)]
pure fn mul(&self, rhs: &T) -> Radians<T> {
Radians(**self * *rhs)
}
}
pub impl<T:Copy Float> Radians<T>: Div<T, Radians<T>> {
#[inline(always)]
pure fn div(&self, rhs: &T) -> Radians<T> {
Radians(**self / *rhs)
}
}
pub impl<T:Copy Float> Radians<T>: Modulo<T, Radians<T>> {
#[inline(always)]
pure fn modulo(&self, rhs: &T) -> Radians<T> {
Radians(**self % *rhs)
}
}
pub impl<T:Copy Float> Radians<T>: Neg<Radians<T>> {
#[inline(always)]
pure fn neg(&self) -> Radians<T> {
Radians(-**self)
}
}
pub impl<T:Copy Float> Radians<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &Radians<T>) -> bool {
(*self).fuzzy_eq(&**other)
}
}
pub impl<T:Copy Float> Radians<T>: Eq {
#[inline(always)] pure fn eq(&self, other: &Radians<T>) -> bool { **self == **other }
#[inline(always)] pure fn ne(&self, other: &Radians<T>) -> bool { **self != **other }
}
pub impl<T:Copy Float> Radians<T>: Ord {
#[inline(always)] pure fn lt(&self, other: &Radians<T>) -> bool { **self < **other }
#[inline(always)] pure fn le(&self, other: &Radians<T>) -> bool { **self <= **other }
#[inline(always)] pure fn ge(&self, other: &Radians<T>) -> bool { **self >= **other }
#[inline(always)] pure fn gt(&self, other: &Radians<T>) -> bool { **self > **other }
}
/**
* # Example
*
* ~~~
* assert fmt!("%s", Radians(1).to_str()) == ~"1 rad";
* ~~~
*/
pub impl<T> Radians<T>: ToStr {
pure fn to_str() -> ~str { fmt!("%? rad", *self) }
}
// pub struct Degrees<T>(T); // error: internal compiler error: deref_cat() invoked on non-derefable type angle::Degrees<'a>
pub enum Degrees<T> = T;
pub impl<T:Copy Float> Degrees<T>: Angle<T> {
#[inline(always)] static pure fn full_turn() -> Degrees<T> { Degrees(Number::from(360.0)) }
#[inline(always)] static pure fn half_turn() -> Degrees<T> { Degrees(Number::from(180.0)) }
#[inline(always)] static pure fn quadrant() -> Degrees<T> { Degrees(Number::from(90.0)) }
#[inline(always)] static pure fn sextant() -> Degrees<T> { Degrees(Number::from(60.0)) }
#[inline(always)] static pure fn octant() -> Degrees<T> { Degrees(Number::from(45.0)) }
#[inline(always)] static pure fn zero() -> Degrees<T> { Degrees(Number::from(0.0)) }
#[inline(always)] pure fn to_radians(&self) -> Radians<T> { Radians(**self * Number::from(Float::pi::<float>() / 180.0)) }
#[inline(always)] pure fn to_degrees(&self) -> Degrees<T> { *self }
#[inline(always)]
pure fn wrap(&self) -> Degrees<T> {
let theta = (*self) % Number::from(360);
// keep in the domain of 0 to 360 degrees
if theta >= Angle::zero() {
theta
} else {
theta + Angle::full_turn()
}
}
#[inline(always)]
pure fn opposite(&self) -> Degrees<T> {
(self + Angle::half_turn()).wrap()
}
}
pub impl<T:Copy Float> Degrees<T>: Add<Degrees<T>, Degrees<T>> {
#[inline(always)]
pure fn add(&self, rhs: &Degrees<T>) -> Degrees<T> {
Degrees(**self + **rhs)
}
}
pub impl<T:Copy Float> Degrees<T>: Sub<Degrees<T>, Degrees<T>> {
#[inline(always)]
pure fn sub(&self, rhs: &Degrees<T>) -> Degrees<T> {
Degrees(**self - **rhs)
}
}
pub impl<T:Copy Float> Degrees<T>: Mul<T, Degrees<T>> {
#[inline(always)]
pure fn mul(&self, rhs: &T) -> Degrees<T> {
Degrees(**self * *rhs)
}
}
pub impl<T:Copy Float> Degrees<T>: Div<T, Degrees<T>> {
#[inline(always)]
pure fn div(&self, rhs: &T) -> Degrees<T> {
Degrees(**self / *rhs)
}
}
pub impl<T:Copy Float> Degrees<T>: Modulo<T, Degrees<T>> {
#[inline(always)]
pure fn modulo(&self, rhs: &T) -> Degrees<T> {
Degrees(**self % *rhs)
}
}
pub impl<T:Copy Float> Degrees<T>: Neg<Degrees<T>> {
#[inline(always)]
pure fn neg(&self) -> Degrees<T> {
Degrees(-**self)
}
}
pub impl<T:Copy Float> Degrees<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &Degrees<T>) -> bool {
(*self).fuzzy_eq(&**other)
}
}
pub impl<T:Copy Float> Degrees<T>: Eq {
#[inline(always)] pure fn eq(&self, other: &Degrees<T>) -> bool { **self == **other }
#[inline(always)] pure fn ne(&self, other: &Degrees<T>) -> bool { **self != **other }
}
pub impl<T:Copy Float> Degrees<T>: Ord {
#[inline(always)] pure fn lt(&self, other: &Degrees<T>) -> bool { **self < **other }
#[inline(always)] pure fn le(&self, other: &Degrees<T>) -> bool { **self <= **other }
#[inline(always)] pure fn ge(&self, other: &Degrees<T>) -> bool { **self >= **other }
#[inline(always)] pure fn gt(&self, other: &Degrees<T>) -> bool { **self > **other }
}
/**
* # Example
*
* ~~~
* assert fmt!("%s", Degrees(180.0).to_str()) == ~"180°";
* ~~~
*/
pub impl<T> Degrees<T>: ToStr {
pure fn to_str() -> ~str { fmt!("%?\xB0", *self) }
}

View file

@ -1,6 +1,8 @@
use funs::triganomic::tan;
use angle::Angle;
use num::types::{Float, Number};
use numeric::traits::*;
use numeric::types::angle::Angle;
use numeric::types::float::Float;
use numeric::types::number::Number;
use mat::Mat4;
/**

View file

@ -22,7 +22,6 @@
use core::sys::size_of;
use angle::{Angle, Radians, Degrees};
use mat::{Matrix, Mat2, Mat3, Mat4};
use vec::{Vector, NumericVector, Vec2, Vec3, Vec4};
use quat::{/*Quaternion, */Quat};
@ -347,56 +346,6 @@ pub impl dmat4 {
}
// Angle unit aliases. These are not present in the GLSL specification, but they
// follow roughly the same nomenclature.
pub type radians = Radians<f32>; /// a single-precision angle with floating-point radian units
pub type dradians = Radians<f64>; /// a double-precision angle with floating-point radian units
pub type degrees = Degrees<f32>; /// a single-precision angle with floating-point degree units
pub type ddegrees = Degrees<f64>; /// a double-precision angle with floating-point degree units
// TODO: not sure about 'ddegrees' - could be easy to mis-type
// Angle unit constructors
pub fn radians(theta: f32) -> radians { Radians(theta) }
pub fn dradians(theta: f64) -> dradians { Radians(theta) }
pub fn degrees(theta: f32) -> degrees { Degrees(theta) }
pub fn ddegrees(theta: f64) -> ddegrees { Degrees(theta) }
pub impl radians {
#[inline(always)] static pure fn full_turn() -> radians { Angle::full_turn() }
#[inline(always)] static pure fn half_turn() -> radians { Angle::half_turn() }
#[inline(always)] static pure fn quadrant() -> radians { Angle::quadrant() }
#[inline(always)] static pure fn sextant() -> radians { Angle::sextant() }
#[inline(always)] static pure fn octant() -> radians { Angle::octant() }
}
pub impl dradians {
#[inline(always)] static pure fn full_turn() -> dradians { Angle::full_turn() }
#[inline(always)] static pure fn half_turn() -> dradians { Angle::half_turn() }
#[inline(always)] static pure fn quadrant() -> dradians { Angle::quadrant() }
#[inline(always)] static pure fn sextant() -> dradians { Angle::sextant() }
#[inline(always)] static pure fn octant() -> dradians { Angle::octant() }
}
pub impl degrees {
#[inline(always)] static pure fn full_turn() -> degrees { Angle::full_turn() }
#[inline(always)] static pure fn half_turn() -> degrees { Angle::half_turn() }
#[inline(always)] static pure fn quadrant() -> degrees { Angle::quadrant() }
#[inline(always)] static pure fn sextant() -> degrees { Angle::sextant() }
#[inline(always)] static pure fn octant() -> degrees { Angle::octant() }
}
pub impl ddegrees {
#[inline(always)] static pure fn full_turn() -> ddegrees { Angle::full_turn() }
#[inline(always)] static pure fn half_turn() -> ddegrees { Angle::half_turn() }
#[inline(always)] static pure fn quadrant() -> ddegrees { Angle::quadrant() }
#[inline(always)] static pure fn sextant() -> ddegrees { Angle::sextant() }
#[inline(always)] static pure fn octant() -> ddegrees { Angle::octant() }
}
// Quaternion aliases. These are not present in the GLSL specification, but
// they follow roughly the same nomenclature.

View file

@ -9,8 +9,8 @@
#[crate_type = "lib"];
extern mod std;
extern mod numeric;
pub mod angle;
pub mod gltypes;
pub mod mat;
pub mod quat;
@ -18,8 +18,6 @@ pub mod vec;
#[test]
mod test {
#[path = "test/test_angle.rs"]
mod test_angle;
#[path = "test/test_gltypes.rs"]
mod test_gltypes;
#[path = "test/test_mat.rs"]
@ -31,25 +29,18 @@ mod test {
}
pub mod funs {
#[path = "funs/common.rs"]
pub mod common;
#[path = "funs/exponential.rs"]
pub mod exponential;
// #[path = "funs/common.rs"]
// pub mod common;
// #[path = "funs/exponential.rs"]
// pub mod exponential;
#[path = "funs/projection.rs"]
pub mod projection;
#[path = "funs/triganomic.rs"]
pub mod triganomic;
// #[path = "funs/triganomic.rs"]
// pub mod triganomic;
#[test]
mod test {
#[path = "funs/test/test_common.rs"]
mod test_common;
// #[path = "funs/test/test_common.rs"]
// mod test_common;
}
}
pub mod num {
#[path = "num/conv.rs"]
pub mod conv;
#[path = "num/types.rs"]
pub mod types;
}

View file

@ -1,7 +1,7 @@
use core::cmp::Eq;
use std::cmp::FuzzyEq;
use numeric::types::angle::Angle;
use angle::Angle;
use quat::Quat;
pub mod mat2;

View file

@ -4,12 +4,11 @@ use core::ptr::to_unsafe_ptr;
use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use numeric::traits::*;
use numeric::types::angle::Angle;
use numeric::types::float::Float;
use numeric::types::number::Number;
use angle::Angle;
use funs::common::*;
use funs::exponential::*;
use funs::triganomic::{sin, cos};
use num::types::{Float, Number};
use vec::Vec2;
/**
@ -273,7 +272,7 @@ pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
}
}
pub impl<T:Copy Float Sign> Mat2<T>: MutableMatrix<T, Vec2<T>> {
pub impl<T:Copy Float> Mat2<T>: MutableMatrix<T, Vec2<T>> {
#[inline(always)]
fn col_mut(&mut self, i: uint) -> &self/mut Vec2<T> {
match i {

View file

@ -4,12 +4,11 @@ use core::ptr::to_unsafe_ptr;
use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use numeric::traits::*;
use numeric::types::angle::Angle;
use numeric::types::float::Float;
use numeric::types::number::Number;
use angle::Angle;
use funs::common::*;
use funs::exponential::*;
use funs::triganomic::{sin, cos};
use num::types::{Float, Number};
use quat::Quat;
use vec::Vec3;
@ -405,7 +404,7 @@ pub impl<T:Copy Float> Mat3<T>: Matrix<T, Vec3<T>> {
}
}
pub impl<T:Copy Float Sign> Mat3<T>: MutableMatrix<T, Vec3<T>> {
pub impl<T:Copy Float> Mat3<T>: MutableMatrix<T, Vec3<T>> {
#[inline(always)]
fn col_mut(&mut self, i: uint) -> &self/mut Vec3<T> {
match i {
@ -486,7 +485,7 @@ pub impl<T:Copy Float Sign> Mat3<T>: MutableMatrix<T, Vec3<T>> {
}
}
pub impl<T:Copy Float Exp> Mat3<T>: Matrix3<T, Vec3<T>> {
pub impl<T:Copy Float> Mat3<T>: Matrix3<T, Vec3<T>> {
#[inline(always)]
static pure fn from_axis_angle<A:Angle<T>>(axis: &Vec3<T>, theta: A) -> Mat3<T> {
let c: T = cos(&theta.to_radians());

View file

@ -4,11 +4,11 @@ use core::ptr::to_unsafe_ptr;
use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use numeric::traits::*;
use numeric::types::angle::Angle;
use numeric::types::float::Float;
use numeric::types::number::Number;
use angle::Angle;
use funs::common::*;
use funs::exponential::*;
use num::types::{Float, Number};
use vec::Vec4;
/**
@ -147,7 +147,7 @@ pub impl<T:Copy Float> Mat4<T> {
}
}
pub impl<T:Copy Float Sign> Mat4<T>: Matrix<T, Vec4<T>> {
pub impl<T:Copy Float> Mat4<T>: Matrix<T, Vec4<T>> {
#[inline(always)]
pure fn col(&self, i: uint) -> Vec4<T> { self[i] }
@ -408,7 +408,7 @@ pub impl<T:Copy Float Sign> Mat4<T>: Matrix<T, Vec4<T>> {
}
}
pub impl<T:Copy Float Sign> Mat4<T>: MutableMatrix<T, Vec4<T>> {
pub impl<T:Copy Float> Mat4<T>: MutableMatrix<T, Vec4<T>> {
#[inline(always)]
fn col_mut(&mut self, i: uint) -> &self/mut Vec4<T> {
match i {

View file

@ -1,255 +0,0 @@
/**
* Wrapper methods for numeric type casts
*/
pub trait NumConv {
pure fn to_u8(&self) -> u8;
pure fn to_u16(&self) -> u16;
pure fn to_u32(&self) -> u32;
pure fn to_u64(&self) -> u64;
pure fn to_uint(&self) -> uint;
pure fn to_i8(&self) -> i8;
pure fn to_i16(&self) -> i16;
pure fn to_i32(&self) -> i32;
pure fn to_i64(&self) -> i64;
pure fn to_int_(&self) -> int; // FIXME: conflict with `num::Num::to_int` :(
pure fn to_f32(&self) -> f32;
pure fn to_f64(&self) -> f64;
pure fn to_float(&self) -> float;
}
pub impl u8: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl u16: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl u32: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl u64: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl uint: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl i8: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl i16: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl i32: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl i64: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl int: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl f32: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl f64: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self }
#[inline(always)] pure fn to_float(&self) -> float { *self as float }
}
pub impl float: NumConv {
#[inline(always)] pure fn to_u8(&self) -> u8 { *self as u8 }
#[inline(always)] pure fn to_u16(&self) -> u16 { *self as u16 }
#[inline(always)] pure fn to_u32(&self) -> u32 { *self as u32 }
#[inline(always)] pure fn to_u64(&self) -> u64 { *self as u64 }
#[inline(always)] pure fn to_uint(&self) -> uint { *self as uint }
#[inline(always)] pure fn to_i8(&self) -> i8 { *self as i8 }
#[inline(always)] pure fn to_i16(&self) -> i16 { *self as i16 }
#[inline(always)] pure fn to_i32(&self) -> i32 { *self as i32 }
#[inline(always)] pure fn to_i64(&self) -> i64 { *self as i64 }
#[inline(always)] pure fn to_int_(&self) -> int { *self as int }
#[inline(always)] pure fn to_f32(&self) -> f32 { *self as f32 }
#[inline(always)] pure fn to_f64(&self) -> f64 { *self as f64 }
#[inline(always)] pure fn to_float(&self) -> float { *self }
}

View file

@ -1,404 +0,0 @@
use core::cmp::{Eq, Ord};
use std::cmp::FuzzyEq;
use num::conv::NumConv;
pub trait Number: Eq Num NumConv Ord {
/**
* Construct a new number by casting a number the the static method's
* enclosing type
*
* # Example
*
* ~~~
* let twenty: f32 = Number::from(0x14);
* assert twenty == 20f32;
* ~~~
*/
static pure fn from<T:NumConv>(n: T) -> self;
static pure fn size_of() -> uint;
static pure fn bits() -> uint;
static pure fn zero() -> self; /// The additive identity
static pure fn one() -> self; // The multiplicative identity
}
pub impl u8: Number {
/**
* Construct a `u8` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> u8 { n.to_u8() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<u8>() }
#[inline(always)] static pure fn bits() -> uint { 8 }
#[inline(always)] static pure fn zero() -> u8 { 0u8 } /// 0u8
#[inline(always)] static pure fn one() -> u8 { 1u8 } // 1u8
}
pub impl u16: Number {
/**
* Construct a `u16` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> u16 { n.to_u16() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<u16>() }
#[inline(always)] static pure fn bits() -> uint { 16 }
#[inline(always)] static pure fn zero() -> u16 { 0u16 } /// 0u16
#[inline(always)] static pure fn one() -> u16 { 1u16 } // 1u16
}
pub impl u32: Number {
/**
* Construct a `u32` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> u32 { n.to_u32() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<u32>() }
#[inline(always)] static pure fn bits() -> uint { 32 }
#[inline(always)] static pure fn zero() -> u32 { 0u32 } /// 0u32
#[inline(always)] static pure fn one() -> u32 { 1u32 } // 1u32
}
pub impl u64: Number {
/**
* Construct a `u64` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> u64 { n.to_u64() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<u64>() }
#[inline(always)] static pure fn bits() -> uint { 64 }
#[inline(always)] static pure fn zero() -> u64 { 0u64 } /// 0u64
#[inline(always)] static pure fn one() -> u64 { 1u64 } // 1u64
}
pub impl uint: Number {
/**
* Construct a `uint` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> uint { n.to_uint() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<uint>() }
#[inline(always)] static pure fn bits() -> uint { sys::size_of::<uint>() * 8 }
#[inline(always)] static pure fn zero() -> uint { 0u } /// 0u
#[inline(always)] static pure fn one() -> uint { 1u } // 1u
}
pub impl i8: Number {
/**
* Construct an `i8` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> i8 { n.to_i8() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<i8>() }
#[inline(always)] static pure fn bits() -> uint { 8 }
#[inline(always)] static pure fn zero() -> i8 { 0i8 } /// 0i8
#[inline(always)] static pure fn one() -> i8 { 1i8 } // 1i8
}
pub impl i16: Number {
/**
* Construct an `i16` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> i16 { n.to_i16() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<i16>() }
#[inline(always)] static pure fn bits() -> uint { 16 }
#[inline(always)] static pure fn zero() -> i16 { 0i16 } /// 0i16
#[inline(always)] static pure fn one() -> i16 { 1i16 } // 1i16
}
pub impl i32: Number {
/**
* Construct an `i32` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> i32 { n.to_i32() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<i32>() }
#[inline(always)] static pure fn bits() -> uint { 32 }
#[inline(always)] static pure fn zero() -> i32 { 0i32 } /// 0i32
#[inline(always)] static pure fn one() -> i32 { 1i32 } // 1i32
}
pub impl i64: Number {
/**
* Construct an `i64` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> i64 { n.to_i64() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<i64>() }
#[inline(always)] static pure fn bits() -> uint { 64 }
#[inline(always)] static pure fn zero() -> i64 { 0i64 } /// 0i64
#[inline(always)] static pure fn one() -> i64 { 1i64 } // 1i64
}
pub impl int: Number {
/**
* Construct an `int` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> int { n.to_int_() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<int>() }
#[inline(always)] static pure fn bits() -> uint { sys::size_of::<int>() * 8 }
#[inline(always)] static pure fn zero() -> int { 0 } /// 0
#[inline(always)] static pure fn one() -> int { 1 } // 1
}
pub impl f32: Number {
/**
* Construct a `f32` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> f32 { n.to_f32() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<f32>() }
#[inline(always)] static pure fn bits() -> uint { 32 }
#[inline(always)] static pure fn zero() -> f32 { 0f32 } /// 0f32
#[inline(always)] static pure fn one() -> f32 { 1f32 } // 1f32
}
pub impl f64: Number {
/**
* Construct a `f64` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> f64 { n.to_f64() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<f64>() }
#[inline(always)] static pure fn bits() -> uint { 64 }
#[inline(always)] static pure fn zero() -> f64 { 0f64 } /// 0f64
#[inline(always)] static pure fn one() -> f64 { 1f64 } // 1f64
}
pub impl float: Number {
/**
* Construct a `float` from the type `T`
*/
#[inline(always)] static pure fn from<T:NumConv>(n: T) -> float { n.to_float() }
#[inline(always)] static pure fn size_of() -> uint { sys::size_of::<float>() }
#[inline(always)] static pure fn bits() -> uint { sys::size_of::<float>() * 8 }
#[inline(always)] static pure fn zero() -> float { 0f } /// 0f
#[inline(always)] static pure fn one() -> float { 1f } // 1f
}
pub trait UnSigned: Number {}
pub impl u8: UnSigned {}
pub impl u16: UnSigned {}
pub impl u32: UnSigned {}
pub impl u64: UnSigned {}
pub impl uint: UnSigned {}
pub trait Signed: Number {
pure fn is_positive(&self) -> bool;
pure fn is_negative(&self) -> bool;
pure fn is_nonpositive(&self) -> bool;
pure fn is_nonnegative(&self) -> bool;
}
pub impl i8: Signed {
#[inline(always)] pure fn is_positive(&self) -> bool { (*self) > 0 }
#[inline(always)] pure fn is_negative(&self) -> bool { (*self) < 0 }
#[inline(always)] pure fn is_nonpositive(&self) -> bool { (*self) <= 0 }
#[inline(always)] pure fn is_nonnegative(&self) -> bool { (*self) >= 0 }
}
pub impl i16: Signed {
#[inline(always)] pure fn is_positive(&self) -> bool { (*self) > 0 }
#[inline(always)] pure fn is_negative(&self) -> bool { (*self) < 0 }
#[inline(always)] pure fn is_nonpositive(&self) -> bool { (*self) <= 0 }
#[inline(always)] pure fn is_nonnegative(&self) -> bool { (*self) >= 0 }
}
pub impl i32: Signed {
#[inline(always)] pure fn is_positive(&self) -> bool { (*self) > 0 }
#[inline(always)] pure fn is_negative(&self) -> bool { (*self) < 0 }
#[inline(always)] pure fn is_nonpositive(&self) -> bool { (*self) <= 0 }
#[inline(always)] pure fn is_nonnegative(&self) -> bool { (*self) >= 0 }
}
pub impl i64: Signed {
#[inline(always)] pure fn is_positive(&self) -> bool { (*self) > 0 }
#[inline(always)] pure fn is_negative(&self) -> bool { (*self) < 0 }
#[inline(always)] pure fn is_nonpositive(&self) -> bool { (*self) <= 0 }
#[inline(always)] pure fn is_nonnegative(&self) -> bool { (*self) >= 0 }
}
pub impl int: Signed {
#[inline(always)] pure fn is_positive(&self) -> bool { (*self) > 0 }
#[inline(always)] pure fn is_negative(&self) -> bool { (*self) < 0 }
#[inline(always)] pure fn is_nonpositive(&self) -> bool { (*self) <= 0 }
#[inline(always)] pure fn is_nonnegative(&self) -> bool { (*self) >= 0 }
}
pub impl f32: Signed {
#[inline(always)] pure fn is_positive(&self) -> bool { f32::is_positive(*self) }
#[inline(always)] pure fn is_negative(&self) -> bool { f32::is_negative(*self) }
#[inline(always)] pure fn is_nonpositive(&self) -> bool { f32::is_nonpositive(*self) }
#[inline(always)] pure fn is_nonnegative(&self) -> bool { f32::is_nonnegative(*self) }
}
pub impl f64: Signed {
#[inline(always)] pure fn is_positive(&self) -> bool { f64::is_positive(*self) }
#[inline(always)] pure fn is_negative(&self) -> bool { f64::is_negative(*self) }
#[inline(always)] pure fn is_nonpositive(&self) -> bool { f64::is_nonpositive(*self) }
#[inline(always)] pure fn is_nonnegative(&self) -> bool { f64::is_nonnegative(*self) }
}
pub impl float: Signed {
#[inline(always)] pure fn is_positive(&self) -> bool { core::float::is_positive(*self) }
#[inline(always)] pure fn is_negative(&self) -> bool { core::float::is_negative(*self) }
#[inline(always)] pure fn is_nonpositive(&self) -> bool { core::float::is_nonpositive(*self) }
#[inline(always)] pure fn is_nonnegative(&self) -> bool { core::float::is_nonnegative(*self) }
}
pub trait Integer: Number {}
pub impl u8: Integer {}
pub impl u16: Integer {}
pub impl u32: Integer {}
pub impl u64: Integer {}
pub impl uint: Integer {}
pub impl i8: Integer {}
pub impl i16: Integer {}
pub impl i32: Integer {}
pub impl i64: Integer {}
pub impl int: Integer {}
pub trait Float: Number FuzzyEq {
static pure fn from_float<T:Float>(n: T) -> self;
static pure fn NaN() -> self;
static pure fn infinity() -> self;
static pure fn neg_infinity() -> self;
pure fn is_NaN(&self) -> bool;
pure fn is_infinite(&self) -> bool;
pure fn is_finite(&self) -> bool;
static pure fn two_pi() -> self; /// 2 × π
static pure fn pi() -> self; /// π
static pure fn frac_pi_2() -> self; /// π / 2
static pure fn frac_pi_3() -> self; /// π / 3
static pure fn frac_pi_4() -> self; /// π / 4
static pure fn frac_pi_6() -> self; /// π / 6
static pure fn frac_pi_8() -> self; /// π / 8
static pure fn frac_1_pi() -> self; /// 1 / π
static pure fn frac_2_pi() -> self; /// 2 / π
static pure fn frac_2_sqrtpi() -> self; /// 2 / sqrt(π)
static pure fn sqrt2() -> self; /// sqrt(2)
static pure fn frac_1_sqrt2() -> self; /// 1 / sqrt(2)
static pure fn e() -> self; /// Euler's number
static pure fn log2_e() -> self; /// log2(e)
static pure fn log10_e() -> self; /// log10(e)
static pure fn ln_2() -> self; /// ln(2)
static pure fn ln_10() -> self; // ln(10)
}
pub impl f32: Float {
#[inline(always)] static pure fn from_float<T:Float>(n: T) -> f32 { n.to_f32() }
#[inline(always)] static pure fn NaN() -> f32 { 0_f32 / 0_f32 }
#[inline(always)] static pure fn infinity() -> f32 { 1_f32 / 0_f32 }
#[inline(always)] static pure fn neg_infinity() -> f32 {-1_f32 / 0_f32 }
#[inline(always)] pure fn is_NaN(&self) -> bool { self != self }
#[inline(always)] pure fn is_infinite(&self) -> bool { (*self) == Float::infinity() || (*self) == Float::neg_infinity() }
#[inline(always)] pure fn is_finite(&self) -> bool { !(self.is_NaN() || self.is_infinite()) }
#[inline(always)] static pure fn two_pi() -> f32 { 6.28318530717958647692528676655900576__f32 } /// 2 × π
#[inline(always)] static pure fn pi() -> f32 { 3.14159265358979323846264338327950288__f32 } /// π
#[inline(always)] static pure fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144__f32 } /// π / 2
#[inline(always)] static pure fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763__f32 } /// π / 3
#[inline(always)] static pure fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721_f32 } /// π / 4
#[inline(always)] static pure fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381__f32 } /// π / 6
#[inline(always)] static pure fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786__f32 } /// π / 8
#[inline(always)] static pure fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724_f32 } /// 1 / π
#[inline(always)] static pure fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448_f32 } /// 2 / π
#[inline(always)] static pure fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517__f32 } /// 2 / sqrt(π)
#[inline(always)] static pure fn sqrt2() -> f32 { 1.41421356237309504880168872420969808__f32 } /// sqrt(2)
#[inline(always)] static pure fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039_f32 } /// 1 / sqrt(2)
#[inline(always)] static pure fn e() -> f32 { 2.71828182845904523536028747135266250__f32 } /// Euler's number
#[inline(always)] static pure fn log2_e() -> f32 { 1.44269504088896340735992468100189214__f32 } /// log2(e)
#[inline(always)] static pure fn log10_e() -> f32 { 0.434294481903251827651128918916605082_f32 } /// log10(e)
#[inline(always)] static pure fn ln_2() -> f32 { 0.693147180559945309417232121458176568_f32 } /// ln(2)
#[inline(always)] static pure fn ln_10() -> f32 { 2.30258509299404568401799145468436421__f32 } // ln(10)
}
pub impl f64: Float {
#[inline(always)] static pure fn from_float<T:Float>(n: T) -> f64 { n.to_f64() }
#[inline(always)] static pure fn NaN() -> f64 { 0_f64 / 0_f64 }
#[inline(always)] static pure fn infinity() -> f64 { 1_f64 / 0_f64 }
#[inline(always)] static pure fn neg_infinity() -> f64 {-1_f64 / 0_f64 }
#[inline(always)] pure fn is_NaN(&self) -> bool { self != self }
#[inline(always)] pure fn is_infinite(&self) -> bool { (*self) == Float::infinity() || (*self) == Float::neg_infinity() }
#[inline(always)] pure fn is_finite(&self) -> bool { !(self.is_NaN() || self.is_infinite()) }
#[inline(always)] static pure fn two_pi() -> f64 { 6.28318530717958647692528676655900576__f64 } /// 2 × π
#[inline(always)] static pure fn pi() -> f64 { 3.14159265358979323846264338327950288__f64 } /// π
#[inline(always)] static pure fn frac_pi_2() -> f64 { 1.57079632679489661923132169163975144__f64 } /// π / 2
#[inline(always)] static pure fn frac_pi_3() -> f64 { 1.04719755119659774615421446109316763__f64 } /// π / 3
#[inline(always)] static pure fn frac_pi_4() -> f64 { 0.785398163397448309615660845819875721_f64 } /// π / 4
#[inline(always)] static pure fn frac_pi_6() -> f64 { 0.52359877559829887307710723054658381__f64 } /// π / 6
#[inline(always)] static pure fn frac_pi_8() -> f64 { 0.39269908169872415480783042290993786__f64 } /// π / 8
#[inline(always)] static pure fn frac_1_pi() -> f64 { 0.318309886183790671537767526745028724_f64 } /// 1 / π
#[inline(always)] static pure fn frac_2_pi() -> f64 { 0.636619772367581343075535053490057448_f64 } /// 2 / π
#[inline(always)] static pure fn frac_2_sqrtpi() -> f64 { 1.12837916709551257389615890312154517__f64 } /// 2 / sqrt(π)
#[inline(always)] static pure fn sqrt2() -> f64 { 1.41421356237309504880168872420969808__f64 } /// sqrt(2)
#[inline(always)] static pure fn frac_1_sqrt2() -> f64 { 0.707106781186547524400844362104849039_f64 } /// 1 / sqrt(2)
#[inline(always)] static pure fn e() -> f64 { 2.71828182845904523536028747135266250__f64 } /// Euler's number
#[inline(always)] static pure fn log2_e() -> f64 { 1.44269504088896340735992468100189214__f64 } /// log2(e)
#[inline(always)] static pure fn log10_e() -> f64 { 0.434294481903251827651128918916605082_f64 } /// log10(e)
#[inline(always)] static pure fn ln_2() -> f64 { 0.693147180559945309417232121458176568_f64 } /// ln(2)
#[inline(always)] static pure fn ln_10() -> f64 { 2.30258509299404568401799145468436421__f64 } // ln(10)
}
pub impl float: Float {
#[inline(always)] static pure fn from_float<T:Float>(n: T) -> float { n.to_float() }
#[inline(always)] static pure fn NaN() -> float { 0_f / 0_f }
#[inline(always)] static pure fn infinity() -> float { 1_f / 0_f }
#[inline(always)] static pure fn neg_infinity() -> float {-1_f / 0_f }
#[inline(always)] pure fn is_NaN(&self) -> bool { self != self }
#[inline(always)] pure fn is_infinite(&self) -> bool { (*self) == Float::infinity() || (*self) == Float::neg_infinity() }
#[inline(always)] pure fn is_finite(&self) -> bool { !(self.is_NaN() || self.is_infinite()) }
#[inline(always)] static pure fn two_pi() -> float { 6.28318530717958647692528676655900576__f } /// 2 × π
#[inline(always)] static pure fn pi() -> float { 3.14159265358979323846264338327950288__f } /// π
#[inline(always)] static pure fn frac_pi_2() -> float { 1.57079632679489661923132169163975144__f } /// π / 2
#[inline(always)] static pure fn frac_pi_3() -> float { 1.04719755119659774615421446109316763__f } /// π / 3
#[inline(always)] static pure fn frac_pi_4() -> float { 0.785398163397448309615660845819875721_f } /// π / 4
#[inline(always)] static pure fn frac_pi_6() -> float { 0.52359877559829887307710723054658381__f } /// π / 6
#[inline(always)] static pure fn frac_pi_8() -> float { 0.39269908169872415480783042290993786__f } /// π / 8
#[inline(always)] static pure fn frac_1_pi() -> float { 0.318309886183790671537767526745028724_f } /// 1 / π
#[inline(always)] static pure fn frac_2_pi() -> float { 0.636619772367581343075535053490057448_f } /// 2 / π
#[inline(always)] static pure fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517__f } /// 2 / sqrt(π)
#[inline(always)] static pure fn sqrt2() -> float { 1.41421356237309504880168872420969808__f } /// sqrt(2)
#[inline(always)] static pure fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039_f } /// 1 / sqrt(2)
#[inline(always)] static pure fn e() -> float { 2.71828182845904523536028747135266250__f } /// Euler's number
#[inline(always)] static pure fn log2_e() -> float { 1.44269504088896340735992468100189214__f } /// log2(e)
#[inline(always)] static pure fn log10_e() -> float { 0.434294481903251827651128918916605082_f } /// log10(e)
#[inline(always)] static pure fn ln_2() -> float { 0.693147180559945309417232121458176568_f } /// ln(2)
#[inline(always)] static pure fn ln_10() -> float { 2.30258509299404568401799145468436421__f } // ln(10)
}

View file

@ -14,13 +14,12 @@ use core::sys::size_of;
use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use numeric::traits::*;
use numeric::types::angle::Angle;
use numeric::types::float::Float;
use numeric::types::number::Number;
use angle::Angle;
use funs::common::*;
use funs::exponential::*;
use funs::triganomic::*;
use mat::{Mat3, Mat4};
use num::types::{Float, Number};
use vec::Vec3;
@ -274,7 +273,7 @@ pub impl<T:Copy> Quat<T>: Index<uint, T> {
}
}
pub impl<T:Copy Float Exp Extent InvTrig> Quat<T>: Quaternion<T, Vec3<T>> {
pub impl<T:Copy Float> Quat<T>: Quaternion<T, Vec3<T>> {
#[inline(always)]
static pure fn identity() -> Quat<T> {
Quat::new(Number::from(1),

View file

@ -1,119 +0,0 @@
use core::float::consts::pi;
use angle::*;
use mat::Mat4;
use vec::{Vec3, Vec4};
#[test]
fn test_radians() {
assert Radians(0.0).to_degrees() == Degrees(0.0);
assert Radians(pi / 4.0).to_degrees() == Degrees(45.0);
assert Radians(pi / 2.0).to_degrees() == Degrees(90.0);
assert Radians(pi).to_degrees() == Degrees(180.0);
assert Radians(2.0 * pi).to_degrees() == Degrees(360.0);
assert Radians(5.0 * pi).to_degrees() == Degrees(900.0);
assert Radians(-pi).to_degrees() == Degrees(-180.0);
assert Radians(0.0).to_radians() == Radians(0.0);
assert Radians(5.0 * pi).to_radians() == Radians(5.0 * pi);
assert Radians(-pi).to_radians() == Radians(-pi);
assert Radians(pi).wrap() == Radians(pi);
assert Radians(3.0 * pi).wrap() == Radians(pi);
assert Radians(2.0 * pi).wrap() == Radians(0.0);
assert Radians(-pi).wrap() == Radians(pi);
assert Radians(-3.0 * pi).wrap() == Radians(pi);
assert Radians(-2.0 * pi).wrap() == Radians(0.0);
assert Radians(0.0).opposite() == Radians(pi as float);
assert Radians(pi / 2.0).opposite() == Radians((pi / 2.0) * 3.0);
assert Radians(pi * 3.0).opposite() == Radians(0.0);
assert Radians(-2.0 * pi).opposite() == Radians(pi);
assert Radians(pi) + Radians(pi) == Radians(2.0 * pi);
assert Radians(2.0 * pi) - Radians(pi) == Radians(pi);
assert Radians(pi) * 2.0 == Radians(2.0 * pi);
assert Radians(pi) / 2.0 == Radians(pi / 2.0);
assert Radians(3.0 * pi) % (2.0 * pi) == Radians(pi);
assert -Radians(pi) == Radians(-pi);
assert fmt!("%s", Radians(1).to_str()) == ~"1 rad";
}
#[test]
fn test_degrees() {
assert Degrees(0.0).to_radians() == Radians(0.0);
assert Degrees(45.0).to_radians() == Radians(pi / 4.0 as float); // Rust can't infer these types
assert Degrees(90.0).to_radians() == Radians(pi / 2.0 as float);
assert Degrees(180.0).to_radians() == Radians(pi as float);
assert Degrees(360.0).to_radians() == Radians(2.0 * pi as float);
assert Degrees(900.0).to_radians() == Radians(5.0 * pi as float);
assert Degrees(-180.0).to_radians() == Radians(-pi as float);
assert Degrees(0.0).to_degrees() == Degrees(0.0);
assert Degrees(900.0).to_degrees() == Degrees(900.0);
assert Degrees(-180.0).to_degrees() == Degrees(-180.0);
assert Degrees(90.0).wrap() == Degrees(90.0);
assert Degrees(450.0).wrap() == Degrees(90.0);
assert Degrees(360.0).wrap() == Degrees(0.0);
assert Degrees(-90.0).wrap() == Degrees(270.0);
assert Degrees(-450.0).wrap() == Degrees(270.0);
assert Degrees(-360.0).wrap() == Degrees(0.0);
assert Degrees(0.0).opposite() == Degrees(180.0);
assert Degrees(90.0).opposite() == Degrees(270.0);
assert Degrees(540.0).opposite() == Degrees(0.0);
assert Degrees(-360.0).opposite() == Degrees(180.0);
assert Degrees(180.0) + Degrees(180.0) == Degrees(360.0);
assert Degrees(360.0) - Degrees(180.0) == Degrees(180.0);
assert Degrees(360.0) * 2.0 == Degrees(720.0);
assert Degrees(180.0) / 2.0 == Degrees(90.0);
assert Degrees(540.0) % (360.0) == Degrees(180.0);
assert -Degrees(180.0) == Degrees(-180.0);
assert fmt!("%s", Degrees(180.0).to_str()) == ~"180°";
}
#[test]
fn test_rotation() {
// {
// let pos = Vec4::new(1.0, 0.0, 0.0, 1.0); // the position to transform
// let rot = Rotation {
// theta: Degrees(180.0).to_radians(),
// axis: Vec3::new(0.0, 0.0, 1.0), // unit_z
// };
// let newpos = rot.to_mat4().mul_v(&pos);
// let expected_pos = Vec4::new(-1.0, 0.0, 0.0, 1.0);
// assert newpos.fuzzy_eq(&expected_pos);
// }
// {
// let pos = Vec4::new(4f32, 0f32, 0f32, 1f32);
// let rot_a = Rotation {
// theta: Degrees(90f32).to_radians(),
// axis: Vec3::new(0f32, 1f32, 0f32), // unit_y
// };
// let rot_b = Rotation {
// theta: Degrees(90f32).to_radians(),
// axis: -Vec3::new(0f32, 1f32, 0f32), // -unit_y
// };
// let newpos_a = rot_a.to_mat4().mul_v(&pos);
// let newpos_b = rot_b.to_mat4().mul_v(&pos);
// let expected_pos_a = Vec4::new(0f32, 0f32, -4f32, 1f32);
// let expected_pos_b = Vec4::new(0f32, 0f32, 4f32, 1f32);
// assert newpos_a.fuzzy_eq(&expected_pos_a);
// assert newpos_b.fuzzy_eq(&expected_pos_b);
// }
// TODO: test to_quat
}

View file

@ -179,26 +179,6 @@ fn test_mat() {
assert dmat4::size_of() == dmat4::rows() * dmat4::cols() * 8;
}
#[test]
fn test_radians() {
// TODO: unit tests
}
#[test]
fn test_degrees() {
// TODO: unit tests
}
#[test]
fn test_rotation() {
// TODO: unit tests
}
#[test]
fn test_euler() {
// TODO: unit tests
}
#[test]
fn test_quat() {
// TODO: unit tests

View file

@ -1,4 +1,6 @@
use funs::exponential::sqrt;
use numeric::traits::sqrt;
use numeric::types::angle::*;
use mat::*;
use quat::*;
use vec::*;

View file

@ -1,5 +1,7 @@
use std::cmp::FuzzyEq;
use angle::*;
use numeric::types::float::*;
use numeric::types::angle::*;
use vec::*;
// TODO

View file

@ -2,9 +2,8 @@ use core::cmp::Eq;
use std::cmp::FuzzyEq;
use angle::Radians;
use num::types::Number;
use numeric::types::angle::Radians;
use numeric::types::number::Number;
pub mod vec2;
pub mod vec3;

View file

@ -4,11 +4,10 @@ use core::ptr::to_unsafe_ptr;
use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use angle::Radians;
use funs::exponential::Exp;
use funs::triganomic::{InvTrig, atan2};
use num::types::Number;
use numeric::traits::*;
use numeric::types::angle::Radians;
use numeric::types::float::Float;
use numeric::types::number::Number;
/**
* A 2-dimensional vector
@ -162,7 +161,7 @@ pub impl<T:Copy Number> Vec2<T>: NumericVector2<T> {
}
}
pub impl<T:Copy Number Exp InvTrig> Vec2<T>: EuclideanVector<T> {
pub impl<T:Copy Float> Vec2<T>: EuclideanVector<T> {
#[inline(always)]
pure fn length2(&self) -> T {
self.dot(self)
@ -207,7 +206,7 @@ pub impl<T:Copy Number Exp InvTrig> Vec2<T>: EuclideanVector<T> {
}
}
pub impl<T:Copy Number Exp InvTrig> Vec2<T>: MutableEuclideanVector<&self/T> {
pub impl<T:Copy Float> Vec2<T>: MutableEuclideanVector<&self/T> {
#[inline(always)]
fn normalize_self(&mut self) {
let mut n: T = Number::from(1);

View file

@ -4,11 +4,10 @@ use core::ptr::to_unsafe_ptr;
use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use angle::Radians;
use funs::exponential::Exp;
use funs::triganomic::{InvTrig, atan2};
use num::types::Number;
use numeric::traits::*;
use numeric::types::angle::Radians;
use numeric::types::float::Float;
use numeric::types::number::Number;
/**
* A 3-dimensional vector
@ -185,7 +184,7 @@ pub impl<T:Copy Number> Vec3<T>: MutableNumericVector3<&self/T> {
}
}
pub impl<T:Copy Number Exp InvTrig> Vec3<T>: EuclideanVector<T> {
pub impl<T:Copy Float> Vec3<T>: EuclideanVector<T> {
#[inline(always)]
pure fn length2(&self) -> T {
self.dot(self)
@ -230,7 +229,7 @@ pub impl<T:Copy Number Exp InvTrig> Vec3<T>: EuclideanVector<T> {
}
}
pub impl<T:Copy Number Exp InvTrig> Vec3<T>: MutableEuclideanVector<&self/T> {
pub impl<T:Copy Float> Vec3<T>: MutableEuclideanVector<&self/T> {
#[inline(always)]
fn normalize_self(&mut self) {
let mut n: T = Number::from(1);

View file

@ -4,11 +4,10 @@ use core::ptr::to_unsafe_ptr;
use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use angle::Radians;
use funs::exponential::Exp;
use funs::triganomic::{InvTrig, acos};
use num::types::Number;
use numeric::traits::*;
use numeric::types::angle::Radians;
use numeric::types::float::Float;
use numeric::types::number::Number;
/**
* A 4-dimensional vector
@ -183,7 +182,7 @@ pub impl<T:Copy Number> Vec4<T>: MutableNumericVector<&self/T> {
}
}
pub impl<T:Copy Number Exp InvTrig> Vec4<T>: EuclideanVector<T> {
pub impl<T:Copy Float> Vec4<T>: EuclideanVector<T> {
#[inline(always)]
pure fn length2(&self) -> T {
self.dot(self)
@ -228,7 +227,7 @@ pub impl<T:Copy Number Exp InvTrig> Vec4<T>: EuclideanVector<T> {
}
}
pub impl<T:Copy Number Exp InvTrig> Vec4<T>: MutableEuclideanVector<&self/T> {
pub impl<T:Copy Float> Vec4<T>: MutableEuclideanVector<&self/T> {
#[inline(always)]
fn normalize_self(&mut self) {
let mut n: T = Number::from(1);