Condense vector impls further using macros

This commit is contained in:
Brendan Zabarauskas 2013-08-27 16:52:33 +10:00
parent 9064b9d5c0
commit 026a5e89b5
4 changed files with 34 additions and 74 deletions

View file

@ -61,8 +61,8 @@ pub trait Indexable<T, Slice> {
} }
macro_rules! impl_indexable( macro_rules! impl_indexable(
($Self:ty, [$T:ty, ..$n:expr]) => ( ($Self:ty, $S:ident, [$T:ty, ..$n:expr]) => (
impl<T> Indexable<$T, [$T,..$n]> for $Self { impl<$S> Indexable<$T, [$T,..$n]> for $Self {
#[inline] #[inline]
fn len(&self) -> uint { $n } fn len(&self) -> uint { $n }

View file

@ -75,9 +75,9 @@ impl<S: Field> Mat4<S> {
// Trait impls // Trait impls
impl_indexable!(Mat2<T>, [Vec2<T>, ..2]) impl_indexable!(Mat2<S>, S, [Vec2<S>, ..2])
impl_indexable!(Mat3<T>, [Vec3<T>, ..3]) impl_indexable!(Mat3<S>, S, [Vec3<S>, ..3])
impl_indexable!(Mat4<T>, [Vec4<T>, ..4]) impl_indexable!(Mat4<S>, S, [Vec4<S>, ..4])
impl<S: Clone + Field> Swappable<Vec2<S>, [Vec2<S>, ..2]> for Mat2<S>; impl<S: Clone + Field> Swappable<Vec2<S>, [Vec2<S>, ..2]> for Mat2<S>;
impl<S: Clone + Field> Swappable<Vec3<S>, [Vec3<S>, ..3]> for Mat3<S>; impl<S: Clone + Field> Swappable<Vec3<S>, [Vec3<S>, ..3]> for Mat3<S>;

View file

@ -60,8 +60,8 @@ impl<S: Field> Sub<Point3<S>, Vec3<S>> for Point3<S> { #[inline(always)] fn sub(
// Trait impls // Trait impls
impl_indexable!(Point2<T>, [T, ..2]) impl_indexable!(Point2<S>, S, [S, ..2])
impl_indexable!(Point3<T>, [T, ..3]) impl_indexable!(Point3<S>, S, [S, ..3])
impl<S: Clone + Field> Swappable<S, [S, ..2]> for Point2<S>; impl<S: Clone + Field> Swappable<S, [S, ..2]> for Point2<S>;
impl<S: Clone + Field> Swappable<S, [S, ..3]> for Point3<S>; impl<S: Clone + Field> Swappable<S, [S, ..3]> for Point3<S>;

View file

@ -18,7 +18,6 @@ use std::num::{Zero, zero};
use std::num::{sqrt, atan2}; use std::num::{sqrt, atan2};
use traits::alg::*; use traits::alg::*;
use traits::ext::*;
use traits::util::*; use traits::util::*;
#[deriving(Eq, Zero, Clone)] pub struct Vec1<S> { x: S } #[deriving(Eq, Zero, Clone)] pub struct Vec1<S> { x: S }
@ -71,28 +70,40 @@ impl_vec_clonable!(Vec6<S>)
// Operator impls // Operator impls
macro_rules! impl_vec_ops( macro_rules! impl_vec_common(
($vec_ops_mod:ident, $Self:ident <$S:ident>) => ( ($vec_ops_mod:ident, $Self:ty, [$S:ident, ..$n:expr]) => (
pub mod $vec_ops_mod { pub mod $vec_ops_mod {
use super::*; use super::*;
use super::super::super::traits::alg::*; use traits::alg::*;
use traits::ext::*;
use traits::util::*;
impl_scalar_binop!($Self<$S>, Mul, mul) impl_indexable!($Self, $S, [$S, ..$n])
impl_scalar_binop!($Self<$S>, Div, div) impl<$S: Clone + Field> Swappable<$S, [$S, ..$n]> for $Self;
impl_scalar_binop!($Self<$S>, Rem, rem) impl<$S: Clone + Field> Coordinate<$S, [$S, ..$n]> for $Self;
impl_coordinate_binop!($Self<$S>, $Self<$S>, $Self<$S>, Add, add)
impl_coordinate_binop!($Self<$S>, $Self<$S>, $Self<$S>, Sub, sub) impl_scalar_binop!($Self, Mul, mul)
impl_coordinate_op!($Self<$S>, $Self<$S>, Neg, neg) impl_scalar_binop!($Self, Div, div)
impl_scalar_binop!($Self, Rem, rem)
impl_coordinate_binop!($Self, $Self, $Self, Add, add)
impl_coordinate_binop!($Self, $Self, $Self, Sub, sub)
impl_coordinate_op!($Self, $Self, Neg, neg)
impl<$S: Field> ScalarMul<$S> for $Self;
impl<$S: Field> Module<$S> for $Self;
impl<$S: Field> VectorSpace<$S> for $Self;
impl<$S: Clone + Field> VectorExt<$S, [$S, ..$n]> for $Self;
} }
) )
) )
impl_vec_ops!(vec1_ops, Vec1<S>) impl_vec_common!(vec1_ops, Vec1<S>, [S, ..1])
impl_vec_ops!(vec2_ops, Vec2<S>) impl_vec_common!(vec2_ops, Vec2<S>, [S, ..2])
impl_vec_ops!(vec3_ops, Vec3<S>) impl_vec_common!(vec3_ops, Vec3<S>, [S, ..3])
impl_vec_ops!(vec4_ops, Vec4<S>) impl_vec_common!(vec4_ops, Vec4<S>, [S, ..4])
impl_vec_ops!(vec5_ops, Vec5<S>) impl_vec_common!(vec5_ops, Vec5<S>, [S, ..5])
impl_vec_ops!(vec6_ops, Vec6<S>) impl_vec_common!(vec6_ops, Vec6<S>, [S, ..6])
/// Operations specific to two-dimensional vectors. /// Operations specific to two-dimensional vectors.
impl<S: Field> Vec2<S> { impl<S: Field> Vec2<S> {
@ -112,50 +123,6 @@ impl<S: Field> Vec3<S> {
} }
} }
// Trait impls
impl_indexable!(Vec1<T>, [T, ..1])
impl_indexable!(Vec2<T>, [T, ..2])
impl_indexable!(Vec3<T>, [T, ..3])
impl_indexable!(Vec4<T>, [T, ..4])
impl_indexable!(Vec5<T>, [T, ..5])
impl_indexable!(Vec6<T>, [T, ..6])
impl<S: Clone + Field> Swappable<S, [S, ..1]> for Vec1<S>;
impl<S: Clone + Field> Swappable<S, [S, ..2]> for Vec2<S>;
impl<S: Clone + Field> Swappable<S, [S, ..3]> for Vec3<S>;
impl<S: Clone + Field> Swappable<S, [S, ..4]> for Vec4<S>;
impl<S: Clone + Field> Swappable<S, [S, ..5]> for Vec5<S>;
impl<S: Clone + Field> Swappable<S, [S, ..6]> for Vec6<S>;
impl<S: Clone + Field> Coordinate<S, [S, ..1]> for Vec1<S>;
impl<S: Clone + Field> Coordinate<S, [S, ..2]> for Vec2<S>;
impl<S: Clone + Field> Coordinate<S, [S, ..3]> for Vec3<S>;
impl<S: Clone + Field> Coordinate<S, [S, ..4]> for Vec4<S>;
impl<S: Clone + Field> Coordinate<S, [S, ..5]> for Vec5<S>;
impl<S: Clone + Field> Coordinate<S, [S, ..6]> for Vec6<S>;
impl<S: Field> ScalarMul<S> for Vec1<S>;
impl<S: Field> ScalarMul<S> for Vec2<S>;
impl<S: Field> ScalarMul<S> for Vec3<S>;
impl<S: Field> ScalarMul<S> for Vec4<S>;
impl<S: Field> ScalarMul<S> for Vec5<S>;
impl<S: Field> ScalarMul<S> for Vec6<S>;
impl<S: Field> Module<S> for Vec1<S>;
impl<S: Field> Module<S> for Vec2<S>;
impl<S: Field> Module<S> for Vec3<S>;
impl<S: Field> Module<S> for Vec4<S>;
impl<S: Field> Module<S> for Vec5<S>;
impl<S: Field> Module<S> for Vec6<S>;
impl<S: Field> VectorSpace<S> for Vec1<S>;
impl<S: Field> VectorSpace<S> for Vec2<S>;
impl<S: Field> VectorSpace<S> for Vec3<S>;
impl<S: Field> VectorSpace<S> for Vec4<S>;
impl<S: Field> VectorSpace<S> for Vec5<S>;
impl<S: Field> VectorSpace<S> for Vec6<S>;
macro_rules! impl_vec_inner_product( macro_rules! impl_vec_inner_product(
($Self:ident <$S:ident>) => ( ($Self:ident <$S:ident>) => (
impl<$S:Real + Field + ApproxEq<$S>> InnerProductSpace<$S> for $Self<$S> { impl<$S:Real + Field + ApproxEq<$S>> InnerProductSpace<$S> for $Self<$S> {
@ -195,10 +162,3 @@ impl<S:Real + Field + ApproxEq<S>> EuclideanSpace<S> for Vec3<S> {
atan2(self.cross(other).length(), self.dot(other)) atan2(self.cross(other).length(), self.dot(other))
} }
} }
impl<S: Clone + Field> VectorExt<S, [S, ..1]> for Vec1<S>;
impl<S: Clone + Field> VectorExt<S, [S, ..2]> for Vec2<S>;
impl<S: Clone + Field> VectorExt<S, [S, ..3]> for Vec3<S>;
impl<S: Clone + Field> VectorExt<S, [S, ..4]> for Vec4<S>;
impl<S: Clone + Field> VectorExt<S, [S, ..5]> for Vec5<S>;
impl<S: Clone + Field> VectorExt<S, [S, ..6]> for Vec6<S>;