diff --git a/src/na.rs b/src/na.rs index d96e7cb2..f57e70fd 100644 --- a/src/na.rs +++ b/src/na.rs @@ -7,6 +7,7 @@ pub use traits::{ AlgebraicVec, AlgebraicVecExt, Basis, + Cast, Col, Cov, Cross, @@ -20,7 +21,6 @@ pub use traits::{ IterableMut, LMul, Mat, - MatCast, Mean, Norm, Outer, @@ -34,7 +34,6 @@ pub use traits::{ Transpose, UniformSphereSample, Vec, - VecCast, VecExt }; @@ -709,26 +708,6 @@ pub fn mean>(observations: &M) -> N { // // -/* - * MatCast - */ - -/// Converts a matrix to a matrix with different value type. -#[inline(always)] -pub fn cast_mat, Res>(m: M) -> Res { - MatCast::from(m) -} - -/* - * VecCast - */ - -/// Converts a matrix to a matrix with different value type. -#[inline(always)] -pub fn cast_vec, Res>(v: V) -> Res { - VecCast::from(v) -} - /* * Basis */ @@ -764,6 +743,28 @@ pub fn dim() -> uint { Dim::dim(None::) } +/* + * Cast + */ +/// Converts an object from one type to another. +/// +/// For primitive types, this is the same as the `as` keywords. +/// Those properties are preserved by a cast: +/// * Type-level geometric invariants cannot be broken (eg. a cast from Rot3 to Rot3 +/// is not possible) +/// * A cast to a type with more type-level invariants cannot be done (eg. a cast from +/// Mat to Rot3 is not possible) +/// * For primitive types an unbounded cast is done using the `as` keyword (this is different +/// from the standard library which makes bound-checking to ensure eg. that a i64 is not out of +/// the range of an i32 when a cast from i64 to i32 is done). +/// * A cast does not affect the dimension of an algebraic object. Note that this prevents an +/// isometric transform to be cast to a raw matrix. Use `to_homogeneous` for that special +/// purpose. +#[inline(always)] +pub fn cast>(t: T) -> U { + Cast::from(t) +} + /* * Indexable */ diff --git a/src/structs/dmat.rs b/src/structs/dmat.rs index 33d66141..8a03280e 100644 --- a/src/structs/dmat.rs +++ b/src/structs/dmat.rs @@ -4,12 +4,13 @@ use std::rand::Rand; use std::rand; -use std::num::{One, Zero, from_f32, from_uint}; +use std::num::{One, Zero}; use std::vec; use std::cmp::ApproxEq; use std::util; use structs::dvec::{DVec, DVecMulRhs}; use traits::operations::{Inv, Transpose, Mean, Cov}; +use traits::structure::Cast; #[doc(hidden)] mod metal; @@ -409,10 +410,10 @@ impl Transpose for DMat { } } -impl Mean> for DMat { +impl + Clone> Mean> for DMat { fn mean(&self) -> DVec { let mut res: DVec = DVec::new_zeros(self.ncols); - let normalizer: N = from_f32(1.0f32 / from_uint(self.nrows).unwrap()).unwrap(); + let normalizer: N = Cast::from(1.0f32 / Cast::from(self.nrows)); for i in range(0u, self.nrows) { for j in range(0u, self.ncols) { @@ -427,7 +428,7 @@ impl Mean> for DMat { } } -impl> + ToStr > Cov> for DMat { +impl + DMatDivRhs> + ToStr > Cov> for DMat { // FIXME: this could be heavily optimized, removing all temporaries by merging loops. fn cov(&self) -> DMat { assert!(self.nrows > 1); @@ -445,7 +446,8 @@ impl> + ToStr > Cov ( - impl + impl + Algebraic + Trigonometric + Num + Clone> RotationMatrix<$tlv, $tav, $trot> for $t { #[inline] fn to_rot_mat(&self) -> $trot { @@ -132,7 +132,7 @@ macro_rules! translate_impl( macro_rules! rotation_impl( ($t: ident, $trot: ident, $tav: ident) => ( - impl Rotation<$tav> for $t { + impl + Num + Trigonometric + Algebraic + Clone> Rotation<$tav> for $t { #[inline] fn rotation(&self) -> $tav { self.rotation.rotation() diff --git a/src/structs/mat.rs b/src/structs/mat.rs index d7476da6..b46853e4 100644 --- a/src/structs/mat.rs +++ b/src/structs/mat.rs @@ -9,7 +9,7 @@ use std::vec::{VecIterator, VecMutIterator}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Vec1MulRhs, Vec4MulRhs, Vec5MulRhs, Vec6MulRhs}; -use traits::structure::{MatCast, Row, Col, Iterable, IterableMut, Dim, Indexable}; +use traits::structure::{Cast, Row, Col, Iterable, IterableMut, Dim, Indexable}; use traits::operations::{Absolute, Transpose, Inv, Outer}; use traits::geometry::{ToHomogeneous, FromHomogeneous}; @@ -42,12 +42,14 @@ double_dispatch_binop_decl_trait!(Mat1, Mat1MulRhs) double_dispatch_binop_decl_trait!(Mat1, Mat1DivRhs) double_dispatch_binop_decl_trait!(Mat1, Mat1AddRhs) double_dispatch_binop_decl_trait!(Mat1, Mat1SubRhs) +double_dispatch_cast_decl_trait!(Mat1, Mat1Cast) mul_redispatch_impl!(Mat1, Mat1MulRhs) div_redispatch_impl!(Mat1, Mat1DivRhs) add_redispatch_impl!(Mat1, Mat1AddRhs) sub_redispatch_impl!(Mat1, Mat1SubRhs) +cast_redispatch_impl!(Mat1, Mat1Cast) mat_impl!(Mat1, m11) -mat_cast_impl!(Mat1, m11) +mat_cast_impl!(Mat1, Mat1Cast, m11) add_impl!(Mat1, Mat1AddRhs, m11) sub_impl!(Mat1, Mat1SubRhs, m11) @@ -133,14 +135,16 @@ double_dispatch_binop_decl_trait!(Mat2, Mat2MulRhs) double_dispatch_binop_decl_trait!(Mat2, Mat2DivRhs) double_dispatch_binop_decl_trait!(Mat2, Mat2AddRhs) double_dispatch_binop_decl_trait!(Mat2, Mat2SubRhs) +double_dispatch_cast_decl_trait!(Mat2, Mat2Cast) mul_redispatch_impl!(Mat2, Mat2MulRhs) div_redispatch_impl!(Mat2, Mat2DivRhs) add_redispatch_impl!(Mat2, Mat2AddRhs) sub_redispatch_impl!(Mat2, Mat2SubRhs) +cast_redispatch_impl!(Mat2, Mat2Cast) mat_impl!(Mat2, m11, m12, m21, m22) -mat_cast_impl!(Mat2, m11, m12, - m21, m22) +mat_cast_impl!(Mat2, Mat2Cast, m11, m12, + m21, m22) add_impl!(Mat2, Mat2AddRhs, m11, m12, m21, m22) sub_impl!(Mat2, Mat2SubRhs, m11, m12, m21, m22) @@ -229,16 +233,18 @@ double_dispatch_binop_decl_trait!(Mat3, Mat3MulRhs) double_dispatch_binop_decl_trait!(Mat3, Mat3DivRhs) double_dispatch_binop_decl_trait!(Mat3, Mat3AddRhs) double_dispatch_binop_decl_trait!(Mat3, Mat3SubRhs) +double_dispatch_cast_decl_trait!(Mat3, Mat3Cast) mul_redispatch_impl!(Mat3, Mat3MulRhs) div_redispatch_impl!(Mat3, Mat3DivRhs) add_redispatch_impl!(Mat3, Mat3AddRhs) sub_redispatch_impl!(Mat3, Mat3SubRhs) +cast_redispatch_impl!(Mat3, Mat3Cast) mat_impl!(Mat3, m11, m12, m13, m21, m22, m23, m31, m32, m33) -mat_cast_impl!(Mat3, m11, m12, m13, - m21, m22, m23, - m31, m32, m33) +mat_cast_impl!(Mat3, Mat3Cast, m11, m12, m13, + m21, m22, m23, + m31, m32, m33) add_impl!(Mat3, Mat3AddRhs, m11, m12, m13, m21, m22, m23, @@ -339,17 +345,19 @@ double_dispatch_binop_decl_trait!(Mat4, Mat4MulRhs) double_dispatch_binop_decl_trait!(Mat4, Mat4DivRhs) double_dispatch_binop_decl_trait!(Mat4, Mat4AddRhs) double_dispatch_binop_decl_trait!(Mat4, Mat4SubRhs) +double_dispatch_cast_decl_trait!(Mat4, Mat4Cast) mul_redispatch_impl!(Mat4, Mat4MulRhs) div_redispatch_impl!(Mat4, Mat4DivRhs) add_redispatch_impl!(Mat4, Mat4AddRhs) sub_redispatch_impl!(Mat4, Mat4SubRhs) +cast_redispatch_impl!(Mat4, Mat4Cast) mat_impl!(Mat4, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44 ) -mat_cast_impl!(Mat4, +mat_cast_impl!(Mat4, Mat4Cast, m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, @@ -501,10 +509,12 @@ double_dispatch_binop_decl_trait!(Mat5, Mat5MulRhs) double_dispatch_binop_decl_trait!(Mat5, Mat5DivRhs) double_dispatch_binop_decl_trait!(Mat5, Mat5AddRhs) double_dispatch_binop_decl_trait!(Mat5, Mat5SubRhs) +double_dispatch_cast_decl_trait!(Mat5, Mat5Cast) mul_redispatch_impl!(Mat5, Mat5MulRhs) div_redispatch_impl!(Mat5, Mat5DivRhs) add_redispatch_impl!(Mat5, Mat5AddRhs) sub_redispatch_impl!(Mat5, Mat5SubRhs) +cast_redispatch_impl!(Mat5, Mat5Cast) mat_impl!(Mat5, m11, m12, m13, m14, m15, m21, m22, m23, m24, m25, @@ -512,7 +522,7 @@ mat_impl!(Mat5, m41, m42, m43, m44, m45, m51, m52, m53, m54, m55 ) -mat_cast_impl!(Mat5, +mat_cast_impl!(Mat5, Mat5Cast, m11, m12, m13, m14, m15, m21, m22, m23, m24, m25, m31, m32, m33, m34, m35, @@ -679,10 +689,12 @@ double_dispatch_binop_decl_trait!(Mat6, Mat6MulRhs) double_dispatch_binop_decl_trait!(Mat6, Mat6DivRhs) double_dispatch_binop_decl_trait!(Mat6, Mat6AddRhs) double_dispatch_binop_decl_trait!(Mat6, Mat6SubRhs) +double_dispatch_cast_decl_trait!(Mat6, Mat6Cast) mul_redispatch_impl!(Mat6, Mat6MulRhs) div_redispatch_impl!(Mat6, Mat6DivRhs) add_redispatch_impl!(Mat6, Mat6AddRhs) sub_redispatch_impl!(Mat6, Mat6SubRhs) +cast_redispatch_impl!(Mat6, Mat6Cast) mat_impl!(Mat6, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26, @@ -691,7 +703,7 @@ mat_impl!(Mat6, m51, m52, m53, m54, m55, m56, m61, m62, m63, m64, m65, m66 ) -mat_cast_impl!(Mat6, +mat_cast_impl!(Mat6, Mat6Cast, m11, m12, m13, m14, m15, m16, m21, m22, m23, m24, m25, m26, m31, m32, m33, m34, m35, m36, diff --git a/src/structs/mat_macros.rs b/src/structs/mat_macros.rs index 439b142e..dc64703c 100644 --- a/src/structs/mat_macros.rs +++ b/src/structs/mat_macros.rs @@ -33,14 +33,14 @@ macro_rules! at_fast_impl( ) macro_rules! mat_cast_impl( - ($t: ident, $comp0: ident $(,$compN: ident)*) => ( - impl MatCast<$t> for $t { - #[inline] - fn from(m: $t) -> $t { - $t::new(NumCast::from(m.$comp0.clone()).unwrap() $(, NumCast::from(m.$compN.clone()).unwrap() )*) + ($t: ident, $tcast: ident, $comp0: ident $(,$compN: ident)*) => ( + impl> $tcast for $t { + #[inline] + fn to(v: $t) -> $t { + $t::new(Cast::from(v.$comp0.clone()) $(, Cast::from(v.$compN.clone()))*) + } } - } - ) + ) ) macro_rules! add_impl( diff --git a/src/structs/metal.rs b/src/structs/metal.rs index 378c9996..21c464b9 100644 --- a/src/structs/metal.rs +++ b/src/structs/metal.rs @@ -62,3 +62,23 @@ macro_rules! sub_redispatch_impl( } ) ) + +// Double dispatch traits to drive the Cast method for structured types with one type parameter. +macro_rules! double_dispatch_cast_decl_trait( + ($t: ident, $tcast: ident) => ( + pub trait $tcast { + fn to(Self) -> $t; + } + ) +) + +macro_rules! cast_redispatch_impl( + ($t:ident, $tcast: ident) => ( + impl, N> Cast for $t { + #[inline(always)] + fn from(t: T) -> $t { + $tcast::to(t) + } + } + ) +) diff --git a/src/structs/mod.rs b/src/structs/mod.rs index e0edd39d..eb735e7d 100644 --- a/src/structs/mod.rs +++ b/src/structs/mod.rs @@ -21,5 +21,6 @@ mod spec { mod mat; mod vec0; mod vec; + mod primitives; // mod complex; } diff --git a/src/structs/rot.rs b/src/structs/rot.rs index cb3d0bc5..10c2a2c3 100644 --- a/src/structs/rot.rs +++ b/src/structs/rot.rs @@ -2,11 +2,11 @@ #[allow(missing_doc)]; -use std::num::{Zero, One, from_f32}; +use std::num::{Zero, One}; use std::rand::{Rand, Rng}; use traits::geometry::{Rotate, Rotation, AbsoluteRotate, RotationMatrix, Transform, ToHomogeneous, Norm, Cross}; -use traits::structure::{Dim, Indexable, Row, Col}; +use traits::structure::{Cast, Dim, Indexable, Row, Col}; use traits::operations::{Absolute, Inv, Transpose}; use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs}; use structs::mat::{Mat2, Mat3, Mat4, Mat5}; @@ -168,11 +168,11 @@ impl Rot3 { } } -impl +impl> Rotation> for Rot3 { #[inline] fn rotation(&self) -> Vec3 { - let angle = ((self.submat.m11 + self.submat.m22 + self.submat.m33 - One::one()) / from_f32(2.0).unwrap()).acos(); + let angle = ((self.submat.m11 + self.submat.m22 + self.submat.m33 - One::one()) / Cast::from(2.0)).acos(); if angle != angle { // FIXME: handle that correctly diff --git a/src/structs/rot_macros.rs b/src/structs/rot_macros.rs index 348a9afa..308807cd 100644 --- a/src/structs/rot_macros.rs +++ b/src/structs/rot_macros.rs @@ -56,7 +56,7 @@ macro_rules! dim_impl( macro_rules! rotation_matrix_impl( ($t: ident, $tlv: ident, $tav: ident) => ( - impl + impl + Algebraic + Trigonometric + Num + Clone> RotationMatrix<$tlv, $tav, $t> for $t { #[inline] fn to_rot_mat(&self) -> $t { diff --git a/src/structs/spec/mat.rs b/src/structs/spec/mat.rs index cf00845e..e54c404c 100644 --- a/src/structs/spec/mat.rs +++ b/src/structs/spec/mat.rs @@ -1,9 +1,9 @@ -use std::num::{Zero, One, from_f32}; +use std::num::{Zero, One}; use structs::vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs}; use structs::mat::{Mat1, Mat2, Mat3, Mat3MulRhs, Mat2MulRhs}; use structs::mat; use traits::operations::{Inv}; -use traits::structure::{Row, Col}; +use traits::structure::{Cast, Row, Col}; // some specializations: impl @@ -266,17 +266,17 @@ impl + Add> Mat2MulRhs> for Vec2 { } // FIXME: move this to another file? -impl mat::Mat4 { +impl + Zero + One> mat::Mat4 { /// Computes a projection matrix given the frustrum near plane width, height, the field of /// view, and the distance to the clipping planes (`znear` and `zfar`). pub fn new_perspective(width: N, height: N, fov: N, znear: N, zfar: N) -> mat::Mat4 { let aspect = width / height; let _1: N = One::one(); - let sy = _1 / (fov * from_f32(0.5).unwrap()).tan(); + let sy = _1 / (fov * Cast::from(0.5)).tan(); let sx = -sy / aspect; let sz = -(zfar + znear) / (znear - zfar); - let tz = zfar * znear * from_f32(2.0).unwrap() / (znear - zfar); + let tz = zfar * znear * Cast::from(2.0) / (znear - zfar); mat::Mat4::new( sx, Zero::zero(), Zero::zero(), Zero::zero(), diff --git a/src/structs/spec/primitives.rs b/src/structs/spec/primitives.rs new file mode 100644 index 00000000..cc7ccd61 --- /dev/null +++ b/src/structs/spec/primitives.rs @@ -0,0 +1,219 @@ +//! nalgebra trait implementation for primitive types. + +#[allow(missing_doc)]; +#[allow(non_camel_case_types)]; + +use traits::structure::Cast; + +// Double dispatch traits to drive the Cast method for primitive types. +macro_rules! primitive_double_dispatch_cast_decl_trait( + ($t: ident, $tcast: ident) => ( + pub trait $tcast { + fn to(Self) -> $t; + } + ) +) + +macro_rules! primitive_double_dispatch_cast_impl( + ($ttarget: ident, $tself: ident, $tcast: ident) => ( + impl $tcast for $tself{ + #[inline(always)] + fn to(v: $tself) -> $ttarget { + v as $ttarget + } + } + ) +) + +macro_rules! primitive_cast_redispatch_impl( + ($t:ident, $tcast: ident) => ( + impl Cast for $t { + #[inline(always)] + fn from(t: T) -> $t { + $tcast::to(t) + } + } + ) +) + +primitive_double_dispatch_cast_decl_trait!(f64, f64Cast) +primitive_double_dispatch_cast_decl_trait!(f32, f32Cast) +primitive_double_dispatch_cast_decl_trait!(i64, i64Cast) +primitive_double_dispatch_cast_decl_trait!(i32, i32Cast) +primitive_double_dispatch_cast_decl_trait!(i16, i16Cast) +primitive_double_dispatch_cast_decl_trait!(i8, i8Cast) +primitive_double_dispatch_cast_decl_trait!(u64, u64Cast) +primitive_double_dispatch_cast_decl_trait!(u32, u32Cast) +primitive_double_dispatch_cast_decl_trait!(u16, u16Cast) +primitive_double_dispatch_cast_decl_trait!(u8, u8Cast) +primitive_double_dispatch_cast_decl_trait!(int, intCast) +primitive_double_dispatch_cast_decl_trait!(uint, uintCast) + +primitive_cast_redispatch_impl!(f64, f64Cast) +primitive_cast_redispatch_impl!(f32, f32Cast) +primitive_cast_redispatch_impl!(i64, i64Cast) +primitive_cast_redispatch_impl!(i32, i32Cast) +primitive_cast_redispatch_impl!(i16, i16Cast) +primitive_cast_redispatch_impl!(i8, i8Cast) +primitive_cast_redispatch_impl!(u64, u64Cast) +primitive_cast_redispatch_impl!(u32, u32Cast) +primitive_cast_redispatch_impl!(u16, u16Cast) +primitive_cast_redispatch_impl!(u8, u8Cast) +primitive_cast_redispatch_impl!(int, intCast) +primitive_cast_redispatch_impl!(uint, uintCast) + +primitive_double_dispatch_cast_impl!(f64, f64, f64Cast) +primitive_double_dispatch_cast_impl!(f64, f32, f64Cast) +primitive_double_dispatch_cast_impl!(f64, i64, f64Cast) +primitive_double_dispatch_cast_impl!(f64, i32, f64Cast) +primitive_double_dispatch_cast_impl!(f64, i16, f64Cast) +primitive_double_dispatch_cast_impl!(f64, i8, f64Cast) +primitive_double_dispatch_cast_impl!(f64, u64, f64Cast) +primitive_double_dispatch_cast_impl!(f64, u32, f64Cast) +primitive_double_dispatch_cast_impl!(f64, u16, f64Cast) +primitive_double_dispatch_cast_impl!(f64, u8, f64Cast) +primitive_double_dispatch_cast_impl!(f64, int, f64Cast) +primitive_double_dispatch_cast_impl!(f64, uint, f64Cast) + +primitive_double_dispatch_cast_impl!(f32, f64, f32Cast) +primitive_double_dispatch_cast_impl!(f32, f32, f32Cast) +primitive_double_dispatch_cast_impl!(f32, i64, f32Cast) +primitive_double_dispatch_cast_impl!(f32, i32, f32Cast) +primitive_double_dispatch_cast_impl!(f32, i16, f32Cast) +primitive_double_dispatch_cast_impl!(f32, i8, f32Cast) +primitive_double_dispatch_cast_impl!(f32, u64, f32Cast) +primitive_double_dispatch_cast_impl!(f32, u32, f32Cast) +primitive_double_dispatch_cast_impl!(f32, u16, f32Cast) +primitive_double_dispatch_cast_impl!(f32, u8, f32Cast) +primitive_double_dispatch_cast_impl!(f32, int, f32Cast) +primitive_double_dispatch_cast_impl!(f32, uint, f32Cast) + +primitive_double_dispatch_cast_impl!(i64, f64, i64Cast) +primitive_double_dispatch_cast_impl!(i64, f32, i64Cast) +primitive_double_dispatch_cast_impl!(i64, i64, i64Cast) +primitive_double_dispatch_cast_impl!(i64, i32, i64Cast) +primitive_double_dispatch_cast_impl!(i64, i16, i64Cast) +primitive_double_dispatch_cast_impl!(i64, i8, i64Cast) +primitive_double_dispatch_cast_impl!(i64, u64, i64Cast) +primitive_double_dispatch_cast_impl!(i64, u32, i64Cast) +primitive_double_dispatch_cast_impl!(i64, u16, i64Cast) +primitive_double_dispatch_cast_impl!(i64, u8, i64Cast) +primitive_double_dispatch_cast_impl!(i64, int, i64Cast) +primitive_double_dispatch_cast_impl!(i64, uint, i64Cast) + +primitive_double_dispatch_cast_impl!(i32, f64, i32Cast) +primitive_double_dispatch_cast_impl!(i32, f32, i32Cast) +primitive_double_dispatch_cast_impl!(i32, i64, i32Cast) +primitive_double_dispatch_cast_impl!(i32, i32, i32Cast) +primitive_double_dispatch_cast_impl!(i32, i16, i32Cast) +primitive_double_dispatch_cast_impl!(i32, i8, i32Cast) +primitive_double_dispatch_cast_impl!(i32, u64, i32Cast) +primitive_double_dispatch_cast_impl!(i32, u32, i32Cast) +primitive_double_dispatch_cast_impl!(i32, u16, i32Cast) +primitive_double_dispatch_cast_impl!(i32, u8, i32Cast) +primitive_double_dispatch_cast_impl!(i32, int, i32Cast) +primitive_double_dispatch_cast_impl!(i32, uint, i32Cast) + +primitive_double_dispatch_cast_impl!(i16, f64, i16Cast) +primitive_double_dispatch_cast_impl!(i16, f32, i16Cast) +primitive_double_dispatch_cast_impl!(i16, i64, i16Cast) +primitive_double_dispatch_cast_impl!(i16, i32, i16Cast) +primitive_double_dispatch_cast_impl!(i16, i16, i16Cast) +primitive_double_dispatch_cast_impl!(i16, i8, i16Cast) +primitive_double_dispatch_cast_impl!(i16, u64, i16Cast) +primitive_double_dispatch_cast_impl!(i16, u32, i16Cast) +primitive_double_dispatch_cast_impl!(i16, u16, i16Cast) +primitive_double_dispatch_cast_impl!(i16, u8, i16Cast) +primitive_double_dispatch_cast_impl!(i16, int, i16Cast) +primitive_double_dispatch_cast_impl!(i16, uint, i16Cast) + +primitive_double_dispatch_cast_impl!(i8, f64, i8Cast) +primitive_double_dispatch_cast_impl!(i8, f32, i8Cast) +primitive_double_dispatch_cast_impl!(i8, i64, i8Cast) +primitive_double_dispatch_cast_impl!(i8, i32, i8Cast) +primitive_double_dispatch_cast_impl!(i8, i16, i8Cast) +primitive_double_dispatch_cast_impl!(i8, i8, i8Cast) +primitive_double_dispatch_cast_impl!(i8, u64, i8Cast) +primitive_double_dispatch_cast_impl!(i8, u32, i8Cast) +primitive_double_dispatch_cast_impl!(i8, u16, i8Cast) +primitive_double_dispatch_cast_impl!(i8, u8, i8Cast) +primitive_double_dispatch_cast_impl!(i8, int, i8Cast) +primitive_double_dispatch_cast_impl!(i8, uint, i8Cast) + +primitive_double_dispatch_cast_impl!(u64, f64, u64Cast) +primitive_double_dispatch_cast_impl!(u64, f32, u64Cast) +primitive_double_dispatch_cast_impl!(u64, i64, u64Cast) +primitive_double_dispatch_cast_impl!(u64, i32, u64Cast) +primitive_double_dispatch_cast_impl!(u64, i16, u64Cast) +primitive_double_dispatch_cast_impl!(u64, i8, u64Cast) +primitive_double_dispatch_cast_impl!(u64, u64, u64Cast) +primitive_double_dispatch_cast_impl!(u64, u32, u64Cast) +primitive_double_dispatch_cast_impl!(u64, u16, u64Cast) +primitive_double_dispatch_cast_impl!(u64, u8, u64Cast) +primitive_double_dispatch_cast_impl!(u64, int, u64Cast) +primitive_double_dispatch_cast_impl!(u64, uint, u64Cast) + +primitive_double_dispatch_cast_impl!(u32, f64, u32Cast) +primitive_double_dispatch_cast_impl!(u32, f32, u32Cast) +primitive_double_dispatch_cast_impl!(u32, i64, u32Cast) +primitive_double_dispatch_cast_impl!(u32, i32, u32Cast) +primitive_double_dispatch_cast_impl!(u32, i16, u32Cast) +primitive_double_dispatch_cast_impl!(u32, i8, u32Cast) +primitive_double_dispatch_cast_impl!(u32, u64, u32Cast) +primitive_double_dispatch_cast_impl!(u32, u32, u32Cast) +primitive_double_dispatch_cast_impl!(u32, u16, u32Cast) +primitive_double_dispatch_cast_impl!(u32, u8, u32Cast) +primitive_double_dispatch_cast_impl!(u32, int, u32Cast) +primitive_double_dispatch_cast_impl!(u32, uint, u32Cast) + +primitive_double_dispatch_cast_impl!(u16, f64, u16Cast) +primitive_double_dispatch_cast_impl!(u16, f32, u16Cast) +primitive_double_dispatch_cast_impl!(u16, i64, u16Cast) +primitive_double_dispatch_cast_impl!(u16, i32, u16Cast) +primitive_double_dispatch_cast_impl!(u16, i16, u16Cast) +primitive_double_dispatch_cast_impl!(u16, i8, u16Cast) +primitive_double_dispatch_cast_impl!(u16, u64, u16Cast) +primitive_double_dispatch_cast_impl!(u16, u32, u16Cast) +primitive_double_dispatch_cast_impl!(u16, u16, u16Cast) +primitive_double_dispatch_cast_impl!(u16, u8, u16Cast) +primitive_double_dispatch_cast_impl!(u16, int, u16Cast) +primitive_double_dispatch_cast_impl!(u16, uint, u16Cast) + +primitive_double_dispatch_cast_impl!(u8, f64, u8Cast) +primitive_double_dispatch_cast_impl!(u8, f32, u8Cast) +primitive_double_dispatch_cast_impl!(u8, i64, u8Cast) +primitive_double_dispatch_cast_impl!(u8, i32, u8Cast) +primitive_double_dispatch_cast_impl!(u8, i16, u8Cast) +primitive_double_dispatch_cast_impl!(u8, i8, u8Cast) +primitive_double_dispatch_cast_impl!(u8, u64, u8Cast) +primitive_double_dispatch_cast_impl!(u8, u32, u8Cast) +primitive_double_dispatch_cast_impl!(u8, u16, u8Cast) +primitive_double_dispatch_cast_impl!(u8, u8, u8Cast) +primitive_double_dispatch_cast_impl!(u8, int, u8Cast) +primitive_double_dispatch_cast_impl!(u8, uint, u8Cast) + +primitive_double_dispatch_cast_impl!(uint, f64, uintCast) +primitive_double_dispatch_cast_impl!(uint, f32, uintCast) +primitive_double_dispatch_cast_impl!(uint, i64, uintCast) +primitive_double_dispatch_cast_impl!(uint, i32, uintCast) +primitive_double_dispatch_cast_impl!(uint, i16, uintCast) +primitive_double_dispatch_cast_impl!(uint, i8, uintCast) +primitive_double_dispatch_cast_impl!(uint, u64, uintCast) +primitive_double_dispatch_cast_impl!(uint, u32, uintCast) +primitive_double_dispatch_cast_impl!(uint, u16, uintCast) +primitive_double_dispatch_cast_impl!(uint, u8, uintCast) +primitive_double_dispatch_cast_impl!(uint, int, uintCast) +primitive_double_dispatch_cast_impl!(uint, uint, uintCast) + +primitive_double_dispatch_cast_impl!(int, f64, intCast) +primitive_double_dispatch_cast_impl!(int, f32, intCast) +primitive_double_dispatch_cast_impl!(int, i64, intCast) +primitive_double_dispatch_cast_impl!(int, i32, intCast) +primitive_double_dispatch_cast_impl!(int, i16, intCast) +primitive_double_dispatch_cast_impl!(int, i8, intCast) +primitive_double_dispatch_cast_impl!(int, u64, intCast) +primitive_double_dispatch_cast_impl!(int, u32, intCast) +primitive_double_dispatch_cast_impl!(int, u16, intCast) +primitive_double_dispatch_cast_impl!(int, u8, intCast) +primitive_double_dispatch_cast_impl!(int, int, intCast) +primitive_double_dispatch_cast_impl!(int, uint, intCast) diff --git a/src/structs/spec/vec.rs b/src/structs/spec/vec.rs index dff4d43b..61bef91f 100644 --- a/src/structs/spec/vec.rs +++ b/src/structs/spec/vec.rs @@ -1,5 +1,5 @@ use std::num::{Zero, One}; -use traits::structure::{VecCast, Row, Basis}; +use traits::structure::{Cast, Row, Basis}; use traits::geometry::{Norm, Cross, CrossMatrix, UniformSphereSample}; use structs::vec::{Vec1, Vec2, Vec3, Vec4}; use structs::mat::Mat3; @@ -115,7 +115,7 @@ impl Basis for Vec3 { } // FIXME: this bad: this fixes definitly the number of samplesā€¦ -static SAMPLES_2_F64: [Vec2, ..21] = [ +static SAMPLES_2_F32: [Vec2, ..21] = [ Vec2 { x: 1.0, y: 0.0 }, Vec2 { x: 0.95557281, y: 0.29475517 }, Vec2 { x: 0.82623877, y: 0.56332006 }, @@ -140,7 +140,7 @@ static SAMPLES_2_F64: [Vec2, ..21] = [ ]; // Those vectors come from bullet 3d -static SAMPLES_3_F64: [Vec3, ..42] = [ +static SAMPLES_3_F32: [Vec3, ..42] = [ Vec3 { x: 0.000000 , y: -0.000000, z: -1.000000 }, Vec3 { x: 0.723608 , y: -0.525725, z: -0.447219 }, Vec3 { x: -0.276388, y: -0.850649, z: -0.447219 }, @@ -192,30 +192,30 @@ impl UniformSphereSample for Vec1 { } } -impl UniformSphereSample for Vec2 { +impl + Clone> UniformSphereSample for Vec2 { #[inline(always)] fn sample(f: &fn(Vec2)) { - for sample in SAMPLES_2_F64.iter() { - f(VecCast::from(*sample)) + for sample in SAMPLES_2_F32.iter() { + f(Cast::from(*sample)) } } } -impl UniformSphereSample for Vec3 { +impl + Clone> UniformSphereSample for Vec3 { #[inline(always)] fn sample(f: &fn(Vec3)) { - for sample in SAMPLES_3_F64.iter() { - f(VecCast::from(*sample)) + for sample in SAMPLES_3_F32.iter() { + f(Cast::from(*sample)) } } } -impl UniformSphereSample for Vec4 { +impl + Clone> UniformSphereSample for Vec4 { #[inline(always)] fn sample(_: &fn(Vec4)) { fail!("UniformSphereSample::>::sample : Not yet implemented.") - // for sample in SAMPLES_3_F64.iter() { - // f(VecCast::from(*sample)) + // for sample in SAMPLES_3_F32.iter() { + // f(Cast::from(*sample)) // } } } diff --git a/src/structs/vec.rs b/src/structs/vec.rs index 825da00e..d78e4868 100644 --- a/src/structs/vec.rs +++ b/src/structs/vec.rs @@ -11,7 +11,7 @@ use std::cmp::ApproxEq; use traits::geometry::{Transform, Rotate, FromHomogeneous, ToHomogeneous, Dot, Norm, Translation, Translate}; -use traits::structure::{VecCast, Basis, Dim, Indexable, Iterable, IterableMut}; +use traits::structure::{Basis, Cast, Dim, Indexable, Iterable, IterableMut}; mod metal; mod vec_macros; @@ -31,15 +31,17 @@ double_dispatch_binop_decl_trait!(Vec1, Vec1MulRhs) double_dispatch_binop_decl_trait!(Vec1, Vec1DivRhs) double_dispatch_binop_decl_trait!(Vec1, Vec1AddRhs) double_dispatch_binop_decl_trait!(Vec1, Vec1SubRhs) +double_dispatch_cast_decl_trait!(Vec1, Vec1Cast) mul_redispatch_impl!(Vec1, Vec1MulRhs) div_redispatch_impl!(Vec1, Vec1DivRhs) add_redispatch_impl!(Vec1, Vec1AddRhs) sub_redispatch_impl!(Vec1, Vec1SubRhs) +cast_redispatch_impl!(Vec1, Vec1Cast) new_impl!(Vec1, x) ord_impl!(Vec1, x) orderable_impl!(Vec1, x) vec_axis_impl!(Vec1, x) -vec_cast_impl!(Vec1, x) +vec_cast_impl!(Vec1, Vec1Cast, x) indexable_impl!(Vec1, 1) at_fast_impl!(Vec1, 1) new_repeat_impl!(Vec1, val, x) @@ -128,15 +130,17 @@ double_dispatch_binop_decl_trait!(Vec2, Vec2MulRhs) double_dispatch_binop_decl_trait!(Vec2, Vec2DivRhs) double_dispatch_binop_decl_trait!(Vec2, Vec2AddRhs) double_dispatch_binop_decl_trait!(Vec2, Vec2SubRhs) +double_dispatch_cast_decl_trait!(Vec2, Vec2Cast) mul_redispatch_impl!(Vec2, Vec2MulRhs) div_redispatch_impl!(Vec2, Vec2DivRhs) add_redispatch_impl!(Vec2, Vec2AddRhs) sub_redispatch_impl!(Vec2, Vec2SubRhs) +cast_redispatch_impl!(Vec2, Vec2Cast) new_impl!(Vec2, x, y) ord_impl!(Vec2, x, y) orderable_impl!(Vec2, x, y) vec_axis_impl!(Vec2, x, y) -vec_cast_impl!(Vec2, x, y) +vec_cast_impl!(Vec2, Vec2Cast, x, y) indexable_impl!(Vec2, 2) at_fast_impl!(Vec2, 2) new_repeat_impl!(Vec2, val, x, y) @@ -227,15 +231,17 @@ double_dispatch_binop_decl_trait!(Vec3, Vec3MulRhs) double_dispatch_binop_decl_trait!(Vec3, Vec3DivRhs) double_dispatch_binop_decl_trait!(Vec3, Vec3AddRhs) double_dispatch_binop_decl_trait!(Vec3, Vec3SubRhs) +double_dispatch_cast_decl_trait!(Vec3, Vec3Cast) mul_redispatch_impl!(Vec3, Vec3MulRhs) div_redispatch_impl!(Vec3, Vec3DivRhs) add_redispatch_impl!(Vec3, Vec3AddRhs) sub_redispatch_impl!(Vec3, Vec3SubRhs) +cast_redispatch_impl!(Vec3, Vec3Cast) new_impl!(Vec3, x, y, z) ord_impl!(Vec3, x, y, z) orderable_impl!(Vec3, x, y, z) vec_axis_impl!(Vec3, x, y, z) -vec_cast_impl!(Vec3, x, y, z) +vec_cast_impl!(Vec3, Vec3Cast, x, y, z) indexable_impl!(Vec3, 3) at_fast_impl!(Vec3, 3) new_repeat_impl!(Vec3, val, x, y, z) @@ -339,14 +345,16 @@ double_dispatch_binop_decl_trait!(PVec3, PVec3MulRhs) double_dispatch_binop_decl_trait!(PVec3, PVec3DivRhs) double_dispatch_binop_decl_trait!(PVec3, PVec3AddRhs) double_dispatch_binop_decl_trait!(PVec3, PVec3SubRhs) +double_dispatch_cast_decl_trait!(PVec3, PVec3Cast) mul_redispatch_impl!(PVec3, PVec3MulRhs) div_redispatch_impl!(PVec3, PVec3DivRhs) add_redispatch_impl!(PVec3, PVec3AddRhs) sub_redispatch_impl!(PVec3, PVec3SubRhs) +cast_redispatch_impl!(PVec3, PVec3Cast) ord_impl!(PVec3, x, y, z) orderable_impl!(PVec3, x, y, z) vec_axis_impl!(PVec3, x, y, z) -vec_cast_impl!(PVec3, x, y, z) +vec_cast_impl!(PVec3, PVec3Cast, x, y, z) indexable_impl!(PVec3, 3) at_fast_impl!(PVec3, 3) new_repeat_impl!(PVec3, val, x, y, z, _unused) @@ -441,15 +449,17 @@ double_dispatch_binop_decl_trait!(Vec4, Vec4MulRhs) double_dispatch_binop_decl_trait!(Vec4, Vec4DivRhs) double_dispatch_binop_decl_trait!(Vec4, Vec4AddRhs) double_dispatch_binop_decl_trait!(Vec4, Vec4SubRhs) +double_dispatch_cast_decl_trait!(Vec4, Vec4Cast) mul_redispatch_impl!(Vec4, Vec4MulRhs) div_redispatch_impl!(Vec4, Vec4DivRhs) add_redispatch_impl!(Vec4, Vec4AddRhs) sub_redispatch_impl!(Vec4, Vec4SubRhs) +cast_redispatch_impl!(Vec4, Vec4Cast) new_impl!(Vec4, x, y, z, w) ord_impl!(Vec4, x, y, z, w) orderable_impl!(Vec4, x, y, z, w) vec_axis_impl!(Vec4, x, y, z, w) -vec_cast_impl!(Vec4, x, y, z, w) +vec_cast_impl!(Vec4, Vec4Cast, x, y, z, w) indexable_impl!(Vec4, 4) at_fast_impl!(Vec4, 4) new_repeat_impl!(Vec4, val, x, y, z, w) @@ -544,15 +554,17 @@ double_dispatch_binop_decl_trait!(Vec5, Vec5MulRhs) double_dispatch_binop_decl_trait!(Vec5, Vec5DivRhs) double_dispatch_binop_decl_trait!(Vec5, Vec5AddRhs) double_dispatch_binop_decl_trait!(Vec5, Vec5SubRhs) +double_dispatch_cast_decl_trait!(Vec5, Vec5Cast) mul_redispatch_impl!(Vec5, Vec5MulRhs) div_redispatch_impl!(Vec5, Vec5DivRhs) add_redispatch_impl!(Vec5, Vec5AddRhs) sub_redispatch_impl!(Vec5, Vec5SubRhs) +cast_redispatch_impl!(Vec5, Vec5Cast) new_impl!(Vec5, x, y, z, w, a) ord_impl!(Vec5, x, y, z, w, a) orderable_impl!(Vec5, x, y, z, w, a) vec_axis_impl!(Vec5, x, y, z, w, a) -vec_cast_impl!(Vec5, x, y, z, w, a) +vec_cast_impl!(Vec5, Vec5Cast, x, y, z, w, a) indexable_impl!(Vec5, 5) at_fast_impl!(Vec5, 5) new_repeat_impl!(Vec5, val, x, y, z, w, a) @@ -649,15 +661,17 @@ double_dispatch_binop_decl_trait!(Vec6, Vec6MulRhs) double_dispatch_binop_decl_trait!(Vec6, Vec6DivRhs) double_dispatch_binop_decl_trait!(Vec6, Vec6AddRhs) double_dispatch_binop_decl_trait!(Vec6, Vec6SubRhs) +double_dispatch_cast_decl_trait!(Vec6, Vec6Cast) mul_redispatch_impl!(Vec6, Vec6MulRhs) div_redispatch_impl!(Vec6, Vec6DivRhs) add_redispatch_impl!(Vec6, Vec6AddRhs) sub_redispatch_impl!(Vec6, Vec6SubRhs) +cast_redispatch_impl!(Vec6, Vec6Cast) new_impl!(Vec6, x, y, z, w, a, b) ord_impl!(Vec6, x, y, z, w, a, b) orderable_impl!(Vec6, x, y, z, w, a, b) vec_axis_impl!(Vec6, x, y, z, w, a, b) -vec_cast_impl!(Vec6, x, y, z, w, a, b) +vec_cast_impl!(Vec6, Vec6Cast, x, y, z, w, a, b) indexable_impl!(Vec6, 6) at_fast_impl!(Vec6, 6) new_repeat_impl!(Vec6, val, x, y, z, w, a, b) diff --git a/src/structs/vec_macros.rs b/src/structs/vec_macros.rs index 357e48c0..1e402352 100644 --- a/src/structs/vec_macros.rs +++ b/src/structs/vec_macros.rs @@ -111,11 +111,11 @@ macro_rules! vec_axis_impl( ) macro_rules! vec_cast_impl( - ($t: ident, $comp0: ident $(,$compN: ident)*) => ( - impl VecCast<$t> for $t { + ($t: ident, $tcast: ident, $comp0: ident $(,$compN: ident)*) => ( + impl> $tcast for $t { #[inline] - fn from(v: $t) -> $t { - $t::new(NumCast::from(v.$comp0.clone()).unwrap() $(, NumCast::from(v.$compN.clone()).unwrap())*) + fn to(v: $t) -> $t { + $t::new(Cast::from(v.$comp0.clone()) $(, Cast::from(v.$compN.clone()))*) } } ) diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 99de789f..b41c4fa5 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -4,8 +4,8 @@ pub use self::geometry::{AbsoluteRotate, Cross, CrossMatrix, Dot, FromHomogeneou Rotation, RotationMatrix, RotationWithTranslation, ToHomogeneous, Transform, Transformation, Translate, Translation, UniformSphereSample}; -pub use self::structure::{AlgebraicVec, AlgebraicVecExt, Basis, Col, Dim, Indexable, Iterable, - IterableMut, Mat, MatCast, Row, Vec, VecCast, VecExt}; +pub use self::structure::{AlgebraicVec, AlgebraicVecExt, Basis, Cast, Col, Dim, Indexable, + Iterable, IterableMut, Mat, Row, Vec, VecExt}; pub use self::operations::{Absolute, Cov, Inv, LMul, Mean, Outer, RMul, ScalarAdd, ScalarSub, Transpose}; diff --git a/src/traits/structure.rs b/src/traits/structure.rs index eb5fe118..87bae128 100644 --- a/src/traits/structure.rs +++ b/src/traits/structure.rs @@ -5,6 +5,12 @@ use std::vec::{VecIterator, VecMutIterator}; use traits::operations::{RMul, LMul, ScalarAdd, ScalarSub}; use traits::geometry::{Dot, Norm, UniformSphereSample}; +/// Traits of objects which can be created from an object of type `T`. +pub trait Cast { + /// Converts an element of type `T` to an element of type `Self`. + fn from(t: T) -> Self; +} + /// Trait of matrices. /// /// A matrix has rows and columns and are able to multiply them. @@ -13,14 +19,6 @@ pub trait Mat : Row + Col + RMul + LMul { } impl + Col + RMul + LMul, R, C> Mat for M { } -/// Trait of matrices which can be converted to another matrix. -/// -/// Use this to change easily the type of a matrix components. -pub trait MatCast { - /// Converts `m` to have the type `M`. - fn from(m: Self) -> M; -} - // XXX: we keep ScalarAdd and ScalarSub here to avoid trait impl conflict (overriding) between the // different Add/Sub traits. This is _so_ unfortunateā€¦ @@ -55,13 +53,6 @@ VecExt for V { } impl + VecExt + Basis + Round> AlgebraicVecExt for V { } -/// Trait of vectors which can be converted to another vector. Used to change the type of a vector -/// components. -pub trait VecCast { - /// Converts `v` to have the type `V`. - fn from(v: Self) -> V; -} - // FIXME: return an iterator instead /// Traits of objects which can form a basis (typically vectors). pub trait Basis {