Use num::ext traits to simplify trait bounds

This commit is contained in:
Brendan Zabarauskas 2012-12-03 11:10:14 +10:00
parent 3d293dce5a
commit 7b3ae88c57
9 changed files with 233 additions and 94 deletions

View file

@ -2,16 +2,6 @@
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.
## Current issues
Some of the trait bounds are currently very brittle and verbose. For example you may see implementations like the following:
pub impl<T:Copy Num NumCast Trig Exp Extent Ord FuzzyEq> Quat<T>: Quaternion<T> { ... }
Ick! Luckily this will be largely eliminated with trait inheritance which will be coming to Rust in the future. That will mean that the above Quaternion implementation would become something like:
pub impl<T:FloatExt> Quat<T>: Quaternion<T> { ... }
## Todo:
- ~~Matrix inversion~~
@ -29,7 +19,7 @@ Ick! Luckily this will be largely eliminated with trait inheritance which will b
Dependant on rust/master:
- Implement trait inheritance
- ~~Implement trait inheritance~~
- Make use of static functions for constants and constructors

View file

@ -40,7 +40,7 @@ pub trait Angle<T>: Add<self,self>
pub enum Radians<T> = T;
// FIXME: not sure why I need the Eq and Ord trait bounds, but Rust complains if I don't include them
pub impl<T:Copy Float Num NumCast Eq Ord> Radians<T>: Angle<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::pi_2()) }
@ -69,54 +69,54 @@ pub impl<T:Copy Float Num NumCast Eq Ord> Radians<T>: Angle<T> {
}
}
pub impl<T:Copy Num> Radians<T>: Add<Radians<T>, Radians<T>> {
pub impl<T:Copy Float> Radians<T>: Add<Radians<T>, Radians<T>> {
#[inline(always)]
pure fn add(rhs: &Radians<T>) -> Radians<T> {
Radians(*self + **rhs)
}
}
pub impl<T:Copy Num> Radians<T>: Sub<Radians<T>, Radians<T>> {
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 Num> Radians<T>: Mul<T, Radians<T>> {
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 Num> Radians<T>: Div<T, Radians<T>> {
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 Num> Radians<T>: Modulo<T, Radians<T>> {
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 Num> Radians<T>: Neg<Radians<T>> {
pub impl<T:Copy Float> Radians<T>: Neg<Radians<T>> {
#[inline(always)]
pure fn neg(&self) -> Radians<T> {
Radians(-**self)
}
}
pub impl<T:Copy Eq> Radians<T>: Eq {
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 Ord> Radians<T>: Ord {
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 }
@ -134,7 +134,7 @@ pub impl<T> Radians<T>: ToStr {
pub enum Degrees<T> = T;
// FIXME: not sure why I need the Eq and Ord trait bounds, but Rust complains if I don't include them
pub impl<T:Copy Num NumCast Eq Ord> Degrees<T>: Angle<T> {
pub impl<T:Copy Float> Degrees<T>: Angle<T> {
#[inline(always)] static pure fn full_turn() -> Degrees<T> { Degrees(cast(360.0)) }
#[inline(always)] static pure fn half_turn() -> Degrees<T> { Degrees(cast(180.0)) }
#[inline(always)] static pure fn quadrant() -> Degrees<T> { Degrees(cast(90.0)) }
@ -163,54 +163,54 @@ pub impl<T:Copy Num NumCast Eq Ord> Degrees<T>: Angle<T> {
}
}
pub impl<T:Copy Num> Degrees<T>: Add<Degrees<T>, Degrees<T>> {
pub impl<T:Copy Float> Degrees<T>: Add<Degrees<T>, Degrees<T>> {
#[inline(always)]
pure fn add(rhs: &Degrees<T>) -> Degrees<T> {
Degrees(*self + **rhs)
}
}
pub impl<T:Copy Num> Degrees<T>: Sub<Degrees<T>, Degrees<T>> {
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 Num> Degrees<T>: Mul<T, Degrees<T>> {
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 Num> Degrees<T>: Div<T, Degrees<T>> {
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 Num> Degrees<T>: Modulo<T, Degrees<T>> {
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 Num> Degrees<T>: Neg<Degrees<T>> {
pub impl<T:Copy Float> Degrees<T>: Neg<Degrees<T>> {
#[inline(always)]
pure fn neg(&self) -> Degrees<T> {
Degrees(-**self)
}
}
pub impl<T:Copy Eq> Degrees<T>: Eq {
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 Ord> Degrees<T>: Ord {
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 }
@ -233,7 +233,7 @@ pub struct Rotation<T> {
axis: Vec3<T>,
}
pub impl<T:Copy Num NumCast> Rotation<T> {
pub impl<T:Copy Float> Rotation<T> {
#[inline(always)]
static pure fn new(theta: Radians<T>, axis: Vec3<T>) -> Rotation<T> {
Rotation { theta: move theta, axis: move axis }

View file

@ -9,6 +9,7 @@ use channel::Channel;
use dim::{Dimensional, ToPtr};
use funs::common::Sign;
use num::cast::{cast, NumCast};
use num::ext::Float;
pub trait Color<T>: Dimensional<T>, ToPtr<T>, Eq {
@ -412,7 +413,7 @@ pub impl<T:Copy> HSV<T>: ToPtr<T> {
}
}
pub impl<T:Copy Num NumCast Channel Eq Ord> HSV<T>: Color<T> {
pub impl<T:Copy Float Channel> HSV<T>: Color<T> {
#[inline(always)]
pure fn inverse(&self) -> HSV<T> {
HSV::new(self.h.opposite(),
@ -442,7 +443,7 @@ pub impl<T:Copy Num NumCast Channel Eq Ord> HSV<T>: Color<T> {
}
}
pub impl<T:Copy Num NumCast Channel Eq Ord> HSV<T>: Color3<T> {
pub impl<T:Copy Float Channel> HSV<T>: Color3<T> {
#[inline(always)] pure fn to_rgba_u8(&self, a: u8) -> RGBA<u8> { RGBA::from_rgb_a(&self.to_rgb_u8(), a) }
#[inline(always)] pure fn to_rgba_u16(&self, a: u16) -> RGBA<u16> { RGBA::from_rgb_a(&self.to_rgb_u16(), a) }
#[inline(always)] pure fn to_rgba_u32(&self, a: u32) -> RGBA<u32> { RGBA::from_rgb_a(&self.to_rgb_u32(), a) }
@ -454,7 +455,7 @@ pub impl<T:Copy Num NumCast Channel Eq Ord> HSV<T>: Color3<T> {
#[inline(always)] pure fn to_hsva_f64(&self, a: f64) -> HSVA<f64> { HSVA::from_hsv_a(&self.to_hsv_f64(), a) }
}
pub impl<T:Copy Eq> HSV<T>: Eq {
pub impl<T:Copy Float> HSV<T>: Eq {
pure fn eq(&self, other: &HSV<T>) -> bool {
self.h == other.h &&
self.s == other.s &&
@ -511,7 +512,7 @@ pub impl<T:Copy> HSVA<T>: ToPtr<T> {
}
}
pub impl<T:Copy Num NumCast Channel Eq Ord> HSVA<T>: Color<T> {
pub impl<T:Copy Float Channel> HSVA<T>: Color<T> {
#[inline(always)]
pure fn inverse(&self) -> HSVA<T> {
HSVA::new(self.h.opposite(),
@ -542,7 +543,7 @@ pub impl<T:Copy Num NumCast Channel Eq Ord> HSVA<T>: Color<T> {
}
}
pub impl<T:Copy Num NumCast Channel Eq Ord> HSVA<T>: Color4<T> {
pub impl<T:Copy Float Channel> HSVA<T>: Color4<T> {
#[inline(always)] pure fn to_rgba_u8(&self) -> RGBA<u8> { RGBA::from_rgb_a(&self.to_rgb_u8(), self.a.to_channel_u8()) }
#[inline(always)] pure fn to_rgba_u16(&self) -> RGBA<u16> { RGBA::from_rgb_a(&self.to_rgb_u16(), self.a.to_channel_u16()) }
#[inline(always)] pure fn to_rgba_u32(&self) -> RGBA<u32> { RGBA::from_rgb_a(&self.to_rgb_u32(), self.a.to_channel_u32()) }
@ -554,7 +555,7 @@ pub impl<T:Copy Num NumCast Channel Eq Ord> HSVA<T>: Color4<T> {
#[inline(always)] pure fn to_hsva_f64(&self) -> HSVA<f64> { HSVA::from_hsv_a(&self.to_hsv_f64(), self.a.to_channel_f64()) }
}
pub impl<T:Copy Eq> HSVA<T>: Eq {
pub impl<T:Copy Float> HSVA<T>: Eq {
pure fn eq(&self, other: &HSVA<T>) -> bool {
self.h == other.h &&
self.s == other.s &&

View file

@ -2,6 +2,7 @@ use funs::triganomic::tan;
use angle::Angle;
use mat::Mat4;
use num::cast::{NumCast, cast};
use num::ext::Float;
/**
* Create a perspective projection matrix
@ -10,7 +11,7 @@ use num::cast::{NumCast, cast};
* can be found [here](http://www.opengl.org/wiki/GluPerspective_code).
*/
#[inline(always)]
pub pure fn perspective<T:Copy Num NumCast, A:Angle<T>>(fovy: A, aspectRatio: T, near: T, far: T) -> Mat4<T> {
pub pure fn perspective<T:Copy Float, A:Angle<T>>(fovy: A, aspectRatio: T, near: T, far: T) -> Mat4<T> {
let ymax = near * tan(&fovy.to_radians());
let xmax = ymax * aspectRatio;
@ -24,7 +25,7 @@ pub pure fn perspective<T:Copy Num NumCast, A:Angle<T>>(fovy: A, aspectRatio: T,
* (http://www.opengl.org/sdk/docs/man2/xhtml/glFrustum.xml) function.
*/
#[inline(always)]
pub pure fn frustum<T:Copy Num NumCast>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
pub pure fn frustum<T:Copy Float>(left: T, right: T, bottom: T, top: T, near: T, far: T) -> Mat4<T> {
let _0: T = cast(0);
let _2: T = cast(2);

View file

@ -122,15 +122,15 @@ fn test_min() {
assert min(&2f32, &1f32) == 1f32;
assert min(&2f64, &1f64) == 1f64;
assert Radians(1).min(&Radians(2)) == Radians(1);
assert Radians(2).min(&Radians(1)) == Radians(1);
assert min(&Radians(1), &Radians(2)) == Radians(1);
assert min(&Radians(2), &Radians(1)) == Radians(1);
assert Radians(1.0).min(&Radians(2.0)) == Radians(1.0);
assert Radians(2.0).min(&Radians(1.0)) == Radians(1.0);
assert min(&Radians(1.0), &Radians(2.0)) == Radians(1.0);
assert min(&Radians(2.0), &Radians(1.0)) == Radians(1.0);
assert Degrees(1).min(&Degrees(2)) == Degrees(1);
assert Degrees(2).min(&Degrees(1)) == Degrees(1);
assert min(&Degrees(1), &Degrees(2)) == Degrees(1);
assert min(&Degrees(2), &Degrees(1)) == Degrees(1);
assert Degrees(1.0).min(&Degrees(2.0)) == Degrees(1.0);
assert Degrees(2.0).min(&Degrees(1.0)) == Degrees(1.0);
assert min(&Degrees(1.0), &Degrees(2.0)) == Degrees(1.0);
assert min(&Degrees(2.0), &Degrees(1.0)) == Degrees(1.0);
assert min(&Vec2::new(1, 2), &Vec2::new(2, 1)) == Vec2::new(1, 1);
assert min(&Vec3::new(1, 2, 3), &Vec3::new(3, 2, 1)) == Vec3::new(1, 2, 1);
@ -201,15 +201,15 @@ fn test_max() {
assert max(&2f32, &1f32) == 2f32;
assert max(&2f64, &1f64) == 2f64;
assert Radians(1).max(&Radians(2)) == Radians(2);
assert Radians(2).max(&Radians(1)) == Radians(2);
assert max(&Radians(1), &Radians(2)) == Radians(2);
assert max(&Radians(2), &Radians(1)) == Radians(2);
assert Radians(1.0).max(&Radians(2.0)) == Radians(2.0);
assert Radians(2.0).max(&Radians(1.0)) == Radians(2.0);
assert max(&Radians(1.0), &Radians(2.0)) == Radians(2.0);
assert max(&Radians(2.0), &Radians(1.0)) == Radians(2.0);
assert Degrees(1).max(&Degrees(2)) == Degrees(2);
assert Degrees(2).max(&Degrees(1)) == Degrees(2);
assert max(&Degrees(1), &Degrees(2)) == Degrees(2);
assert max(&Degrees(2), &Degrees(1)) == Degrees(2);
assert Degrees(1.0).max(&Degrees(2.0)) == Degrees(2.0);
assert Degrees(2.0).max(&Degrees(1.0)) == Degrees(2.0);
assert max(&Degrees(1.0), &Degrees(2.0)) == Degrees(2.0);
assert max(&Degrees(2.0), &Degrees(1.0)) == Degrees(2.0);
assert max(&Vec2::new(1, 2), &Vec2::new(2, 1)) == Vec2::new(2, 2);
assert max(&Vec3::new(1, 2, 3), &Vec3::new(3, 2, 1)) == Vec3::new(3, 2, 3);

View file

@ -11,6 +11,7 @@ use funs::common::*;
use funs::exponential::*;
use num::cast::*;
use num::default_eq::DefaultEq;
use num::ext::Float;
use quat::{Quat, ToQuat};
use vec::{NumericVector, Vec2, Vec3, Vec4};
@ -70,7 +71,7 @@ pub trait Matrix4<T,V>: Matrix<T,V> {
*/
pub struct Mat2<T> { x: Vec2<T>, y: Vec2<T> }
pub impl<T:Copy NumCast> Mat2<T> {
pub impl<T:Copy Float> Mat2<T> {
#[inline(always)]
static pure fn new(c0r0: T, c0r1: T,
c1r0: T, c1r1: T) -> Mat2<T> {
@ -109,7 +110,7 @@ pub impl<T:Copy NumCast> Mat2<T> {
}
}
pub impl<T:Copy Num NumCast DefaultEq> Mat2<T>: Matrix<T, Vec2<T>> {
pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
#[inline(always)]
pure fn col(&self, i: uint) -> Vec2<T> { self[i] }
@ -226,7 +227,7 @@ pub impl<T:Copy Num NumCast DefaultEq> Mat2<T>: Matrix<T, Vec2<T>> {
}
}
pub impl<T:Copy NumCast> Mat2<T>: Matrix2<T, Vec2<T>> {
pub impl<T:Copy Float> Mat2<T>: Matrix2<T, Vec2<T>> {
#[inline(always)]
pure fn to_mat3(&self) -> Mat3<T> {
Mat3::from_Mat2(self)
@ -263,14 +264,14 @@ pub impl<T:Copy> Mat2<T>: ToPtr<T> {
}
}
pub impl<T:Copy Num NumCast> Mat2<T>: Neg<Mat2<T>> {
pub impl<T:Copy Float> Mat2<T>: Neg<Mat2<T>> {
#[inline(always)]
pure fn neg(&self) -> Mat2<T> {
Mat2::from_cols(-self[0], -self[1])
}
}
pub impl<T:Copy DefaultEq> Mat2<T>: Eq {
pub impl<T:Copy Float> Mat2<T>: Eq {
#[inline(always)]
pure fn eq(&self, other: &Mat2<T>) -> bool {
self[0] == other[0] &&
@ -283,7 +284,7 @@ pub impl<T:Copy DefaultEq> Mat2<T>: Eq {
}
}
pub impl<T:Copy FuzzyEq> Mat2<T>: FuzzyEq {
pub impl<T:Copy Float> Mat2<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &Mat2<T>) -> bool {
self[0].fuzzy_eq(&other[0]) &&
@ -291,7 +292,7 @@ pub impl<T:Copy FuzzyEq> Mat2<T>: FuzzyEq {
}
}
pub impl<T:Copy DefaultEq> Mat2<T>: DefaultEq {
pub impl<T:Copy Float> Mat2<T>: DefaultEq {
#[inline(always)]
pure fn default_eq(&self, other: &Mat2<T>) -> bool {
self[0].default_eq(&other[0]) &&
@ -309,7 +310,7 @@ pub impl<T:Copy DefaultEq> Mat2<T>: DefaultEq {
*/
pub struct Mat3<T> { x: Vec3<T>, y: Vec3<T>, z: Vec3<T> }
pub impl<T:Copy NumCast> Mat3<T> {
pub impl<T:Copy Float> Mat3<T> {
#[inline(always)]
static pure fn new(c0r0:T, c0r1:T, c0r2:T,
c1r0:T, c1r1:T, c1r2:T,
@ -363,7 +364,7 @@ pub impl<T:Copy NumCast> Mat3<T> {
}
}
pub impl<T:Copy Num NumCast DefaultEq> Mat3<T>: Matrix<T, Vec3<T>> {
pub impl<T:Copy Float> Mat3<T>: Matrix<T, Vec3<T>> {
#[inline(always)]
pure fn col(&self, i: uint) -> Vec3<T> { self[i] }
@ -503,14 +504,14 @@ pub impl<T:Copy Num NumCast DefaultEq> Mat3<T>: Matrix<T, Vec3<T>> {
}
}
pub impl<T:Copy NumCast> Mat3<T>: Matrix3<T, Vec3<T>> {
pub impl<T:Copy Float> Mat3<T>: Matrix3<T, Vec3<T>> {
#[inline(always)]
pure fn to_mat4(&self) -> Mat4<T> {
Mat4::from_Mat3(self)
}
}
pub impl<T:Copy Num NumCast Ord DefaultEq> Mat3<T>: ToQuat<T> {
pub impl<T:Copy Float> Mat3<T>: ToQuat<T> {
pure fn to_Quat() -> Quat<T> {
// Implemented using a mix of ideas from jMonkeyEngine and Ken Shoemake's
// paper on Quaternions: http://www.cs.ucr.edu/~vbz/resources/Quatut.pdf
@ -578,14 +579,14 @@ pub impl<T:Copy> Mat3<T>: ToPtr<T> {
}
}
pub impl<T:Copy Num NumCast> Mat3<T>: Neg<Mat3<T>> {
pub impl<T:Copy Float> Mat3<T>: Neg<Mat3<T>> {
#[inline(always)]
pure fn neg(&self) -> Mat3<T> {
Mat3::from_cols(-self[0], -self[1], -self[2])
}
}
pub impl<T:Copy DefaultEq> Mat3<T>: Eq {
pub impl<T:Copy Float> Mat3<T>: Eq {
#[inline(always)]
pure fn eq(&self, other: &Mat3<T>) -> bool {
self[0] == other[0] &&
@ -599,7 +600,7 @@ pub impl<T:Copy DefaultEq> Mat3<T>: Eq {
}
}
pub impl<T:Copy FuzzyEq> Mat3<T>: FuzzyEq {
pub impl<T:Copy Float> Mat3<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &Mat3<T>) -> bool {
self[0].fuzzy_eq(&other[0]) &&
@ -608,7 +609,7 @@ pub impl<T:Copy FuzzyEq> Mat3<T>: FuzzyEq {
}
}
pub impl<T:Copy DefaultEq> Mat3<T>: DefaultEq {
pub impl<T:Copy Float> Mat3<T>: DefaultEq {
#[inline(always)]
pure fn default_eq(&self, other: &Mat3<T>) -> bool {
self[0].default_eq(&other[0]) &&
@ -627,7 +628,7 @@ pub impl<T:Copy DefaultEq> Mat3<T>: DefaultEq {
*/
pub struct Mat4<T> { x: Vec4<T>, y: Vec4<T>, z: Vec4<T>, w: Vec4<T> }
pub impl<T:Copy NumCast> Mat4<T> {
pub impl<T:Copy Float> Mat4<T> {
#[inline(always)]
static pure fn new(c0r0: T, c0r1: T, c0r2: T, c0r3: T,
c1r0: T, c1r1: T, c1r2: T, c1r3: T,
@ -698,7 +699,7 @@ pub impl<T:Copy NumCast> Mat4<T> {
}
}
pub impl<T:Copy Num NumCast DefaultEq Sign Ord> Mat4<T>: Matrix<T, Vec4<T>> {
pub impl<T:Copy Float Sign> Mat4<T>: Matrix<T, Vec4<T>> {
#[inline(always)]
pure fn col(&self, i: uint) -> Vec4<T> { self[i] }
@ -921,7 +922,7 @@ pub impl<T:Copy Num NumCast DefaultEq Sign Ord> Mat4<T>: Matrix<T, Vec4<T>> {
pub impl<T> Mat4<T>: Matrix4<T, Vec4<T>> {
}
pub impl<T:Copy Num NumCast> Mat4<T>: Neg<Mat4<T>> {
pub impl<T:Copy Float> Mat4<T>: Neg<Mat4<T>> {
#[inline(always)]
pure fn neg(&self) -> Mat4<T> {
Mat4::from_cols(-self[0], -self[1], -self[2], -self[3])
@ -953,7 +954,7 @@ pub impl<T:Copy> Mat4<T>: ToPtr<T> {
}
}
pub impl<T:Copy DefaultEq> Mat4<T>: Eq {
pub impl<T:Copy Float> Mat4<T>: Eq {
#[inline(always)]
pure fn eq(&self, other: &Mat4<T>) -> bool {
self[0] == other[0] &&
@ -968,7 +969,7 @@ pub impl<T:Copy DefaultEq> Mat4<T>: Eq {
}
}
pub impl<T:Copy FuzzyEq> Mat4<T>: FuzzyEq {
pub impl<T:Copy Float> Mat4<T>: FuzzyEq {
#[inline(always)]
pure fn fuzzy_eq(other: &Mat4<T>) -> bool {
self[0].fuzzy_eq(&other[0]) &&
@ -978,7 +979,7 @@ pub impl<T:Copy FuzzyEq> Mat4<T>: FuzzyEq {
}
}
pub impl<T:Copy DefaultEq> Mat4<T>: DefaultEq {
pub impl<T:Copy Float> Mat4<T>: DefaultEq {
#[inline(always)]
pure fn default_eq(&self, other: &Mat4<T>) -> bool {
self[0].default_eq(&other[0]) &&

View file

@ -1,16 +1,82 @@
use core::cmp::{Eq, Ord};
use std::cmp::FuzzyEq;
use num::cast::*;
use num::default_eq::*;
use num::cast::NumCast;
use num::default_eq::DefaultEq;
pub trait Number: Copy, Eq, Num, NumCast, Ord {
pub trait Number: DefaultEq, Eq, Num, NumCast, Ord {
static pure fn zero() -> self;
static pure fn one() -> self;
}
pub impl u8: Number {
#[inline(always)] static pure fn zero() -> u8 { 0u8 }
#[inline(always)] static pure fn one() -> u8 { 1u8 }
}
pub trait UnSigned /*:Number*/ {}
pub impl u16: Number {
#[inline(always)] static pure fn zero() -> u16 { 0u16 }
#[inline(always)] static pure fn one() -> u16 { 1u16 }
}
pub impl u32: Number {
#[inline(always)] static pure fn zero() -> u32 { 0u32 }
#[inline(always)] static pure fn one() -> u32 { 1u32 }
}
pub impl u64: Number {
#[inline(always)] static pure fn zero() -> u64 { 0u64 }
#[inline(always)] static pure fn one() -> u64 { 1u64 }
}
pub impl uint: Number {
#[inline(always)] static pure fn zero() -> uint { 0u }
#[inline(always)] static pure fn one() -> uint { 1u }
}
pub impl i8: Number {
#[inline(always)] static pure fn zero() -> i8 { 0i8 }
#[inline(always)] static pure fn one() -> i8 { 1i8 }
}
pub impl i16: Number {
#[inline(always)] static pure fn zero() -> i16 { 0i16 }
#[inline(always)] static pure fn one() -> i16 { 1i16 }
}
pub impl i32: Number {
#[inline(always)] static pure fn zero() -> i32 { 0i32 }
#[inline(always)] static pure fn one() -> i32 { 1i32 }
}
pub impl i64: Number {
#[inline(always)] static pure fn zero() -> i64 { 0i64 }
#[inline(always)] static pure fn one() -> i64 { 1i64 }
}
pub impl int: Number {
#[inline(always)] static pure fn zero() -> int { 0 }
#[inline(always)] static pure fn one() -> int { 1 }
}
pub impl f32: Number {
#[inline(always)] static pure fn zero() -> f32 { 0f32 }
#[inline(always)] static pure fn one() -> f32 { 1f32 }
}
pub impl f64: Number {
#[inline(always)] static pure fn zero() -> f64 { 0f64 }
#[inline(always)] static pure fn one() -> f64 { 1f64 }
}
pub impl float: Number {
#[inline(always)] static pure fn zero() -> float { 0f }
#[inline(always)] static pure fn one() -> float { 1f }
}
pub trait UnSigned: Number {}
pub impl u8: UnSigned {}
pub impl u16: UnSigned {}
@ -19,7 +85,7 @@ pub impl u64: UnSigned {}
pub impl uint: UnSigned {}
pub trait Signed /*:Number*/ {}
pub trait Signed: Number {}
pub impl i8: Signed {}
pub impl i16: Signed {}
@ -32,7 +98,7 @@ pub impl f64: Signed {}
pub impl float: Signed {}
pub trait Integer /*:Number*/ {}
pub trait Integer: Number {}
pub impl u8: Integer {}
pub impl u16: Integer {}
@ -47,7 +113,7 @@ pub impl i64: Integer {}
pub impl int: Integer {}
pub trait Float /*:Number, FuzzyEq*/ {
pub trait Float: Number, FuzzyEq {
pure fn to_float() -> float;
static pure fn from_float(n: float) -> self;

View file

@ -13,6 +13,7 @@ use funs::triganomic::*;
use mat::{Mat3, Mat4};
use num::cast::*;
use num::default_eq::DefaultEq;
use num::ext::Float;
use vec::Vec3;
@ -95,7 +96,7 @@ pub impl<T:Copy> Quat<T>: ToPtr<T> {
}
}
pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Quat<T>: Quaternion<T> {
pub impl<T:Copy Float Exp Extent InvTrig> Quat<T>: Quaternion<T> {
#[inline(always)]
static pure fn identity() -> Quat<T> {
Quat::new(NumCast::one(),
@ -301,4 +302,82 @@ pub impl<T:Copy DefaultEq> Quat<T>: DefaultEq {
self[2].default_eq(&other[2]) &&
self[3].default_eq(&other[3])
}
}
}
// // Operator Overloads
// pub impl<T, Result, RHS: QuatAddRHS<T, Result>> Quat<T>: Add<RHS,Result> {
// #[inline(always)]
// pure fn add(rhs: &RHS) -> Result {
// rhs.quat_add_rhs(&self)
// }
// }
// pub impl<T, Result, RHS: QuatSubRHS<T, Result>> Quat<T>: Sub<RHS,Result> {
// #[inline(always)]
// pure fn sub(&self, rhs: &RHS) -> Result {
// rhs.quat_sub_rhs(self)
// }
// }
// pub impl<T, Result, RHS: QuatMulRHS<T, Result>> Quat<T>: Mul<RHS,Result> {
// #[inline(always)]
// pure fn mul(&self, rhs: &RHS) -> Result {
// rhs.quat_mul_rhs(self)
// }
// }
// pub impl<T, Result, RHS: QuatDivRHS<T, Result>> Quat<T>: Div<RHS,Result> {
// #[inline(always)]
// pure fn div(&self, rhs: &RHS) -> Result {
// rhs.quat_div_rhs(self)
// }
// }
// // RHS Traits for Operator overloads
// pub trait QuatAddRHS<T, Result> { pure fn quat_add_rhs(&self, lhs: &Quat<T>) -> Result; }
// pub trait QuatSubRHS<T, Result> { pure fn quat_sub_rhs(&self, lhs: &Quat<T>) -> Result; }
// pub trait QuatMulRHS<T, Result> { pure fn quat_mul_rhs(&self, lhs: &Quat<T>) -> Result; }
// pub trait QuatDivRHS<T, Result> { pure fn quat_div_rhs(&self, lhs: &Quat<T>) -> Result; }
// // Quat/Scalar Multiplication
// pub impl f32: QuatMulRHS<f32, Quat<f32>> { #[inline(always)] pure fn quat_mul_rhs(&self, lhs: &Quat<f32>) -> Quat<f32> { lhs.mul_t(self) } }
// pub impl f64: QuatMulRHS<f64, Quat<f64>> { #[inline(always)] pure fn quat_mul_rhs(&self, lhs: &Quat<f64>) -> Quat<f64> { lhs.mul_t(self) } }
// pub impl float: QuatMulRHS<float, Quat<float>> { #[inline(always)] pure fn quat_mul_rhs(&self, lhs: &Quat<float>) -> Quat<float> { lhs.mul_t(self) } }
// // Quat/Scalar Division
// pub impl f32: QuatDivRHS<f32, Quat<f32>> { #[inline(always)] pure fn quat_div_rhs(&self, lhs: &Quat<f32>) -> Quat<f32> { lhs.div_t(self) } }
// pub impl f64: QuatDivRHS<f64, Quat<f64>> { #[inline(always)] pure fn quat_div_rhs(&self, lhs: &Quat<f64>) -> Quat<f64> { lhs.div_t(self) } }
// pub impl float: QuatDivRHS<float, Quat<float>> { #[inline(always)] pure fn quat_div_rhs(&self, lhs: &Quat<float>) -> Quat<float> { lhs.div_t(self) } }
// // Quat/Vector Multiplication
// pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Vec3<T>: QuatMulRHS<T, Vec3<T>> {
// #[inline(always)]
// pure fn quat_mul_rhs(&self, lhs: &Quat<T>) -> Vec3<T> {
// lhs.mul_v(self)
// }
// }
// // // Quat/Quat Addition
// // pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Quat<T>: QuatAddRHS<Quat<T>, Quat<T>> {
// // #[inline(always)]
// // pure fn quat_add_rhs(&self, lhs: &Quat<T>) -> Quat<T> {
// // lhs.add_q(self)
// // }
// // }
// // Quat/Quat Subtraction
// pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Quat<T>: QuatSubRHS<T, Quat<T>> {
// #[inline(always)]
// pure fn quat_sub_rhs(&self, lhs: &Quat<T>) -> Quat<T> {
// lhs.sub_q(self)
// }
// }
// // Quat/Quat Multiplication
// pub impl<T:Copy Num NumCast Exp Extent Ord InvTrig> Quat<T>: QuatMulRHS<T, Quat<T>> {
// #[inline(always)]
// pure fn quat_mul_rhs(&self, lhs: &Quat<T>) -> Quat<T> {
// lhs.mul_q(self)
// }
// }

View file

@ -10,6 +10,7 @@ use dim::{Dimensional, ToPtr};
use funs::exponential::Exp;
use num::cast::*;
use num::default_eq::DefaultEq;
use num::ext::Number;
///
/// The base vector trait
@ -132,7 +133,7 @@ pub impl<T:Copy> Vec2<T>: ToPtr<T> {
}
}
pub impl<T:Copy Num NumCast> Vec2<T>: NumericVector<T> {
pub impl<T:Copy Number> Vec2<T>: NumericVector<T> {
#[inline(always)]
static pure fn identity() -> Vec2<T> {
Vec2::new(NumCast::one(),
@ -176,14 +177,14 @@ pub impl<T:Copy Num NumCast> Vec2<T>: NumericVector<T> {
}
}
pub impl<T:Copy Num> Vec2<T>: Neg<Vec2<T>> {
pub impl<T:Copy Number> Vec2<T>: Neg<Vec2<T>> {
#[inline(always)]
pure fn neg(&self) -> Vec2<T> {
Vec2::new(-self[0], -self[1])
}
}
pub impl<T:Copy Num NumCast Exp> Vec2<T>: GeometricVector<T> {
pub impl<T:Copy Number Exp> Vec2<T>: GeometricVector<T> {
#[inline(always)]
pure fn length2(&self) -> T {
self.dot(self)
@ -294,7 +295,7 @@ pub impl<T:Copy> Vec3<T>: ToPtr<T> {
}
}
pub impl<T:Copy Num NumCast> Vec3<T>: NumericVector<T> {
pub impl<T:Copy Number> Vec3<T>: NumericVector<T> {
#[inline(always)]
static pure fn identity() -> Vec3<T> {
Vec3::new(NumCast::one(),
@ -345,14 +346,14 @@ pub impl<T:Copy Num NumCast> Vec3<T>: NumericVector<T> {
}
}
pub impl<T:Copy Num> Vec3<T>: Neg<Vec3<T>> {
pub impl<T:Copy Number> Vec3<T>: Neg<Vec3<T>> {
#[inline(always)]
pure fn neg(&self) -> Vec3<T> {
Vec3::new(-self[0], -self[1], -self[2])
}
}
pub impl<T:Copy Num> Vec3<T>: NumericVector3<T> {
pub impl<T:Copy Number> Vec3<T>: NumericVector3<T> {
#[inline(always)]
pure fn cross(&self, other: &Vec3<T>) -> Vec3<T> {
Vec3::new((self[1] * other[2]) - (self[2] * other[1]),
@ -361,7 +362,7 @@ pub impl<T:Copy Num> Vec3<T>: NumericVector3<T> {
}
}
pub impl<T:Copy Num NumCast Exp> Vec3<T>: GeometricVector<T> {
pub impl<T:Copy Number Exp> Vec3<T>: GeometricVector<T> {
#[inline(always)]
pure fn length2(&self) -> T {
self.dot(self)
@ -474,7 +475,7 @@ pub impl<T:Copy> Vec4<T>: ToPtr<T> {
}
}
pub impl<T:Copy Num NumCast> Vec4<T>: NumericVector<T> {
pub impl<T:Copy Number> Vec4<T>: NumericVector<T> {
#[inline(always)]
static pure fn identity() -> Vec4<T> {
Vec4::new(NumCast::one(),
@ -532,14 +533,14 @@ pub impl<T:Copy Num NumCast> Vec4<T>: NumericVector<T> {
}
}
pub impl<T:Copy Num> Vec4<T>: Neg<Vec4<T>> {
pub impl<T:Copy Number> Vec4<T>: Neg<Vec4<T>> {
#[inline(always)]
pure fn neg(&self) -> Vec4<T> {
Vec4::new(-self[0], -self[1], -self[2], -self[3])
}
}
pub impl<T:Copy Num NumCast Exp> Vec4<T>: GeometricVector<T> {
pub impl<T:Copy Number Exp> Vec4<T>: GeometricVector<T> {
#[inline(always)]
pure fn length2(&self) -> T {
self.dot(self)