"Remove" the RMul and LMul trait. Use the regular Mul trait.
Those traits are not really removed since they are useful on generic code (to work around curret limitations of rust traits system).
This commit is contained in:
parent
514bf74efe
commit
6dc8139794
|
@ -1,7 +1,7 @@
|
||||||
nalgebra
|
nalgebra
|
||||||
========
|
========
|
||||||
|
|
||||||
**nalgebra** is a n-dimensional linear algebra library written with the rust
|
**nalgebra** is a _n_-dimensional linear algebra library written with the rust
|
||||||
programming language.
|
programming language.
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,3 +15,10 @@ If you encounter problems, make sure you have the last version before creating a
|
||||||
git clone git://github.com/sebcrozet/nalgebra.git
|
git clone git://github.com/sebcrozet/nalgebra.git
|
||||||
cd nalgebra
|
cd nalgebra
|
||||||
make
|
make
|
||||||
|
|
||||||
|
## Design note
|
||||||
|
**nalgebra** is mostly written with non-idiomatic rust code. This is mostly because of limitations
|
||||||
|
of the trait system not allowing (easy) multiple overloading. Those overloading problems ares
|
||||||
|
worked around by this
|
||||||
|
[hack](http://smallcultfollowing.com/babysteps/blog/2012/10/04/refining-traits-slash-impls/)
|
||||||
|
(section _What if I want overloading_).
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use std::num::{One, Zero};
|
use std::num::{One, Zero};
|
||||||
use std::rand::{Rand, Rng, RngUtil};
|
use std::rand::{Rand, Rng, RngUtil};
|
||||||
use std::cmp::ApproxEq;
|
use std::cmp::ApproxEq;
|
||||||
use traits::rlmul::{RMul, LMul};
|
|
||||||
use traits::cross::Cross;
|
use traits::cross::Cross;
|
||||||
use traits::dim::Dim;
|
use traits::dim::Dim;
|
||||||
use traits::inv::Inv;
|
use traits::inv::Inv;
|
||||||
|
@ -15,9 +14,12 @@ use traits::homogeneous::ToHomogeneous;
|
||||||
use traits::indexable::Indexable;
|
use traits::indexable::Indexable;
|
||||||
use traits::norm::Norm;
|
use traits::norm::Norm;
|
||||||
use traits::comp::absolute_rotate::AbsoluteRotate;
|
use traits::comp::absolute_rotate::AbsoluteRotate;
|
||||||
use vec::{Vec1, Vec2, Vec3};
|
use vec::{Vec1, Vec2, Vec3, Vec2MulRhs, Vec3MulRhs};
|
||||||
use mat::{Mat2, Mat3};
|
use mat::{Mat2, Mat3};
|
||||||
|
|
||||||
|
#[path = "../metal.rs"]
|
||||||
|
mod metal;
|
||||||
|
|
||||||
/// Matrix wrapper representing rotation matrix. It is built uppon another matrix and ensures (at
|
/// Matrix wrapper representing rotation matrix. It is built uppon another matrix and ensures (at
|
||||||
/// the type-level) that it will always represent a rotation. Rotation matrices have some
|
/// the type-level) that it will always represent a rotation. Rotation matrices have some
|
||||||
/// properties useful for performances, like the fact that the inversion is simply a transposition.
|
/// properties useful for performances, like the fact that the inversion is simply a transposition.
|
||||||
|
@ -26,6 +28,19 @@ pub struct Rotmat<M> {
|
||||||
priv submat: M
|
priv submat: M
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait of object `o` which can be multiplied by a `Rotmat` `r`: `r * o`.
|
||||||
|
pub trait RotmatMulRhs<M, Res> {
|
||||||
|
/// Multiplies a rotation matrix by `Self`.
|
||||||
|
fn binop(left: &Rotmat<M>, right: &Self) -> Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M, Rhs: RotmatMulRhs<M, Res>, Res> Mul<Rhs, Res> for Rotmat<M> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn mul(&self, other: &Rhs) -> Res {
|
||||||
|
RotmatMulRhs::binop(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<M: Clone> Rotmat<M> {
|
impl<M: Clone> Rotmat<M> {
|
||||||
/// Gets a copy of the internal representation of the rotation.
|
/// Gets a copy of the internal representation of the rotation.
|
||||||
pub fn submat(&self) -> M {
|
pub fn submat(&self) -> M {
|
||||||
|
@ -229,19 +244,19 @@ impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M> {
|
impl<M, V: RotmatMulRhs<M, V> + Mul<Rotmat<M>, V>> Rotate<V> for Rotmat<M> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate(&self, v: &V) -> V {
|
fn rotate(&self, v: &V) -> V {
|
||||||
self.rmul(v)
|
self * *v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inv_rotate(&self, v: &V) -> V {
|
fn inv_rotate(&self, v: &V) -> V {
|
||||||
self.lmul(v)
|
v * *self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V> + LMul<V>, V> Transform<V> for Rotmat<M> {
|
impl<M, V: RotmatMulRhs<M, V> + Mul<Rotmat<M>, V>> Transform<V> for Rotmat<M> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform(&self, v: &V) -> V {
|
fn transform(&self, v: &V) -> V {
|
||||||
self.rotate(v)
|
self.rotate(v)
|
||||||
|
@ -275,24 +290,41 @@ impl<M: One + Zero> One for Rotmat<M> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Mul<M, M>> Mul<Rotmat<M>, Rotmat<M>> for Rotmat<M> {
|
impl<M: Mul<M, M>> RotmatMulRhs<M, Rotmat<M>> for Rotmat<M> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(&self, other: &Rotmat<M>) -> Rotmat<M> {
|
fn binop(left: &Rotmat<M>, right: &Rotmat<M>) -> Rotmat<M> {
|
||||||
Rotmat { submat: self.submat.mul(&other.submat) }
|
Rotmat { submat: left.submat * right.submat }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V, M: RMul<V>> RMul<V> for Rotmat<M> {
|
/*
|
||||||
|
* Right/Left multiplication implementation for Vec3 and Vec2.
|
||||||
|
*/
|
||||||
|
impl<M: Mul<Vec3<N>, Vec3<N>>, N> RotmatMulRhs<M, Vec3<N>> for Vec3<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rmul(&self, other: &V) -> V {
|
fn binop(left: &Rotmat<M>, right: &Vec3<N>) -> Vec3<N> {
|
||||||
self.submat.rmul(other)
|
left.submat * *right
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V, M: LMul<V>> LMul<V> for Rotmat<M> {
|
impl<M: Mul<Vec2<N>, Vec2<N>>, N> RotmatMulRhs<M, Vec2<N>> for Vec2<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lmul(&self, other: &V) -> V {
|
fn binop(left: &Rotmat<M>, right: &Vec2<N>) -> Vec2<N> {
|
||||||
self.submat.lmul(other)
|
left.submat * *right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, M: Vec3MulRhs<N, Vec3<N>>> Vec3MulRhs<N, Vec3<N>> for Rotmat<M> {
|
||||||
|
#[inline]
|
||||||
|
fn binop(left: &Vec3<N>, right: &Rotmat<M>) -> Vec3<N> {
|
||||||
|
*left * right.submat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, M: Vec2MulRhs<N, Vec2<N>>> Vec2MulRhs<N, Vec2<N>> for Rotmat<M> {
|
||||||
|
#[inline]
|
||||||
|
fn binop(left: &Vec2<N>, right: &Rotmat<M>) -> Vec2<N> {
|
||||||
|
*left * right.submat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,12 @@ use traits::rotation::{Rotation, Rotate, RotationMatrix};
|
||||||
use traits::translation::{Translation, Translate};
|
use traits::translation::{Translation, Translate};
|
||||||
use Ts = traits::transformation::Transform;
|
use Ts = traits::transformation::Transform;
|
||||||
use traits::transformation::{Transformation};
|
use traits::transformation::{Transformation};
|
||||||
use traits::rlmul::{RMul, LMul};
|
use traits::rlmul::RMul;
|
||||||
use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
|
use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
|
||||||
use traits::column::Column;
|
use traits::column::Column;
|
||||||
use traits::comp::absolute_rotate::AbsoluteRotate;
|
use traits::comp::absolute_rotate::AbsoluteRotate;
|
||||||
use adaptors::rotmat::Rotmat;
|
use adaptors::rotmat::Rotmat;
|
||||||
use vec::Vec3;
|
use vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs};
|
||||||
use mat::Mat3;
|
use mat::Mat3;
|
||||||
|
|
||||||
/// Matrix-Vector wrapper used to represent a matrix multiplication followed by a translation.
|
/// Matrix-Vector wrapper used to represent a matrix multiplication followed by a translation.
|
||||||
|
@ -42,6 +42,19 @@ impl<V, M> Transform<V, M> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait of object `o` which can be multiplied by a `Transform` `t`: `t * o`.
|
||||||
|
pub trait TransformMulRhs<V, M, Res> {
|
||||||
|
/// Multiplies a transformation matrix by `Self`.
|
||||||
|
fn binop(left: &Transform<V, M>, right: &Self) -> Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V, M, Rhs: TransformMulRhs<V, M, Res>, Res> Mul<Rhs, Res> for Transform<V, M> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn mul(&self, other: &Rhs) -> Res {
|
||||||
|
TransformMulRhs::binop(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<V: Clone, M: Clone> Transform<V, M> {
|
impl<V: Clone, M: Clone> Transform<V, M> {
|
||||||
/// Gets a copy of the internal matrix.
|
/// Gets a copy of the internal matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -125,28 +138,45 @@ impl<M: Zero, V: Zero> Zero for Transform<V, M> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V> + Mul<M, M>, V: Add<V, V>>
|
impl<M: RMul<V> + Mul<M, M>, V: Add<V, V>> TransformMulRhs<V, M, Transform<V, M>> for Transform<V, M> {
|
||||||
Mul<Transform<V, M>, Transform<V, M>> for Transform<V, M> {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(&self, other: &Transform<V, M>) -> Transform<V, M> {
|
fn binop(left: &Transform<V, M>, right: &Transform<V, M>) -> Transform<V, M> {
|
||||||
Transform {
|
Transform {
|
||||||
submat: self.submat * other.submat,
|
submat: left.submat * right.submat,
|
||||||
subtrans: self.subtrans + self.submat.rmul(&other.subtrans)
|
subtrans: left.subtrans + left.submat.rmul(&right.subtrans)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V>, V: Add<V, V>> RMul<V> for Transform<V, M> {
|
impl<N: Clone + Add<N, N>, M: Mul<Vec2<N>, Vec2<N>>>
|
||||||
|
TransformMulRhs<Vec2<N>, M, Vec2<N>> for Vec2<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rmul(&self, other: &V) -> V {
|
fn binop(left: &Transform<Vec2<N>, M>, right: &Vec2<N>) -> Vec2<N> {
|
||||||
self.submat.rmul(other) + self.subtrans
|
left.subtrans + left.submat * *right
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: LMul<V>, V: Add<V, V>> LMul<V> for Transform<V, M> {
|
impl<N: Clone + Add<N, N>, M: Mul<Vec3<N>, Vec3<N>>>
|
||||||
|
TransformMulRhs<Vec3<N>, M, Vec3<N>> for Vec3<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lmul(&self, other: &V) -> V {
|
fn binop(left: &Transform<Vec3<N>, M>, right: &Vec3<N>) -> Vec3<N> {
|
||||||
self.submat.lmul(other) + self.subtrans
|
left.subtrans + left.submat * *right
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Clone + Add<N, N>, M: Vec2MulRhs<N, Vec2<N>>>
|
||||||
|
Vec2MulRhs<N, Vec2<N>> for Transform<Vec2<N>, M> {
|
||||||
|
#[inline]
|
||||||
|
fn binop(left: &Vec2<N>, right: &Transform<Vec2<N>, M>) -> Vec2<N> {
|
||||||
|
(left + right.subtrans) * right.submat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: Clone + Add<N, N>, M: Vec3MulRhs<N, Vec3<N>>>
|
||||||
|
Vec3MulRhs<N, Vec3<N>> for Transform<Vec3<N>, M> {
|
||||||
|
#[inline]
|
||||||
|
fn binop(left: &Vec3<N>, right: &Transform<Vec3<N>, M>) -> Vec3<N> {
|
||||||
|
(left + right.subtrans) * right.submat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ macro_rules! bench_mul_mat_vec(
|
||||||
|
|
||||||
do $bh.iter {
|
do $bh.iter {
|
||||||
do 1000.times {
|
do 1000.times {
|
||||||
v = m.rmul(&v)
|
v = m * v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ macro_rules! bench_mul_dmat_dvec(
|
||||||
|
|
||||||
do $bh.iter {
|
do $bh.iter {
|
||||||
do 1000.times {
|
do 1000.times {
|
||||||
v = m.rmul(&v)
|
v = m * v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
61
src/dmat.rs
61
src/dmat.rs
|
@ -4,10 +4,9 @@ use std::num::{One, Zero};
|
||||||
use std::vec;
|
use std::vec;
|
||||||
use std::cmp::ApproxEq;
|
use std::cmp::ApproxEq;
|
||||||
use std::util;
|
use std::util;
|
||||||
|
use dvec::{DVec, DVecMulRhs};
|
||||||
use traits::inv::Inv;
|
use traits::inv::Inv;
|
||||||
use traits::transpose::Transpose;
|
use traits::transpose::Transpose;
|
||||||
use traits::rlmul::{RMul, LMul};
|
|
||||||
use dvec::DVec;
|
|
||||||
|
|
||||||
/// Matrix with dimensions unknown at compile-time.
|
/// Matrix with dimensions unknown at compile-time.
|
||||||
#[deriving(Eq, ToStr, Clone)]
|
#[deriving(Eq, ToStr, Clone)]
|
||||||
|
@ -17,6 +16,19 @@ pub struct DMat<N> {
|
||||||
priv mij: ~[N]
|
priv mij: ~[N]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait of object `o` which can be multiplied by a `DMat` `d`: `d * o`.
|
||||||
|
pub trait DMatMulRhs<N, Res> {
|
||||||
|
/// Multiplies a `DMat` by `Self`.
|
||||||
|
fn binop(left: &DMat<N>, right: &Self) -> Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, Rhs: DMatMulRhs<N, Res>, Res> Mul<Rhs, Res> for DMat<N> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn mul(&self, other: &Rhs) -> Res {
|
||||||
|
DMatMulRhs::binop(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N> DMat<N> {
|
impl<N> DMat<N> {
|
||||||
/// Creates an uninitialized matrix.
|
/// Creates an uninitialized matrix.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -160,19 +172,19 @@ impl<N: Clone> DMat<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Mul<N, N> + Add<N, N> + Zero> Mul<DMat<N>, DMat<N>> for DMat<N> {
|
impl<N: Clone + Mul<N, N> + Add<N, N> + Zero> DMatMulRhs<N, DMat<N>> for DMat<N> {
|
||||||
fn mul(&self, other: &DMat<N>) -> DMat<N> {
|
fn binop(left: &DMat<N>, right: &DMat<N>) -> DMat<N> {
|
||||||
assert!(self.ncols == other.nrows);
|
assert!(left.ncols == right.nrows);
|
||||||
|
|
||||||
let mut res = unsafe { DMat::new_uninitialized(self.nrows, other.ncols) };
|
let mut res = unsafe { DMat::new_uninitialized(left.nrows, right.ncols) };
|
||||||
|
|
||||||
for i in range(0u, self.nrows) {
|
for i in range(0u, left.nrows) {
|
||||||
for j in range(0u, other.ncols) {
|
for j in range(0u, right.ncols) {
|
||||||
let mut acc: N = Zero::zero();
|
let mut acc: N = Zero::zero();
|
||||||
|
|
||||||
for k in range(0u, self.ncols) {
|
for k in range(0u, left.ncols) {
|
||||||
unsafe {
|
unsafe {
|
||||||
acc = acc + self.at_fast(i, k) * other.at_fast(k, j);
|
acc = acc + left.at_fast(i, k) * right.at_fast(k, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,18 +197,18 @@ impl<N: Clone + Mul<N, N> + Add<N, N> + Zero> Mul<DMat<N>, DMat<N>> for DMat<N>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
|
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
|
||||||
RMul<DVec<N>> for DMat<N> {
|
DMatMulRhs<N, DVec<N>> for DVec<N> {
|
||||||
fn rmul(&self, other: &DVec<N>) -> DVec<N> {
|
fn binop(left: &DMat<N>, right: &DVec<N>) -> DVec<N> {
|
||||||
assert!(self.ncols == other.at.len());
|
assert!(left.ncols == right.at.len());
|
||||||
|
|
||||||
let mut res : DVec<N> = unsafe { DVec::new_uninitialized(self.nrows) };
|
let mut res : DVec<N> = unsafe { DVec::new_uninitialized(left.nrows) };
|
||||||
|
|
||||||
for i in range(0u, self.nrows) {
|
for i in range(0u, left.nrows) {
|
||||||
let mut acc: N = Zero::zero();
|
let mut acc: N = Zero::zero();
|
||||||
|
|
||||||
for j in range(0u, self.ncols) {
|
for j in range(0u, left.ncols) {
|
||||||
unsafe {
|
unsafe {
|
||||||
acc = acc + other.at_fast(j) * self.at_fast(i, j);
|
acc = acc + left.at_fast(i, j) * right.at_fast(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,19 +219,20 @@ RMul<DVec<N>> for DMat<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
|
impl<N: Clone + Add<N, N> + Mul<N, N> + Zero>
|
||||||
LMul<DVec<N>> for DMat<N> {
|
DVecMulRhs<N, DVec<N>> for DMat<N> {
|
||||||
fn lmul(&self, other: &DVec<N>) -> DVec<N> {
|
fn binop(left: &DVec<N>, right: &DMat<N>) -> DVec<N> {
|
||||||
assert!(self.nrows == other.at.len());
|
assert!(right.nrows == left.at.len());
|
||||||
|
|
||||||
let mut res : DVec<N> = unsafe { DVec::new_uninitialized(self.ncols) };
|
let mut res : DVec<N> = unsafe { DVec::new_uninitialized(right.ncols) };
|
||||||
|
|
||||||
for i in range(0u, self.ncols) {
|
for i in range(0u, right.ncols) {
|
||||||
let mut acc: N = Zero::zero();
|
let mut acc: N = Zero::zero();
|
||||||
|
|
||||||
for j in range(0u, self.nrows) {
|
for j in range(0u, right.nrows) {
|
||||||
unsafe {
|
unsafe {
|
||||||
acc = acc + other.at_fast(j) * self.at_fast(j, i);
|
acc = acc + left.at_fast(j) * right.at_fast(j, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
147
src/dvec.rs
147
src/dvec.rs
|
@ -1,3 +1,5 @@
|
||||||
|
#[doc(hidden)]; // we hide doc to not have to document the $trhs double dispatch trait.
|
||||||
|
|
||||||
use std::num::{Zero, One, Algebraic};
|
use std::num::{Zero, One, Algebraic};
|
||||||
use std::rand::Rand;
|
use std::rand::Rand;
|
||||||
use std::rand;
|
use std::rand;
|
||||||
|
@ -10,6 +12,8 @@ use traits::norm::Norm;
|
||||||
use traits::iterable::{Iterable, IterableMut};
|
use traits::iterable::{Iterable, IterableMut};
|
||||||
use traits::translation::Translation;
|
use traits::translation::Translation;
|
||||||
|
|
||||||
|
mod metal;
|
||||||
|
|
||||||
/// Vector with a dimension unknown at compile-time.
|
/// Vector with a dimension unknown at compile-time.
|
||||||
#[deriving(Eq, ToStr, Clone)]
|
#[deriving(Eq, ToStr, Clone)]
|
||||||
pub struct DVec<N> {
|
pub struct DVec<N> {
|
||||||
|
@ -17,6 +21,16 @@ pub struct DVec<N> {
|
||||||
at: ~[N]
|
at: ~[N]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double_dispatch_binop_decl_trait!(DVec, DVecMulRhs)
|
||||||
|
double_dispatch_binop_decl_trait!(DVec, DVecDivRhs)
|
||||||
|
double_dispatch_binop_decl_trait!(DVec, DVecAddRhs)
|
||||||
|
double_dispatch_binop_decl_trait!(DVec, DVecSubRhs)
|
||||||
|
|
||||||
|
mul_redispatch_impl!(DVec, DVecMulRhs)
|
||||||
|
div_redispatch_impl!(DVec, DVecDivRhs)
|
||||||
|
add_redispatch_impl!(DVec, DVecAddRhs)
|
||||||
|
sub_redispatch_impl!(DVec, DVecSubRhs)
|
||||||
|
|
||||||
impl<N: Zero + Clone> DVec<N> {
|
impl<N: Zero + Clone> DVec<N> {
|
||||||
/// Builds a vector filled with zeros.
|
/// Builds a vector filled with zeros.
|
||||||
///
|
///
|
||||||
|
@ -123,7 +137,7 @@ impl<N> FromIterator<N> for DVec<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Num + Algebraic + ApproxEq<N>> DVec<N> {
|
impl<N: Clone + Num + Algebraic + ApproxEq<N> + DVecMulRhs<N, DVec<N>>> DVec<N> {
|
||||||
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
/// Computes the canonical basis for the given dimension. A canonical basis is a set of
|
||||||
/// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
|
/// vectors, mutually orthogonal, with all its component equal to 0.0 exept one which is equal
|
||||||
/// to 1.0.
|
/// to 1.0.
|
||||||
|
@ -177,22 +191,22 @@ impl<N: Clone + Num + Algebraic + ApproxEq<N>> DVec<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Add<N,N>> Add<DVec<N>, DVec<N>> for DVec<N> {
|
impl<N: Add<N, N>> DVecAddRhs<N, DVec<N>> for DVec<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add(&self, other: &DVec<N>) -> DVec<N> {
|
fn binop(left: &DVec<N>, right: &DVec<N>) -> DVec<N> {
|
||||||
assert!(self.at.len() == other.at.len());
|
assert!(left.at.len() == right.at.len());
|
||||||
DVec {
|
DVec {
|
||||||
at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a + *b).collect()
|
at: left.at.iter().zip(right.at.iter()).map(|(a, b)| *a + *b).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Sub<N,N>> Sub<DVec<N>, DVec<N>> for DVec<N> {
|
impl<N: Sub<N, N>> DVecSubRhs<N, DVec<N>> for DVec<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn sub(&self, other: &DVec<N>) -> DVec<N> {
|
fn binop(left: &DVec<N>, right: &DVec<N>) -> DVec<N> {
|
||||||
assert!(self.at.len() == other.at.len());
|
assert!(left.at.len() == right.at.len());
|
||||||
DVec {
|
DVec {
|
||||||
at: self.at.iter().zip(other.at.iter()).map(|(a, b)| *a - *b).collect()
|
at: left.at.iter().zip(right.at.iter()).map(|(a, b)| *a - *b).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -230,21 +244,6 @@ impl<N: Num> Dot<N> for DVec<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N>> Mul<N, DVec<N>> for DVec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn mul(&self, s: &N) -> DVec<N> {
|
|
||||||
DVec { at: self.at.iter().map(|a| a * *s).collect() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl<N: Div<N, N>> Div<N, DVec<N>> for DVec<N> {
|
|
||||||
#[inline]
|
|
||||||
fn div(&self, s: &N) -> DVec<N> {
|
|
||||||
DVec { at: self.at.iter().map(|a| a / *s).collect() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> {
|
impl<N: Add<N, N> + Neg<N> + Clone> Translation<DVec<N>> for DVec<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn translation(&self) -> DVec<N> {
|
fn translation(&self) -> DVec<N> {
|
||||||
|
@ -331,3 +330,103 @@ impl<N: ApproxEq<N>> ApproxEq<N> for DVec<N> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! scalar_mul_impl (
|
||||||
|
($n: ident) => (
|
||||||
|
impl DVecMulRhs<$n, DVec<$n>> for $n {
|
||||||
|
#[inline]
|
||||||
|
fn binop(left: &DVec<$n>, right: &$n) -> DVec<$n> {
|
||||||
|
DVec { at: left.at.iter().map(|a| a * *right).collect() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! scalar_div_impl (
|
||||||
|
($n: ident) => (
|
||||||
|
impl DVecDivRhs<$n, DVec<$n>> for $n {
|
||||||
|
#[inline]
|
||||||
|
fn binop(left: &DVec<$n>, right: &$n) -> DVec<$n> {
|
||||||
|
DVec { at: left.at.iter().map(|a| a / *right).collect() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! scalar_add_impl (
|
||||||
|
($n: ident) => (
|
||||||
|
impl DVecAddRhs<$n, DVec<$n>> for $n {
|
||||||
|
#[inline]
|
||||||
|
fn binop(left: &DVec<$n>, right: &$n) -> DVec<$n> {
|
||||||
|
DVec { at: left.at.iter().map(|a| a + *right).collect() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
macro_rules! scalar_sub_impl (
|
||||||
|
($n: ident) => (
|
||||||
|
impl DVecSubRhs<$n, DVec<$n>> for $n {
|
||||||
|
#[inline]
|
||||||
|
fn binop(left: &DVec<$n>, right: &$n) -> DVec<$n> {
|
||||||
|
DVec { at: left.at.iter().map(|a| a - *right).collect() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
scalar_mul_impl!(f64)
|
||||||
|
scalar_mul_impl!(f32)
|
||||||
|
scalar_mul_impl!(u64)
|
||||||
|
scalar_mul_impl!(u32)
|
||||||
|
scalar_mul_impl!(u16)
|
||||||
|
scalar_mul_impl!(u8)
|
||||||
|
scalar_mul_impl!(i64)
|
||||||
|
scalar_mul_impl!(i32)
|
||||||
|
scalar_mul_impl!(i16)
|
||||||
|
scalar_mul_impl!(i8)
|
||||||
|
scalar_mul_impl!(float)
|
||||||
|
scalar_mul_impl!(uint)
|
||||||
|
scalar_mul_impl!(int)
|
||||||
|
|
||||||
|
scalar_div_impl!(f64)
|
||||||
|
scalar_div_impl!(f32)
|
||||||
|
scalar_div_impl!(u64)
|
||||||
|
scalar_div_impl!(u32)
|
||||||
|
scalar_div_impl!(u16)
|
||||||
|
scalar_div_impl!(u8)
|
||||||
|
scalar_div_impl!(i64)
|
||||||
|
scalar_div_impl!(i32)
|
||||||
|
scalar_div_impl!(i16)
|
||||||
|
scalar_div_impl!(i8)
|
||||||
|
scalar_div_impl!(float)
|
||||||
|
scalar_div_impl!(uint)
|
||||||
|
scalar_div_impl!(int)
|
||||||
|
|
||||||
|
scalar_add_impl!(f64)
|
||||||
|
scalar_add_impl!(f32)
|
||||||
|
scalar_add_impl!(u64)
|
||||||
|
scalar_add_impl!(u32)
|
||||||
|
scalar_add_impl!(u16)
|
||||||
|
scalar_add_impl!(u8)
|
||||||
|
scalar_add_impl!(i64)
|
||||||
|
scalar_add_impl!(i32)
|
||||||
|
scalar_add_impl!(i16)
|
||||||
|
scalar_add_impl!(i8)
|
||||||
|
scalar_add_impl!(float)
|
||||||
|
scalar_add_impl!(uint)
|
||||||
|
scalar_add_impl!(int)
|
||||||
|
|
||||||
|
scalar_sub_impl!(f64)
|
||||||
|
scalar_sub_impl!(f32)
|
||||||
|
scalar_sub_impl!(u64)
|
||||||
|
scalar_sub_impl!(u32)
|
||||||
|
scalar_sub_impl!(u16)
|
||||||
|
scalar_sub_impl!(u8)
|
||||||
|
scalar_sub_impl!(i64)
|
||||||
|
scalar_sub_impl!(i32)
|
||||||
|
scalar_sub_impl!(i16)
|
||||||
|
scalar_sub_impl!(i8)
|
||||||
|
scalar_sub_impl!(float)
|
||||||
|
scalar_sub_impl!(uint)
|
||||||
|
scalar_sub_impl!(int)
|
||||||
|
|
|
@ -2,7 +2,6 @@ use std::num::{One, Zero};
|
||||||
use mat;
|
use mat;
|
||||||
use traits::inv::Inv;
|
use traits::inv::Inv;
|
||||||
use traits::transpose::Transpose;
|
use traits::transpose::Transpose;
|
||||||
use traits::rlmul::{RMul, LMul};
|
|
||||||
use traits::translation::{Translation, Translate};
|
use traits::translation::{Translation, Translate};
|
||||||
use traits::rotation::{Rotation, Rotate};
|
use traits::rotation::{Rotation, Rotate};
|
||||||
use traits::transformation::{Transformation, Transform};
|
use traits::transformation::{Transformation, Transform};
|
||||||
|
@ -24,21 +23,9 @@ impl Inv for mat::Identity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Clone> RMul<M> for mat::Identity {
|
impl<T: Clone> Mul<T, T> for mat::Identity {
|
||||||
fn rmul(&self, m: &M) -> M {
|
|
||||||
m.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<M: Clone> LMul<M> for mat::Identity {
|
|
||||||
fn lmul(&self, m: &M) -> M {
|
|
||||||
m.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<M: Clone> Mul<M, M> for mat::Identity {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(&self, other: &M) -> M {
|
fn mul(&self, other: &T) -> T {
|
||||||
other.clone()
|
other.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
20
src/mat.rs
20
src/mat.rs
|
@ -4,7 +4,7 @@ use std::cast;
|
||||||
use std::num::{One, Zero};
|
use std::num::{One, Zero};
|
||||||
use std::cmp::ApproxEq;
|
use std::cmp::ApproxEq;
|
||||||
use std::vec::{VecIterator, VecMutIterator};
|
use std::vec::{VecIterator, VecMutIterator};
|
||||||
use vec::{Vec1, Vec2, Vec3, Vec4, Vec5, Vec6, Outer};
|
use vec::*;
|
||||||
|
|
||||||
// traits
|
// traits
|
||||||
pub use traits::mat::Mat;
|
pub use traits::mat::Mat;
|
||||||
|
@ -16,7 +16,7 @@ pub use traits::scalar_op::{ScalarSub, ScalarAdd};
|
||||||
pub use traits::mat_cast::MatCast;
|
pub use traits::mat_cast::MatCast;
|
||||||
pub use traits::column::Column;
|
pub use traits::column::Column;
|
||||||
pub use traits::inv::Inv;
|
pub use traits::inv::Inv;
|
||||||
pub use traits::rlmul::{RMul, LMul};
|
pub use traits::rlmul::RMul;
|
||||||
pub use traits::rotation::{Rotation, RotationMatrix, Rotate};
|
pub use traits::rotation::{Rotation, RotationMatrix, Rotate};
|
||||||
pub use traits::transformation::{Transformation, Transform};
|
pub use traits::transformation::{Transformation, Transform};
|
||||||
pub use traits::translation::{Translation, Translate};
|
pub use traits::translation::{Translation, Translate};
|
||||||
|
@ -132,8 +132,8 @@ at_fast_impl!(Mat1, 1)
|
||||||
dim_impl!(Mat1, 1)
|
dim_impl!(Mat1, 1)
|
||||||
indexable_impl!(Mat1, 1)
|
indexable_impl!(Mat1, 1)
|
||||||
mat_mul_mat_impl!(Mat1, Mat1MulRhs, 1)
|
mat_mul_mat_impl!(Mat1, Mat1MulRhs, 1)
|
||||||
rmul_impl!(Mat1, Vec1, 1)
|
mat_mul_vec_impl!(Mat1, Vec1, Mat1MulRhs, 1)
|
||||||
vec_mul_mat_impl!(Mat1, Vec1, Mat1MulRhs, 1)
|
vec_mul_mat_impl!(Mat1, Vec1, Vec1MulRhs, 1)
|
||||||
transform_impl!(Mat1, Vec1)
|
transform_impl!(Mat1, Vec1)
|
||||||
// (specialized) inv_impl!(Mat1, 1)
|
// (specialized) inv_impl!(Mat1, 1)
|
||||||
transpose_impl!(Mat1, 1)
|
transpose_impl!(Mat1, 1)
|
||||||
|
@ -519,8 +519,8 @@ dim_impl!(Mat4, 4)
|
||||||
indexable_impl!(Mat4, 4)
|
indexable_impl!(Mat4, 4)
|
||||||
at_fast_impl!(Mat4, 4)
|
at_fast_impl!(Mat4, 4)
|
||||||
mat_mul_mat_impl!(Mat4, Mat4MulRhs, 4)
|
mat_mul_mat_impl!(Mat4, Mat4MulRhs, 4)
|
||||||
rmul_impl!(Mat4, Vec4, 4)
|
mat_mul_vec_impl!(Mat4, Vec4, Mat4MulRhs, 4)
|
||||||
vec_mul_mat_impl!(Mat4, Vec4, Mat4MulRhs, 4)
|
vec_mul_mat_impl!(Mat4, Vec4, Vec4MulRhs, 4)
|
||||||
transform_impl!(Mat4, Vec4)
|
transform_impl!(Mat4, Vec4)
|
||||||
inv_impl!(Mat4, 4)
|
inv_impl!(Mat4, 4)
|
||||||
transpose_impl!(Mat4, 4)
|
transpose_impl!(Mat4, 4)
|
||||||
|
@ -706,8 +706,8 @@ dim_impl!(Mat5, 5)
|
||||||
indexable_impl!(Mat5, 5)
|
indexable_impl!(Mat5, 5)
|
||||||
at_fast_impl!(Mat5, 5)
|
at_fast_impl!(Mat5, 5)
|
||||||
mat_mul_mat_impl!(Mat5, Mat5MulRhs, 5)
|
mat_mul_mat_impl!(Mat5, Mat5MulRhs, 5)
|
||||||
rmul_impl!(Mat5, Vec5, 5)
|
mat_mul_vec_impl!(Mat5, Vec5, Mat5MulRhs, 5)
|
||||||
vec_mul_mat_impl!(Mat5, Vec5, Mat5MulRhs, 5)
|
vec_mul_mat_impl!(Mat5, Vec5, Vec5MulRhs, 5)
|
||||||
transform_impl!(Mat5, Vec5)
|
transform_impl!(Mat5, Vec5)
|
||||||
inv_impl!(Mat5, 5)
|
inv_impl!(Mat5, 5)
|
||||||
transpose_impl!(Mat5, 5)
|
transpose_impl!(Mat5, 5)
|
||||||
|
@ -949,8 +949,8 @@ dim_impl!(Mat6, 6)
|
||||||
indexable_impl!(Mat6, 6)
|
indexable_impl!(Mat6, 6)
|
||||||
at_fast_impl!(Mat6, 6)
|
at_fast_impl!(Mat6, 6)
|
||||||
mat_mul_mat_impl!(Mat6, Mat6MulRhs, 6)
|
mat_mul_mat_impl!(Mat6, Mat6MulRhs, 6)
|
||||||
rmul_impl!(Mat6, Vec6, 6)
|
mat_mul_vec_impl!(Mat6, Vec6, Mat6MulRhs, 6)
|
||||||
vec_mul_mat_impl!(Mat6, Vec6, Mat6MulRhs, 6)
|
vec_mul_mat_impl!(Mat6, Vec6, Vec6MulRhs, 6)
|
||||||
transform_impl!(Mat6, Vec6)
|
transform_impl!(Mat6, Vec6)
|
||||||
inv_impl!(Mat6, 6)
|
inv_impl!(Mat6, 6)
|
||||||
transpose_impl!(Mat6, 6)
|
transpose_impl!(Mat6, 6)
|
||||||
|
|
|
@ -47,8 +47,8 @@ macro_rules! add_impl(
|
||||||
($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + Add<N, N>> $trhs<N, $t<N>> for $t<N> {
|
impl<N: Clone + Add<N, N>> $trhs<N, $t<N>> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, other: &$t<N>) -> $t<N> {
|
fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> {
|
||||||
$t::new(self.$comp0 + other.$comp0 $(, self.$compN + other.$compN)*)
|
$t::new(left.$comp0 + right.$comp0 $(, left.$compN + right.$compN)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -58,8 +58,8 @@ macro_rules! sub_impl(
|
||||||
($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + Sub<N, N>> $trhs<N, $t<N>> for $t<N> {
|
impl<N: Clone + Sub<N, N>> $trhs<N, $t<N>> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, other: &$t<N>) -> $t<N> {
|
fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> {
|
||||||
$t::new(other.$comp0 - self.$comp0 $(, other.$compN - self.$compN)*)
|
$t::new(left.$comp0 - right.$comp0 $(, left.$compN - right.$compN)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -69,8 +69,8 @@ macro_rules! scalar_mul_impl(
|
||||||
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl $trhs<$n, $t<$n>> for $n {
|
impl $trhs<$n, $t<$n>> for $n {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, s: &$t<$n>) -> $t<$n> {
|
fn binop(left: &$t<$n>, right: &$n) -> $t<$n> {
|
||||||
$t::new(s.$comp0 * *self $(, s.$compN * *self)*)
|
$t::new(left.$comp0 * *right $(, left.$compN * *right)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -80,8 +80,8 @@ macro_rules! scalar_div_impl(
|
||||||
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl $trhs<$n, $t<$n>> for $n {
|
impl $trhs<$n, $t<$n>> for $n {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, s: &$t<$n>) -> $t<$n> {
|
fn binop(left: &$t<$n>, right: &$n) -> $t<$n> {
|
||||||
$t::new(s.$comp0 / *self $(, s.$compN / *self)*)
|
$t::new(left.$comp0 / *right $(, left.$compN / *right)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -91,8 +91,8 @@ macro_rules! scalar_add_impl(
|
||||||
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl $trhs<$n, $t<$n>> for $n {
|
impl $trhs<$n, $t<$n>> for $n {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, s: &$t<$n>) -> $t<$n> {
|
fn binop(left: &$t<$n>, right: &$n) -> $t<$n> {
|
||||||
$t::new(s.$comp0 + *self $(, s.$compN + *self)*)
|
$t::new(left.$comp0 + *right $(, left.$compN + *right)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -102,8 +102,8 @@ macro_rules! scalar_sub_impl(
|
||||||
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl $trhs<$n, $t<$n>> for $n {
|
impl $trhs<$n, $t<$n>> for $n {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, s: &$t<$n>) -> $t<$n> {
|
fn binop(left: &$t<$n>, right: &$n) -> $t<$n> {
|
||||||
$t::new(s.$comp0 - *self $(, s.$compN - *self)*)
|
$t::new(left.$comp0 - *right $(, left.$compN - *right)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -282,7 +282,7 @@ macro_rules! mat_mul_mat_impl(
|
||||||
($t: ident, $trhs: ident, $dim: expr) => (
|
($t: ident, $trhs: ident, $dim: expr) => (
|
||||||
impl<N: Clone + Num> $trhs<N, $t<N>> for $t<N> {
|
impl<N: Clone + Num> $trhs<N, $t<N>> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, other: &$t<N>) -> $t<N> {
|
fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> {
|
||||||
// careful! we need to comute other * self here (self is the rhs).
|
// 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();
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ macro_rules! mat_mul_mat_impl(
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
for k in range(0u, $dim) {
|
for k in range(0u, $dim) {
|
||||||
acc = acc + other.at_fast((i, k)) * self.at_fast((k, j));
|
acc = acc + left.at_fast((i, k)) * right.at_fast((k, j));
|
||||||
}
|
}
|
||||||
|
|
||||||
res.set_fast((i, j), acc);
|
res.set_fast((i, j), acc);
|
||||||
|
@ -306,17 +306,17 @@ macro_rules! mat_mul_mat_impl(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! rmul_impl(
|
macro_rules! vec_mul_mat_impl(
|
||||||
($t: ident, $v: ident, $dim: expr) => (
|
($t: ident, $v: ident, $trhs: ident, $dim: expr) => (
|
||||||
impl<N: Clone + Num> RMul<$v<N>> for $t<N> {
|
impl<N: Clone + Num> $trhs<N, $v<N>> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rmul(&self, other: &$v<N>) -> $v<N> {
|
fn binop(left: &$v<N>, right: &$t<N>) -> $v<N> {
|
||||||
let mut res : $v<N> = Zero::zero();
|
let mut res : $v<N> = Zero::zero();
|
||||||
|
|
||||||
for i in range(0u, $dim) {
|
for i in range(0u, $dim) {
|
||||||
for j in range(0u, $dim) {
|
for j in range(0u, $dim) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let val = res.at_fast(i) + other.at_fast(j) * self.at_fast((i, j));
|
let val = res.at_fast(i) + left.at_fast(j) * right.at_fast((j, i));
|
||||||
res.set_fast(i, val)
|
res.set_fast(i, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -328,17 +328,17 @@ macro_rules! rmul_impl(
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
macro_rules! vec_mul_mat_impl(
|
macro_rules! mat_mul_vec_impl(
|
||||||
($t: ident, $v: ident, $trhs: ident, $dim: expr) => (
|
($t: ident, $v: ident, $trhs: ident, $dim: expr) => (
|
||||||
impl<N: Clone + Num> $trhs<N, $v<N>> for $v<N> {
|
impl<N: Clone + Num> $trhs<N, $v<N>> for $v<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, other: &$t<N>) -> $v<N> {
|
fn binop(left: &$t<N>, right: &$v<N>) -> $v<N> {
|
||||||
let mut res : $v<N> = Zero::zero();
|
let mut res : $v<N> = Zero::zero();
|
||||||
|
|
||||||
for i in range(0u, $dim) {
|
for i in range(0u, $dim) {
|
||||||
for j in range(0u, $dim) {
|
for j in range(0u, $dim) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let val = self.at_fast(i) + self.at_fast(j) * other.at_fast((j, i));
|
let val = res.at_fast(i) + left.at_fast((i, j)) * right.at_fast(j);
|
||||||
res.set_fast(i, val)
|
res.set_fast(i, val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::num::{Zero, One};
|
use std::num::{Zero, One};
|
||||||
use vec::{Vec2, Vec3};
|
use vec::{Vec2, Vec3, Vec2MulRhs, Vec3MulRhs};
|
||||||
use mat::{Mat1, Mat2, Mat3, Inv, Row, Col, RMul, LMul, Mat3MulRhs, Mat2MulRhs};
|
use mat::{Mat1, Mat2, Mat3, Inv, Row, Col, Mat3MulRhs, Mat2MulRhs};
|
||||||
use mat;
|
use mat;
|
||||||
|
|
||||||
// some specializations:
|
// some specializations:
|
||||||
|
@ -191,74 +191,74 @@ impl<N: Clone> Col<Vec3<N>> for Mat3<N> {
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Add<N, N>> Mat3MulRhs<N, Mat3<N>> for Mat3<N> {
|
impl<N: Mul<N, N> + Add<N, N>> Mat3MulRhs<N, Mat3<N>> for Mat3<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn Mat3MulRhs(&self, other: &Mat3<N>) -> Mat3<N> {
|
fn binop(left: &Mat3<N>, right: &Mat3<N>) -> Mat3<N> {
|
||||||
Mat3::new(
|
Mat3::new(
|
||||||
other.m11 * self.m11 + other.m12 * self.m21 + other.m13 * self.m31,
|
left.m11 * right.m11 + left.m12 * right.m21 + left.m13 * right.m31,
|
||||||
other.m11 * self.m12 + other.m12 * self.m22 + other.m13 * self.m32,
|
left.m11 * right.m12 + left.m12 * right.m22 + left.m13 * right.m32,
|
||||||
other.m11 * self.m13 + other.m12 * self.m23 + other.m13 * self.m33,
|
left.m11 * right.m13 + left.m12 * right.m23 + left.m13 * right.m33,
|
||||||
|
|
||||||
other.m21 * self.m11 + other.m22 * self.m21 + other.m23 * self.m31,
|
left.m21 * right.m11 + left.m22 * right.m21 + left.m23 * right.m31,
|
||||||
other.m21 * self.m12 + other.m22 * self.m22 + other.m23 * self.m32,
|
left.m21 * right.m12 + left.m22 * right.m22 + left.m23 * right.m32,
|
||||||
other.m21 * self.m13 + other.m22 * self.m23 + other.m23 * self.m33,
|
left.m21 * right.m13 + left.m22 * right.m23 + left.m23 * right.m33,
|
||||||
|
|
||||||
other.m31 * self.m11 + other.m32 * self.m21 + other.m33 * self.m31,
|
left.m31 * right.m11 + left.m32 * right.m21 + left.m33 * right.m31,
|
||||||
other.m31 * self.m12 + other.m32 * self.m22 + other.m33 * self.m32,
|
left.m31 * right.m12 + left.m32 * right.m22 + left.m33 * right.m32,
|
||||||
other.m31 * self.m13 + other.m32 * self.m23 + other.m33 * self.m33
|
left.m31 * right.m13 + left.m32 * right.m23 + left.m33 * right.m33
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Add<N, N>> Mat2MulRhs<N, Mat2<N>> for Mat2<N> {
|
impl<N: Mul<N, N> + Add<N, N>> Mat2MulRhs<N, Mat2<N>> for Mat2<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn Mat2MulRhs(&self, other: &Mat2<N>) -> Mat2<N> {
|
fn binop(left: &Mat2<N>, right: &Mat2<N>) -> Mat2<N> {
|
||||||
Mat2::new(
|
Mat2::new(
|
||||||
other.m11 * self.m11 + other.m12 * self.m21,
|
left.m11 * right.m11 + left.m12 * right.m21,
|
||||||
other.m11 * self.m12 + other.m12 * self.m22,
|
left.m11 * right.m12 + left.m12 * right.m22,
|
||||||
|
|
||||||
other.m21 * self.m11 + other.m22 * self.m21,
|
left.m21 * right.m11 + left.m22 * right.m21,
|
||||||
other.m21 * self.m12 + other.m22 * self.m22
|
left.m21 * right.m12 + left.m22 * right.m22
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Add<N, N>> RMul<Vec3<N>> for Mat3<N> {
|
impl<N: Mul<N, N> + Add<N, N>> Mat3MulRhs<N, Vec3<N>> for Vec3<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn rmul(&self, v: &Vec3<N>) -> Vec3<N> {
|
fn binop(left: &Mat3<N>, right: &Vec3<N>) -> Vec3<N> {
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
self.m11 * v.x + self.m12 * v.y + self.m13 * v.z,
|
left.m11 * right.x + left.m12 * right.y + left.m13 * right.z,
|
||||||
self.m21 * v.x + self.m22 * v.y + self.m23 * v.z,
|
left.m21 * right.x + left.m22 * right.y + left.m23 * right.z,
|
||||||
self.m31 * v.x + self.m32 * v.y + self.m33 * v.z
|
left.m31 * right.x + left.m32 * right.y + left.m33 * right.z
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Add<N, N>> LMul<Vec3<N>> for Mat3<N> {
|
impl<N: Mul<N, N> + Add<N, N>> Vec3MulRhs<N, Vec3<N>> for Mat3<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn lmul(&self, v: &Vec3<N>) -> Vec3<N> {
|
fn binop(left: &Vec3<N>, right: &Mat3<N>) -> Vec3<N> {
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
self.m11 * v.x + self.m21 * v.y + self.m31 * v.z,
|
left.x * right.m11 + left.y * right.m21 + left.z * right.m31,
|
||||||
self.m12 * v.x + self.m22 * v.y + self.m32 * v.z,
|
left.x * right.m12 + left.y * right.m22 + left.z * right.m32,
|
||||||
self.m13 * v.x + self.m23 * v.y + self.m33 * v.z
|
left.x * right.m13 + left.y * right.m23 + left.z * right.m33
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Add<N, N>> RMul<Vec2<N>> for Mat2<N> {
|
impl<N: Mul<N, N> + Add<N, N>> Vec2MulRhs<N, Vec2<N>> for Mat2<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn rmul(&self, v: &Vec2<N>) -> Vec2<N> {
|
fn binop(left: &Vec2<N>, right: &Mat2<N>) -> Vec2<N> {
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
self.m11 * v.x + self.m12 * v.y,
|
left.x * right.m11 + left.y * right.m21,
|
||||||
self.m21 * v.x + self.m22 * v.y
|
left.x * right.m12 + left.y * right.m22
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Mul<N, N> + Add<N, N>> LMul<Vec2<N>> for Mat2<N> {
|
impl<N: Mul<N, N> + Add<N, N>> Mat2MulRhs<N, Vec2<N>> for Vec2<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn lmul(&self, v: &Vec2<N>) -> Vec2<N> {
|
fn binop(left: &Mat2<N>, right: &Vec2<N>) -> Vec2<N> {
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
self.m11 * v.x + self.m21 * v.y,
|
left.m11 * right.x + left.m21 * right.y,
|
||||||
self.m12 * v.x + self.m22 * v.y
|
left.m12 * right.x + left.m22 * right.y
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
62
src/metal.rs
62
src/metal.rs
|
@ -8,55 +8,55 @@
|
||||||
macro_rules! double_dispatch_binop_decl_trait(
|
macro_rules! double_dispatch_binop_decl_trait(
|
||||||
($t: ident, $trhs: ident) => (
|
($t: ident, $trhs: ident) => (
|
||||||
pub trait $trhs<N, Res> {
|
pub trait $trhs<N, Res> {
|
||||||
fn $trhs(&self, other: &$t<N>) -> Res;
|
fn binop(left: &$t<N>, right: &Self) -> Res;
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Macro driving the `Mul` trait to use the related trait for double redispatch.
|
// Macro driving the `Mul` trait to use the related trait for double redispatch.
|
||||||
macro_rules! mul_redispatch_impl(
|
macro_rules! mul_redispatch_impl(
|
||||||
($t: ident, $trhs: ident) => (
|
($t: ident, $trhs: ident) => (
|
||||||
impl<N, Rhs: $trhs<N, Res>, Res> Mul<Rhs, Res> for $t<N> {
|
impl<N, Rhs: $trhs<N, Res>, Res> Mul<Rhs, Res> for $t<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn mul(&self, other: &Rhs) -> Res {
|
fn mul(&self, other: &Rhs) -> Res {
|
||||||
other.$trhs(self)
|
$trhs::binop(self, other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Macro driving the `Div` trait to use the related trait for double redispatch.
|
// Macro driving the `Div` trait to use the related trait for double redispatch.
|
||||||
macro_rules! div_redispatch_impl(
|
macro_rules! div_redispatch_impl(
|
||||||
($t: ident, $trhs: ident) => (
|
($t: ident, $trhs: ident) => (
|
||||||
impl<N, Rhs: $trhs<N, Res>, Res> Div<Rhs, Res> for $t<N> {
|
impl<N, Rhs: $trhs<N, Res>, Res> Div<Rhs, Res> for $t<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn div(&self, other: &Rhs) -> Res {
|
fn div(&self, other: &Rhs) -> Res {
|
||||||
other.$trhs(self)
|
$trhs::binop(self, other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Macro driving the `Div` trait to use the related trait for double redispatch.
|
// Macro driving the `Add` trait to use the related trait for double redispatch.
|
||||||
macro_rules! add_redispatch_impl(
|
macro_rules! add_redispatch_impl(
|
||||||
($t: ident, $trhs: ident) => (
|
($t: ident, $trhs: ident) => (
|
||||||
impl<N, Rhs: $trhs<N, Res>, Res> Add<Rhs, Res> for $t<N> {
|
impl<N, Rhs: $trhs<N, Res>, Res> Add<Rhs, Res> for $t<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn add(&self, other: &Rhs) -> Res {
|
fn add(&self, other: &Rhs) -> Res {
|
||||||
other.$trhs(self)
|
$trhs::binop(self, other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Macro driving the `Div` trait to use the related trait for double redispatch.
|
// Macro driving the `Sub` trait to use the related trait for double redispatch.
|
||||||
macro_rules! sub_redispatch_impl(
|
macro_rules! sub_redispatch_impl(
|
||||||
($t: ident, $trhs: ident) => (
|
($t: ident, $trhs: ident) => (
|
||||||
impl<N, Rhs: $trhs<N, Res>, Res> Sub<Rhs, Res> for $t<N> {
|
impl<N, Rhs: $trhs<N, Res>, Res> Sub<Rhs, Res> for $t<N> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn sub(&self, other: &Rhs) -> Res {
|
fn sub(&self, other: &Rhs) -> Res {
|
||||||
other.$trhs(self)
|
$trhs::binop(self, other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
// XXX: those traits should not exist since there is generalized operator overloading of Add and
|
||||||
|
// Sub.
|
||||||
|
// However, using the same trait multiple time as a trait bound (ex: impl<T: Add<N, V> + Add<V, V>)
|
||||||
|
// does not work properly, mainly because the way we are doing generalized operator overloading is
|
||||||
|
// verry hacky.
|
||||||
|
//
|
||||||
|
// Hopefully, this will be fixed on a future version of the language!
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait of objects having a right multiplication with another element.
|
* Trait of objects having a right multiplication with another element.
|
||||||
*/
|
*/
|
||||||
|
@ -6,6 +14,12 @@ pub trait RMul<V> {
|
||||||
fn rmul(&self, v: &V) -> V;
|
fn rmul(&self, v: &V) -> V;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<M: Mul<T, T>, T> RMul<T> for M {
|
||||||
|
fn rmul(&self, v: &T) -> T {
|
||||||
|
self * *v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait of objects having a left multiplication with another element.
|
* Trait of objects having a left multiplication with another element.
|
||||||
*/
|
*/
|
||||||
|
@ -13,3 +27,9 @@ pub trait LMul<V> {
|
||||||
/// Computes v * self
|
/// Computes v * self
|
||||||
fn lmul(&self, &V) -> V;
|
fn lmul(&self, &V) -> V;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Mul<M, T>, M> LMul<T> for M {
|
||||||
|
fn lmul(&self, v: &T) -> T {
|
||||||
|
v * *self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// does not work properly, mainly because the way we are doing generalized operator overloading is
|
// does not work properly, mainly because the way we are doing generalized operator overloading is
|
||||||
// verry hacky.
|
// verry hacky.
|
||||||
//
|
//
|
||||||
// Hopefull, this will be fixed on the future.
|
// Hopefully, this will be fixed on a future version of the language!
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trait of objects having an addition with a scalar.
|
* Trait of objects having an addition with a scalar.
|
||||||
|
|
|
@ -269,8 +269,8 @@ macro_rules! add_impl(
|
||||||
($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + Add<N, N>> $trhs<N, $t<N>> for $t<N> {
|
impl<N: Clone + Add<N, N>> $trhs<N, $t<N>> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, other: &$t<N>) -> $t<N> {
|
fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> {
|
||||||
$t::new(self.$comp0 + other.$comp0 $(, self.$compN + other.$compN)*)
|
$t::new(left.$comp0 + right.$comp0 $(, left.$compN + right.$compN)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -280,8 +280,8 @@ macro_rules! sub_impl(
|
||||||
($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl<N: Clone + Sub<N, N>> $trhs<N, $t<N>> for $t<N> {
|
impl<N: Clone + Sub<N, N>> $trhs<N, $t<N>> for $t<N> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, other: &$t<N>) -> $t<N> {
|
fn binop(left: &$t<N>, right: &$t<N>) -> $t<N> {
|
||||||
$t::new(other.$comp0 - self.$comp0 $(, other.$compN - self.$compN)*)
|
$t::new(left.$comp0 - right.$comp0 $(, left.$compN - right.$compN)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -318,8 +318,8 @@ macro_rules! scalar_mul_impl(
|
||||||
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl $trhs<$n, $t<$n>> for $n {
|
impl $trhs<$n, $t<$n>> for $n {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, s: &$t<$n>) -> $t<$n> {
|
fn binop(left: &$t<$n>, right: &$n) -> $t<$n> {
|
||||||
$t::new(s.$comp0 * *self $(, s.$compN * *self)*)
|
$t::new(left.$comp0 * *right $(, left.$compN * *right)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -329,8 +329,8 @@ macro_rules! scalar_div_impl(
|
||||||
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl $trhs<$n, $t<$n>> for $n {
|
impl $trhs<$n, $t<$n>> for $n {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, s: &$t<$n>) -> $t<$n> {
|
fn binop(left: &$t<$n>, right: &$n) -> $t<$n> {
|
||||||
$t::new(s.$comp0 / *self $(, s.$compN / *self)*)
|
$t::new(left.$comp0 / *right $(, left.$compN / *right)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -340,8 +340,8 @@ macro_rules! scalar_add_impl(
|
||||||
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl $trhs<$n, $t<$n>> for $n {
|
impl $trhs<$n, $t<$n>> for $n {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, s: &$t<$n>) -> $t<$n> {
|
fn binop(left: &$t<$n>, right: &$n) -> $t<$n> {
|
||||||
$t::new(s.$comp0 + *self $(, s.$compN + *self)*)
|
$t::new(left.$comp0 + *right $(, left.$compN + *right)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -351,8 +351,8 @@ macro_rules! scalar_sub_impl(
|
||||||
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
($t: ident, $n: ident, $trhs: ident, $comp0: ident $(,$compN: ident)*) => (
|
||||||
impl $trhs<$n, $t<$n>> for $n {
|
impl $trhs<$n, $t<$n>> for $n {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn $trhs(&self, s: &$t<$n>) -> $t<$n> {
|
fn binop(left: &$t<$n>, right: &$n) -> $t<$n> {
|
||||||
$t::new(s.$comp0 - *self $(, s.$compN - *self)*)
|
$t::new(left.$comp0 - *right $(, left.$compN - *right)*)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue