#[macro_escape]; macro_rules! clone_impl( ($t:ident) => ( // FIXME: use 'Clone' alone. For the moment, we need 'Copy' because the automatic // implementation of Clone for [t, ..n] is badly typed. impl Clone for $t { fn clone(&self) -> $t { $t { at: copy self.at } } } ) ) macro_rules! deep_clone_impl( ($t:ident) => ( // FIXME: use 'DeepClone' alone. For the moment, we need 'Copy' because the automatic // implementation of DeepClone for [t, ..n] is badly typed. // XXX: this does not do a real deep clone impl DeepClone for $t { fn deep_clone(&self) -> $t { $t { at: copy self.at } } } ) ) macro_rules! new_impl( ($t: ident, $dim: expr) => ( impl $t { #[inline] pub fn new(at: [N, ..$dim]) -> $t { $t { at: at } } } ) ) macro_rules! indexable_impl( ($t: ident) => ( impl Indexable for $t { #[inline] pub fn at(&self, i: uint) -> N { self.at[i].clone() } #[inline] pub fn set(&mut self, i: uint, val: N) { self.at[i] = val } } ) ) macro_rules! new_repeat_impl( ($t: ident, $param: ident, [ $($elem: ident)|+ ]) => ( impl $t { #[inline] pub fn new_repeat($param: N) -> $t { $t{ at: [ $( $elem.clone(), )+ ] } } } ) ) macro_rules! iterable_impl( ($t: ident) => ( impl Iterable for $t { fn iter<'l>(&'l self) -> VecIterator<'l, N> { self.at.iter() } } ) ) macro_rules! iterable_mut_impl( ($t: ident) => ( impl IterableMut for $t { fn mut_iter<'l>(&'l mut self) -> VecMutIterator<'l, N> { self.at.mut_iter() } } ) ) macro_rules! eq_impl( ($t: ident) => ( impl Eq for $t { #[inline] fn eq(&self, other: &$t) -> bool { self.at.iter().zip(other.at.iter()).all(|(a, b)| a == b) } #[inline] fn ne(&self, other: &$t) -> bool { self.at.iter().zip(other.at.iter()).all(|(a, b)| a != b) } } ) ) macro_rules! dim_impl( ($t: ident, $dim: expr) => ( impl Dim for $t { #[inline] fn dim() -> uint { $dim } } ) ) // FIXME: add the possibility to specialize that macro_rules! basis_impl( ($t: ident, $dim: expr) => ( impl> Basis for $t { pub fn canonical_basis(f: &fn($t)) { for iterate(0u, $dim) |i| { let mut basis_element : $t = Zero::zero(); basis_element.at[i] = One::one(); f(basis_element); } } pub fn orthonormal_subspace_basis(&self, f: &fn($t)) { // compute the basis of the orthogonal subspace using Gram-Schmidt // orthogonalization algorithm let mut basis: ~[$t] = ~[]; for iterate(0u, $dim) |i| { let mut basis_element : $t = Zero::zero(); basis_element.at[i] = One::one(); if basis.len() == $dim - 1 { break; } let mut elt = basis_element.clone(); elt = elt - self.scalar_mul(&basis_element.dot(self)); for basis.iter().advance |v| { elt = elt - v.scalar_mul(&elt.dot(v)) }; if !elt.sqnorm().approx_eq(&Zero::zero()) { let new_element = elt.normalized(); f(new_element.clone()); basis.push(new_element); } } } } ) ) macro_rules! add_impl( ($t: ident) => ( impl> Add<$t, $t> for $t { #[inline] fn add(&self, other: &$t) -> $t { self.at.iter() .zip(other.at.iter()) .transform(|(a, b)| { *a + *b }) .collect() } } ) ) macro_rules! sub_impl( ($t: ident) => ( impl> Sub<$t, $t> for $t { #[inline] fn sub(&self, other: &$t) -> $t { self.at.iter() .zip(other.at.iter()) .transform(| (a, b) | { *a - *b }) .collect() } } ) ) macro_rules! neg_impl( ($t: ident) => ( impl> Neg<$t> for $t { #[inline] fn neg(&self) -> $t { self.at.iter().transform(|a| -a).collect() } } ) ) macro_rules! dot_impl( ($t: ident, $dim: expr) => ( impl Dot for $t { #[inline] fn dot(&self, other: &$t) -> N { let mut res = Zero::zero::(); for iterate(0u, $dim) |i| { res = res + self.at[i] * other.at[i]; } res } } ) ) macro_rules! sub_dot_impl( ($t: ident, $dim: expr) => ( impl SubDot for $t { #[inline] fn sub_dot(&self, a: &$t, b: &$t) -> N { let mut res = Zero::zero::(); for iterate(0u, $dim) |i| { res = res + (self.at[i] - a.at[i]) * b.at[i]; } res } } ) ) macro_rules! scalar_mul_impl( ($t: ident, $dim: expr) => ( impl> ScalarMul for $t { #[inline] fn scalar_mul(&self, s: &N) -> $t { self.at.iter().transform(|a| a * *s).collect() } #[inline] fn scalar_mul_inplace(&mut self, s: &N) { for iterate(0u, $dim) |i| { self.at[i] = self.at[i] * *s; } } } ) ) macro_rules! scalar_div_impl( ($t: ident, $dim: expr) => ( impl> ScalarDiv for $t { #[inline] fn scalar_div(&self, s: &N) -> $t { self.at.iter().transform(|a| a / *s).collect() } #[inline] fn scalar_div_inplace(&mut self, s: &N) { for iterate(0u, $dim) |i| { self.at[i] = self.at[i] / *s; } } } ) ) macro_rules! scalar_add_impl( ($t: ident, $dim: expr) => ( impl> ScalarAdd for $t { #[inline] fn scalar_add(&self, s: &N) -> $t { self.at.iter().transform(|a| a + *s).collect() } #[inline] fn scalar_add_inplace(&mut self, s: &N) { for iterate(0u, $dim) |i| { self.at[i] = self.at[i] + *s; } } } ) ) macro_rules! scalar_sub_impl( ($t: ident, $dim: expr) => ( impl> ScalarSub for $t { #[inline] fn scalar_sub(&self, s: &N) -> $t { self.at.iter().transform(|a| a - *s).collect() } #[inline] fn scalar_sub_inplace(&mut self, s: &N) { for iterate(0u, $dim) |i| { self.at[i] = self.at[i] - *s; } } } ) ) macro_rules! translation_impl( ($t: ident) => ( impl + Neg> Translation<$t> for $t { #[inline] fn translation(&self) -> $t { self.clone() } #[inline] fn inv_translation(&self) -> $t { -self } #[inline] fn translate_by(&mut self, t: &$t) { *self = *self + *t; } } ) ) macro_rules! translatable_impl( ($t: ident) => ( impl + Neg + Clone> Translatable<$t, $t> for $t { #[inline] fn translated(&self, t: &$t) -> $t { self + *t } } ) ) macro_rules! norm_impl( ($t: ident, $dim: expr) => ( impl Norm for $t { #[inline] fn sqnorm(&self) -> N { self.dot(self) } #[inline] fn norm(&self) -> N { self.sqnorm().sqrt() } #[inline] fn normalized(&self) -> $t { let mut res : $t = self.clone(); res.normalize(); res } #[inline] fn normalize(&mut self) -> N { let l = self.norm(); for iterate(0u, $dim) |i| { self.at[i] = self.at[i] / l; } l } } ) ) macro_rules! approx_eq_impl( ($t: ident) => ( impl> ApproxEq for $t { #[inline] fn approx_epsilon() -> N { ApproxEq::approx_epsilon::() } #[inline] fn approx_eq(&self, other: &$t) -> bool { let mut zip = self.at.iter().zip(other.at.iter()); do zip.all |(a, b)| { a.approx_eq(b) } } #[inline] fn approx_eq_eps(&self, other: &$t, epsilon: &N) -> bool { let mut zip = self.at.iter().zip(other.at.iter()); do zip.all |(a, b)| { a.approx_eq_eps(b, epsilon) } } } ) ) macro_rules! zero_impl( ($t: ident) => ( impl Zero for $t { #[inline] fn zero() -> $t { $t::new_repeat(Zero::zero()) } #[inline] fn is_zero(&self) -> bool { self.at.iter().all(|e| e.is_zero()) } } ) ) macro_rules! one_impl( ($t: ident) => ( impl One for $t { #[inline] fn one() -> $t { $t::new_repeat(One::one()) } } ) ) macro_rules! rand_impl( ($t: ident, $param: ident, [ $($elem: ident)|+ ]) => ( impl Rand for $t { #[inline] fn rand($param: &mut R) -> $t { $t::new([ $( $elem.gen(), )+ ]) } } ) ) macro_rules! from_any_iterator_impl( ($t: ident, $param: ident, [ $($elem: ident)|+ ]) => ( impl FromAnyIterator for $t { fn from_iterator<'l>($param: &mut VecIterator<'l, N>) -> $t { $t { at: [ $( $elem.next().unwrap().clone(), )+ ] } } fn from_mut_iterator<'l>($param: &mut VecMutIterator<'l, N>) -> $t { $t { at: [ $( $elem.next().unwrap().clone(), )+ ] } } } ) ) macro_rules! from_iterator_impl( ($t: ident, $param: ident, [ $($elem: ident)|+ ]) => ( impl> FromIterator for $t { fn from_iterator($param: &mut Iter) -> $t { $t { at: [ $( $elem.next().unwrap(), )+ ] } } } ) ) macro_rules! bounded_impl( ($t: ident) => ( impl Bounded for $t { #[inline] fn max_value() -> $t { $t::new_repeat(Bounded::max_value()) } #[inline] fn min_value() -> $t { $t::new_repeat(Bounded::min_value()) } } ) ) macro_rules! to_homogeneous_impl( ($t: ident, $t2: ident) => { impl ToHomogeneous<$t2> for $t { fn to_homogeneous(&self) -> $t2 { let mut res: $t2 = One::one(); for self.iter().zip(res.mut_iter()).advance |(in, out)| { *out = in.clone() } res } } } ) macro_rules! from_homogeneous_impl( ($t: ident, $t2: ident, $dim2: expr) => { impl + One + Zero> FromHomogeneous<$t2> for $t { fn from_homogeneous(v: &$t2) -> $t { let mut res: $t = Zero::zero(); for v.iter().zip(res.mut_iter()).advance |(in, out)| { *out = in.clone() } res.scalar_div(&v.at[$dim2 - 1]); res } } } )