#automatic #overloading #operator #implementation #macro

macro auto-impl-ops

semi-automatic implementation proc-macro for binary operations

5 releases

0.2.1 Mar 2, 2023
0.2.0 Feb 27, 2023
0.1.2 Feb 21, 2023
0.1.1 Nov 27, 2022
0.1.0 Jul 16, 2022

#8 in #overload

Download history 100/week @ 2024-07-25 88/week @ 2024-08-01 86/week @ 2024-08-08 98/week @ 2024-08-15 80/week @ 2024-08-22 109/week @ 2024-08-29 86/week @ 2024-09-05 85/week @ 2024-09-12 101/week @ 2024-09-19 121/week @ 2024-09-26 92/week @ 2024-10-03 103/week @ 2024-10-10 104/week @ 2024-10-17 96/week @ 2024-10-24 114/week @ 2024-10-31 62/week @ 2024-11-07

391 downloads per month
Used in 7 crates (4 directly)

AGPL-3.0-or-later

43KB
1K SLoC

semi-automatic implementation proc-macro for binary operations

#[auto_ops] make implementation for T += U, T + U, T + &U, &T + U, &T + &U from implementation for T += &U.

supported list (@ is +, -, *, /, %, &, |, ^, << or >>.)

  • T @= &U => T @= U, &T @ &U, &T @ U, T @ &U, T @ U
  • T @= U => T @= &U, &T @ &U, &T @ U, T @ &U, T @ U
  • &T @ &U => T @= &U, T @= U, &T @ U, T @ &U, T @ U
  • &T @ U => T @= &U, T @= U, &T @ &U, T @ &U, T @ U
  • T @ &U => T @= &U, T @= U, &T @ &U, &T @ U, T @ U
  • T @ U => T @= &U, T @= U, &T @ U, T @ &U, T @ U

Example

use std::ops::*;
# 
# #[derive(Clone, Default)]
# struct A<T>(T);

#[auto_impl_ops::auto_ops]
impl<M> AddAssign<&A<M>> for A<M>
where
    for<'x> &'x M: Add<Output = M>,
{
    fn add_assign(&mut self, other: &Self) {
        self.0 = &self.0 + &other.0;
    }
}

Above code is expanded into below code. For more examples see examples/a.rs.

use std::ops::*;
# 
# #[derive(Clone, Default)]
# struct A<T>(T);

impl<M> AddAssign<&A<M>> for A<M>
where
    for<'x> &'x M: Add<Output = M>,
{
    fn add_assign(&mut self, other: &Self) {
        self.0 = &self.0 + &other.0;
    }
}
#[allow(clippy::extra_unused_lifetimes)]
impl<M> AddAssign<A<M>> for A<M>
where
    for<'x> &'x M: Add<Output = M>,
{
    fn add_assign(&mut self, rhs: A<M>) {
        let rhs = &rhs;
        self.add_assign(rhs);
    }
}
impl<M> Add<&A<M>> for &A<M>
where
    for<'x> &'x M: Add<Output = M>,
    A<M>: Clone,
{
    type Output = A<M>;
    fn add(self, rhs: &A<M>) -> Self::Output {
        let mut lhs = self.clone();
        lhs.add_assign(rhs);
        lhs
    }
}
impl<M> Add<A<M>> for &A<M>
where
    for<'x> &'x M: Add<Output = M>,
    A<M>: Clone,
{
    type Output = A<M>;
    fn add(self, rhs: A<M>) -> Self::Output {
        let mut lhs = self.clone();
        let rhs = &rhs;
        lhs.add_assign(rhs);
        lhs
    }
}
impl<M> Add<&A<M>> for A<M>
where
    for<'x> &'x M: Add<Output = M>,
{
    type Output = A<M>;
    fn add(self, rhs: &A<M>) -> Self::Output {
        let mut lhs = self;
        lhs.add_assign(rhs);
        lhs
    }
}
#[allow(clippy::extra_unused_lifetimes)]
impl<M> Add<A<M>> for A<M>
where
    for<'x> &'x M: Add<Output = M>,
{
    type Output = A<M>;
    fn add(self, rhs: A<M>) -> Self::Output {
        let mut lhs = self;
        let rhs = &rhs;
        lhs.add_assign(rhs);
        lhs
    }
}

License

auto-impl-ops is AGPL-3.0-or-later. The code generated by this proc-macro is exception of AGPL. You can choose its license as you like.

Dependencies

~1.5MB
~38K SLoC