openalgebra 0.0.1

Rust linear algebra library for OpenCL
use super::af;
use std::ops::*;

use super::{Vector};

macro_rules! arith_func {
    ($type_name: ty, $op_name: ident, $fn_name: ident) => (
        impl<'a> $op_name<&'a $type_name> for &'a Vector {
            type Output = Vector;
            fn $fn_name(self, rhs: &$type_name) -> Self::Output {
                let rhs = Vector::from(rhs);
                Vector::from(af::$fn_name(&self.backend, &rhs.backend, false))
            }
        }

        impl $op_name<$type_name> for Vector {
            type Output = Vector;
            fn $fn_name(self, rhs: $type_name) -> Self::Output {
                let rhs = Vector::from(rhs);
                Vector::from(af::$fn_name(&self.backend, &rhs.backend, false))
            }
        }
    );
}

macro_rules! rem_func {
    ($type_name: ty, $op_name: ident, $fn_name: ident) => (
        impl<'a> $op_name<&'a $type_name> for &'a Vector {
            type Output = Vector;
            fn rem(self, rhs: &$type_name) -> Self::Output {
                let rhs = Vector::from(rhs);
                Vector::from(af::$fn_name(&self.backend, &rhs.backend, false))
            }
        }

        impl $op_name<$type_name> for Vector {
            type Output = Vector;
            fn rem(self, rhs: $type_name) -> Self::Output {
                let rhs = Vector::from(rhs);
                Vector::from(af::$fn_name(&self.backend, &rhs.backend, false))
            }
        }
    );
}

macro_rules! arith_func_type {
    ($type_name: ty) => (
        arith_func!($type_name, Add, add);
        arith_func!($type_name, Sub, sub);
        arith_func!($type_name, Div, div);
        arith_func!($type_name, Mul, mul);
        rem_func!($type_name, Rem, modulo);
    );
}

macro_rules! arith_assign_func {
    ($type_name: ty, $op_name: ident, $fn_name: ident, $base_name: ident) => (
        impl $op_name<$type_name> for Vector {
            fn $fn_name(&mut self, rhs: $type_name) {
                let rhs = Vector::from(rhs);
                *self = Vector::from(af::$base_name(&self.backend, &rhs.backend, false));
            }
        }
    );
}

macro_rules! arith_assign_func_type {
    ($type_name: ty) => (
        arith_assign_func!($type_name, AddAssign, add_assign, add);
        arith_assign_func!($type_name, SubAssign, sub_assign, sub);
        arith_assign_func!($type_name, DivAssign, div_assign, div);
        arith_assign_func!($type_name, MulAssign, mul_assign, mul);
        arith_assign_func!($type_name, RemAssign, rem_assign, rem);
    );
}

macro_rules! generate {
    ($type_name: ty) => (
        arith_func_type!($type_name);
        arith_assign_func_type!($type_name);
    )
}

generate!(Vector);
generate!(f64);

impl Neg for Vector {
    type Output = Vector;
    fn neg(self) -> Self::Output {
        Vector::from(-self.backend)
    }
}