Set up the hack to allow better overloads of the Mul trait.

This is strongly inpired by
http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/
This commit is contained in:
Sébastien Crozet 2013-09-14 17:08:48 +02:00
parent 06c7293e83
commit e3a1d56e58
2 changed files with 40 additions and 9 deletions

View File

@ -54,6 +54,7 @@ pub struct Mat1<N> {
m11: N m11: N
} }
double_dispatch_binop_decl_trait!(Mat1, Mat1MulRhs)
mat_impl!(Mat1, m11) mat_impl!(Mat1, m11)
mat_cast_impl!(Mat1, m11) mat_cast_impl!(Mat1, m11)
add_impl!(Mat1, m11) add_impl!(Mat1, m11)
@ -69,7 +70,8 @@ iterable_mut_impl!(Mat1, 1)
at_fast_impl!(Mat1, 1) at_fast_impl!(Mat1, 1)
dim_impl!(Mat1, 1) dim_impl!(Mat1, 1)
indexable_impl!(Mat1, 1) indexable_impl!(Mat1, 1)
mul_impl!(Mat1, 1) mul_redispatch_impl!(Mat1, Mat1MulRhs)
mat_mul_mat_impl!(Mat1, Mat1MulRhs, 1)
rmul_impl!(Mat1, Vec1, 1) rmul_impl!(Mat1, Vec1, 1)
lmul_impl!(Mat1, Vec1, 1) lmul_impl!(Mat1, Vec1, 1)
transform_impl!(Mat1, Vec1) transform_impl!(Mat1, Vec1)
@ -195,6 +197,7 @@ pub struct Mat4<N> {
m41: N, m42: N, m43: N, m44: N m41: N, m42: N, m43: N, m44: N
} }
double_dispatch_binop_decl_trait!(Mat4, Mat4MulRhs)
mat_impl!(Mat4, mat_impl!(Mat4,
m11, m12, m13, m14, m11, m12, m13, m14,
m21, m22, m23, m24, m21, m22, m23, m24,
@ -258,7 +261,8 @@ iterable_mut_impl!(Mat4, 4)
dim_impl!(Mat4, 4) dim_impl!(Mat4, 4)
indexable_impl!(Mat4, 4) indexable_impl!(Mat4, 4)
at_fast_impl!(Mat4, 4) at_fast_impl!(Mat4, 4)
mul_impl!(Mat4, 4) mul_redispatch_impl!(Mat4, Mat4MulRhs)
mat_mul_mat_impl!(Mat4, Mat4MulRhs, 4)
rmul_impl!(Mat4, Vec4, 4) rmul_impl!(Mat4, Vec4, 4)
lmul_impl!(Mat4, Vec4, 4) lmul_impl!(Mat4, Vec4, 4)
transform_impl!(Mat4, Vec4) transform_impl!(Mat4, Vec4)
@ -282,6 +286,7 @@ pub struct Mat5<N> {
m51: N, m52: N, m53: N, m54: N, m55: N m51: N, m52: N, m53: N, m54: N, m55: N
} }
double_dispatch_binop_decl_trait!(Mat5, Mat5MulRhs)
mat_impl!(Mat5, mat_impl!(Mat5,
m11, m12, m13, m14, m15, m11, m12, m13, m14, m15,
m21, m22, m23, m24, m25, m21, m22, m23, m24, m25,
@ -357,7 +362,8 @@ iterable_mut_impl!(Mat5, 5)
dim_impl!(Mat5, 5) dim_impl!(Mat5, 5)
indexable_impl!(Mat5, 5) indexable_impl!(Mat5, 5)
at_fast_impl!(Mat5, 5) at_fast_impl!(Mat5, 5)
mul_impl!(Mat5, 5) mul_redispatch_impl!(Mat5, Mat5MulRhs)
mat_mul_mat_impl!(Mat5, Mat5MulRhs, 5)
rmul_impl!(Mat5, Vec5, 5) rmul_impl!(Mat5, Vec5, 5)
lmul_impl!(Mat5, Vec5, 5) lmul_impl!(Mat5, Vec5, 5)
transform_impl!(Mat5, Vec5) transform_impl!(Mat5, Vec5)
@ -382,6 +388,7 @@ pub struct Mat6<N> {
m61: N, m62: N, m63: N, m64: N, m65: N, m66: N m61: N, m62: N, m63: N, m64: N, m65: N, m66: N
} }
double_dispatch_binop_decl_trait!(Mat6, Mat6MulRhs)
mat_impl!(Mat6, mat_impl!(Mat6,
m11, m12, m13, m14, m15, m16, m11, m12, m13, m14, m15, m16,
m21, m22, m23, m24, m25, m26, m21, m22, m23, m24, m25, m26,
@ -467,7 +474,8 @@ iterable_mut_impl!(Mat6, 6)
dim_impl!(Mat6, 6) dim_impl!(Mat6, 6)
indexable_impl!(Mat6, 6) indexable_impl!(Mat6, 6)
at_fast_impl!(Mat6, 6) at_fast_impl!(Mat6, 6)
mul_impl!(Mat6, 6) mul_redispatch_impl!(Mat6, Mat6MulRhs)
mat_mul_mat_impl!(Mat6, Mat6MulRhs, 6)
rmul_impl!(Mat6, Vec6, 6) rmul_impl!(Mat6, Vec6, 6)
lmul_impl!(Mat6, Vec6, 6) lmul_impl!(Mat6, Vec6, 6)
transform_impl!(Mat6, Vec6) transform_impl!(Mat6, Vec6)

View File

@ -292,11 +292,34 @@ macro_rules! col_impl(
) )
) )
macro_rules! mul_impl( // Create the traits needed to do fancy operator oveloading.
($t: ident, $dim: expr) => ( // This is a meta version of
impl<N: Clone + Num> Mul<$t<N>, $t<N>> for $t<N> { // http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/
macro_rules! double_dispatch_binop_decl_trait(
($t: ident, $trhs: ident) => (
pub trait $trhs<N, Res> {
fn $trhs(&self, other: &$t<N>) -> Res;
}
)
)
macro_rules! mul_redispatch_impl(
($t: ident, $trhs: ident) => (
impl<N: Clone + Num, Rhs: $trhs<N, Res>, Res> Mul<Rhs, Res> for $t<N> {
#[inline] #[inline]
fn mul(&self, other: &$t<N>) -> $t<N> { fn mul(&self, other: &Rhs) -> Res {
other.$trhs(self)
}
}
)
)
macro_rules! mat_mul_mat_impl(
($t: ident, $trhs: ident, $dim: expr) => (
impl<N: Clone + Num> $trhs<N, $t<N>> for $t<N> {
#[inline]
fn $trhs(&self, other: &$t<N>) -> $t<N> {
// careful! we need to comute other * self here (self is the rhs).
let mut res: $t<N> = Zero::zero(); let mut res: $t<N> = Zero::zero();
for i in range(0u, $dim) { for i in range(0u, $dim) {
@ -305,7 +328,7 @@ macro_rules! mul_impl(
unsafe { unsafe {
for k in range(0u, $dim) { for k in range(0u, $dim) {
acc = acc + self.at_fast((i, k)) * other.at_fast((k, j)); acc = acc + other.at_fast((i, k)) * self.at_fast((k, j));
} }
res.set_fast((i, j), acc); res.set_fast((i, j), acc);