gen_ops 0.4.0

Macros for operator overloading for generic types
Documentation
use gen_ops::*;

fn add_arr<const SZ:usize>(a: &[i32;SZ], b: &[i32;SZ]) -> [i32; SZ] {
    let mut ret = *a;
    for i in 0..SZ {
        ret[i] += b[i];
    }
    return ret;
}

fn add_assign_arr<const SZ:usize>(a: &mut [i32; SZ], b: &[i32;SZ]) {
    for i in 0..SZ {
        a[i] += b[i];
    }
}

fn neg_arr<const SZ:usize>(a: & [i32; SZ]) -> [i32; SZ] {
    let mut ret = [0; SZ];
    for i in 0..SZ {
        ret[i] = -a[i];
    }
    return ret;
}

mod const_gen_ncomm {
    use super::*;

    #[derive(Copy, Clone, Debug, PartialEq)]
    struct IntArray<const SZ: usize>( pub [i32; SZ] );

    gen_ops!(
        <| const SZ: usize>;
        types IntArray<SZ>, IntArray<SZ> => IntArray<SZ>;
        for + call |a: &IntArray<SZ>, b: &IntArray<SZ>| { IntArray(add_arr(&a.0, &b.0)) };
    );

    gen_ops!(
        <| const SZ: usize>;
        types IntArray<SZ>, IntArray<SZ> ;
        for += call |a: &mut IntArray<SZ>, b: &IntArray<SZ>| { add_assign_arr(&mut a.0, &b.0) };
    );

    gen_ops!(
        <| const SZ: usize>;
        types IntArray<SZ> => IntArray<SZ>;
        for - call |a: &IntArray<SZ>| { IntArray(neg_arr(&a.0)) };
    );

    #[test]
    fn ncomm_add_const_gen_test() {
        let a = IntArray([10, 20, 30]);
        let b = IntArray([5, 3, 2]);
        assert_eq!(a+b, IntArray([15, 23, 32]));
    }

    #[test]
    fn add_assign_const_gen_test() {
        let mut a = IntArray([10, 20, 30]);
        let b = IntArray([5, 3, 2]);
        a += b;
        assert_eq!(a, IntArray([15, 23, 32]));
    }

    #[test]
    fn neg_const_gen_test() {
        let a = IntArray([10, 20, 30]);
        let b = -a;
        assert_eq!(b, IntArray([-10, -20, -30]));
    }
}

mod const_gen_bin_comm {
    use super::*;

    #[derive(Copy, Clone, Debug, PartialEq)]
    struct IntArray<const SZ: usize>( pub [i32; SZ] );

    gen_ops_comm!(
        <| const SZ: usize>;
        types IntArray<SZ>, i32 => IntArray<SZ>;
        for + call |a: &IntArray<SZ>, b: &i32| { IntArray(add_arr(&a.0, &[*b; SZ])) };
    );

    #[test]
    fn comm_add_const_gen_test() {
        let a = IntArray([10, 20, 30]);
        assert_eq!(a+5, IntArray([15, 25, 35]));
        assert_eq!(5+a, IntArray([15, 25, 35]));
    }
}

mod const_gen_bin_ex {
    use super::*;

    #[derive(Copy, Clone, Debug, PartialEq)]
    struct IntArray<const SZ: usize>( pub [i32; SZ] );

    gen_ops_ex!(
        <| const SZ: usize>;
        types ref IntArray<SZ>, i32 => IntArray<SZ>;
        for + call |a: &IntArray<SZ>, b: &i32| { IntArray(add_arr(&a.0, &[*b; SZ])) };
    );

    #[test]
    fn ncomm_ex_add_const_gen_test() {
        let a = IntArray([10, 20, 30]);
        assert_eq!(a + 5, IntArray([15, 25, 35]));
        assert_eq!(&a + 5, IntArray([15, 25, 35]));
    }
}

mod const_gen_bin_comm_ex {
    use super::*;

    #[derive(Copy, Clone, Debug, PartialEq)]
    struct IntArray<const SZ: usize>( pub [i32; SZ] );

    gen_ops_comm_ex!(
        <| const SZ: usize>;
        types ref IntArray<SZ>, i32 => IntArray<SZ>;
        for + call |a: &IntArray<SZ>, b: &i32| { IntArray(add_arr(&a.0, &[*b; SZ])) };
    );

    #[test]
    fn comm_add_ex_const_gen_test() {
        let a = IntArray([10, 20, 30]);
        assert_eq!(a+5, IntArray([15, 25, 35]));
        assert_eq!(5+a, IntArray([15, 25, 35]));
        assert_eq!(&a+5, IntArray([15, 25, 35]));
        assert_eq!(5+&a, IntArray([15, 25, 35]));
    }
}

mod const_gen_asgn_ex {
    use super::*;

    #[derive(Copy, Clone, Debug, PartialEq)]
    struct IntArray<const SZ: usize>( pub [i32; SZ] );

    gen_ops_ex!(
        <| const SZ: usize>;
        types mut IntArray<SZ>, IntArray<SZ> ;
        for += call |a: &mut IntArray<SZ>, b: &IntArray<SZ>| { add_assign_arr(&mut a.0, &b.0) };
    );

    #[test]
    fn add_assign_ex_const_gen_test() {
        let mut x = IntArray([10, 20, 30]);
        {
            let mut a = x.clone();
            let b = IntArray([5, 3, 2]);
            a += b;
            assert_eq!(a, IntArray([15, 23, 32]));
        }
        {
            let mut a = &mut x;
            let b = IntArray([5, 3, 2]);
            a += b;
            assert_eq!(x, IntArray([15, 23, 32]));
        }
    }
}

mod const_gen_un_ex {
    use super::*;

    #[derive(Copy, Clone, Debug, PartialEq)]
    struct IntArray<const SZ: usize>( pub [i32; SZ] );

    gen_ops_ex!(
        <| const SZ: usize>;
        types mut IntArray<SZ> => IntArray<SZ>;
        for - call |a: &IntArray<SZ>| { IntArray(neg_arr(&a.0)) };
    );

    #[test]
    fn neg_const_gen_test() {
        let mut a = IntArray([10, 20, 30]);
        assert_eq!(-a, IntArray([-10, -20, -30]));
        {
            let b = &a;
            assert_eq!(-b, IntArray([-10, -20, -30]));
        }
        {
            let b = &mut a;
            assert_eq!(-b, IntArray([-10, -20, -30]));
        }
    }
}