Macro gen_ops

Source
macro_rules! gen_ops {
    ($(<$($($lt:lifetime),+)? $(,)? $($($gen:ident),+)? $(| $(const $C:ident : $Ct:ty),+)?>;)? types $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types $lhs:ty, $rhs:ty => $out:ty;$($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types &$lhs:ty, $rhs:ty => $out:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types $lhs:ty, &$rhs:ty => $out:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*);types &$lhs:ty, &$rhs:ty => $out:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types &mut $lhs:ty, $rhs:ty => $out:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types $lhs:ty, &mut $rhs:ty => $out:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types &mut $lhs:ty, &mut $rhs:ty => $out:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types &mut $lhs:ty, &$rhs:ty => $out:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types &$lhs:ty, &mut $rhs:ty => $out:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types $lhs:ty, $rhs:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types $lhs:ty, &$rhs:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types $lhs:ty, &mut $rhs:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types mut $lhs:ty, $rhs:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types mut $lhs:ty, &$rhs:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types mut $lhs:ty, &mut $rhs:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types $lhs:ty => $output:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types &$lhs:ty => $output:ty; $($rest:tt)+) => { ... };
    (@step1 ($($gen:tt)*); types &mut$lhs:ty => $output:ty; $($rest:tt)+) => { ... };
}
Expand description

The primary macro for all operators.

§Example

#[derive(Debug, Copy, Clone, PartialEq)]
struct Pair<T>(pub T, pub T);
 
gen_ops!(
    <T>;
    types Pair<T>, Pair<T> => Pair<T>;
    for + call |a: &Pair<T>, b: &Pair<T>| Pair(a.0 + b.0, a.1 + b.1);
    (where T: Add<Output=T>)

    for - call |a: &Pair<T>, b: &Pair<T>| Pair(a.0 - b.0, a.1 - b.1);
    (where T: Sub<Output=T>)
 
    where T: Copy
);
 
let a = Pair(10, 5);
let b = Pair(8, 9);
 
println!("a + b = {:?}", a + b); // a + b = Pair(18, 14)
println!("a - b = {:?}", a - b); // a - b = Pair(2, -4)

§Note

Type signatures supported for gen_ops! are

  • types Lhs, Rhs => Out; for binary
  • types Lhs, Rhs; for assignment
  • types Lhs => Out; for unary

Lhs and Rhs can be borrowed types except for assignment operators where Lhs cannot be immutably borrowed.

For unary and binary operators, the callable expressions must take immutable borrowed types as argument(s) and return the result of the Out type. And for assignment operators the callable expressions must take mutable borrowed type as first argument, take immutable borrowed type as second argument and return nothing;