#![macro_use] macro_rules! pointwise_mul( ($t: ident, $($compN: ident),+) => ( impl> Mul<$t> for $t { type Output = $t; #[inline] fn mul(self, right: $t) -> $t { $t::new($(self.$compN * right.$compN),+) } } impl> MulAssign<$t> for $t { #[inline] fn mul_assign(&mut self, right: $t) { $( self.$compN *= right.$compN; )+ } } ) ); macro_rules! pointwise_div( ($t: ident, $($compN: ident),+) => ( impl> Div<$t> for $t { type Output = $t; #[inline] fn div(self, right: $t) -> $t { $t::new($(self.$compN / right.$compN),+) } } impl> DivAssign<$t> for $t { #[inline] fn div_assign(&mut self, right: $t) { $( self.$compN /= right.$compN; )+ } } ) ); macro_rules! pointwise_add( ($t: ident, $($compN: ident),+) => ( impl> Add<$t> for $t { type Output = $t; #[inline] fn add(self, right: $t) -> $t { $t::new($(self.$compN + right.$compN),+) } } impl> AddAssign<$t> for $t { #[inline] fn add_assign(&mut self, right: $t) { $( self.$compN += right.$compN; )+ } } ) ); macro_rules! pointwise_sub( ($t: ident, $($compN: ident),+) => ( impl> Sub<$t> for $t { type Output = $t; #[inline] fn sub(self, right: $t) -> $t { $t::new($(self.$compN - right.$compN),+) } } impl> SubAssign<$t> for $t { #[inline] fn sub_assign(&mut self, right: $t) { $( self.$compN -= right.$compN; )+ } } ) ); macro_rules! pointwise_scalar_mul( ($t: ident, $($compN: ident),+) => ( impl> Mul for $t { type Output = $t; #[inline] fn mul(self, right: N) -> $t { $t::new($(self.$compN * right),+) } } impl> MulAssign for $t { #[inline] fn mul_assign(&mut self, right: N) { $( self.$compN *= right; )+ } } impl Mul<$t> for f32 { type Output = $t; #[inline] fn mul(self, right: $t) -> $t { $t::new($(self * right.$compN),+) } } impl Mul<$t> for f64 { type Output = $t; #[inline] fn mul(self, right: $t) -> $t { $t::new($(self * right.$compN),+) } } ) ); macro_rules! pointwise_scalar_div( ($t: ident, $($compN: ident),+) => ( impl> Div for $t { type Output = $t; #[inline] fn div(self, right: N) -> $t { $t::new($(self.$compN / right),+) } } impl> DivAssign for $t { #[inline] fn div_assign(&mut self, right: N) { $( self.$compN /= right; )+ } } ) ); macro_rules! pointwise_scalar_add( ($t: ident, $($compN: ident),+) => ( impl> Add for $t { type Output = $t; #[inline] fn add(self, right: N) -> $t { $t::new($(self.$compN + right),+) } } impl> AddAssign for $t { #[inline] fn add_assign(&mut self, right: N) { $( self.$compN += right; )+ } } impl Add<$t> for f32 { type Output = $t; #[inline] fn add(self, right: $t) -> $t { $t::new($(self + right.$compN),+) } } impl Add<$t> for f64 { type Output = $t; #[inline] fn add(self, right: $t) -> $t { $t::new($(self + right.$compN),+) } } ) ); macro_rules! pointwise_scalar_sub( ($t: ident, $($compN: ident),+) => ( impl> Sub for $t { type Output = $t; #[inline] fn sub(self, right: N) -> $t { $t::new($(self.$compN - right),+) } } impl> SubAssign for $t { #[inline] fn sub_assign(&mut self, right: N) { $( self.$compN -= right; )+ } } impl Sub<$t> for f32 { type Output = $t; #[inline] fn sub(self, right: $t) -> $t { $t::new($(self - right.$compN),+) } } impl Sub<$t> for f64 { type Output = $t; #[inline] fn sub(self, right: $t) -> $t { $t::new($(self - right.$compN),+) } } ) ); macro_rules! componentwise_neg( ($t: ident, $($compN: ident),+) => ( impl + Copy> Neg for $t { type Output = $t; #[inline] fn neg(self) -> $t { $t::new($(-self.$compN ),+) } } ) ); macro_rules! componentwise_repeat( ($t: ident, $($compN: ident),+) => ( impl Repeat for $t { fn repeat(val: N) -> $t { $t { $($compN: val ),+ } } } ) ); macro_rules! componentwise_absolute( ($t: ident, $($compN: ident),+) => ( impl> Absolute<$t> for $t { #[inline] fn abs(m: &$t) -> $t { $t::new($(::abs(&m.$compN) ),+) } } ) ); macro_rules! componentwise_zero( ($t: ident, $($compN: ident),+ ) => ( impl Zero for $t { #[inline] fn zero() -> $t { $t { $($compN: ::zero() ),+ } } #[inline] fn is_zero(&self) -> bool { $(::is_zero(&self.$compN) )&&+ } } ) ); macro_rules! componentwise_one( ($t: ident, $($compN: ident),+ ) => ( impl One for $t { #[inline] fn one() -> $t { $t { $($compN: ::one() ),+ } } } ) ); // Implements Arbitrary by setting each components to Arbitrary::arbitrary. macro_rules! componentwise_arbitrary( ($t: ident, $($compN: ident),+ ) => ( #[cfg(feature="arbitrary")] impl Arbitrary for $t { #[inline] fn arbitrary(g: &mut G) -> $t { $t { $($compN: Arbitrary::arbitrary(g),)* } } } ) ); // Implements Rand by setting each components to Rand::rand. macro_rules! componentwise_rand( ($t: ident, $($compN: ident),+ ) => ( impl Rand for $t { #[inline] fn rand(rng: &mut R) -> $t { $t { $($compN: Rand::rand(rng), )* } } } ) ); macro_rules! component_basis_element( ($t: ident, $($compN: ident),+ ) => ( /* * * Element of the canonical basis. * */ impl $t { $( /// Create the element of the canonical basis having this component set to one and /// all the others set to zero. #[inline] pub fn $compN() -> $t { let mut res: $t = ::zero(); res.$compN = ::one(); res } )+ } ) ); // A function to create a new element from its component values. macro_rules! component_new( ($t: ident, $($compN: ident),+) => ( impl $t { /// Creation from component values. #[inline] pub fn new($($compN: N ),+) -> $t { $t { $($compN: $compN ),+ } } } ); ); macro_rules! fold_add( // base case ($x:expr) => { $x }; // `$x` followed by at least one `$y,` ($x:expr, $($y:expr),+) => { // call min! on the tail `$y` Add::add($x, fold_add!($($y),+)) } );