diff --git a/src/cgmath/vector.rs b/src/cgmath/vector.rs index e482b7c..a4cddd9 100644 --- a/src/cgmath/vector.rs +++ b/src/cgmath/vector.rs @@ -35,10 +35,6 @@ pub trait ToVec2 { fn to_vec2(&self) -> Vec2; } pub trait ToVec3 { fn to_vec3(&self) -> Vec3; } pub trait ToVec4 { fn to_vec4(&self) -> Vec4; } -approx_eq!(impl Vec2) -approx_eq!(impl Vec3) -approx_eq!(impl Vec4) - // Utility macro for generating associated functions for the vectors macro_rules! vec( (impl $Self:ident <$S:ident> { $($field:ident),+ }) => ( @@ -51,7 +47,7 @@ macro_rules! vec( /// Construct a vector from a single value. #[inline] pub fn from_value(value: $S) -> $Self<$S> { - Array::build(|_| value.clone()) + $Self { $($field: value.clone()),+ } } /// The additive identity of the vector. @@ -73,9 +69,9 @@ array!(impl Vec2 -> [S, ..2]) array!(impl Vec3 -> [S, ..3]) array!(impl Vec4 -> [S, ..4]) -impl One for Vec2 { #[inline] fn one() -> Vec2 { Vec2::ident() } } -impl One for Vec3 { #[inline] fn one() -> Vec3 { Vec3::ident() } } -impl One for Vec4 { #[inline] fn one() -> Vec4 { Vec4::ident() } } +approx_eq!(impl Vec2) +approx_eq!(impl Vec3) +approx_eq!(impl Vec4) /// A trait that specifies a range of numeric operations for vectors. Not all /// of these make sense from a linear algebra point of view, but are included @@ -89,45 +85,41 @@ pub trait Vector + Neg + Zero + One { - // TODO: These method impls use iterators and higher order functions to - // provide generic impls for vector types of different dimensions. We - // need to check llvm's output to see how well it optimses these. + #[inline] fn add_s(&self, s: S) -> Self; + #[inline] fn sub_s(&self, s: S) -> Self; + #[inline] fn mul_s(&self, s: S) -> Self; + #[inline] fn div_s(&self, s: S) -> Self; + #[inline] fn rem_s(&self, s: S) -> Self; - #[inline] fn add_s(&self, s: S) -> Self { self.map(|x| x.add(&s)) } - #[inline] fn sub_s(&self, s: S) -> Self { self.map(|x| x.sub(&s)) } - #[inline] fn mul_s(&self, s: S) -> Self { self.map(|x| x.mul(&s)) } - #[inline] fn div_s(&self, s: S) -> Self { self.map(|x| x.div(&s)) } - #[inline] fn rem_s(&self, s: S) -> Self { self.map(|x| x.rem(&s)) } + #[inline] fn add_v(&self, other: &Self) -> Self; + #[inline] fn sub_v(&self, other: &Self) -> Self; + #[inline] fn mul_v(&self, other: &Self) -> Self; + #[inline] fn div_v(&self, other: &Self) -> Self; + #[inline] fn rem_v(&self, other: &Self) -> Self; - #[inline] fn add_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.add(b) ) } - #[inline] fn sub_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.sub(b) ) } - #[inline] fn mul_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.mul(b) ) } - #[inline] fn div_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.div(b) ) } - #[inline] fn rem_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.rem(b) ) } + #[inline] fn neg_self(&mut self); - #[inline] fn neg_self(&mut self) { for x in self.mut_iter() { *x = x.neg() } } + #[inline] fn add_self_s(&mut self, s: S); + #[inline] fn sub_self_s(&mut self, s: S); + #[inline] fn mul_self_s(&mut self, s: S); + #[inline] fn div_self_s(&mut self, s: S); + #[inline] fn rem_self_s(&mut self, s: S); - #[inline] fn add_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.add(&s) } } - #[inline] fn sub_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.sub(&s) } } - #[inline] fn mul_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.mul(&s) } } - #[inline] fn div_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.div(&s) } } - #[inline] fn rem_self_s(&mut self, s: S) { for x in self.mut_iter() { *x = x.rem(&s) } } + #[inline] fn add_self_v(&mut self, other: &Self); + #[inline] fn sub_self_v(&mut self, other: &Self); + #[inline] fn mul_self_v(&mut self, other: &Self); + #[inline] fn div_self_v(&mut self, other: &Self); + #[inline] fn rem_self_v(&mut self, other: &Self); - #[inline] fn add_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.add(b) } } - #[inline] fn sub_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.sub(b) } } - #[inline] fn mul_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.mul(b) } } - #[inline] fn div_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.div(b) } } - #[inline] fn rem_self_v(&mut self, other: &Self) { for (a, b) in self.mut_iter().zip(other.iter()) { *a = a.rem(b) } } + /// The sum of each component of the vector. + #[inline] fn comp_add(&self) -> S; + + /// The product of each component of the vector. + #[inline] fn comp_mul(&self) -> S; /// Vector dot product. #[inline] fn dot(&self, other: &Self) -> S { self.mul_v(other).comp_add() } - /// The sum of each component of the vector. - #[inline] fn comp_add(&self) -> S { self.iter().fold(zero::(), |a, b| a.add(b)) } - - /// The product of each component of the vector. - #[inline] fn comp_mul(&self) -> S { self.iter().fold(one::(), |a, b| a.mul(b)) } - /// The minimum component of the vector. #[inline] fn comp_min(&self) -> S { self.iter().min().unwrap().clone() } @@ -135,6 +127,10 @@ pub trait Vector #[inline] fn comp_max(&self) -> S { self.iter().max().unwrap().clone() } } +impl One for Vec2 { #[inline] fn one() -> Vec2 { Vec2::ident() } } +impl One for Vec3 { #[inline] fn one() -> Vec3 { Vec3::ident() } } +impl One for Vec4 { #[inline] fn one() -> Vec4 { Vec4::ident() } } + impl Neg> for Vec2 { #[inline] fn neg(&self) -> Vec2 { Vec2::new(-self.x, -self.y) } } impl Neg> for Vec3 { #[inline] fn neg(&self) -> Vec3 { Vec3::new(-self.x, -self.y, -self.z) } } impl Neg> for Vec4 { #[inline] fn neg(&self) -> Vec4 { Vec4::new(-self.x, -self.y, -self.z, -self.w) } } @@ -142,10 +138,6 @@ impl Neg> for Vec4 { #[inline] fn neg(&self) -> macro_rules! vector( (impl $Self:ident <$S:ident> $Slice:ty { $x:ident, $($xs:ident),+ }) => ( impl<$S: Clone + Num + Ord> Vector<$S, $Slice> for $Self<$S> { - // TODO: These method impls use iterators and higher order functions to - // provide generic impls for vector types of different dimensions. We - // need to check llvm's output to see how well it optimses these. - #[inline] fn add_s(&self, s: S) -> $Self<$S> { $Self::new(self.$x.add(&s), $(self.$xs.add(&s)),+) } #[inline] fn sub_s(&self, s: S) -> $Self<$S> { $Self::new(self.$x.sub(&s), $(self.$xs.sub(&s)),+) } #[inline] fn mul_s(&self, s: S) -> $Self<$S> { $Self::new(self.$x.mul(&s), $(self.$xs.mul(&s)),+) }